[API-515] feat: add SafeTransferLibTron for Tron USDT compatibility#123
Open
[API-515] feat: add SafeTransferLibTron for Tron USDT compatibility#123
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Tron USDT's
transfer()returnsfalse(32 bytes of zeros) on success. Solady'ssafeTransfercheckseq(mload(0x00), 1)and reverts — making USDT transfers through our escrow settler impossible on Tron.approve()andtransferFrom()returntruecorrectly, so the fix replacessafeTransferwith an approve-then-transferFrom pattern via a new Tron-scoped library. All existing chains are unaffected.Linear: https://linear.app/lifi-linear/issue/API-515/handle-tron-usdt-broken-transfer-return-value-via-solady-transfer
Files touched
Ticket-named scope
src/libs/SafeTransferLib.tron.solSafeTransferLibTronlibrary;safeTransferchecks self-allowance via inline assembly and callssafeApproveWithRetry+safeTransferFromto bypasstransfer()src/input/escrow/InputSettlerEscrowLIFI.tron.solInputSettlerEscrowLIFITronextendsInputSettlerEscrowLIFI; overrides_resolveLock()to useSafeTransferLibTronin place of Solady'ssafeTransferat both the fee and destination transfer sitestest/mocks/MockUSDT.tron.solMockTronUSDTextends OIF'sMockERC20; overridestransfer()to execute normally but returnfalsetest/libs/SafeTransferLib.tron.t.solsafeTransferreverts withTransferFailedon the mocktest/input/escrow/InputSettlerEscrowLIFI.tron.t.solInputSettlerEscrowLIFITronTestextends OIF'sInputSettlerEscrowTest(24 inherited tests pass withMockTronUSDT); adds fee-distribution and no-fee casesOut-of-ticket-scope
src/input/escrow/InputSettlerEscrowLIFI.sol—_domainName()madevirtualInputSettlerEscrowLIFI.tron.solto override and set a distinct EIP712 domain ("OIFEscrowLIFITron"), preventing cross-chain signature replaysnapshots/inputSettler.json— gas snapshots updatedforge test; new Tron test snapshots addedOut of scope (untouched, per ticket)
InputSettlerCompactLIFI— ticket notes it "may need similar treatment if it ever does direct transfers on Tron"; it currently uses ERC6909batchClaim, no direct ERC20 transfersHow it works
SafeTransferLibTron.safeTransferavoids callingtransfer()entirely. It reads self-allowance via a memory-safe assemblystaticcalltoallowance(self, self), approvestype(uint256).maxif needed (viasafeApproveWithRetry, which handles the reset-to-zero pattern), then callssafeTransferFrom(self, to, amount). BothapproveandtransferFromreturntrueon Tron USDT, so all Solady checks pass.How to validate
forge build— cleanforge test— 77/77 passInputSettlerEscrowLIFITronto Tron testnet, submit an order with USDT, confirm_resolveLockexecutes without revertRisk & rollback
InputSettlerEscrowLIFITronis a new contract; existing deployments on all other chains useInputSettlerEscrowLIFIand are untouched. No rollback needed for non-Tron chains.