| id | TIP-1035 |
|---|---|
| title | Implicit Approval List |
| description | Defines an in-protocol list of precompiles that may call system_transfer_from to pull TIP-20 tokens without requiring a prior approve() call. |
| authors | Dan Robinson |
| status | Draft |
| related | TIP-20, TIP-1022 |
| protocolVersion | T5 |
This TIP introduces a protocol-level Implicit Approval List: an explicit, enumerated set of precompile addresses that may pull TIP-20 tokens from a user via a system_transfer_from function that skips the allowance check. The list is hardfork-gated and discoverable on-chain. No changes are made to approve, permit, or allowance semantics.
Today, a user who wants to interact with the StablecoinDEX must first submit a separate approve call for each token. This has three costs:
- User experience: The first interaction with a given token requires two transactions (or a batch call). Wallets may have to prompt for approval before every new token interaction, adding friction.
- Gas cost: Each
approvecall costs ~250,000 gas for the cold SSTORE to the allowance slot. Every subsequenttransferFrompays extra gas to load, check, and update the allowance. - State bloat: Every approval writes a storage slot in the token's allowance mapping.
The approval check is redundant for contracts that only pull tokens from msg.sender — the caller is always the one authorizing the transaction, so the approve step provides no additional security.
Rather than adding approval-free pull behavior ad hoc to individual precompiles, the protocol should maintain an explicit, auditable list of precompiles authorized to call system_transfer_from. This makes the set visible in one place, simplifies future additions and removals, and gives integrators a canonical hardfork-aware query surface.
- Precompile code is part of the node implementation and is not executed via EVM opcodes. Concerns such as
DELEGATECALL, proxy patterns, and code mutability do not apply. - Listed precompiles are trusted protocol components whose token-pull logic has been reviewed. The security model depends on strict admission criteria and review of each listed precompile's code.
system_transfer_fromalready exists in the TIP-20 implementation as an internal function that transfers tokens without checking allowances. This TIP restricts its use to precompiles on the Implicit Approval List.
The protocol maintains an explicit set of addresses called the Implicit Approval List. Addresses on this list are authorized to call system_transfer_from on TIP-20 tokens.
system_transfer_from(from, to, amount) is not part of the TIP-20 contract interface. It is a special function only available to other precompiles within the node implementation — it cannot be called via the ABI or by external contracts. It transfers tokens without checking or updating allowances. It:
- Verifies that the calling precompile is on the Implicit Approval List. If not, the call reverts.
- Enforces TIP-403 transfer policies via
ensure_transfer_authorized. - Enforces AccountKeychain spending limits via
check_and_update_spending_limit. - Debits
fromand creditsto. Reverts withInsufficientBalanceiffromhas insufficient balance. - Emits a standard TIP-20
Transfer(from, to, amount)event.
approve(spender, amount)behaves exactly as specified by TIP-20 for all addresses, including listed precompiles.permit()behaves exactly as specified by TIP-20 for all addresses, including listed precompiles.allowance(owner, spender)returns the stored allowance value for all addresses, including listed precompiles.transferFromcontinues to check and decrement allowances as before for all callers.
The AddressRegistry precompile MUST expose a hardfork-aware helper:
function isImplicitlyApproved(address addr) external view returns (bool);This function returns true if and only if addr is on the Implicit Approval List for the active hardfork. Before TIP-1035 activates, it returns false for all addresses.
| Address | Contract | Rationale |
|---|---|---|
0xfeEC000000000000000000000000000000000000 |
TipFeeManager (FeeAMM) | Already relies on system_transfer_from for fee collection and liquidity operations |
0xDEc0000000000000000000000000000000000000 |
StablecoinDEX | Removes redundant approvals for DEX order placement and swap flows |
0x4D50500000000000000000000000000000000000 |
TIP20ChannelEscrow (MPP) | Removes redundant approvals for channel open and topUp escrow funding |
With this TIP activation, StablecoinDEX and TIP20ChannelEscrow MUST switch from using transfer_from to system_transfer_from.
system_transfer_from does not restrict the from parameter — a listed precompile could pass any address, not just msg.sender. The caller-only-pulls property is enforced by the listed precompile's own code, not by the implicit approval system. The security of this TIP therefore depends on strict admission criteria for the list and on review of each listed precompile's token-pull logic.
The following are security guidelines for adding a precompile to the Implicit Approval List. Precompiles that do not satisfy these guidelines may still be added, but the amendment TIP MUST include an explicit safety argument explaining why the alternative pattern is secure.
- Caller-only pulls: Every reachable code path that pulls tokens via
system_transfer_fromSHOULD usefrom == msg.senderfor the current call, or transfer with a non-replayable signed authorization from the transferor. Other patterns could theoretically be secure, but should be vetted with significantly more scrutiny.
Listed status is not a one-way ratchet. A future TIP MAY add or remove addresses from the Implicit Approval List.
Integrators with non-upgradeable flows who want compatibility across potential future list changes SHOULD query AddressRegistry.isImplicitlyApproved(spender) to branch on the current protocol state and determine whether the precompile path will skip approvals.
Additional precompiles may be added to or removed from the Implicit Approval List via future TIPs that reference and amend this one. Each addition should include a safety argument demonstrating that the precompile satisfies the eligibility guidelines above.
- Allowance bypass:
system_transfer_fromMUST skip the allowance check and allowance decrement. All other checks — balance, TIP-403 transfer policies, AccountKeychain spending limits, andTransferevent emission — MUST still be enforced. - List gating: Only precompiles on the Implicit Approval List may call
system_transfer_from. Calls from unlisted addresses MUST revert. - Standard semantics preserved:
approve,permit,allowance, andtransferFromMUST behave identically to their pre-TIP-1035 TIP-20 semantics for all addresses, including listed precompiles. - List discoverability:
AddressRegistry.isImplicitlyApproved(addr)MUST match the protocol-defined Implicit Approval List for the active hardfork. - Hardfork gating: The behavior change MUST be gated behind the TIP-1035 activation hardfork. Before activation,
system_transfer_fromaccess restrictions andisImplicitlyApprovedare not active.