|
| 1 | +# InvCon — Invariant Mining Results |
| 2 | + |
| 3 | +This directory contains the invariant files (`.inv`) produced by running [InvCon](https://github.com/ASSERT-KTH/InvCon-Tool) against a curated dataset of real-world vulnerable Ethereum smart contracts. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Directory Structure |
| 8 | + |
| 9 | +Each subdirectory corresponds to one contract run and is named after the incident identifier from the dfhl-invariants database: |
| 10 | + |
| 11 | +``` |
| 12 | +results/ |
| 13 | +├── 201804_BEC/ |
| 14 | +│ ├── <contract_address>.inv # Daikon invariant file |
| 15 | +├── 201804_SmartMesh/ |
| 16 | +│ └── ... |
| 17 | +├── 202102_Yearn_ydai/ |
| 18 | +│ └── ... |
| 19 | +└── ... |
| 20 | +``` |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## How These Results Were Generated |
| 25 | + |
| 26 | +### Environment |
| 27 | + |
| 28 | +All runs were performed inside a Docker container built from the `Dockerfile` at the root of this repository. The image is based on `ubuntu:22.04` and pins the following key dependencies: |
| 29 | + |
| 30 | +| Dependency | Version | |
| 31 | +|---|---| |
| 32 | +| Python | 3.10 (system) | |
| 33 | +| Slither | 0.10.0 | |
| 34 | +| Daikon | 5.8.6 | |
| 35 | +| Node.js | system (apt) | |
| 36 | +| web3.py | bundled with Slither | |
| 37 | + |
| 38 | +### Running a Single Contract |
| 39 | + |
| 40 | +```bash |
| 41 | +# Build the image |
| 42 | +docker build -t invcon . |
| 43 | + |
| 44 | +# Run against a contract address |
| 45 | +docker run --rm \ |
| 46 | + -e ETHERSCAN_API_KEY=$ETHERSCAN_API_KEY \ |
| 47 | + -v $(pwd)/results/<incident_name>:/home/realworldcontracts/ \ |
| 48 | + invcon \ |
| 49 | + --eth_address <0x_contract_address> \ |
| 50 | + --workspace /home/realworldcontracts/ |
| 51 | +``` |
| 52 | + |
| 53 | +The `ETHERSCAN_API_KEY` environment variable must be set to a valid [Etherscan V2 API key](https://docs.etherscan.io/getting-started/viewing-api-usage-statistics). The tool fetches source code, ABI, and transaction histories live from Etherscan. |
| 54 | + |
| 55 | +### Running the Full Batch |
| 56 | + |
| 57 | +The full batch was executed using the following script on a WSL (Ubuntu) host: |
| 58 | + |
| 59 | +```bash |
| 60 | +#!/bin/bash |
| 61 | +mkdir -p ~/invcon-results |
| 62 | + |
| 63 | +# Parse contract addresses from the dfhl-invariants database JSON |
| 64 | +python3 -c " |
| 65 | +import json |
| 66 | +db = json.load(open('database.json')) |
| 67 | +for name, entry in db.items(): |
| 68 | + if entry.get('blockchain') == 'Ethereum' and entry.get('vulnerable_contract_address'): |
| 69 | + print(f\"{name},{entry['vulnerable_contract_address']}\") |
| 70 | +" > /tmp/contracts.csv |
| 71 | + |
| 72 | +while IFS=, read -r name address; do |
| 73 | + echo "=== Running $name ($address) ===" |
| 74 | + mkdir -p ~/invcon-results/$name |
| 75 | + docker run --rm \ |
| 76 | + -e ETHERSCAN_API_KEY=$ETHERSCAN_API_KEY \ |
| 77 | + -v ~/invcon-results/$name:/home/realworldcontracts/ \ |
| 78 | + invcon \ |
| 79 | + --eth_address "$address" \ |
| 80 | + --workspace /home/realworldcontracts/ \ |
| 81 | + > ~/invcon-results/$name/run.log 2>&1 || true |
| 82 | + echo "Done." |
| 83 | +done < /tmp/contracts.csv |
| 84 | +``` |
| 85 | + |
| 86 | +### Committing Results to This Repository |
| 87 | + |
| 88 | +Results were pushed to this repository as follows: |
| 89 | + |
| 90 | +```bash |
| 91 | +# From the repo root (after running the batch) |
| 92 | +cp -r ~/invcon-results/* results/ |
| 93 | + |
| 94 | +# Stage and commit |
| 95 | +git add results/ |
| 96 | +git commit -m "feat(results): add InvCon invariant mining output for dfhl-invariants dataset |
| 97 | +
|
| 98 | +- 26 contracts attempted from the ASSERT-KTH dfhl-invariants database |
| 99 | +- 12 clean successful runs, 3 partial (no Daikon samples), 9 hard failures |
| 100 | +- See results/README.md for full execution outcome table and root cause analysis" |
| 101 | + |
| 102 | +git push origin main |
| 103 | +``` |
| 104 | + |
| 105 | +--- |
| 106 | + |
| 107 | +## Execution Outcomes |
| 108 | + |
| 109 | +| Incident ID | Contract | Status | `.inv` File | Notes | |
| 110 | +|---|---|:---:|:---:|---| |
| 111 | +| 201804_BEC | `0xC5d...` | ✅ | `BecToken.inv` | ERC20 token; fallback IndexErrors non-fatal | |
| 112 | +| 201804_SmartMesh | `0x55f...` | ✅ | `SMT.inv` | ERC20 token; 3000 txs in ~18 min | |
| 113 | +| 202008_Opyn | `0x951...` | ❌ | — | `Web3.soliditySha3` deprecated API crash | |
| 114 | +| 202102_Yearn_ydai | `0xACd...` | ✅ | `yVault.inv` | Vault contract; 2000 txs | |
| 115 | +| 202109_Nimbus | `0xc0A...` | ❌ | — | `uint112` not supported in storage layout parser | |
| 116 | +| 202201_Anyswap | `0x6b7...` | ✅ | `AnyswapV4Router.inv` | Cross-chain router; 3000 txs | |
| 117 | +| 202202_TecraSpace | `0x...` | ❌ | — | Crawler `SystemExit(-1)` — Etherscan data unavailable | |
| 118 | +| 202206_InverseFinance | `0xE8b...` | ⚠️ | `YVCrv3CryptoFeed.inv` (empty) | 0 transactions crawled — likely proxy contract | |
| 119 | +| 202209_BadGuysbyRPF | `0xB84...` | ❌ | — | Unsupported NFT parameter types (URI strings, bytes) | |
| 120 | +| 202210_N00d | `0x356...` | ✅ | `SushiBar.inv` | 97 txs; clean run | |
| 121 | +| 202210_Uerii | `0x418...` | ✅ | `Token.inv` | 491 txs; clean run | |
| 122 | +| 202212_JAY | `0xf29...` | ⚠️ | `JAY.inv` (partial) | Malformed dtrace at line 5520 (string escaping) | |
| 123 | +| 202301_QTN | `0xC9f...` | ✅ | `QUATERNION.inv` | 387 txs; clean run | |
| 124 | +| 202305_ERC20TokenBank | `0x765...` | ⚠️ | `ExchangeBetweenPools.inv` (empty) | 0 tx — proxy/router pattern | |
| 125 | +| 202306_VINU | `0xF7e...` | ✅ | `VINU.in` | 14 txs; clean run | |
| 126 | +| 202308_Uwerx | `0x430...` | ✅ | `Uwerx.inv` | 75 txs; clean run | |
| 127 | +| 202309_uniclyNFT | `0xd3c...` | ❌ | — | `bytes4` not supported in storage layout parser | |
| 128 | +| 202310_PseudoETH | `0x203...` | ❌ | — | `uint112` not supported (Uniswap V2 pattern) | |
| 129 | +| 202311_grok | `0x839...` | ✅ | `GROK.inv` | 3000 txs; ~35 min crawl | |
| 130 | +| 202404_HoppyFrogERC | `0xe5c...` | ✅ | `Hoppy.inv` | ERC721; 2000 txs; non-fatal NFT param errors | |
| 131 | +| 202406_APEMAGA | `0x56f...` | ✅ | `Tonken.inv` | 20 txs; clean run | |
| 132 | +| 202406_JokInTheBox | `0xA64...` | ❌ | — | Source is Handlebars template `{{` — Slither compile fail | |
| 133 | +| 202406_WIFCOIN_ETH | `0xA1c...` | ❌ | — | Same `{{` template source issue | |
| 134 | +| 202408_OMPxContract | `0x203...` | ❌ | — | `Unknown Error` in `Contract.__init__` | |
| 135 | +| 202409_Bedrock_DeFi | `0x702...` | ✅ | `Vault.inv` | 2 txs; clean run | |
| 136 | +| 202409_OnyxDAO | `0x...` | ❌ | — | `Unknown Error` in `Contract.__init__` | |
| 137 | + |
| 138 | +**Legend:** ✅ Full success — `.inv` file produced with Daikon output · ⚠️ Tool completed but no usable invariants · ❌ Hard failure — no output produced |
| 139 | + |
| 140 | +--- |
| 141 | + |
| 142 | +## Known Limitations |
| 143 | + |
| 144 | +1. **Transaction cap:** InvCon fetches at most 2,000 transactions per contract (configurable via `--txs_limit`). Invariants derived from fewer transactions have lower statistical confidence. |
| 145 | +2. **Etherscan dependency:** Results require a live Etherscan connection. API rate limits may cause partial crawls. The API key used during this study has been revoked after use. |
| 146 | +3. **Unsupported Solidity types:** InvCon's storage layout parser (`parsing/storageLayout.py`) does not handle sub-32-byte integer types (`uint112`, `uint96`, etc.) or fixed-size byte arrays (`bytes4`, `bytes8`). Contracts using these types (e.g., Uniswap V2 forks using `uint112` for reserves) will fail. |
| 147 | +4. **Proxy contracts:** InvCon queries only the specified address. Proxy contracts that delegate all logic to an implementation contract will return 0 transactions and produce empty invariant files. |
| 148 | +5. **No ERC721 support:** NFT-specific parameter types (`tokenId` + `bytes data` in `safeTransferFrom`) cause non-fatal decoding errors. Some invariants may be absent for ERC721 contracts. |
| 149 | + |
| 150 | +--- |
| 151 | + |
| 152 | +*Generated April 2026 · InvCon commit: ASSERT-KTH/InvCon-Tool `main`* |
0 commit comments