Open
Conversation
Implements comprehensive helper system for testing protocols against non-standard ERC20 token behaviors. Addresses GitHub issue crytic#20. ## Overview Creates `ERC20EdgeCases` helper that deploys 20 different ERC20 token implementations, each exhibiting specific non-standard behaviors found in real tokens. This enables developers to test their protocols (DEXs, vaults, lending platforms) against all known ERC20 edge cases with a single import. ## Created Files (23 total) ### Core Helper (1 file) - **ERC20EdgeCases.sol**: Main helper contract that deploys all tokens and provides accessor functions: - `all_erc20()` - returns all 20 token addresses - `all_erc20_standard()` - returns only standard-compliant tokens - `all_erc20_non_standard()` - returns only non-standard tokens - `tokenByName(string)` - get specific token by name (e.g., "USDT-like") - Category helpers: `tokens_with_fee()`, `tokens_reentrant()`, etc. ### Token Implementations (20 files) Each token is a complete, working ERC20 with one specific edge case behavior: **Missing Return Values:** - MissingReturns.sol - No return value (USDT, BNB, OMG) - ReturnsFalse.sol - Returns false on success (Tether Gold) **Fee on Transfer:** - TransferFee.sol - Charges fee on transfer (STA, PAXG) - caused $500k Balancer drain **Reentrant Callbacks:** - Reentrant.sol - ERC777-style hooks (AMP, imBTC) - caused Uniswap/lendf.me drains **Admin Controls:** - BlockList.sol - Admin blocklist (USDC, USDT) - Pausable.sol - Admin pause (BNB, ZIL) **Transfer Quirks:** - RevertZero.sol - Reverts on zero transfers (LEND) - RevertToZero.sol - Reverts on transfer to address(0) (OpenZeppelin) - NoRevert.sol - Returns false instead of reverting (ZRX, EURS) - TransferFromSelf.sol - Doesn't decrease allowance if from == msg.sender (DSToken, WETH) - TransferMax.sol - Transfers full balance if amount == max uint256 (cUSDCv3) **Approval Quirks:** - ApprovalRaceProtection.sol - Can't change non-zero allowance (USDT, KNC) - ApprovalToZeroAddress.sol - Reverts on approve(address(0), amt) (OpenZeppelin) - RevertZeroApproval.sol - Reverts on approve(spender, 0) (BNB) - Uint96.sol - Reverts if amount >= 2^96 (UNI, COMP) **Metadata Quirks:** - Bytes32Metadata.sol - name/symbol as bytes32 (MKR) - LowDecimals.sol - 6 decimals (USDC) or 2 decimals (Gemini USD) - HighDecimals.sol - 24 decimals (YAM-V2) **Permit Issues:** - PermitNoOp.sol - permit() doesn't revert but does nothing (WETH) - caused Multichain hack **Baseline:** - StandardERC20.sol - Compliant implementation for comparison ### Documentation (1 file) - **README.md**: Comprehensive guide covering: - All 20 token types with real-world examples - Usage patterns and best practices - Real exploits that would have been prevented - Integration with Echidna/Medusa - Code examples for common testing scenarios ### Example Test Harness (1 file) - **tests/ERC20EdgeCases/ExampleVaultTest.sol**: Complete example showing: - Testing vault with all token types - Testing specific edge cases (fee tokens, reentrant tokens) - Proper accounting that handles fee-on-transfer - SafeERC20-style handling of missing return values - Example vault implementation with correct edge case handling ## Usage ```solidity import "@crytic/properties/contracts/util/erc20/ERC20EdgeCases.sol"; contract MyProtocolTest { ERC20EdgeCases edgeCases; constructor() { edgeCases = new ERC20EdgeCases(); } function test_protocolWithAllTokens() public { address[] memory tokens = edgeCases.all_erc20(); for (uint i = 0; i < tokens.length; i++) { // Test your protocol with each token } } } ``` ## Real-World Exploits Prevented This helper would have caught: - **Balancer STA Exploit (2020)**: $500k drained via fee-on-transfer tokens - **imBTC Uniswap Pool Drain**: Reentrancy via ERC777 hooks - **lendf.me Hack**: $25M stolen via reentrancy - **Multichain Hack**: Assumed permit succeeded without checking allowance - **Countless integration bugs**: Missing return values, approval race conditions, etc. ## Integration Points - Updated CLAUDE.md with new section on ERC20 edge case testing - Follows existing project patterns (NatSpec, testing structure) - Compatible with Echidna/Medusa fuzzing workflows - Complementary to existing ERC20 property tests (tests implementations vs. integrations) ## References - GitHub issue crytic#20: Create helpers for non-standard ERC20 - weird-erc20 repository: https://github.com/d-xo/weird-erc20 - Trail of Bits token integration checklist - All tokens based on real-world examples with documented exploits Closes crytic#20
|
Omar Inuwa seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements comprehensive helper system for testing protocols against non-standard ERC20 token behaviors. Addresses issue #20.
Overview
Creates
ERC20EdgeCaseshelper that deploys 20 different ERC20 token implementations, each exhibiting specific non-standard behaviors found in real tokens. This enables developers to test their protocols against all known ERC20 edge cases with a single import.