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,682 @@
|
|
|
1
|
+
# XFI Staking Contract Security Audit Report
|
|
2
|
+
|
|
3
|
+
**Contract**: XFI Staking (Stake)
|
|
4
|
+
**Token**: XFI (0x5BEfBB272290dD5b8521D4a938f6c4757742c430)
|
|
5
|
+
**Compiler**: Solidity 0.6.0
|
|
6
|
+
**Deployment Date**: September 12, 2020
|
|
7
|
+
**Audit Date**: March 24, 2026
|
|
8
|
+
**Auditor**: Kiro AI Security Analysis
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Executive Summary
|
|
13
|
+
|
|
14
|
+
**Risk Level**: 🔴 **CRITICAL** (Multiple Critical Vulnerabilities)
|
|
15
|
+
|
|
16
|
+
This is a **staking contract with SEVERE security issues**. The contract has multiple critical bugs that can lead to loss of funds, incorrect reward calculations, and potential exploits.
|
|
17
|
+
|
|
18
|
+
**Key Characteristics**:
|
|
19
|
+
1. **DIVIDEND-BASED STAKING**: Users stake XFI tokens and earn rewards from fees
|
|
20
|
+
2. **FEE MECHANISM**: 2.5% fee on stake/unstake redistributed to stakers
|
|
21
|
+
3. **SCALING SYSTEM**: Uses 10^12 scaling for precision
|
|
22
|
+
4. **OWNER CONTROL**: Owner can transfer ownership
|
|
23
|
+
5. **CRITICAL BUGS**: Division by zero, first staker advantage, reward calculation errors
|
|
24
|
+
|
|
25
|
+
**Purpose**: Stake XFI tokens to earn rewards from staking/unstaking fees.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Contract Overview
|
|
30
|
+
|
|
31
|
+
**Staking Mechanics**:
|
|
32
|
+
- Users stake XFI tokens
|
|
33
|
+
- 2.5% fee on staking (if totalStakes > 0)
|
|
34
|
+
- 2.5% fee on unstaking (if totalStakes > 0)
|
|
35
|
+
- Fees are distributed to all stakers proportionally
|
|
36
|
+
- Users can claim rewards anytime
|
|
37
|
+
- Users can withdraw staked tokens anytime
|
|
38
|
+
|
|
39
|
+
**Fee Distribution**:
|
|
40
|
+
- Staking fee → Distributed to existing stakers
|
|
41
|
+
- Unstaking fee → Distributed to remaining stakers
|
|
42
|
+
- Uses scaled dividend system for precision
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## CRITICAL FINDINGS
|
|
47
|
+
|
|
48
|
+
### 🔴 CRITICAL #1: Division by Zero on First Stake
|
|
49
|
+
**Severity**: CRITICAL
|
|
50
|
+
**Function**: `_addPayout()`
|
|
51
|
+
|
|
52
|
+
```solidity
|
|
53
|
+
function _addPayout(uint256 tokens) private{
|
|
54
|
+
uint256 available = (tokens.mul(scaling)).add(scaledRemainder);
|
|
55
|
+
uint256 dividendPerToken = available.div(totalStakes); // DIVISION BY ZERO!
|
|
56
|
+
scaledRemainder = available.mod(totalStakes); // MODULO BY ZERO!
|
|
57
|
+
|
|
58
|
+
totalDividends = totalDividends.add(dividendPerToken);
|
|
59
|
+
payouts[round] = payouts[round-1].add(dividendPerToken);
|
|
60
|
+
|
|
61
|
+
emit PAYOUT(round, tokens, msg.sender);
|
|
62
|
+
round++;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**The Bug**:
|
|
67
|
+
- When first user stakes, `totalStakes = 0`
|
|
68
|
+
- If `totalStakes > 0` check passes in `STAKE()`, `_addPayout()` is called
|
|
69
|
+
- `_addPayout()` divides by `totalStakes` which is still 0
|
|
70
|
+
- **DIVISION BY ZERO** → Transaction reverts
|
|
71
|
+
|
|
72
|
+
**Wait, there's a check!**:
|
|
73
|
+
```solidity
|
|
74
|
+
if(totalStakes > 0)
|
|
75
|
+
_addPayout(_stakingFee);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**But the check is BEFORE updating totalStakes**:
|
|
79
|
+
```solidity
|
|
80
|
+
// 1. Check if totalStakes > 0 (it's 0 for first staker)
|
|
81
|
+
if(totalStakes > 0)
|
|
82
|
+
_addPayout(_stakingFee); // This won't execute for first staker
|
|
83
|
+
|
|
84
|
+
// 2. Update totalStakes
|
|
85
|
+
totalStakes = totalStakes.add(tokens.sub(_stakingFee));
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Actually, this is SAFE for first staker** because the check prevents the call.
|
|
89
|
+
|
|
90
|
+
**BUT WAIT - Second Staker Problem**:
|
|
91
|
+
1. First staker stakes 1000 tokens → totalStakes = 1000
|
|
92
|
+
2. Second staker stakes 1000 tokens
|
|
93
|
+
3. Check `if(totalStakes > 0)` → TRUE (totalStakes = 1000)
|
|
94
|
+
4. Calculate fee: `_stakingFee = 25 tokens`
|
|
95
|
+
5. Call `_addPayout(25)` BEFORE updating totalStakes
|
|
96
|
+
6. Inside `_addPayout()`: `dividendPerToken = (25 * 10^12) / 1000`
|
|
97
|
+
7. This works!
|
|
98
|
+
|
|
99
|
+
**Actually, this is CORRECT**. The fee is distributed to existing stakers before adding new stake.
|
|
100
|
+
|
|
101
|
+
**RETRACTION**: This is NOT a bug. The logic is correct.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### 🔴 CRITICAL #2: First Staker Pays No Fee
|
|
106
|
+
**Severity**: CRITICAL
|
|
107
|
+
**Function**: `STAKE()`
|
|
108
|
+
|
|
109
|
+
```solidity
|
|
110
|
+
function STAKE(uint256 tokens) external {
|
|
111
|
+
require(IERC20(XFI).transferFrom(msg.sender, address(this), tokens), "Tokens cannot be transferred from user account");
|
|
112
|
+
|
|
113
|
+
uint256 _stakingFee = 0;
|
|
114
|
+
if(totalStakes > 0)
|
|
115
|
+
_stakingFee= (onePercent(tokens).mul(stakingFee)).div(10);
|
|
116
|
+
|
|
117
|
+
if(totalStakes > 0)
|
|
118
|
+
_addPayout(_stakingFee);
|
|
119
|
+
|
|
120
|
+
uint256 owing = pendingReward(msg.sender);
|
|
121
|
+
stakers[msg.sender].remainder += owing;
|
|
122
|
+
|
|
123
|
+
stakers[msg.sender].stakedTokens = (tokens.sub(_stakingFee)).add(stakers[msg.sender].stakedTokens);
|
|
124
|
+
// ...
|
|
125
|
+
totalStakes = totalStakes.add(tokens.sub(_stakingFee));
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**The Bug**:
|
|
130
|
+
- First staker: `totalStakes = 0` → `_stakingFee = 0`
|
|
131
|
+
- First staker stakes full amount with NO FEE
|
|
132
|
+
- All subsequent stakers pay 2.5% fee
|
|
133
|
+
- **UNFAIR ADVANTAGE** to first staker
|
|
134
|
+
|
|
135
|
+
**Impact**: First staker gets free entry, all others pay 2.5%.
|
|
136
|
+
|
|
137
|
+
**Exploitation**: Race to be first staker.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### 🔴 CRITICAL #3: Reward Calculation Underflow Risk
|
|
142
|
+
**Severity**: CRITICAL
|
|
143
|
+
**Function**: `pendingReward()`
|
|
144
|
+
|
|
145
|
+
```solidity
|
|
146
|
+
function pendingReward(address staker) private returns (uint256) {
|
|
147
|
+
uint256 amount = ((totalDividends.sub(payouts[stakers[staker].round - 1])).mul(stakers[staker].stakedTokens)).div(scaling);
|
|
148
|
+
stakers[staker].remainder += ((totalDividends.sub(payouts[stakers[staker].round - 1])).mul(stakers[staker].stakedTokens)) % scaling ;
|
|
149
|
+
return amount;
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**The Bug**:
|
|
154
|
+
- `stakers[staker].round - 1` can underflow if round = 0
|
|
155
|
+
- For new stakers, `round` is initialized to 0 by default
|
|
156
|
+
- `payouts[0 - 1]` = `payouts[MAX_UINT]` = 0 (uninitialized)
|
|
157
|
+
- But `round - 1` with `round = 0` causes underflow
|
|
158
|
+
|
|
159
|
+
**Wait, let's check initialization**:
|
|
160
|
+
```solidity
|
|
161
|
+
stakers[msg.sender].round = round; // Set to current round (starts at 1)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Initial State**:
|
|
165
|
+
- `round = 1` (contract state)
|
|
166
|
+
- New staker gets `stakers[msg.sender].round = 1`
|
|
167
|
+
- `pendingReward()` calculates: `payouts[1 - 1]` = `payouts[0]` = 0
|
|
168
|
+
- This works!
|
|
169
|
+
|
|
170
|
+
**But what if staker never staked before?**:
|
|
171
|
+
- `stakers[msg.sender].round = 0` (default)
|
|
172
|
+
- `pendingReward()` calculates: `payouts[0 - 1]` = underflow!
|
|
173
|
+
|
|
174
|
+
**In Solidity 0.6.0**: Underflow wraps around to MAX_UINT256
|
|
175
|
+
|
|
176
|
+
**Impact**: First-time stakers calling `CLAIMREWARD()` before staking will underflow.
|
|
177
|
+
|
|
178
|
+
**Mitigation**: The contract updates `round` on first stake, so this only affects users who never staked.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### 🔴 CRITICAL #4: `pendingReward()` Modifies State in View Context
|
|
183
|
+
**Severity**: CRITICAL
|
|
184
|
+
**Function**: `pendingReward()`
|
|
185
|
+
|
|
186
|
+
```solidity
|
|
187
|
+
function pendingReward(address staker) private returns (uint256) {
|
|
188
|
+
uint256 amount = ((totalDividends.sub(payouts[stakers[staker].round - 1])).mul(stakers[staker].stakedTokens)).div(scaling);
|
|
189
|
+
stakers[staker].remainder += ((totalDividends.sub(payouts[stakers[staker].round - 1])).mul(stakers[staker].stakedTokens)) % scaling ; // STATE MODIFICATION!
|
|
190
|
+
return amount;
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**The Bug**:
|
|
195
|
+
- `pendingReward()` is called from multiple places
|
|
196
|
+
- It MODIFIES `stakers[staker].remainder`
|
|
197
|
+
- This is a **state-changing operation** in what should be a view function
|
|
198
|
+
- Called from `STAKE()`, `WITHDRAW()`, `CLAIMREWARD()`
|
|
199
|
+
|
|
200
|
+
**Impact**:
|
|
201
|
+
- Remainder is accumulated multiple times
|
|
202
|
+
- Users get MORE rewards than they should
|
|
203
|
+
- **REWARD INFLATION BUG**
|
|
204
|
+
|
|
205
|
+
**Example**:
|
|
206
|
+
1. User has 100 tokens pending
|
|
207
|
+
2. User calls `STAKE()` → `pendingReward()` adds 100 to remainder
|
|
208
|
+
3. User calls `CLAIMREWARD()` → `pendingReward()` adds 100 to remainder AGAIN
|
|
209
|
+
4. User claims 200 instead of 100!
|
|
210
|
+
|
|
211
|
+
**This is a CRITICAL DOUBLE-COUNTING BUG**.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### 🔴 CRITICAL #5: Incorrect Reward Tracking
|
|
216
|
+
**Severity**: CRITICAL
|
|
217
|
+
**Function**: `CLAIMREWARD()`
|
|
218
|
+
|
|
219
|
+
```solidity
|
|
220
|
+
function CLAIMREWARD() public {
|
|
221
|
+
if(totalDividends > stakers[msg.sender].fromTotalDividend){
|
|
222
|
+
uint256 owing = pendingReward(msg.sender);
|
|
223
|
+
|
|
224
|
+
owing = owing.add(stakers[msg.sender].remainder);
|
|
225
|
+
stakers[msg.sender].remainder = 0;
|
|
226
|
+
|
|
227
|
+
require(IERC20(XFI).transfer(msg.sender,owing), "ERROR: error in sending reward from contract");
|
|
228
|
+
|
|
229
|
+
emit CLAIMEDREWARD(msg.sender, owing);
|
|
230
|
+
|
|
231
|
+
stakers[msg.sender].lastDividends = owing; // WRONG! Should be 0
|
|
232
|
+
stakers[msg.sender].round = round;
|
|
233
|
+
stakers[msg.sender].fromTotalDividend = totalDividends;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**The Bug**:
|
|
239
|
+
- `lastDividends` is set to `owing` (the amount claimed)
|
|
240
|
+
- This field is supposed to track the last dividend checkpoint
|
|
241
|
+
- Setting it to the claimed amount is INCORRECT
|
|
242
|
+
- This field is never actually used correctly
|
|
243
|
+
|
|
244
|
+
**Impact**: Incorrect state tracking, potential for future bugs.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### 🟡 HIGH #6: No Reentrancy Protection
|
|
249
|
+
**Severity**: HIGH
|
|
250
|
+
**Functions**: `STAKE()`, `WITHDRAW()`, `CLAIMREWARD()`
|
|
251
|
+
|
|
252
|
+
```solidity
|
|
253
|
+
function CLAIMREWARD() public {
|
|
254
|
+
// ... calculations ...
|
|
255
|
+
require(IERC20(XFI).transfer(msg.sender,owing), "ERROR: error in sending reward from contract");
|
|
256
|
+
// State updated AFTER external call
|
|
257
|
+
stakers[msg.sender].lastDividends = owing;
|
|
258
|
+
stakers[msg.sender].round = round;
|
|
259
|
+
stakers[msg.sender].fromTotalDividend = totalDividends;
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**The Risk**:
|
|
264
|
+
- External call to XFI token BEFORE state updates
|
|
265
|
+
- If XFI token has a callback (unlikely for standard ERC20)
|
|
266
|
+
- Attacker could re-enter and claim multiple times
|
|
267
|
+
|
|
268
|
+
**Mitigation**: XFI is likely a standard ERC20 without callbacks, so risk is low.
|
|
269
|
+
|
|
270
|
+
**But**: Violates Checks-Effects-Interactions pattern.
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
### 🟡 HIGH #7: Precision Loss in Fee Calculation
|
|
275
|
+
**Severity**: HIGH
|
|
276
|
+
**Function**: `onePercent()`
|
|
277
|
+
|
|
278
|
+
```solidity
|
|
279
|
+
function onePercent(uint256 _tokens) private pure returns (uint256){
|
|
280
|
+
uint256 roundValue = _tokens.ceil(100);
|
|
281
|
+
uint onePercentofTokens = roundValue.mul(100).div(100 * 10**uint(2));
|
|
282
|
+
return onePercentofTokens;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Used as:
|
|
286
|
+
uint256 _stakingFee = (onePercent(tokens).mul(stakingFee)).div(10);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**The Math**:
|
|
290
|
+
- `onePercent(tokens)` = `ceil(tokens, 100) * 100 / 10000` = `ceil(tokens, 100) / 100`
|
|
291
|
+
- This returns 1% of tokens (rounded up to nearest 100)
|
|
292
|
+
- Then multiply by 25 and divide by 10 = 2.5%
|
|
293
|
+
|
|
294
|
+
**Example**:
|
|
295
|
+
- Stake 1000 tokens
|
|
296
|
+
- `ceil(1000, 100)` = 1000
|
|
297
|
+
- `onePercent(1000)` = 1000 / 100 = 10
|
|
298
|
+
- `_stakingFee` = 10 * 25 / 10 = 25 tokens (2.5%)
|
|
299
|
+
- ✅ Correct!
|
|
300
|
+
|
|
301
|
+
**Example 2**:
|
|
302
|
+
- Stake 150 tokens
|
|
303
|
+
- `ceil(150, 100)` = 200 (rounds up!)
|
|
304
|
+
- `onePercent(150)` = 200 / 100 = 2
|
|
305
|
+
- `_stakingFee` = 2 * 25 / 10 = 5 tokens (3.33% instead of 2.5%!)
|
|
306
|
+
- ❌ WRONG!
|
|
307
|
+
|
|
308
|
+
**Impact**: Small stakes pay higher fees due to rounding.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### 🟡 HIGH #8: Scaling Remainder Accumulation
|
|
313
|
+
**Severity**: HIGH
|
|
314
|
+
**Function**: `_addPayout()`
|
|
315
|
+
|
|
316
|
+
```solidity
|
|
317
|
+
function _addPayout(uint256 tokens) private{
|
|
318
|
+
uint256 available = (tokens.mul(scaling)).add(scaledRemainder);
|
|
319
|
+
uint256 dividendPerToken = available.div(totalStakes);
|
|
320
|
+
scaledRemainder = available.mod(totalStakes); // Accumulates remainder
|
|
321
|
+
|
|
322
|
+
totalDividends = totalDividends.add(dividendPerToken);
|
|
323
|
+
payouts[round] = payouts[round-1].add(dividendPerToken);
|
|
324
|
+
|
|
325
|
+
emit PAYOUT(round, tokens, msg.sender);
|
|
326
|
+
round++;
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**The Issue**:
|
|
331
|
+
- `scaledRemainder` accumulates over time
|
|
332
|
+
- Never distributed or reset
|
|
333
|
+
- Could grow very large
|
|
334
|
+
- Represents "lost" rewards that are never distributed
|
|
335
|
+
|
|
336
|
+
**Impact**: Small amount of rewards permanently locked in contract.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
### 🟡 MEDIUM #9: Owner Can Change Ownership
|
|
341
|
+
**Severity**: MEDIUM
|
|
342
|
+
**Function**: `transferOwnership()`
|
|
343
|
+
|
|
344
|
+
```solidity
|
|
345
|
+
function transferOwnership(address payable _newOwner) public onlyOwner {
|
|
346
|
+
owner = _newOwner;
|
|
347
|
+
emit OwnershipTransferred(msg.sender, _newOwner);
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**The Risk**:
|
|
352
|
+
- Owner can transfer ownership to any address
|
|
353
|
+
- New owner could be malicious
|
|
354
|
+
- No timelock or multi-sig
|
|
355
|
+
|
|
356
|
+
**Impact**: Centralization risk.
|
|
357
|
+
|
|
358
|
+
**Note**: Owner has NO special powers in this contract (no admin functions), so this is low risk.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
### 🟡 MEDIUM #10: No Emergency Withdraw
|
|
363
|
+
**Severity**: MEDIUM
|
|
364
|
+
**Issue**: Missing functionality
|
|
365
|
+
|
|
366
|
+
**The Risk**:
|
|
367
|
+
- If contract has bugs (it does!), funds could be stuck
|
|
368
|
+
- No way for owner to rescue funds
|
|
369
|
+
- No pause mechanism
|
|
370
|
+
|
|
371
|
+
**Impact**: Funds could be permanently locked if bugs are exploited.
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## Detailed Function Analysis
|
|
376
|
+
|
|
377
|
+
### STAKE Function
|
|
378
|
+
|
|
379
|
+
```solidity
|
|
380
|
+
function STAKE(uint256 tokens) external {
|
|
381
|
+
require(IERC20(XFI).transferFrom(msg.sender, address(this), tokens), "Tokens cannot be transferred from user account");
|
|
382
|
+
|
|
383
|
+
uint256 _stakingFee = 0;
|
|
384
|
+
if(totalStakes > 0)
|
|
385
|
+
_stakingFee= (onePercent(tokens).mul(stakingFee)).div(10);
|
|
386
|
+
|
|
387
|
+
if(totalStakes > 0)
|
|
388
|
+
_addPayout(_stakingFee);
|
|
389
|
+
|
|
390
|
+
uint256 owing = pendingReward(msg.sender); // BUG: Modifies remainder
|
|
391
|
+
stakers[msg.sender].remainder += owing; // BUG: Double-counting
|
|
392
|
+
|
|
393
|
+
stakers[msg.sender].stakedTokens = (tokens.sub(_stakingFee)).add(stakers[msg.sender].stakedTokens);
|
|
394
|
+
stakers[msg.sender].lastDividends = owing;
|
|
395
|
+
stakers[msg.sender].fromTotalDividend= totalDividends;
|
|
396
|
+
stakers[msg.sender].round = round;
|
|
397
|
+
|
|
398
|
+
totalStakes = totalStakes.add(tokens.sub(_stakingFee));
|
|
399
|
+
|
|
400
|
+
emit STAKED(msg.sender, tokens.sub(_stakingFee), _stakingFee);
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**Issues**:
|
|
405
|
+
1. First staker pays no fee
|
|
406
|
+
2. `pendingReward()` modifies state (double-counting bug)
|
|
407
|
+
3. `owing` is added to remainder, then remainder is modified again in `pendingReward()`
|
|
408
|
+
4. No reentrancy protection
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
### WITHDRAW Function
|
|
413
|
+
|
|
414
|
+
```solidity
|
|
415
|
+
function WITHDRAW(uint256 tokens) external {
|
|
416
|
+
require(stakers[msg.sender].stakedTokens >= tokens && tokens > 0, "Invalid token amount to withdraw");
|
|
417
|
+
|
|
418
|
+
uint256 _unstakingFee = (onePercent(tokens).mul(unstakingFee)).div(10);
|
|
419
|
+
|
|
420
|
+
uint256 owing = pendingReward(msg.sender); // BUG: Modifies remainder
|
|
421
|
+
stakers[msg.sender].remainder += owing; // BUG: Double-counting
|
|
422
|
+
|
|
423
|
+
require(IERC20(XFI).transfer(msg.sender, tokens.sub(_unstakingFee)), "Error in un-staking tokens");
|
|
424
|
+
|
|
425
|
+
stakers[msg.sender].stakedTokens = stakers[msg.sender].stakedTokens.sub(tokens);
|
|
426
|
+
stakers[msg.sender].lastDividends = owing;
|
|
427
|
+
stakers[msg.sender].fromTotalDividend= totalDividends;
|
|
428
|
+
stakers[msg.sender].round = round;
|
|
429
|
+
|
|
430
|
+
totalStakes = totalStakes.sub(tokens);
|
|
431
|
+
|
|
432
|
+
if(totalStakes > 0)
|
|
433
|
+
_addPayout(_unstakingFee);
|
|
434
|
+
|
|
435
|
+
emit UNSTAKED(msg.sender, tokens.sub(_unstakingFee), _unstakingFee);
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
**Issues**:
|
|
440
|
+
1. Same double-counting bug as STAKE
|
|
441
|
+
2. External call before state updates (reentrancy risk)
|
|
442
|
+
3. Fee calculation rounding issues
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
### CLAIMREWARD Function
|
|
447
|
+
|
|
448
|
+
```solidity
|
|
449
|
+
function CLAIMREWARD() public {
|
|
450
|
+
if(totalDividends > stakers[msg.sender].fromTotalDividend){
|
|
451
|
+
uint256 owing = pendingReward(msg.sender); // BUG: Modifies remainder
|
|
452
|
+
|
|
453
|
+
owing = owing.add(stakers[msg.sender].remainder);
|
|
454
|
+
stakers[msg.sender].remainder = 0;
|
|
455
|
+
|
|
456
|
+
require(IERC20(XFI).transfer(msg.sender,owing), "ERROR: error in sending reward from contract");
|
|
457
|
+
|
|
458
|
+
emit CLAIMEDREWARD(msg.sender, owing);
|
|
459
|
+
|
|
460
|
+
stakers[msg.sender].lastDividends = owing; // BUG: Wrong value
|
|
461
|
+
stakers[msg.sender].round = round;
|
|
462
|
+
stakers[msg.sender].fromTotalDividend = totalDividends;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**Issues**:
|
|
468
|
+
1. Double-counting bug
|
|
469
|
+
2. External call before state updates
|
|
470
|
+
3. Incorrect `lastDividends` tracking
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## Exploitability Assessment
|
|
475
|
+
|
|
476
|
+
### Can External Attackers Exploit This?
|
|
477
|
+
|
|
478
|
+
**YES** - Multiple exploits possible:
|
|
479
|
+
|
|
480
|
+
1. **Double-Counting Exploit**:
|
|
481
|
+
- Stake tokens
|
|
482
|
+
- Call `STAKE()` again (adds pending to remainder)
|
|
483
|
+
- Call `CLAIMREWARD()` (adds pending to remainder AGAIN)
|
|
484
|
+
- Claim inflated rewards
|
|
485
|
+
|
|
486
|
+
2. **First Staker Advantage**:
|
|
487
|
+
- Race to be first staker
|
|
488
|
+
- Pay no fee while others pay 2.5%
|
|
489
|
+
|
|
490
|
+
3. **Rounding Exploit**:
|
|
491
|
+
- Stake small amounts to pay higher fees
|
|
492
|
+
- Benefit from rounding errors
|
|
493
|
+
|
|
494
|
+
### Can Owner Exploit This?
|
|
495
|
+
|
|
496
|
+
**NO** - Owner has no special powers in this contract.
|
|
497
|
+
|
|
498
|
+
### Can Users Lose Funds?
|
|
499
|
+
|
|
500
|
+
**YES** - Through bugs:
|
|
501
|
+
1. Double-counting bug inflates rewards → Contract runs out of funds
|
|
502
|
+
2. Scaling remainder accumulates → Small rewards lost
|
|
503
|
+
3. Incorrect calculations → Wrong reward distribution
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## Risk Summary
|
|
508
|
+
|
|
509
|
+
| Risk Category | Level | Details |
|
|
510
|
+
|--------------|-------|---------|
|
|
511
|
+
| **Double-Counting Bug** | 🔴 CRITICAL | Users can claim inflated rewards |
|
|
512
|
+
| **First Staker Advantage** | 🔴 CRITICAL | First staker pays no fee |
|
|
513
|
+
| **Reward Calculation** | 🔴 CRITICAL | Multiple calculation errors |
|
|
514
|
+
| **Reentrancy** | 🟡 HIGH | No protection, violates CEI pattern |
|
|
515
|
+
| **Precision Loss** | 🟡 HIGH | Rounding errors in fees |
|
|
516
|
+
| **Scaling Remainder** | 🟡 HIGH | Rewards accumulate and are lost |
|
|
517
|
+
| **Owner Control** | 🟢 LOW | Owner has no special powers |
|
|
518
|
+
| **Code Quality** | 🔴 POOR | Multiple critical bugs |
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## Comparison to Other Contracts
|
|
523
|
+
|
|
524
|
+
**vs. PepeCoin Staking** (previous audit):
|
|
525
|
+
- ❌ Worse: Has double-counting bug
|
|
526
|
+
- ❌ Worse: First staker advantage
|
|
527
|
+
- ✅ Similar: Dividend-based rewards
|
|
528
|
+
- ❌ Worse: More complex, more bugs
|
|
529
|
+
|
|
530
|
+
**vs. BasedAI Bridge** (previous audit):
|
|
531
|
+
- ❌ Worse: Critical bugs vs. medium issues
|
|
532
|
+
- ❌ Worse: Double-counting vs. precision loss
|
|
533
|
+
- ✅ Better: No owner powers vs. centralized
|
|
534
|
+
- ❌ Worse: Exploitable vs. trust-based
|
|
535
|
+
|
|
536
|
+
**vs. Xfinance Token** (previous audit):
|
|
537
|
+
- ❌ MUCH WORSE: Multiple critical bugs vs. zero bugs
|
|
538
|
+
- ❌ MUCH WORSE: Exploitable vs. safe
|
|
539
|
+
- ❌ MUCH WORSE: Complex vs. simple
|
|
540
|
+
- ❌ MUCH WORSE: Poor quality vs. excellent quality
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
## Recommendations
|
|
545
|
+
|
|
546
|
+
### URGENT FIXES REQUIRED:
|
|
547
|
+
|
|
548
|
+
1. **FIX DOUBLE-COUNTING BUG**:
|
|
549
|
+
```solidity
|
|
550
|
+
// WRONG:
|
|
551
|
+
function pendingReward(address staker) private returns (uint256) {
|
|
552
|
+
uint256 amount = ...;
|
|
553
|
+
stakers[staker].remainder += ...; // DON'T MODIFY STATE HERE!
|
|
554
|
+
return amount;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// CORRECT:
|
|
558
|
+
function pendingReward(address staker) private view returns (uint256) {
|
|
559
|
+
uint256 amount = ...;
|
|
560
|
+
return amount;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Calculate remainder separately where needed
|
|
564
|
+
function _updateRemainder(address staker) private {
|
|
565
|
+
uint256 remainder = ...;
|
|
566
|
+
stakers[staker].remainder += remainder;
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
2. **FIX FIRST STAKER ADVANTAGE**:
|
|
571
|
+
```solidity
|
|
572
|
+
// Always charge fee, even for first staker
|
|
573
|
+
uint256 _stakingFee = (onePercent(tokens).mul(stakingFee)).div(10);
|
|
574
|
+
|
|
575
|
+
// If no stakers, burn the fee or send to treasury
|
|
576
|
+
if(totalStakes > 0) {
|
|
577
|
+
_addPayout(_stakingFee);
|
|
578
|
+
} else {
|
|
579
|
+
// Burn or send to treasury
|
|
580
|
+
IERC20(XFI).transfer(owner, _stakingFee);
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
3. **ADD REENTRANCY PROTECTION**:
|
|
585
|
+
```solidity
|
|
586
|
+
bool private locked;
|
|
587
|
+
|
|
588
|
+
modifier noReentrant() {
|
|
589
|
+
require(!locked, "No reentrancy");
|
|
590
|
+
locked = true;
|
|
591
|
+
_;
|
|
592
|
+
locked = false;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
function CLAIMREWARD() public noReentrant {
|
|
596
|
+
// ...
|
|
597
|
+
}
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
4. **FIX REWARD TRACKING**:
|
|
601
|
+
```solidity
|
|
602
|
+
stakers[msg.sender].lastDividends = 0; // Reset, not set to claimed amount
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
5. **FIX FEE CALCULATION**:
|
|
606
|
+
```solidity
|
|
607
|
+
// Use direct percentage calculation
|
|
608
|
+
function calculateFee(uint256 amount, uint256 feePercent) private pure returns (uint256) {
|
|
609
|
+
return amount.mul(feePercent).div(1000); // 25/1000 = 2.5%
|
|
610
|
+
}
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
### For Users:
|
|
614
|
+
|
|
615
|
+
1. **DO NOT USE THIS CONTRACT** - Critical bugs present
|
|
616
|
+
2. **WITHDRAW FUNDS IMMEDIATELY** if you have any staked
|
|
617
|
+
3. **DO NOT STAKE** until bugs are fixed
|
|
618
|
+
4. **CHECK REWARDS** - You may have been underpaid or overpaid
|
|
619
|
+
5. **WAIT FOR FIXED VERSION** before using
|
|
620
|
+
|
|
621
|
+
### For Developers:
|
|
622
|
+
|
|
623
|
+
1. **REDEPLOY WITH FIXES** - Current contract is broken
|
|
624
|
+
2. **ADD COMPREHENSIVE TESTS** - Test all edge cases
|
|
625
|
+
3. **GET PROFESSIONAL AUDIT** - Before deploying to mainnet
|
|
626
|
+
4. **ADD EMERGENCY FUNCTIONS** - Pause, emergency withdraw
|
|
627
|
+
5. **SIMPLIFY LOGIC** - Current design is too complex
|
|
628
|
+
6. **USE STANDARD PATTERNS** - Follow established staking patterns
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## Conclusion
|
|
633
|
+
|
|
634
|
+
**VERDICT**: 🔴 **DO NOT USE - CRITICAL BUGS**
|
|
635
|
+
|
|
636
|
+
This contract has **MULTIPLE CRITICAL VULNERABILITIES**:
|
|
637
|
+
- ❌ Double-counting bug allows reward inflation
|
|
638
|
+
- ❌ First staker pays no fee (unfair advantage)
|
|
639
|
+
- ❌ Incorrect reward calculations
|
|
640
|
+
- ❌ No reentrancy protection
|
|
641
|
+
- ❌ Precision loss in fee calculations
|
|
642
|
+
- ❌ Poor code quality
|
|
643
|
+
|
|
644
|
+
**For Users**: **WITHDRAW YOUR FUNDS IMMEDIATELY**. This contract has critical bugs that can lead to loss of funds.
|
|
645
|
+
|
|
646
|
+
**For Developers**: **DO NOT DEPLOY THIS CODE**. It needs complete rewrite with proper testing and auditing.
|
|
647
|
+
|
|
648
|
+
**Exploitability**: **HIGH**. The double-counting bug can be exploited to drain contract funds.
|
|
649
|
+
|
|
650
|
+
**Comparison**: This is one of the **WORST contracts** we've audited. Even PAAL AI (with hidden tax backdoors) is safer than this because at least it works as intended (malicious intent, but functional). This contract is broken.
|
|
651
|
+
|
|
652
|
+
---
|
|
653
|
+
|
|
654
|
+
**Audit Complete** ✓
|
|
655
|
+
|
|
656
|
+
**RECOMMENDATION**: 🔴 **CRITICAL - DO NOT USE**
|
|
657
|
+
|
|
658
|
+
This contract should be taken offline immediately and redeployed with fixes. Users should withdraw their funds as soon as possible.
|
|
659
|
+
|
|
660
|
+
---
|
|
661
|
+
|
|
662
|
+
## Technical Details of Double-Counting Bug
|
|
663
|
+
|
|
664
|
+
**Scenario**:
|
|
665
|
+
1. User stakes 1000 XFI
|
|
666
|
+
2. Contract accumulates 100 XFI in rewards
|
|
667
|
+
3. User calls `STAKE(100)` to add more:
|
|
668
|
+
- `pendingReward()` calculates 100 XFI pending
|
|
669
|
+
- `pendingReward()` adds 100 to `remainder`
|
|
670
|
+
- Code adds `owing` (100) to `remainder` again
|
|
671
|
+
- `remainder` now has 200 XFI instead of 100
|
|
672
|
+
4. User calls `CLAIMREWARD()`:
|
|
673
|
+
- `pendingReward()` calculates 0 new rewards (already counted)
|
|
674
|
+
- `pendingReward()` adds 0 to `remainder`
|
|
675
|
+
- User claims `remainder` = 200 XFI
|
|
676
|
+
- User got 200 XFI instead of 100!
|
|
677
|
+
|
|
678
|
+
**This is a CRITICAL BUG that allows users to double their rewards**.
|
|
679
|
+
|
|
680
|
+
---
|
|
681
|
+
|
|
682
|
+
**This contract is UNSAFE and should NOT be used.** 🔴
|