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,240 @@
|
|
|
1
|
+
= How to set up on-chain governance
|
|
2
|
+
|
|
3
|
+
In this guide we will learn how OpenZeppelin’s Governor contract works, how to set it up, and how to use it to create proposals, vote for them, and execute them, using tools provided by Ethers.js and Tally.
|
|
4
|
+
|
|
5
|
+
NOTE: Find detailed contract documentation at xref:api:governance.adoc[Governance API].
|
|
6
|
+
|
|
7
|
+
== Introduction
|
|
8
|
+
|
|
9
|
+
Decentralized protocols are in constant evolution from the moment they are publicly released. Often, the initial team retains control of this evolution in the first stages, but eventually delegates it to a community of stakeholders. The process by which this community makes decisions is called on-chain governance, and it has become a central component of decentralized protocols, fueling varied decisions such as parameter tweaking, smart contract upgrades, integrations with other protocols, treasury management, grants, etc.
|
|
10
|
+
|
|
11
|
+
This governance protocol is generally implemented in a special-purpose contract called “Governor”. The GovernorAlpha and GovernorBravo contracts designed by Compound have been very successful and popular so far, with the downside that projects with different requirements have had to fork the code to customize it for their needs, which can pose a high risk of introducing security issues. For OpenZeppelin Contracts, we set out to build a modular system of Governor contracts so that forking is not needed, and different requirements can be accommodated by writing small modules using Solidity inheritance. You will find the most common requirements out of the box in OpenZeppelin Contracts, but writing additional ones is simple, and we will be adding new features as requested by the community in future releases. Additionally, the design of OpenZeppelin Governor requires minimal use of storage and results in more gas efficient operation.
|
|
12
|
+
|
|
13
|
+
== Compatibility
|
|
14
|
+
|
|
15
|
+
OpenZeppelin’s Governor system was designed with a concern for compatibility with existing systems that were based on Compound’s GovernorAlpha and GovernorBravo. Because of this, you will find that many modules are presented in two variants, one of which is built for compatibility with those systems.
|
|
16
|
+
|
|
17
|
+
=== ERC20Votes & ERC20VotesComp
|
|
18
|
+
|
|
19
|
+
The ERC20 extension to keep track of votes and vote delegation is one such case. The shorter one is the more generic version because it can support token supplies greater than 2^96, while the “Comp” variant is limited in that regard, but exactly fits the interface of the COMP token that is used by GovernorAlpha and Bravo. Both contract variants share the same events, so they are fully compatible when looking at events only.
|
|
20
|
+
|
|
21
|
+
=== Governor & GovernorStorage
|
|
22
|
+
|
|
23
|
+
An OpenZeppelin Governor contract is not interface-compatible with Compound's GovernorAlpha or Bravo. Even though events are fully compatible, proposal lifecycle functions (creation, execution, etc.) have different signatures that are meant to optimize storage use. Other functions from GovernorAlpha are Bravo are likewise not available. It’s possible to opt in some Bravo-like behavior by inheriting from the GovernorStorage module. This module provides proposal enumerability and alternate versions of the `queue`, `execute` and `cancel` function that only take the proposal id. This module reduces the calldata needed by some operations in exchange for an increased the storage footprint. This might be a good trade-off for some L2 chains. It also provides primitives for indexer-free frontends.
|
|
24
|
+
|
|
25
|
+
Note that even with the use of this module, one important difference with Compound's GovernorBravo is the way that `proposalId`s are calculated. Governor uses the hash of the proposal parameters with the purpose of keeping its data off-chain by event indexing, while the original Bravo implementation uses sequential `proposalId`s.
|
|
26
|
+
|
|
27
|
+
=== GovernorTimelockControl & GovernorTimelockCompound
|
|
28
|
+
|
|
29
|
+
When using a timelock with your Governor contract, you can use either OpenZeppelin’s TimelockController or Compound’s Timelock. Based on the choice of timelock, you should choose the corresponding Governor module: GovernorTimelockControl or GovernorTimelockCompound respectively. This allows you to migrate an existing GovernorAlpha instance to an OpenZeppelin-based Governor without changing the timelock in use.
|
|
30
|
+
|
|
31
|
+
=== Tally
|
|
32
|
+
|
|
33
|
+
https://www.tally.xyz[Tally] is a full-fledged application for user owned on-chain governance. It comprises a voting dashboard, proposal creation wizard, real time research and analysis, and educational content.
|
|
34
|
+
|
|
35
|
+
For all of these options, the Governor will be compatible with Tally: users will be able to create proposals, visualize voting power and advocates, navigate proposals, and cast votes. For proposal creation in particular, projects can also use Defender Admin as an alternative interface.
|
|
36
|
+
|
|
37
|
+
In the rest of this guide, we will focus on a fresh deploy of the vanilla OpenZeppelin Governor features without concern for compatibility with GovernorAlpha or Bravo.
|
|
38
|
+
|
|
39
|
+
== Setup
|
|
40
|
+
|
|
41
|
+
=== Token
|
|
42
|
+
|
|
43
|
+
The voting power of each account in our governance setup will be determined by an ERC20 token. The token has to implement the ERC20Votes extension. This extension will keep track of historical balances so that voting power is retrieved from past snapshots rather than current balance, which is an important protection that prevents double voting.
|
|
44
|
+
|
|
45
|
+
```solidity
|
|
46
|
+
include::api:example$governance/MyToken.sol[]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If your project already has a live token that does not include ERC20Votes and is not upgradeable, you can wrap it in a governance token by using ERC20Wrapper. This will allow token holders to participate in governance by wrapping their tokens 1-to-1.
|
|
50
|
+
|
|
51
|
+
```solidity
|
|
52
|
+
include::api:example$governance/MyTokenWrapped.sol[]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
NOTE: The only other source of voting power available in OpenZeppelin Contracts currently is xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`]. ERC721 tokens that don't provide this functionality can be wrapped into a voting tokens using a combination of xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`] and xref:api:token/ERC721Wrapper.adoc#ERC721Wrapper[`ERC721Wrapper`].
|
|
56
|
+
|
|
57
|
+
NOTE: The internal clock used by the token to store voting balances will dictate the operating mode of the Governor contract attached to it. By default, block numbers are used. Since v4.9, developers can override the xref:api:interfaces.adoc#IERC6372[IERC6372] clock to use timestamps instead of block numbers.
|
|
58
|
+
|
|
59
|
+
=== Governor
|
|
60
|
+
|
|
61
|
+
Initially, we will build a Governor without a timelock. The core logic is given by the Governor contract, but we still need to choose: 1) how voting power is determined, 2) how many votes are needed for quorum, 3) what options people have when casting a vote and how those votes are counted, and 4) what type of token should be used to vote. Each of these aspects is customizable by writing your own module, or more easily choosing one from OpenZeppelin Contracts.
|
|
62
|
+
|
|
63
|
+
For 1) we will use the GovernorVotes module, which hooks to an IVotes instance to determine the voting power of an account based on the token balance they hold when a proposal becomes active. This module requires as a constructor parameter the address of the token. This module also discovers the clock mode (ERC6372) used by the token and applies it to the Governor.
|
|
64
|
+
|
|
65
|
+
For 2) we will use GovernorVotesQuorumFraction which works together with ERC20Votes to define quorum as a percentage of the total supply at the block a proposal’s voting power is retrieved. This requires a constructor parameter to set the percentage. Most Governors nowadays use 4%, so we will initialize the module with parameter 4 (this indicates the percentage, resulting in 4%).
|
|
66
|
+
|
|
67
|
+
For 3) we will use GovernorCountingSimple, a module that offers 3 options to voters: For, Against, and Abstain, and where only For and Abstain votes are counted towards quorum.
|
|
68
|
+
|
|
69
|
+
Besides these modules, Governor itself has some parameters we must set.
|
|
70
|
+
|
|
71
|
+
votingDelay: How long after a proposal is created should voting power be fixed. A large voting delay gives users time to unstake tokens if necessary.
|
|
72
|
+
|
|
73
|
+
votingPeriod: How long does a proposal remain open to votes.
|
|
74
|
+
|
|
75
|
+
These parameters are specified in the unit defined in the token's clock. Assuming the token uses block numbers, and assuming block time of around 12 seconds, we will have set votingDelay = 1 day = 7200 blocks, and votingPeriod = 1 week = 50400 blocks.
|
|
76
|
+
|
|
77
|
+
We can optionally set a proposal threshold as well. This restricts proposal creation to accounts who have enough voting power.
|
|
78
|
+
|
|
79
|
+
```solidity
|
|
80
|
+
include::api:example$governance/MyGovernor.sol[]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
=== Timelock
|
|
84
|
+
|
|
85
|
+
It is good practice to add a timelock to governance decisions. This allows users to exit the system if they disagree with a decision before it is executed. We will use OpenZeppelin’s TimelockController in combination with the GovernorTimelockControl module.
|
|
86
|
+
|
|
87
|
+
IMPORTANT: When using a timelock, it is the timelock that will execute proposals and thus the timelock that should hold any funds, ownership, and access control roles. Before version 4.5 there was no way to recover funds in the Governor contract when using a timelock! Before version 4.3, when using the Compound Timelock, ETH in the timelock was not easily accessible.
|
|
88
|
+
|
|
89
|
+
TimelockController uses an AccessControl setup that we need to understand in order to set up roles.
|
|
90
|
+
|
|
91
|
+
- The Proposer role is in charge of queueing operations: this is the role the Governor instance should be granted, and it should likely be the only proposer in the system.
|
|
92
|
+
- The Executor role is in charge of executing already available operations: we can assign this role to the special zero address to allow anyone to execute (if operations can be particularly time sensitive, the Governor should be made Executor instead).
|
|
93
|
+
- Lastly, there is the Admin role, which can grant and revoke the two previous roles: this is a very sensitive role that will be granted automatically to the timelock itself, and optionally to a second account, which can be used for ease of setup but should promptly renounce the role.
|
|
94
|
+
|
|
95
|
+
== Proposal Lifecycle
|
|
96
|
+
|
|
97
|
+
Let’s walk through how to create and execute a proposal on our newly deployed Governor.
|
|
98
|
+
|
|
99
|
+
A proposal is a sequence of actions that the Governor contract will perform if it passes. Each action consists of a target address, calldata encoding a function call, and an amount of ETH to include. Additionally, a proposal includes a human-readable description.
|
|
100
|
+
|
|
101
|
+
=== Create a Proposal
|
|
102
|
+
|
|
103
|
+
Let’s say we want to create a proposal to give a team a grant, in the form of ERC20 tokens from the governance treasury. This proposal will consist of a single action where the target is the ERC20 token, calldata is the encoded function call `transfer(<team wallet>, <grant amount>)`, and with 0 ETH attached.
|
|
104
|
+
|
|
105
|
+
Generally a proposal will be created with the help of an interface such as Tally or Defender. Here we will show how to create the proposal using Ethers.js.
|
|
106
|
+
|
|
107
|
+
First we get all the parameters necessary for the proposal action.
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
const tokenAddress = ...;
|
|
111
|
+
const token = await ethers.getContractAt(‘ERC20’, tokenAddress);
|
|
112
|
+
|
|
113
|
+
const teamAddress = ...;
|
|
114
|
+
const grantAmount = ...;
|
|
115
|
+
const transferCalldata = token.interface.encodeFunctionData(‘transfer’, [teamAddress, grantAmount]);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Now we are ready to call the propose function of the Governor. Note that we don’t pass in one array of actions, but instead three arrays corresponding to the list of targets, the list of values, and the list of calldatas. In this case it’s a single action, so it’s simple:
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
await governor.propose(
|
|
122
|
+
[tokenAddress],
|
|
123
|
+
[0],
|
|
124
|
+
[transferCalldata],
|
|
125
|
+
“Proposal #1: Give grant to team”,
|
|
126
|
+
);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
This will create a new proposal, with a proposal id that is obtained by hashing together the proposal data, and which will also be found in an event in the logs of the transaction.
|
|
130
|
+
|
|
131
|
+
=== Cast a Vote
|
|
132
|
+
|
|
133
|
+
Once a proposal is active, delegates can cast their vote. Note that it is delegates who carry voting power: if a token holder wants to participate, they can set a trusted representative as their delegate, or they can become a delegate themselves by self-delegating their voting power.
|
|
134
|
+
|
|
135
|
+
Votes are cast by interacting with the Governor contract through the `castVote` family of functions. Voters would generally invoke this from a governance UI such as Tally.
|
|
136
|
+
|
|
137
|
+
image::tally-vote.png[Voting in Tally]
|
|
138
|
+
|
|
139
|
+
=== Execute the Proposal
|
|
140
|
+
|
|
141
|
+
Once the voting period is over, if quorum was reached (enough voting power participated) and the majority voted in favor, the proposal is considered successful and can proceed to be executed. Once a proposal passes, it can be queued and executed from the same place you voted.
|
|
142
|
+
|
|
143
|
+
image::tally-exec.png[Administration Panel in Tally]
|
|
144
|
+
|
|
145
|
+
We will see now how to do this manually using Ethers.js.
|
|
146
|
+
|
|
147
|
+
If a timelock was set up, the first step to execution is queueing. You will notice that both the queue and execute functions require passing in the entire proposal parameters, as opposed to just the proposal id. This is necessary because this data is not stored on chain, as a measure to save gas. Note that these parameters can always be found in the events emitted by the contract. The only parameter that is not sent in its entirety is the description, since this is only needed in its hashed form to compute the proposal id.
|
|
148
|
+
|
|
149
|
+
To queue, we call the queue function:
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
const descriptionHash = ethers.utils.id(“Proposal #1: Give grant to team”);
|
|
153
|
+
|
|
154
|
+
await governor.queue(
|
|
155
|
+
[tokenAddress],
|
|
156
|
+
[0],
|
|
157
|
+
[transferCalldata],
|
|
158
|
+
descriptionHash,
|
|
159
|
+
);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
This will cause the Governor to interact with the timelock contract and queue the actions for execution after the required delay.
|
|
163
|
+
|
|
164
|
+
After enough time has passed (according to the timelock parameters), the proposal can be executed. If there was no timelock to begin with, this step can be ran immediately after the proposal succeeds.
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
await governor.execute(
|
|
168
|
+
[tokenAddress],
|
|
169
|
+
[0],
|
|
170
|
+
[transferCalldata],
|
|
171
|
+
descriptionHash,
|
|
172
|
+
);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Executing the proposal will transfer the ERC20 tokens to the chosen recipient. To wrap up: we set up a system where a treasury is controlled by the collective decision of the token holders of a project, and all actions are executed via proposals enforced by on-chain votes.
|
|
176
|
+
|
|
177
|
+
== Timestamp based governance
|
|
178
|
+
|
|
179
|
+
=== Motivation
|
|
180
|
+
|
|
181
|
+
It is sometimes difficult to deal with durations expressed in number of blocks because of inconsistent or unpredictable time between blocks. This is particularly true of some L2 networks where blocks are produced based on blockchain usage. Using number of blocks can also lead to the governance rules being affected by network upgrades that modify the expected time between blocks.
|
|
182
|
+
|
|
183
|
+
The difficulty of replacing block numbers with timestamps is that the Governor and the token must both use the same format when querying past votes. If a token is designed around block numbers, it is not possible for a Governor to reliably do timestamp based lookups.
|
|
184
|
+
|
|
185
|
+
Therefore, designing a timestamp based voting system starts with the token.
|
|
186
|
+
|
|
187
|
+
=== Token
|
|
188
|
+
|
|
189
|
+
Since v4.9, all voting contracts (including xref:api:token/ERC20.adoc#ERC20Votes[`ERC20Votes`] and xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`]) rely on xref:api:interfaces.adoc#IERC6372[IERC6372] for clock management. In order to change from operating with block numbers to operating with timestamps, all that is required is to override the `clock()` and `CLOCK_MODE()` functions.
|
|
190
|
+
|
|
191
|
+
```solidity
|
|
192
|
+
include::api:example$governance/MyTokenTimestampBased.sol[]
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
=== Governor
|
|
196
|
+
|
|
197
|
+
The Governor will automatically detect the clock mode used by the token and adapt to it. There is no need to override anything in the Governor contract. However, the clock mode does affect how some values are interpreted. It is therefore necessary to set the `votingDelay()` and `votingPeriod()` accordingly.
|
|
198
|
+
|
|
199
|
+
```solidity
|
|
200
|
+
// SPDX-License-Identifier: MIT
|
|
201
|
+
pragma solidity ^0.8.20;
|
|
202
|
+
|
|
203
|
+
import {Governor} from "@openzeppelin/contracts/governance/Governor.sol";
|
|
204
|
+
import {GovernorCountingSimple} from "@openzeppelin/contracts/governance/compatibility/GovernorCountingSimple.sol";
|
|
205
|
+
import {GovernorVotes} from "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
|
|
206
|
+
import {GovernorVotesQuorumFraction} from "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
|
|
207
|
+
import {GovernorTimelockControl} from "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
|
|
208
|
+
import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol";
|
|
209
|
+
import {IVotes} from "@openzeppelin/contracts/governance/utils/IVotes.sol";
|
|
210
|
+
|
|
211
|
+
contract MyGovernor is Governor, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl {
|
|
212
|
+
constructor(IVotes _token, TimelockController _timelock)
|
|
213
|
+
Governor("MyGovernor")
|
|
214
|
+
GovernorVotes(_token)
|
|
215
|
+
GovernorVotesQuorumFraction(4)
|
|
216
|
+
GovernorTimelockControl(_timelock)
|
|
217
|
+
{}
|
|
218
|
+
|
|
219
|
+
function votingDelay() public pure virtual override returns (uint256) {
|
|
220
|
+
return 1 days;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function votingPeriod() public pure virtual override returns (uint256) {
|
|
224
|
+
return 1 weeks;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function proposalThreshold() public pure virtual override returns (uint256) {
|
|
228
|
+
return 0;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ...
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
=== Disclaimer
|
|
237
|
+
|
|
238
|
+
Timestamp based voting is a recent feature that was formalized in EIP-6372 and EIP-5805, and introduced in v4.9. At the time this feature is released, governance tooling such as https://www.tally.xyz[Tally] does not support it yet. While support for timestamps should come soon, users can expect invalid reporting of deadlines & durations. This invalid reporting by offchain tools does not affect the onchain security and functionality of the governance contract.
|
|
239
|
+
|
|
240
|
+
Governors with timestamp support (v4.9 and above) are compatible with old tokens (before v4.9) and will operate in "block number" mode (which is the mode all old tokens operate on). On the other hand, old Governor instances (before v4.9) are not compatible with new tokens operating using timestamps. If you update your token code to use timestamps, make sure to also update your Governor code.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
= Contracts
|
|
2
|
+
|
|
3
|
+
*A library for secure smart contract development.* Build on a solid foundation of community-vetted code.
|
|
4
|
+
|
|
5
|
+
* Implementations of standards like xref:erc20.adoc[ERC20] and xref:erc721.adoc[ERC721].
|
|
6
|
+
* Flexible xref:access-control.adoc[role-based permissioning] scheme.
|
|
7
|
+
* Reusable xref:utilities.adoc[Solidity components] to build custom contracts and complex decentralized systems.
|
|
8
|
+
|
|
9
|
+
IMPORTANT: OpenZeppelin Contracts uses semantic versioning to communicate backwards compatibility of its API and storage layout. For upgradeable contracts, the storage layout of different major versions should be assumed incompatible, for example, it is unsafe to upgrade from 4.9.3 to 5.0.0. Learn more at xref:backwards-compatibility.adoc[Backwards Compatibility].
|
|
10
|
+
|
|
11
|
+
== Overview
|
|
12
|
+
|
|
13
|
+
[[install]]
|
|
14
|
+
=== Installation
|
|
15
|
+
|
|
16
|
+
==== Hardhat, Truffle (npm)
|
|
17
|
+
|
|
18
|
+
```console
|
|
19
|
+
$ npm install @openzeppelin/contracts
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
==== Foundry (git)
|
|
23
|
+
|
|
24
|
+
WARNING: When installing via git, it is a common error to use the `master` branch. This is a development branch that should be avoided in favor of tagged releases. The release process involves security measures that the `master` branch does not guarantee.
|
|
25
|
+
|
|
26
|
+
WARNING: Foundry installs the latest version initially, but subsequent `forge update` commands will use the `master` branch.
|
|
27
|
+
|
|
28
|
+
```console
|
|
29
|
+
$ forge install OpenZeppelin/openzeppelin-contracts
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Add `@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/` in `remappings.txt.`
|
|
33
|
+
|
|
34
|
+
[[usage]]
|
|
35
|
+
=== Usage
|
|
36
|
+
|
|
37
|
+
Once installed, you can use the contracts in the library by importing them:
|
|
38
|
+
|
|
39
|
+
[source,solidity]
|
|
40
|
+
----
|
|
41
|
+
// contracts/MyNFT.sol
|
|
42
|
+
// SPDX-License-Identifier: MIT
|
|
43
|
+
pragma solidity ^0.8.20;
|
|
44
|
+
|
|
45
|
+
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
|
|
46
|
+
|
|
47
|
+
contract MyNFT is ERC721 {
|
|
48
|
+
constructor() ERC721("MyNFT", "MNFT") {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
----
|
|
52
|
+
|
|
53
|
+
TIP: If you're new to smart contract development, head to xref:learn::developing-smart-contracts.adoc[Developing Smart Contracts] to learn about creating a new project and compiling your contracts.
|
|
54
|
+
|
|
55
|
+
To keep your system secure, you should **always** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself. The library is designed so that only the contracts and functions you use are deployed, so you don't need to worry about it needlessly increasing gas costs.
|
|
56
|
+
|
|
57
|
+
[[security]]
|
|
58
|
+
== Security
|
|
59
|
+
|
|
60
|
+
Please report any security issues you find via our https://www.immunefi.com/bounty/openzeppelin[bug bounty program on Immunefi] or directly to security@openzeppelin.org.
|
|
61
|
+
|
|
62
|
+
The https://contracts.openzeppelin.com/security[Security Center] contains more details about the secure development process.
|
|
63
|
+
|
|
64
|
+
[[next-steps]]
|
|
65
|
+
== Learn More
|
|
66
|
+
|
|
67
|
+
The guides in the sidebar will teach about different concepts, and how to use the related contracts that OpenZeppelin Contracts provides:
|
|
68
|
+
|
|
69
|
+
* xref:access-control.adoc[Access Control]: decide who can perform each of the actions on your system.
|
|
70
|
+
* xref:tokens.adoc[Tokens]: create tradable assets or collectibles, like the well known xref:erc20.adoc[ERC20] and xref:erc721.adoc[ERC721] standards.
|
|
71
|
+
* xref:utilities.adoc[Utilities]: generic useful tools, including non-overflowing math, signature verification, and trustless paying systems.
|
|
72
|
+
|
|
73
|
+
The xref:api:token/ERC20.adoc[full API] is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts' development in the https://forum.openzeppelin.com[community forum].
|
|
74
|
+
|
|
75
|
+
Finally, you may want to take a look at the https://blog.openzeppelin.com/guides/[guides on our blog], which cover several common use cases and good practices. The following articles provide great background reading, though please note, some of the referenced tools have changed as the tooling in the ecosystem continues to rapidly evolve.
|
|
76
|
+
|
|
77
|
+
* https://blog.openzeppelin.com/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05[The Hitchhiker’s Guide to Smart Contracts in Ethereum] will help you get an overview of the various tools available for smart contract development, and help you set up your environment.
|
|
78
|
+
* https://blog.openzeppelin.com/a-gentle-introduction-to-ethereum-programming-part-1-783cc7796094[A Gentle Introduction to Ethereum Programming, Part 1] provides very useful information on an introductory level, including many basic concepts from the Ethereum platform.
|
|
79
|
+
* For a more in-depth dive, you may read the guide https://blog.openzeppelin.com/designing-the-architecture-for-your-ethereum-application-9cec086f8317[Designing the architecture for your Ethereum application], which discusses how to better structure your application and its relationship to the real world.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
= Tokens
|
|
2
|
+
|
|
3
|
+
Ah, the "token": blockchain's most powerful and most misunderstood tool.
|
|
4
|
+
|
|
5
|
+
A token is a _representation of something in the blockchain_. This something can be money, time, services, shares in a company, a virtual pet, anything. By representing things as tokens, we can allow smart contracts to interact with them, exchange them, create or destroy them.
|
|
6
|
+
|
|
7
|
+
[[but_first_coffee_a_primer_on_token_contracts]]
|
|
8
|
+
== But First, [strikethrough]#Coffee# a Primer on Token Contracts
|
|
9
|
+
|
|
10
|
+
Much of the confusion surrounding tokens comes from two concepts getting mixed up: _token contracts_ and the actual _tokens_.
|
|
11
|
+
|
|
12
|
+
A _token contract_ is simply an Ethereum smart contract. "Sending tokens" actually means "calling a method on a smart contract that someone wrote and deployed". At the end of the day, a token contract is not much more than a mapping of addresses to balances, plus some methods to add and subtract from those balances.
|
|
13
|
+
|
|
14
|
+
It is these balances that represent the _tokens_ themselves. Someone "has tokens" when their balance in the token contract is non-zero. That's it! These balances could be considered money, experience points in a game, deeds of ownership, or voting rights, and each of these tokens would be stored in different token contracts.
|
|
15
|
+
|
|
16
|
+
[[different-kinds-of-tokens]]
|
|
17
|
+
== Different Kinds of Tokens
|
|
18
|
+
|
|
19
|
+
Note that there's a big difference between having two voting rights and two deeds of ownership: each vote is equal to all others, but houses usually are not! This is called https://en.wikipedia.org/wiki/Fungibility[fungibility]. _Fungible goods_ are equivalent and interchangeable, like Ether, fiat currencies, and voting rights. _Non-fungible_ goods are unique and distinct, like deeds of ownership, or collectibles.
|
|
20
|
+
|
|
21
|
+
In a nutshell, when dealing with non-fungibles (like your house) you care about _which ones_ you have, while in fungible assets (like your bank account statement) what matters is _how much_ you have.
|
|
22
|
+
|
|
23
|
+
== Standards
|
|
24
|
+
|
|
25
|
+
Even though the concept of a token is simple, they have a variety of complexities in the implementation. Because everything in Ethereum is just a smart contract, and there are no rules about what smart contracts have to do, the community has developed a variety of *standards* (called EIPs or ERCs) for documenting how a contract can interoperate with other contracts.
|
|
26
|
+
|
|
27
|
+
You've probably heard of the ERC20 or ERC721 token standards, and that's why you're here. Head to our specialized guides to learn more about these:
|
|
28
|
+
|
|
29
|
+
* xref:erc20.adoc[ERC20]: the most widespread token standard for fungible assets, albeit somewhat limited by its simplicity.
|
|
30
|
+
* xref:erc721.adoc[ERC721]: the de-facto solution for non-fungible tokens, often used for collectibles and games.
|
|
31
|
+
* xref:erc1155.adoc[ERC1155]: a novel standard for multi-tokens, allowing for a single contract to represent multiple fungible and non-fungible tokens, along with batched operations for increased gas efficiency.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
= Using with Upgrades
|
|
2
|
+
|
|
3
|
+
If your contract is going to be deployed with upgradeability, such as using the xref:upgrades-plugins::index.adoc[OpenZeppelin Upgrades Plugins], you will need to use the Upgradeable variant of OpenZeppelin Contracts.
|
|
4
|
+
|
|
5
|
+
This variant is available as a separate package called `@openzeppelin/contracts-upgradeable`, which is hosted in the repository https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable[OpenZeppelin/openzeppelin-contracts-upgradeable]. It uses `@openzeppelin/contracts` as a peer dependency.
|
|
6
|
+
|
|
7
|
+
It follows all of the rules for xref:upgrades-plugins::writing-upgradeable.adoc[Writing Upgradeable Contracts]: constructors are replaced by initializer functions, state variables are initialized in initializer functions, and we additionally check for storage incompatibilities across minor versions.
|
|
8
|
+
|
|
9
|
+
TIP: OpenZeppelin provides a full suite of tools for deploying and securing upgradeable smart contracts. xref:openzeppelin::upgrades.adoc[Check out the full list of resources].
|
|
10
|
+
|
|
11
|
+
== Overview
|
|
12
|
+
|
|
13
|
+
=== Installation
|
|
14
|
+
|
|
15
|
+
```console
|
|
16
|
+
$ npm install @openzeppelin/contracts-upgradeable @openzeppelin/contracts
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
=== Usage
|
|
20
|
+
|
|
21
|
+
The Upgradeable package replicates the structure of the main OpenZeppelin Contracts package, but every file and contract has the suffix `Upgradeable`.
|
|
22
|
+
|
|
23
|
+
```diff
|
|
24
|
+
-import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
|
|
25
|
+
+import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
|
|
26
|
+
|
|
27
|
+
-contract MyCollectible is ERC721 {
|
|
28
|
+
+contract MyCollectible is ERC721Upgradeable {
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
NOTE: Interfaces and libraries are not included in the Upgradeable package, but are instead imported from the main OpenZeppelin Contracts package.
|
|
32
|
+
|
|
33
|
+
Constructors are replaced by internal initializer functions following the naming convention `+__{ContractName}_init+`. Since these are internal, you must always define your own public initializer function and call the parent initializer of the contract you extend.
|
|
34
|
+
|
|
35
|
+
```diff
|
|
36
|
+
- constructor() ERC721("MyCollectible", "MCO") public {
|
|
37
|
+
+ function initialize() initializer public {
|
|
38
|
+
+ __ERC721_init("MyCollectible", "MCO");
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
CAUTION: Use with multiple inheritance requires special attention. See the section below titled <<multiple-inheritance>>.
|
|
43
|
+
|
|
44
|
+
Once this contract is set up and compiled, you can deploy it using the xref:upgrades-plugins::index.adoc[Upgrades Plugins]. The following snippet shows an example deployment script using Hardhat.
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
// scripts/deploy-my-collectible.js
|
|
48
|
+
const { ethers, upgrades } = require("hardhat");
|
|
49
|
+
|
|
50
|
+
async function main() {
|
|
51
|
+
const MyCollectible = await ethers.getContractFactory("MyCollectible");
|
|
52
|
+
|
|
53
|
+
const mc = await upgrades.deployProxy(MyCollectible);
|
|
54
|
+
|
|
55
|
+
await mc.waitForDeployment();
|
|
56
|
+
console.log("MyCollectible deployed to:", await mc.getAddress());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
main();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
== Further Notes
|
|
63
|
+
|
|
64
|
+
[[multiple-inheritance]]
|
|
65
|
+
=== Multiple Inheritance
|
|
66
|
+
|
|
67
|
+
Initializer functions are not linearized by the compiler like constructors. Because of this, each `+__{ContractName}_init+` function embeds the linearized calls to all parent initializers. As a consequence, calling two of these `init` functions can potentially initialize the same contract twice.
|
|
68
|
+
|
|
69
|
+
The function `+__{ContractName}_init_unchained+` found in every contract is the initializer function minus the calls to parent initializers, and can be used to avoid the double initialization problem, but doing this manually is not recommended. We hope to be able to implement safety checks for this in future versions of the Upgrades Plugins.
|
|
70
|
+
|
|
71
|
+
=== Namespaced Storage
|
|
72
|
+
|
|
73
|
+
You may notice that contracts use a struct with the `@custom:storage-location erc7201:<NAMESPACE_ID>` annotation to store the contract's state variables. This follows the https://eips.ethereum.org/EIPS/eip-7201[ERC-7201: Namespaced Storage Layout] pattern, where each contract has its own storage layout in a namespace that is separate from other contracts in the inheritance chain.
|
|
74
|
+
|
|
75
|
+
Without namespaced storage, it isn't safe to simply add a state variable because it "shifts down" all of the state variables below in the inheritance chain. This makes the storage layouts incompatible, as explained in xref:upgrades-plugins::writing-upgradeable.adoc#modifying-your-contracts[Writing Upgradeable Contracts].
|
|
76
|
+
|
|
77
|
+
The namespaced storage pattern used in the Upgradeable package allows us to freely add new state variables in the future without compromising the storage compatibility with existing deployments. It also allows changing the inheritance order with no impact on the resulting storage layout, as long as all inherited contracts use namespaced storage.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
= Utilities
|
|
2
|
+
|
|
3
|
+
The OpenZeppelin Contracts provide a ton of useful utilities that you can use in your project. Here are some of the more popular ones.
|
|
4
|
+
|
|
5
|
+
[[cryptography]]
|
|
6
|
+
== Cryptography
|
|
7
|
+
|
|
8
|
+
=== Checking Signatures On-Chain
|
|
9
|
+
|
|
10
|
+
xref:api:utils.adoc#ECDSA[`ECDSA`] provides functions for recovering and managing Ethereum account ECDSA signatures. These are often generated via https://web3js.readthedocs.io/en/v1.7.3/web3-eth.html#sign[`web3.eth.sign`], and are a 65 byte array (of type `bytes` in Solidity) arranged the following way: `[[v (1)], [r (32)], [s (32)]]`.
|
|
11
|
+
|
|
12
|
+
The data signer can be recovered with xref:api:utils.adoc#ECDSA-recover-bytes32-bytes-[`ECDSA.recover`], and its address compared to verify the signature. Most wallets will hash the data to sign and add the prefix '\x19Ethereum Signed Message:\n', so when attempting to recover the signer of an Ethereum signed message hash, you'll want to use xref:api:utils.adoc#MessageHashUtils-toEthSignedMessageHash-bytes32-[`toEthSignedMessageHash`].
|
|
13
|
+
|
|
14
|
+
[source,solidity]
|
|
15
|
+
----
|
|
16
|
+
using ECDSA for bytes32;
|
|
17
|
+
using MessageHashUtils for bytes32;
|
|
18
|
+
|
|
19
|
+
function _verify(bytes32 data, bytes memory signature, address account) internal pure returns (bool) {
|
|
20
|
+
return data
|
|
21
|
+
.toEthSignedMessageHash()
|
|
22
|
+
.recover(signature) == account;
|
|
23
|
+
}
|
|
24
|
+
----
|
|
25
|
+
|
|
26
|
+
WARNING: Getting signature verification right is not trivial: make sure you fully read and understand xref:api:utils.adoc#MessageHashUtils[`MessageHashUtils`]'s and xref:api:utils.adoc#ECDSA[`ECDSA`]'s documentation.
|
|
27
|
+
|
|
28
|
+
=== Verifying Merkle Proofs
|
|
29
|
+
|
|
30
|
+
xref:api:utils.adoc#MerkleProof[`MerkleProof`] provides:
|
|
31
|
+
|
|
32
|
+
* xref:api:utils.adoc#MerkleProof-verify-bytes32---bytes32-bytes32-[`verify`] - can prove that some value is part of a https://en.wikipedia.org/wiki/Merkle_tree[Merkle tree].
|
|
33
|
+
|
|
34
|
+
* xref:api:utils.adoc#MerkleProof-multiProofVerify-bytes32-bytes32---bytes32---bool---[`multiProofVerify`] - can prove multiple values are part of a Merkle tree.
|
|
35
|
+
|
|
36
|
+
[[introspection]]
|
|
37
|
+
== Introspection
|
|
38
|
+
|
|
39
|
+
In Solidity, it's frequently helpful to know whether or not a contract supports an interface you'd like to use. ERC165 is a standard that helps do runtime interface detection. Contracts provide helpers both for implementing ERC165 in your contracts and querying other contracts:
|
|
40
|
+
|
|
41
|
+
* xref:api:utils.adoc#IERC165[`IERC165`] — this is the ERC165 interface that defines xref:api:utils.adoc#IERC165-supportsInterface-bytes4-[`supportsInterface`]. When implementing ERC165, you'll conform to this interface.
|
|
42
|
+
* xref:api:utils.adoc#ERC165[`ERC165`] — inherit this contract if you'd like to support interface detection using a lookup table in contract storage. You can register interfaces using xref:api:utils.adoc#ERC165-_registerInterface-bytes4-[`_registerInterface(bytes4)`]: check out example usage as part of the ERC721 implementation.
|
|
43
|
+
* xref:api:utils.adoc#ERC165Checker[`ERC165Checker`] — ERC165Checker simplifies the process of checking whether or not a contract supports an interface you care about.
|
|
44
|
+
* include with `using ERC165Checker for address;`
|
|
45
|
+
* xref:api:utils.adoc#ERC165Checker-_supportsInterface-address-bytes4-[`myAddress._supportsInterface(bytes4)`]
|
|
46
|
+
* xref:api:utils.adoc#ERC165Checker-_supportsAllInterfaces-address-bytes4---[`myAddress._supportsAllInterfaces(bytes4[\])`]
|
|
47
|
+
|
|
48
|
+
[source,solidity]
|
|
49
|
+
----
|
|
50
|
+
contract MyContract {
|
|
51
|
+
using ERC165Checker for address;
|
|
52
|
+
|
|
53
|
+
bytes4 private InterfaceId_ERC721 = 0x80ac58cd;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @dev transfer an ERC721 token from this contract to someone else
|
|
57
|
+
*/
|
|
58
|
+
function transferERC721(
|
|
59
|
+
address token,
|
|
60
|
+
address to,
|
|
61
|
+
uint256 tokenId
|
|
62
|
+
)
|
|
63
|
+
public
|
|
64
|
+
{
|
|
65
|
+
require(token.supportsInterface(InterfaceId_ERC721), "IS_NOT_721_TOKEN");
|
|
66
|
+
IERC721(token).transferFrom(address(this), to, tokenId);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
----
|
|
70
|
+
|
|
71
|
+
[[math]]
|
|
72
|
+
== Math
|
|
73
|
+
|
|
74
|
+
The most popular math related library OpenZeppelin Contracts provides is xref:api:utils.adoc#SafeMath[`SafeMath`], which provides mathematical functions that protect your contract from overflows and underflows.
|
|
75
|
+
|
|
76
|
+
Include the contract with `using SafeMath for uint256;` and then call the functions:
|
|
77
|
+
|
|
78
|
+
* `myNumber.add(otherNumber)`
|
|
79
|
+
* `myNumber.sub(otherNumber)`
|
|
80
|
+
* `myNumber.div(otherNumber)`
|
|
81
|
+
* `myNumber.mul(otherNumber)`
|
|
82
|
+
* `myNumber.mod(otherNumber)`
|
|
83
|
+
|
|
84
|
+
Easy!
|
|
85
|
+
|
|
86
|
+
[[payment]]
|
|
87
|
+
== Payment
|
|
88
|
+
|
|
89
|
+
Want to split some payments between multiple people? Maybe you have an app that sends 30% of art purchases to the original creator and 70% of the profits to the current owner; you can build that with xref:api:finance.adoc#PaymentSplitter[`PaymentSplitter`]!
|
|
90
|
+
|
|
91
|
+
In Solidity, there are some security concerns with blindly sending money to accounts, since it allows them to execute arbitrary code. You can read up on these security concerns in the https://consensys.github.io/smart-contract-best-practices/[Ethereum Smart Contract Best Practices] website.
|
|
92
|
+
|
|
93
|
+
[[collections]]
|
|
94
|
+
== Collections
|
|
95
|
+
|
|
96
|
+
If you need support for more powerful collections than Solidity's native arrays and mappings, take a look at xref:api:utils.adoc#EnumerableSet[`EnumerableSet`] and xref:api:utils.adoc#EnumerableMap[`EnumerableMap`]. They are similar to mappings in that they store and remove elements in constant time and don't allow for repeated entries, but they also support _enumeration_, which means you can easily query all stored entries both on and off-chain.
|
|
97
|
+
|
|
98
|
+
[[misc]]
|
|
99
|
+
== Misc
|
|
100
|
+
|
|
101
|
+
=== Base64
|
|
102
|
+
|
|
103
|
+
xref:api:utils.adoc#Base64[`Base64`] util allows you to transform `bytes32` data into its Base64 `string` representation.
|
|
104
|
+
|
|
105
|
+
This is especially useful for building URL-safe tokenURIs for both xref:api:token/ERC721.adoc#IERC721Metadata-tokenURI-uint256-[`ERC721`] or xref:api:token/ERC1155.adoc#IERC1155MetadataURI-uri-uint256-[`ERC1155`]. This library provides a clever way to serve URL-safe https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs/[Data URI] compliant strings to serve on-chain data structures.
|
|
106
|
+
|
|
107
|
+
Here is an example to send JSON Metadata through a Base64 Data URI using an ERC721:
|
|
108
|
+
|
|
109
|
+
[source, solidity]
|
|
110
|
+
----
|
|
111
|
+
// contracts/My721Token.sol
|
|
112
|
+
// SPDX-License-Identifier: MIT
|
|
113
|
+
|
|
114
|
+
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
|
|
115
|
+
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
|
116
|
+
import {Base64} from "@openzeppelin/contracts/utils/Base64.sol";
|
|
117
|
+
|
|
118
|
+
contract My721Token is ERC721 {
|
|
119
|
+
using Strings for uint256;
|
|
120
|
+
|
|
121
|
+
constructor() ERC721("My721Token", "MTK") {}
|
|
122
|
+
|
|
123
|
+
...
|
|
124
|
+
|
|
125
|
+
function tokenURI(uint256 tokenId)
|
|
126
|
+
public
|
|
127
|
+
pure
|
|
128
|
+
override
|
|
129
|
+
returns (string memory)
|
|
130
|
+
{
|
|
131
|
+
bytes memory dataURI = abi.encodePacked(
|
|
132
|
+
'{',
|
|
133
|
+
'"name": "My721Token #', tokenId.toString(), '"',
|
|
134
|
+
// Replace with extra ERC721 Metadata properties
|
|
135
|
+
'}'
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
return string(
|
|
139
|
+
abi.encodePacked(
|
|
140
|
+
"data:application/json;base64,",
|
|
141
|
+
Base64.encode(dataURI)
|
|
142
|
+
)
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
----
|
|
147
|
+
|
|
148
|
+
=== Multicall
|
|
149
|
+
|
|
150
|
+
The `Multicall` abstract contract comes with a `multicall` function that bundles together multiple calls in a single external call. With it, external accounts may perform atomic operations comprising several function calls. This is not only useful for EOAs to make multiple calls in a single transaction, it's also a way to revert a previous call if a later one fails.
|
|
151
|
+
|
|
152
|
+
Consider this dummy contract:
|
|
153
|
+
|
|
154
|
+
[source,solidity]
|
|
155
|
+
----
|
|
156
|
+
// contracts/Box.sol
|
|
157
|
+
// SPDX-License-Identifier: MIT
|
|
158
|
+
pragma solidity ^0.8.20;
|
|
159
|
+
|
|
160
|
+
import "@openzeppelin/contracts/utils/Multicall.sol";
|
|
161
|
+
|
|
162
|
+
contract Box is Multicall {
|
|
163
|
+
function foo() public {
|
|
164
|
+
...
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function bar() public {
|
|
168
|
+
...
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
----
|
|
172
|
+
|
|
173
|
+
This is how to call the `multicall` function using Truffle, allowing `foo` and `bar` to be called in a single transaction:
|
|
174
|
+
[source,javascript]
|
|
175
|
+
----
|
|
176
|
+
// scripts/foobar.js
|
|
177
|
+
|
|
178
|
+
const Box = artifacts.require('Box');
|
|
179
|
+
const instance = await Box.new();
|
|
180
|
+
|
|
181
|
+
await instance.multicall([
|
|
182
|
+
instance.contract.methods.foo().encodeABI(),
|
|
183
|
+
instance.contract.methods.bar().encodeABI()
|
|
184
|
+
]);
|
|
185
|
+
----
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
= Contracts Wizard
|
|
2
|
+
:page-notoc:
|
|
3
|
+
|
|
4
|
+
Not sure where to start? Use the interactive generator below to bootstrap your
|
|
5
|
+
contract and learn about the components offered in OpenZeppelin Contracts.
|
|
6
|
+
|
|
7
|
+
TIP: Place the resulting contract in your `contracts` directory in order to compile it with a tool like Hardhat or Truffle. Consider reading our guide on xref:learn::developing-smart-contracts.adoc[Developing Smart Contracts] for more guidance!
|
|
8
|
+
|
|
9
|
+
++++
|
|
10
|
+
<script async src="https://wizard.openzeppelin.com/build/embed.js"></script>
|
|
11
|
+
|
|
12
|
+
<oz-wizard style="display: block; min-height: 40rem;"></oz-wizard>
|
|
13
|
+
++++
|
|
14
|
+
|
|
15
|
+
|