Smart Contract Security

ERC-20 Token Security: Common Pitfalls That Cost Projects Everything

Kennedy OwiroDecember 29, 20259 min read

The ERC-20 standard is DeFi's lingua franca — but it's also a minefield. Fee-on-transfer tokens break lending protocols. Rebasing tokens corrupt vault accounting. The approve/transferFrom pattern enables frontrunning attacks. And hundreds of tokens deviate from the standard in ways that silently break integrations. If your protocol handles ERC-20 tokens, you need to know these pitfalls.

1. Approval Frontrunning (The Double-Spend)

When a user calls approve(spender, newAmount), a frontrunner can spend the old allowance AND the new one in the same block.

// Attack scenario:
// Alice approved Bob for 100 tokens
// Alice calls approve(Bob, 50) to reduce allowance
// Bob frontruns: transferFrom(Alice, Bob, 100) using old allowance
// Alice's tx executes: approve(Bob, 50)
// Bob calls: transferFrom(Alice, Bob, 50) using new allowance
// Total stolen: 150 tokens instead of 50

// SOLUTION: Use increaseAllowance/decreaseAllowance
// Or: Set to 0 first, then set new amount in separate tx

2. Fee-on-Transfer Tokens

Some tokens (STA, PAXG, certain deflationary tokens) deduct a fee on every transfer. If your contract expects to receive exactly the amount transferred, accounting will be wrong.

// VULNERABLE: Assumes received amount == transferred amount
function deposit(uint256 amount) external {
    token.transferFrom(msg.sender, address(this), amount);
    balances[msg.sender] += amount;  // Overstated if token has transfer fee!
}

// SECURE: Check actual received amount
function deposit(uint256 amount) external {
    uint256 before = token.balanceOf(address(this));
    token.transferFrom(msg.sender, address(this), amount);
    uint256 received = token.balanceOf(address(this)) - before;
    balances[msg.sender] += received;
}

3. Rebasing Tokens

Tokens like stETH and AMPL change balances automatically. Vault contracts that cache balances will have stale accounting. Use wrapped versions (wstETH) in DeFi protocols.

4. Non-Standard Return Values

USDT, BNB, and ~300+ tokens don't follow the standard bool return on transfer(). Always use OpenZeppelin's SafeERC20 library.

5. Tokens with Hooks (ERC-777)

ERC-777 tokens have tokensReceived callbacks that can trigger reentrancy. Multiple DeFi protocols were drained by ERC-777 reentrancy.

ERC-20 Integration Checklist

  • ✅ Use SafeERC20 for all token operations
  • ✅ Check actual received balance for fee-on-transfer support
  • ✅ Use wrapped versions of rebasing tokens
  • ✅ Guard against ERC-777 reentrancy with nonReentrant
  • ✅ Handle tokens with >18 and <18 decimals
  • ✅ Test with USDT, USDC, WBTC, stETH, and deflationary tokens

How Vultbase Detects ERC-20 Issues

  1. Pattern DB — 32 ERC-20 integration patterns covering all non-standard behaviors
  2. Static Analysis — Flags missing SafeERC20, unchecked returns, and balance assumptions
  3. DeFi Challenge — Tests with adversarial token implementations

ERC-20 compatibility is harder than it looks. Audit your token integration before one non-standard token breaks everything.

ERC-20token securityapprovalfee-on-transferrebasingSolidity
Share

Written by

Kennedy Owiro

Founder & CTO, Vultbase

14+ years building security and QA systems at scale. Background in fintech security and Web3 smart contract testing. Built Vultbase's Intelligence Engine with 1,200+ exploit patterns from $40B+ in historical DeFi losses.

Protect your protocol before launch.

Submit your smart contracts for automated security analysis powered by 1,200+ real exploit patterns.

Start Your Audit →