Critical security flaws in token contracts that attackers exploit to drain funds or manipulate protocol logic.
Exploitable Patterns in Token Contract Implementations
Core Vulnerability Categories
Access Control Flaws
Privilege escalation occurs when functions lack proper permission checks, allowing unauthorized users to perform admin actions.\n\n- Missing onlyOwner modifiers on critical functions like mint or pause.\n- Using tx.origin for authorization, which can be manipulated via a malicious contract.\n- This matters because it can lead to unlimited token minting or protocol shutdown by any user.
Arithmetic Issues
Integer overflows and underflows happen when arithmetic operations exceed a variable's storage limits, causing wrap-around behavior.\n\n- An unchecked balance - amount can underflow, granting a huge balance.\n- Batch transfer loops that miscalculate total sums can be exploited.\n- This matters as it can create tokens from nothing or lock user funds unexpectedly.
Reentrancy Attacks
State inconsistency is exploited by malicious contracts that call back into a vulnerable function before its state updates are complete.\n\n- The classic pattern involves a withdraw function that updates balances after sending ETH.\n- ERC-777 tokensReceived hooks can facilitate reentrancy in token contracts.\n- This matters because it allows attackers to drain contracts multiple times per transaction.
Logic & Business Rule Flaws
Incorrect validation of business rules or token economics can be manipulated for profit.\n\n- Fee-on-transfer tokens where the contract assumes a 1:1 transfer ratio.\n- Vesting contracts with flawed time-lock logic allowing early withdrawals.\n- This matters as it breaks core protocol assumptions, leading to unfair advantage or loss.
Oracle Manipulation
Price feed attacks target contracts that rely on external data sources for critical valuations.\n\n- Using a single DEX pool's spot price, which can be skewed with a flash loan.\n- Lack of circuit breakers or time-weighted average prices (TWAP).\n- This matters for lending protocols and synthetic assets, as it enables undercollateralized borrowing.
ERC Standard Non-Compliance
Deviations from expected behavior in ERC-20, ERC-721, or ERC-1155 can break integrations.\n\n- Returning false instead of reverting on failed transfers (non-standard).\n- Fee-on-transfer or rebasing tokens that cause balance discrepancies.\n- This matters because wallets, DEXs, and other contracts may handle tokens incorrectly, leading to locked funds.
Vulnerabilities by Token Standard
Common Implementation Flaws
ERC-20 is the foundational token standard, but its simplicity leads to exploitable patterns. The approve/transferFrom mechanism is a primary attack vector. A common mistake is failing to handle the race condition where a user changes an approval from 5 to 3 tokens, but an attacker front-runs the transaction to spend the original 5 before the reduction takes effect. This is mitigated by first setting approval to zero before setting a new value, a pattern now enforced by many wallets.
Critical Vulnerabilities
- Incorrect balance updates: Early implementations sometimes updated balances before checking for sufficient funds, leading to integer underflows.
- Missing return value checks: Not all ERC-20 tokens properly implement the
boolreturn value; integrations that don't check it can fail silently. - Fee-on-transfer tokens: Tokens like STAKE deduct a fee on transfer, causing integrations like Uniswap pools to miscalculate input/output amounts if they assume the received balance equals the sent amount.
Example
A lending protocol like Compound that accepts any ERC-20 as collateral must explicitly handle fee-on-transfer tokens, or an attacker could deposit them and instantly borrow more than the net collateral received by the contract.
Methodology for Identifying Exploits
A systematic process for analyzing token contracts to uncover vulnerabilities.
Establish the Contract Context
Gather and analyze foundational contract information.
Detailed Instructions
Begin by obtaining the verified source code and ABI for the target token contract from a block explorer like Etherscan. Decompile the bytecode using tools like panoramix if source is unavailable. Identify the token standard (e.g., ERC-20, ERC-721) and map out the inheritance hierarchy and key dependencies, such as imported libraries or proxy implementations. Review the contract's creation and recent transaction history to understand its deployment context and typical usage patterns.
- Sub-step 1: Retrieve contract address and source from Etherscan or Blockscout.
- Sub-step 2: Examine the constructor arguments and initial state setup.
- Sub-step 3: Catalog all public and external functions listed in the ABI.
- Sub-step 4: Note any admin or owner privileges and associated addresses.
solidity// Example: Checking for a common proxy pattern storage slot bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
Tip: Use
cast code <ADDRESS>from Foundry to fetch bytecode directly for analysis.
Analyze State Variable Layout and Access
Examine storage variables for unsafe visibility or incorrect mappings.
Detailed Instructions
Manually audit the declaration and usage of all state variables. Critical vulnerabilities often arise from public variables that should be private or internal, such as mapping structures storing balances or allowances. Scrutinize the storage layout for potential collisions, especially in upgradeable contracts using unstructured storage proxies. Verify that sensitive mappings (e.g., mapping(address => uint256) private _balances;) are indeed private and that any public getters do not expose unintended data. Check for the use of packed storage variables and ensure bit-level operations are safe from overflows.
- Sub-step 1: List all state variables and their visibility modifiers.
- Sub-step 2: Trace read/write access for each variable across all functions.
- Sub-step 3: Identify any
publicmappings or arrays that could be manipulated. - Sub-step 4: Use
slither-check-ercto detect standard conformance issues.
solidity// Vulnerable example: Public mapping exposing internal logic mapping(address => uint256) public customBalances; // Risk: External writes may be possible.
Tip: Tools like
hevmcan interactively explore storage layouts for a given contract.
Trace External Call Flows and Reentrancy Vectors
Map all interactions with external addresses and contracts.
Detailed Instructions
Identify every call, delegatecall, staticcall, and external contract interaction (e.g., IERC20.transfer). The checks-effects-interactions pattern must be validated for each function. Manually trace the flow of execution to spot classic reentrancy vulnerabilities where state changes occur after an external call. Pay special attention to low-level .call{value:}() operations and functions that transfer tokens or ETH. Assess the trust assumptions of any integrated protocols or oracles; a malicious token contract received in a swap could callback into your function.
- Sub-step 1: Use
slitherto generate a function call graph and identify external calls. - Sub-step 2: For each state-changing function, verify state updates happen before any external call.
- Sub-step 3: Check for use of
nonReentrantmodifiers or equivalent mutex locks. - Sub-step 4: Review
approve/transferFromflows for ERC-20 race conditions.
solidity// Example: Checking for unsafe call pattern function withdraw() public { (bool success, ) = msg.sender.call{value: address(this).balance}(""); // Interaction FIRST require(success); balances[msg.sender] = 0; // Effects AFTER - VULNERABLE }
Tip: Fuzz tests in Foundry can simulate malicious contracts re-entering your functions.
Audit Arithmetic Operations and Token Supply Logic
Review all mathematical operations for overflow/underflow and supply manipulation.
Detailed Instructions
Examine every arithmetic operation involving +, -, *, ++, --, and += or -=. While Solidity 0.8+ has default overflow checks, inline assembly or older compilers require manual SafeMath verification. Pay critical attention to the total supply mechanism in mintable/burnable tokens; an attacker may mint unlimited tokens if access control is flawed. Verify that functions like _mint and _burn correctly update both the recipient/destroyer balance and the _totalSupply state variable. Check for rounding errors in fee calculations or rebase logic that could be exploited over multiple transactions.
- Sub-step 1: Use
slitherwith the--detect overflowflag to flag risky operations. - Sub-step 2: Manually verify the logic in
mintandburnfunctions for proper access control and supply updates. - Sub-step 3: Audit any fee-on-transfer or tax logic for discrepancies between transferred and received amounts.
- Sub-step 4: Check for division before multiplication, which can lead to significant rounding down.
solidity// Example: Safe arithmetic using Solidity 0.8+ function transfer(address to, uint256 amount) public returns (bool) { _balances[msg.sender] -= amount; // Built-in overflow check _balances[to] += amount; return true; }
Tip: Write invariant tests asserting
totalSupply()always equals the sum of all balances.
Simulate Attack Vectors with Unit and Fuzz Testing
Construct and execute targeted tests to validate findings.
Detailed Instructions
Translate identified suspicious patterns into executable test cases using a framework like Foundry. Fuzz testing is essential for uncovering edge cases in input validation and state transitions. Write tests that simulate an attacker's actions: for example, a contract that re-enters during a transfer, or a user who front-runs an approve transaction. Use forge test --match-contract <TestName> -vvv for detailed traces. Create invariant tests (forge invariant) to check that core properties (e.g., totalSupply conservation) hold under random sequences of calls. Compare the contract's behavior against the official EIP specification.
- Sub-step 1: For each potential vulnerability, write a
testFailortest_Exploitfunction. - Sub-step 2: Use
vm.prankandvm.dealto simulate attacks from malicious addresses. - Sub-step 3: Fuzz function parameters with
@invariantand@fuzzannotations. - Sub-step 4: Run differential fuzzing against a known-correct reference implementation.
solidity// Foundry test example for reentrancy function test_ReentrancyExploit() public { VulnerableToken token = new VulnerableToken(); AttackerContract attacker = new AttackerContract(address(token)); token.deposit{value: 1 ether}(); attacker.attack(); // Should fail if reentrancy guard works }
Tip: Leverage Foundry's
cheatcodesto warp time, modify storage, and impersonate users for comprehensive testing.
Historical Exploit Case Studies
Analysis of major token contract vulnerabilities and their outcomes.
| Vulnerability Type | Exploit Case | Primary Vector | Loss Amount (USD) | Root Cause |
|---|---|---|---|---|
Incorrect Fee-on-Transfer Logic | Fei Protocol Rari Fuse (2022) | Balance accounting error in | 80 million | Fee-on-transfer token integration without adjusting for deducted fees |
Reentrancy on ERC-777 tokens | Uniswap/Lendf.Me (2020) | ERC-777 | 25 million | Reentrant call during balance update in a non-reentrant guard function |
Incorrect ERC20 | Bondly Finance (2021) | Proxy storage collision | 5.8 million | Uninitialized proxy contract storing |
Signature Replay Across Forks | SushiSwap MISO (2021) | ERC20Permit signature reuse | 3 million | Missing chain ID validation in permit message hashing |
Flash Loan Price Manipulation | Harvest Finance (2020) | Oracle price manipulation via Curve pool | 34 million | Reliance on a single DEX pool's spot price for value calculations |
Insufficient Access Control on | PolyNetwork (2021) | Unverified | 611 million | Missing owner/role validation on critical functions in a cross-chain contract |
Integer Overflow in | BEC Token (2018) | Batch transfer overflow | Vast supply inflation | Lack of SafeMath or compiler >=0.8; |
Mitigation Strategies and Secure Patterns
Further Reading and Tools
Ready to Start Building?
Let's bring your Web3 vision to life.
From concept to deployment, ChainScore helps you architect, build, and scale secure blockchain solutions.