fix: Tron USDT fix#1430
Conversation
| * a Tron-variant clone. | ||
| * @custom:security-contact [email protected] | ||
| */ | ||
| contract CounterfactualDepositSpokePoolTr is CounterfactualDepositSpokePool { |
There was a problem hiding this comment.
Tron network limits contract names to 32 characters. Contracts with names longer than that aren't deployable on the network - so had to truncate this one
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dcb782c336
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| /// even on successful transfers. | ||
| function _noRevertTransfer(address token, address to, uint256 amount) internal override returns (bool) { | ||
| (bool callOk, bool balanceOk) = TronTransferLib._balanceDeltaTransfer(token, to, amount); | ||
| return callOk && balanceOk; |
There was a problem hiding this comment.
Keep
_noRevertTransfer from misclassifying fee transfers
Returning callOk && balanceOk here treats fee-on-transfer/rebasing-style successful transfers as failures whenever the recipient balance does not increase by exactly amount. In the refund path, SpokePool._distributeRelayerRefunds() interprets that false as an unexecuted refund and credits relayerRefund[...] += refundAmount, so a relayer can receive tokens from the original transfer and still claim the full refund later, creating overpayment and pool accounting drift if such a token is ever routed on Tron.
Useful? React with 👍 / 👎.
Adds Tron-specific variants of SpokePool and the counterfactual contracts (CounterfactualDepositSpokePool, WithdrawImplementation) to handle Tron USDT's non-standard transfer, which moves balances correctly but always returns false — breaking SafeERC20.safeTransfer and the existing _noRevertTransfer return-value check.
Introduces a shared SafeTransferERC20 mixin in contracts/libraries/ exposing a virtual _safeTransfer hook (default: OZ safeTransfer); both the base SpokePool and the counterfactual contracts inherit from it. The Tron variants override the hook with a balance-delta success check (via TronTransferLib._safeTransferBalanceCheck for the counterfactual variants, inline in Tron_SpokePool), reverting with TronTransferFailed on genuine failure. transferFrom is correct on Tron USDT, so safeTransferFrom paths are unchanged, as are CCTP (USDC-only) and OFT (bridges USDT0, a compliant ERC20).
Tron_SpokePool extends Universal_SpokePool and overrides only _safeTransfer and _noRevertTransfer; CounterfactualDepositSpokePoolTron and WithdrawImplementationTron follow the same single-hook-override pattern. Includes deploy scripts and Foundry tests covering both the success path and genuine-failure paths (e.g. blacklisted recipient).
Re-deploys the changed contracts to Tron