Transfer Methods
Standard Transfer
Transfer tokens from the caller to a recipient:- Contract is not paused
- Recipient is not the zero address or another TIP-20 contract
- Caller has sufficient balance
- Both caller and recipient are authorized by the transfer policy
- To existing address: ~50,000 gas (0.1 cent)
- To new address: ~300,000 gas (0.6 cent, includes 250,000 gas state creation cost from TIP-1000)
Transfer From
Transfer tokens on behalf of another address using allowance:- Caller has sufficient allowance from
fromaddress - Allowance is decremented (unless set to
type(uint256).max)
- Similar to
transfer()plus ~5,000 gas for allowance update
Transfer With Memo
Transfer tokens with an attached 32-byte memo:- Adds ~5,000 gas to standard transfer for memo emission
- Memo is indexed, enabling efficient event filtering
Transfer From With Memo
Combines allowance-based transfer with memo attachment:- Payment processors spending on behalf of users
- Invoice payments with reference tracking
- Multi-party payment coordination
System Transfers
System Transfer From
Internal precompile-only transfer function:- Only callable by the FeeManager precompile (
0xfeeC000000000000000000000000000000000000) - Bypasses allowance checks
- Still enforces transfer policy authorization
Fee Management
TIP-20 integrates with the FeeManager precompile for transaction fee deduction:transferFeePreTxmoves estimated fee from user to FeeManager- Transaction executes
transferFeePostTxrefunds unused gas to user
- Pre-transfer moves funds without full transfer checks
- Post-transfer only refunds, minimizing gas overhead
- Emits
Transferevent for actual fee used
Transfer Authorization
All transfers check policy authorization via TIP-403:- Sender authorization checks if
fromcan send tokens - Recipient authorization checks if
tocan receive tokens - Allows asymmetric policies (e.g., vendor credits)
Protected Recipients
Transfers cannot be sent to:address(0)(burning must useburn()functions)- Other TIP-20 token contracts (prevents accidental token loss)
Pause State
When a token is paused, all transfer functions revert:transfer(),transferFrom()transferWithMemo(),transferFromWithMemo()mint(),burn()- Reward distribution and claims
approve()(setting allowances)permit()(gasless approvals)- View functions (balances, allowances)
Gas Cost Breakdown
Transfer to Existing Address
| Component | Gas Cost |
|---|---|
| Base transaction cost | ~21,000 |
| Transfer logic | ~24,000 |
| Balance updates (2 × SSTORE) | ~5,000 |
| Total | ~50,000 |
| Cost at baseline | 0.1 cent |
Transfer to New Address
| Component | Gas Cost |
|---|---|
| Base transaction cost | ~21,000 |
| Transfer logic | ~24,000 |
| New state element (balance) | 250,000 |
| Balance updates | ~5,000 |
| Total | ~300,000 |
| Cost at baseline | 0.6 cent |
First Transaction from New Account
| Component | Gas Cost |
|---|---|
| Base transaction cost | ~21,000 |
| Account creation (nonce 0→1) | 250,000 |
| Transfer logic | ~24,000 |
| Balance updates | ~5,000 |
| Total | ~300,000 |
| Cost at baseline | 0.6 cent |
- Receive tokens (new balance): ~300,000 gas (0.6 cent)
- First send (account creation): ~300,000 gas (0.6 cent)
- Total: ~600,000 gas (1.2 cent)
Transfer With Memo
| Component | Gas Cost |
|---|---|
| Standard transfer | ~50,000 or ~300,000 |
| Memo event emission | ~5,000 |
| Total | ~55,000 or ~305,000 |
Allowances
Approve
Set spending allowance for another address:Permit (EIP-2612)
Gasless approval via off-chain signature (TIP-1004):- No separate approval transaction needed
- User signs off-chain message
- Relayer or spender submits permit + action in one transaction
Reward Accounting
Transfers automatically update reward accounting for opted-in addresses:- Accrues pending rewards before balance changes
- Updates opted-in supply tracking
- No additional gas for non-opted-in transfers
- Opted-in transfers add ~10,000 gas
Error Conditions
Integration Example
Best Practices
Gas Optimization
- Use infinite approvals (
type(uint256).max) to save gas on repeated transfers - Batch transfers when possible to amortize transaction costs
- Use memos only when needed for reconciliation
- Consider permit for gasless approval flows
Error Handling
- Check token balance before attempting transfers
- Verify transfer policy authorization if known
- Handle paused state gracefully
- Use try/catch for external token transfers
Security
- Never transfer to computed addresses without validation
- Verify recipient is not another TIP-20 contract
- Check transfer success return value
- Consider reentrancy when transferring to contracts
See Also
- Memos - Payment references and reconciliation
- Compliance - Transfer policy integration
- TIP-1000 - State creation costs
- TIP-1015 - Directional authorization