---
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
---

# TIP-1035: Implicit Approval List

## Abstract

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.

## Motivation

Today, a user who wants to interact with the StablecoinDEX must first submit a separate `approve` call for each token. This has three costs:

1. **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.
2. **Gas cost**: Each `approve` call costs ~250,000 gas for the cold SSTORE to the allowance slot. Every subsequent `transferFrom` pays extra gas to load, check, and update the allowance.
3. **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.

## Assumptions

1. 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.
2. 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.
3. `system_transfer_from` already 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.

---

# Specification

## 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`

`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:

1. Verifies that the calling precompile is on the Implicit Approval List. If not, the call reverts.
2. Enforces TIP-403 transfer policies via `ensure_transfer_authorized`.
3. Enforces AccountKeychain spending limits via `check_and_update_spending_limit`.
4. Debits `from` and credits `to`. Reverts with `InsufficientBalance` if `from` has insufficient balance.
5. Emits a standard TIP-20 `Transfer(from, to, amount)` event.

### What is unchanged

- `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.
- `transferFrom` continues to check and decrement allowances as before for all callers.

## Discoverability

The AddressRegistry precompile MUST expose a hardfork-aware helper:

```solidity
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.

## Initial List

| 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 |

With this TIP activation, `StablecoinDEX` MUST switch from using `transfer_from` to `system_transfer_from`.

## Security Model

`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.

## Eligibility Guidelines

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.

1. **Caller-only pulls**: Every reachable code path that pulls tokens via `system_transfer_from` SHOULD use `from == msg.sender` for 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.

## Integrator Guidance

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.

## Future Amendments

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.

---

# Invariants

1. **Allowance bypass**: `system_transfer_from` MUST skip the allowance check and allowance decrement. All other checks — balance, TIP-403 transfer policies, AccountKeychain spending limits, and `Transfer` event emission — MUST still be enforced.
2. **List gating**: Only precompiles on the Implicit Approval List may call `system_transfer_from`. Calls from unlisted addresses MUST revert.
3. **Standard semantics preserved**: `approve`, `permit`, `allowance`, and `transferFrom` MUST behave identically to their pre-TIP-1035 TIP-20 semantics for all addresses, including listed precompiles.
4. **List discoverability**: `AddressRegistry.isImplicitlyApproved(addr)` MUST match the protocol-defined Implicit Approval List for the active hardfork.
5. **Hardfork gating**: The behavior change MUST be gated behind the TIP-1035 activation hardfork. Before activation, `system_transfer_from` access restrictions and `isImplicitlyApproved` are not active.
