Background
ERC-3009 lets a token holder authorize a transfer with an off-chain EIP-712 signature that any third party (a relayer) can submit on-chain and pay fees for — enabling gasless token transfers. It defines transferWithAuthorization, receiveWithAuthorization, and cancelAuthorization. transferWithAuthorization and receiveWithAuthorization use distinct EIP-712 primary types: a transferWithAuthorization signature can be submitted by anyone, while receiveWithAuthorization binds the payee path and additionally requires to == msg.sender (mitigating front-running of the relayed call). Transfer/receive authorizations carry validAfter/validBefore time bounds and use random 32-byte nonces (not sequential), so they can be created and redeemed out of order / in parallel; cancelAuthorization signs only authorizer + nonce (no time window). It is the mechanism behind Circle's USDC gasless transfers.
It differs from the permit pattern (TIP-2612): permit sets an allowance (still needing a later transferFrom) with sequential nonces, whereas ERC-3009 performs the transfer itself by signature with random nonces. Stablecoin transfers dominate TRON usage and "holds tokens but no TRX for fees" is a common friction point, so we propose to track ERC-3009 and introduce it to TRON as a TIP (proposed TIP-3009), as an extension for TIP-20 tokens — a token-level building block for gasless transfers that complements TIP-2612 (permit) and TRC-2771 (#852) (meta-transaction forwarding).
Scope
- Follow ERC-3009's functions and EIP-712 typed-data definitions as closely as possible.
- Apply to TIP-20 tokens (not native TRX or TRC-10).
- Provide TRON-specific guidance only where TIP-712, address encoding, or the resource model requires clarification.
Compatibility Topics for Discussion
- Positioning within TRON's gasless stack. TRON would then have three related primitives — TIP-2612 (permit, allowance-by-signature), TRC-2771 (forwarded meta-tx), TRC-3009 (direct signed transfer). How builders should choose among them, and whether there is redundancy to call out or they are complementary (3009 for direct payments, 2612 for approving contracts, 2771 for arbitrary calls).
- Relayer economics on TRON. "Gasless" means the relayer pays energy/bandwidth (staked or burned TRX), as discussed for TRC-2771 (#852). Note that ERC-3009 itself has no fee field or relayer-recipient parameter, so any relayer compensation (fee skimmed from the token, off-chain payment, sponsored service) is an application-layer/wrapper concern, not part of the standard — this should be a non-normative note. Whether TRON's regenerating-energy model makes high-throughput relayers cheaper at scale is also worth a non-normative note.
- TIP-712 domain, address encoding, and replay protection. The authorization is an EIP-712 signed message. A complete TRON domain should bind
name, version, TIP-712 chainId (block.chainid & 0xffffffff), and verifyingContract — chainId alone cannot prevent replay between two 3009 contracts on the same network. Addresses are encoded as the 20-byte form after stripping the 0x41 prefix (per TIP-712 / TIP-2612), while wallets may display Base58Check; the random 32-byte-nonce semantics and the authorizationState view should be preserved exactly, and validAfter/validBefore evaluated against TVM block.timestamp.
receiveWithAuthorization front-running on TRON. Since transferWithAuthorization signatures are submittable by anyone, receiveWithAuthorization (distinct primary type, to == msg.sender) exists to let a payee claim safely. TRON's Super Representative block production does not remove the front-running risk (nodes/observers can still replay a transferWithAuthorization), so both functions should be included for parity.
- Signature verification on TVM. Whether the TVM
ecrecover precompile recovers EIP-712 signatures identically, and the standard's known edge cases must be handled: malformed signatures returning address(0), low-s/v normalization, and an authorizer != address(0) check (cf. the permit warnings in TIP-2612). Wallets must sign TIP-712 typed data without TRON-specific message prefixes that would break verification. Whether secp256r1/passkey signing is in scope: TIP-7951 (#785) verifies a P-256 signature against an explicit public key (it does not recover an address like ecrecover), so the core 3009 should stay secp256k1/TIP-712 and any passkey variant needs a separate signer-binding model.
- Adoption by existing stablecoins (open). Already-deployed token code/ABI cannot be extended in place unless the token was designed with proxy-style upgrade dispatch — so for major TRON stablecoins (e.g., USDT) adoption realistically targets new tokens, future token versions, or a future/new official USDC deployment. Whether the TIP should recommend ERC-3009 as a default extension for new TIP-20 stablecoins.
References
Background
ERC-3009 lets a token holder authorize a transfer with an off-chain EIP-712 signature that any third party (a relayer) can submit on-chain and pay fees for — enabling gasless token transfers. It defines
transferWithAuthorization,receiveWithAuthorization, andcancelAuthorization.transferWithAuthorizationandreceiveWithAuthorizationuse distinct EIP-712 primary types: atransferWithAuthorizationsignature can be submitted by anyone, whilereceiveWithAuthorizationbinds the payee path and additionally requiresto == msg.sender(mitigating front-running of the relayed call). Transfer/receive authorizations carryvalidAfter/validBeforetime bounds and use random 32-byte nonces (not sequential), so they can be created and redeemed out of order / in parallel;cancelAuthorizationsigns onlyauthorizer + nonce(no time window). It is the mechanism behind Circle's USDC gasless transfers.It differs from the permit pattern (TIP-2612): permit sets an allowance (still needing a later
transferFrom) with sequential nonces, whereas ERC-3009 performs the transfer itself by signature with random nonces. Stablecoin transfers dominate TRON usage and "holds tokens but no TRX for fees" is a common friction point, so we propose to track ERC-3009 and introduce it to TRON as a TIP (proposed TIP-3009), as an extension for TIP-20 tokens — a token-level building block for gasless transfers that complements TIP-2612 (permit) and TRC-2771 (#852) (meta-transaction forwarding).Scope
Compatibility Topics for Discussion
name,version, TIP-712chainId(block.chainid & 0xffffffff), andverifyingContract—chainIdalone cannot prevent replay between two 3009 contracts on the same network. Addresses are encoded as the 20-byte form after stripping the0x41prefix (per TIP-712 / TIP-2612), while wallets may display Base58Check; the random 32-byte-nonce semantics and theauthorizationStateview should be preserved exactly, andvalidAfter/validBeforeevaluated against TVMblock.timestamp.receiveWithAuthorizationfront-running on TRON. SincetransferWithAuthorizationsignatures are submittable by anyone,receiveWithAuthorization(distinct primary type,to == msg.sender) exists to let a payee claim safely. TRON's Super Representative block production does not remove the front-running risk (nodes/observers can still replay atransferWithAuthorization), so both functions should be included for parity.ecrecoverprecompile recovers EIP-712 signatures identically, and the standard's known edge cases must be handled: malformed signatures returningaddress(0), low-s/vnormalization, and anauthorizer != address(0)check (cf. the permit warnings in TIP-2612). Wallets must sign TIP-712 typed data without TRON-specific message prefixes that would break verification. Whether secp256r1/passkey signing is in scope: TIP-7951 (#785) verifies a P-256 signature against an explicit public key (it does not recover an address likeecrecover), so the core 3009 should stay secp256k1/TIP-712 and any passkey variant needs a separate signer-binding model.References