polkamarkets-js 3.4.1 → 3.4.2
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/package.json +1 -1
- package/src/models/PredictionMarketV3Contract.js +49 -16
- package/abis/AccessControlUpgradeable.json +0 -1
- package/abis/AddAdminToLand.json +0 -1
- package/abis/AddressUpgradeable.json +0 -1
- package/abis/ClaimMerkleRoot.json +0 -1
- package/abis/CreateLand.json +0 -1
- package/abis/CreateMarkets.json +0 -1
- package/abis/DeployContracts.json +0 -1
- package/abis/DeployMerkleRewardsDistributor.json +0 -1
- package/abis/DeployToken.json +0 -1
- package/abis/DeployUSDT.json +0 -1
- package/abis/ECDSA.json +0 -1
- package/abis/ERC165Upgradeable.json +0 -1
- package/abis/ERC1967UpgradeUpgradeable.json +0 -1
- package/abis/Hashes.json +0 -1
- package/abis/IBeaconUpgradeable.json +0 -1
- package/abis/IERC1822ProxiableUpgradeable.json +0 -1
- package/abis/IERC20PermitUpgradeable.json +0 -1
- package/abis/IERC20Upgradeable.json +0 -1
- package/abis/Manager.json +0 -1
- package/abis/MerkleProof.json +0 -1
- package/abis/MerkleRewardsDistributor.json +0 -1
- package/abis/MerkleRewardsDistributorTest.json +0 -1
- package/abis/MessageHashUtils.json +0 -1
- package/abis/MintTokens.json +0 -1
- package/abis/Nonces.json +0 -1
- package/abis/Panic.json +0 -1
- package/abis/PublishMerkleRoot.json +0 -1
- package/abis/ResolveMarket.json +0 -1
- package/abis/RewardsDistributor.json +0 -1
- package/abis/RewardsDistributorTest.json +0 -1
- package/abis/SafeCast.json +0 -1
- package/abis/SafeERC20Upgradeable.json +0 -1
- package/abis/SignedMath.json +0 -1
- package/abis/StorageSlotUpgradeable.json +0 -1
- package/abis/TradeMarket.json +0 -1
- package/abis/USDT.json +0 -1
- package/abis/UpdateMarket.json +0 -1
- package/abis/UpdateTest.json +0 -1
- package/abis/WhaleTest.json +0 -1
- package/lib/openzeppelin-contracts/contracts/mocks/docs/ERC20WithAutoMinerReward.sol +0 -22
- package/lib/openzeppelin-contracts/contracts/mocks/docs/ERC4626Fees.sol +0 -109
- package/lib/openzeppelin-contracts/contracts/mocks/docs/MyNFT.sol +0 -9
- package/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintBase.sol +0 -25
- package/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintMissing.sol +0 -24
- package/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintOnlyRole.sol +0 -23
- package/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlModified.sol +0 -14
- package/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessManagedERC20MintBase.sol +0 -16
- package/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/MyContractOwnable.sol +0 -17
- package/lib/openzeppelin-contracts/contracts/mocks/docs/account/MyAccountERC7702.sol +0 -20
- package/lib/openzeppelin-contracts/contracts/mocks/docs/account/MyFactoryAccount.sol +0 -37
- package/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyGovernor.sol +0 -80
- package/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyToken.sol +0 -21
- package/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyTokenTimestampBased.sol +0 -32
- package/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyTokenWrapped.sol +0 -28
- package/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC1155/GameItems.sol +0 -21
- package/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC1155/MyERC115HolderContract.sol +0 -7
- package/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC20/GLDToken.sol +0 -11
- package/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC6909/ERC6909GameItems.sol +0 -26
- package/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC721/GameItem.sol +0 -19
- package/lib/openzeppelin-contracts/contracts/mocks/docs/utilities/Base64NFT.sol +0 -27
- package/lib/openzeppelin-contracts/contracts/mocks/docs/utilities/Multicall.sol +0 -15
- package/lib/openzeppelin-contracts/docs/README.md +0 -16
- package/lib/openzeppelin-contracts/docs/antora.yml +0 -7
- package/lib/openzeppelin-contracts/docs/config.js +0 -21
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/access-control-multiple.svg +0 -97
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/access-manager-functions.svg +0 -47
- package/lib/openzeppelin-contracts/docs/modules/ROOT/images/access-manager.svg +0 -99
- 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 +0 -29
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/access-control.adoc +0 -288
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/account-abstraction.adoc +0 -100
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/accounts.adoc +0 -354
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/backwards-compatibility.adoc +0 -50
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/eoa-delegation.adoc +0 -143
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc1155.adoc +0 -118
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc20-supply.adoc +0 -71
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc20.adoc +0 -67
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc4626.adoc +0 -214
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc6909.adoc +0 -47
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc721.adoc +0 -58
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/extending-contracts.adoc +0 -51
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/faq.adoc +0 -13
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/governance.adoc +0 -239
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/index.adoc +0 -70
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/multisig.adoc +0 -306
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/tokens.adoc +0 -31
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/upgradeable.adoc +0 -77
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/utilities.adoc +0 -591
- package/lib/openzeppelin-contracts/docs/modules/ROOT/pages/wizard.adoc +0 -15
- package/lib/openzeppelin-contracts/docs/templates/contract.hbs +0 -141
- package/lib/openzeppelin-contracts/docs/templates/helpers.js +0 -46
- package/lib/openzeppelin-contracts/docs/templates/page.hbs +0 -4
- package/lib/openzeppelin-contracts/docs/templates/properties.js +0 -88
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/ERC20WithAutoMinerRewardUpgradeable.sol +0 -28
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/ERC4626FeesUpgradeable.sol +0 -115
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/MyNFTUpgradeable.sol +0 -14
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/access-control/AccessControlERC20MintBaseUpgradeable.sol +0 -31
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/access-control/AccessControlERC20MintMissingUpgradeable.sol +0 -30
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/access-control/AccessControlERC20MintOnlyRoleUpgradeable.sol +0 -29
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/access-control/AccessControlModifiedUpgradeable.sol +0 -20
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/access-control/AccessManagedERC20MintBaseUpgradeable.sol +0 -22
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/access-control/MyContractOwnableUpgradeable.sol +0 -22
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/account/MyAccountERC7702Upgradeable.sol +0 -26
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/account/MyFactoryAccountUpgradeable.sol +0 -42
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/governance/MyGovernorUpgradeable.sol +0 -92
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/governance/MyTokenTimestampBasedUpgradeable.sol +0 -39
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/governance/MyTokenUpgradeable.sol +0 -28
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/governance/MyTokenWrappedUpgradeable.sol +0 -39
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/token/ERC1155/GameItemsUpgradeable.sol +0 -27
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/token/ERC1155/MyERC115HolderContractUpgradeable.sol +0 -13
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/token/ERC20/GLDTokenUpgradeable.sol +0 -17
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/token/ERC6909/ERC6909GameItemsUpgradeable.sol +0 -31
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/token/ERC721/GameItemUpgradeable.sol +0 -24
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/utilities/Base64NFTUpgradeable.sol +0 -32
- package/lib/openzeppelin-contracts-upgradeable/contracts/mocks/docs/utilities/MulticallUpgradeable.sol +0 -21
- package/lib/openzeppelin-contracts-upgradeable/docs/README.md +0 -16
- package/lib/openzeppelin-contracts-upgradeable/docs/antora.yml +0 -7
- package/lib/openzeppelin-contracts-upgradeable/docs/config.js +0 -21
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/access-control-multiple.svg +0 -97
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/access-manager-functions.svg +0 -47
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/access-manager.svg +0 -99
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/erc4626-attack-3a.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/erc4626-attack-3b.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/erc4626-attack-6.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/erc4626-attack.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/erc4626-deposit.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/erc4626-mint.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/erc4626-rate-linear.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/erc4626-rate-loglog.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/erc4626-rate-loglogext.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/tally-exec.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/images/tally-vote.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/nav.adoc +0 -29
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/access-control.adoc +0 -288
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/account-abstraction.adoc +0 -100
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/accounts.adoc +0 -354
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/backwards-compatibility.adoc +0 -50
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/eoa-delegation.adoc +0 -143
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/erc1155.adoc +0 -118
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/erc20-supply.adoc +0 -71
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/erc20.adoc +0 -67
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/erc4626.adoc +0 -214
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/erc6909.adoc +0 -47
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/erc721.adoc +0 -58
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/extending-contracts.adoc +0 -51
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/faq.adoc +0 -13
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/governance.adoc +0 -239
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/index.adoc +0 -70
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/multisig.adoc +0 -306
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/tokens.adoc +0 -31
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/upgradeable.adoc +0 -77
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/utilities.adoc +0 -591
- package/lib/openzeppelin-contracts-upgradeable/docs/modules/ROOT/pages/wizard.adoc +0 -15
- package/lib/openzeppelin-contracts-upgradeable/docs/templates/contract.hbs +0 -141
- package/lib/openzeppelin-contracts-upgradeable/docs/templates/helpers.js +0 -46
- package/lib/openzeppelin-contracts-upgradeable/docs/templates/page.hbs +0 -4
- package/lib/openzeppelin-contracts-upgradeable/docs/templates/properties.js +0 -88
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/ERC20WithAutoMinerReward.sol +0 -22
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/ERC4626Fees.sol +0 -109
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/MyNFT.sol +0 -9
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintBase.sol +0 -25
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintMissing.sol +0 -24
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintOnlyRole.sol +0 -23
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlModified.sol +0 -14
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessManagedERC20MintBase.sol +0 -16
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/access-control/MyContractOwnable.sol +0 -17
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/account/MyAccountERC7702.sol +0 -20
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/account/MyFactoryAccount.sol +0 -37
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyGovernor.sol +0 -80
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyToken.sol +0 -21
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyTokenTimestampBased.sol +0 -32
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/governance/MyTokenWrapped.sol +0 -28
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC1155/GameItems.sol +0 -21
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC1155/MyERC115HolderContract.sol +0 -7
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC20/GLDToken.sol +0 -11
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC6909/ERC6909GameItems.sol +0 -26
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/token/ERC721/GameItem.sol +0 -19
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/utilities/Base64NFT.sol +0 -27
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/mocks/docs/utilities/Multicall.sol +0 -15
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/README.md +0 -16
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/antora.yml +0 -7
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/config.js +0 -21
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/access-control-multiple.svg +0 -97
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/access-manager-functions.svg +0 -47
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/access-manager.svg +0 -99
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack-3a.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack-3b.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack-6.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-attack.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-deposit.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-mint.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-rate-linear.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-rate-loglog.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/erc4626-rate-loglogext.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/tally-exec.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/images/tally-vote.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/nav.adoc +0 -29
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/access-control.adoc +0 -288
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/account-abstraction.adoc +0 -100
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/accounts.adoc +0 -354
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/backwards-compatibility.adoc +0 -50
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/eoa-delegation.adoc +0 -143
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc1155.adoc +0 -118
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc20-supply.adoc +0 -71
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc20.adoc +0 -67
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc4626.adoc +0 -214
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc6909.adoc +0 -47
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/erc721.adoc +0 -58
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/extending-contracts.adoc +0 -51
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/faq.adoc +0 -13
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/governance.adoc +0 -239
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/index.adoc +0 -70
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/multisig.adoc +0 -306
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/tokens.adoc +0 -31
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/upgradeable.adoc +0 -77
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/utilities.adoc +0 -591
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/modules/ROOT/pages/wizard.adoc +0 -15
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/templates/contract.hbs +0 -141
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/templates/helpers.js +0 -46
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/templates/page.hbs +0 -4
- package/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/docs/templates/properties.js +0 -88
- package/lib/openzeppelin-contracts-upgradeable.git/docs/antora.yml +0 -6
- package/lib/openzeppelin-contracts-upgradeable.git/docs/config.js +0 -21
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/images/tally-exec.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/images/tally-vote.png +0 -0
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/nav.adoc +0 -23
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/access-control.adoc +0 -217
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/crosschain.adoc +0 -210
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/crowdsales.adoc +0 -11
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/drafts.adoc +0 -19
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/erc1155.adoc +0 -153
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/erc20-supply.adoc +0 -113
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/erc20.adoc +0 -85
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/erc721.adoc +0 -90
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/erc777.adoc +0 -73
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/extending-contracts.adoc +0 -129
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/governance.adoc +0 -321
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/index.adoc +0 -63
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/releases-stability.adoc +0 -85
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/tokens.adoc +0 -32
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/upgradeable.adoc +0 -73
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/utilities.adoc +0 -190
- package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/wizard.adoc +0 -15
- package/lib/openzeppelin-contracts-upgradeable.git/docs/templates/contract.hbs +0 -85
- package/lib/openzeppelin-contracts-upgradeable.git/docs/templates/helpers.js +0 -46
- package/lib/openzeppelin-contracts-upgradeable.git/docs/templates/page.hbs +0 -4
- package/lib/openzeppelin-contracts-upgradeable.git/docs/templates/properties.js +0 -49
- package/lib/openzeppelin-contracts.git/docs/antora.yml +0 -6
- package/lib/openzeppelin-contracts.git/docs/config.js +0 -21
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/images/tally-exec.png +0 -0
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/images/tally-vote.png +0 -0
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/nav.adoc +0 -23
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/access-control.adoc +0 -217
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/crosschain.adoc +0 -210
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/crowdsales.adoc +0 -11
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/drafts.adoc +0 -19
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/erc1155.adoc +0 -153
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/erc20-supply.adoc +0 -113
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/erc20.adoc +0 -85
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/erc721.adoc +0 -90
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/erc777.adoc +0 -73
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/extending-contracts.adoc +0 -129
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/governance.adoc +0 -321
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/index.adoc +0 -63
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/releases-stability.adoc +0 -85
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/tokens.adoc +0 -32
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/upgradeable.adoc +0 -73
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/utilities.adoc +0 -190
- package/lib/openzeppelin-contracts.git/docs/modules/ROOT/pages/wizard.adoc +0 -15
- package/lib/openzeppelin-contracts.git/docs/templates/contract.hbs +0 -85
- package/lib/openzeppelin-contracts.git/docs/templates/helpers.js +0 -46
- package/lib/openzeppelin-contracts.git/docs/templates/page.hbs +0 -4
- package/lib/openzeppelin-contracts.git/docs/templates/properties.js +0 -49
- package/lib/reality-eth-monorepo/packages/docs/Audit_Reality_v3_202108.pdf +0 -0
- package/lib/reality-eth-monorepo/packages/docs/Makefile +0 -20
- package/lib/reality-eth-monorepo/packages/docs/arbitrators.rst +0 -85
- package/lib/reality-eth-monorepo/packages/docs/audit.rst +0 -12
- package/lib/reality-eth-monorepo/packages/docs/audit_v2.rst +0 -249
- package/lib/reality-eth-monorepo/packages/docs/audit_v2_ERC20.rst +0 -1075
- package/lib/reality-eth-monorepo/packages/docs/audit_v3.rst +0 -70
- package/lib/reality-eth-monorepo/packages/docs/conf.py +0 -155
- package/lib/reality-eth-monorepo/packages/docs/contract_explanation.rst +0 -82
- package/lib/reality-eth-monorepo/packages/docs/contracts.rst +0 -277
- package/lib/reality-eth-monorepo/packages/docs/dapp.rst +0 -126
- package/lib/reality-eth-monorepo/packages/docs/dapp_links.rst +0 -67
- package/lib/reality-eth-monorepo/packages/docs/fees.rst +0 -89
- package/lib/reality-eth-monorepo/packages/docs/index.rst +0 -26
- package/lib/reality-eth-monorepo/packages/docs/javascript.rst +0 -142
- package/lib/reality-eth-monorepo/packages/docs/make.bat +0 -36
- package/lib/reality-eth-monorepo/packages/docs/question_box.png +0 -0
- package/lib/reality-eth-monorepo/packages/docs/requirements.txt +0 -24
- package/lib/reality-eth-monorepo/packages/docs/whitepaper.rst +0 -165
- package/script/AddAdminToLand.s.sol +0 -29
- package/script/ClaimMerkleRoot.s.sol +0 -34
- package/script/CreateLand.s.sol +0 -28
- package/script/CreateMarkets.s.sol +0 -71
- package/script/DeployContracts.s.sol +0 -94
- package/script/DeployMerkleRewardsDistributor.s.sol +0 -27
- package/script/DeployToken.s.sol +0 -17
- package/script/DeployUSDT.s.sol +0 -24
- package/script/MintTokens.s.sol +0 -21
- package/script/PublishMerkleRoot.s.sol +0 -50
- package/script/ResolveMarket.s.sol +0 -23
- package/script/TradeMarket.s.sol +0 -28
- package/test/UpdateTest.t.sol +0 -55
- package/test/WhaleTest.t.sol +0 -188
- package/tooling/docs/jsdoc.json +0 -6
|
@@ -1,239 +0,0 @@
|
|
|
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 ERC-20 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 and 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 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, see voting periods and delays following xref:api:interfaces.adoc#IERC6372[IERC6372], visualize voting power and advocates, navigate proposals, and cast votes. For proposal creation in particular, projects can also use https://docs.openzeppelin.com/defender/module/actions#transaction-proposals-reference[Defender Transaction Proposals] 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 ERC-20 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`]. ERC-721 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/ERC721.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 (ERC-6372) 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 that 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 ERC-20 tokens from the governance treasury. This proposal will consist of a single action where the target is the ERC-20 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 https://docs.openzeppelin.com/defender/module/actions#transaction-proposals-reference[Defender Proposals]. 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 ERC-20 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
|
-
=== Disclaimer
|
|
236
|
-
|
|
237
|
-
Timestamp based voting is a recent feature that was formalized in ERC-6372 and ERC-5805, and introduced in v4.9. At the time this feature is released, some governance tooling may not support it yet. Users can expect invalid reporting of deadlines & durations if the tool is not able to interpret the ERC6372 clock. This invalid reporting by offchain tools does not affect the onchain security and functionality of the governance contract.
|
|
238
|
-
|
|
239
|
-
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.
|
|
@@ -1,70 +0,0 @@
|
|
|
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 (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
|
-
include::api:example$MyNFT.sol[]
|
|
42
|
-
----
|
|
43
|
-
|
|
44
|
-
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.
|
|
45
|
-
|
|
46
|
-
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.
|
|
47
|
-
|
|
48
|
-
[[security]]
|
|
49
|
-
== Security
|
|
50
|
-
|
|
51
|
-
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.
|
|
52
|
-
|
|
53
|
-
The https://contracts.openzeppelin.com/security[Security Center] contains more details about the secure development process.
|
|
54
|
-
|
|
55
|
-
[[next-steps]]
|
|
56
|
-
== Learn More
|
|
57
|
-
|
|
58
|
-
The guides in the sidebar will teach about different concepts, and how to use the related contracts that OpenZeppelin Contracts provides:
|
|
59
|
-
|
|
60
|
-
* xref:access-control.adoc[Access Control]: decide who can perform each of the actions on your system.
|
|
61
|
-
* xref:tokens.adoc[Tokens]: create tradable assets or collectibles, like the well known xref:erc20.adoc[ERC20] and xref:erc721.adoc[ERC721] standards.
|
|
62
|
-
* xref:utilities.adoc[Utilities]: generic useful tools, including non-overflowing math, signature verification, and trustless paying systems.
|
|
63
|
-
|
|
64
|
-
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].
|
|
65
|
-
|
|
66
|
-
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.
|
|
67
|
-
|
|
68
|
-
* 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.
|
|
69
|
-
* 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.
|
|
70
|
-
* 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.
|
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
= Multisig Account
|
|
2
|
-
|
|
3
|
-
A multi-signature (multisig) account is a smart account that requires multiple authorized signers to approve operations before execution. Unlike traditional accounts controlled by a single private key, multisigs distribute control among multiple parties, eliminating single points of failure. For example, a 2-of-3 multisig requires signatures from at least 2 out of 3 possible signers.
|
|
4
|
-
|
|
5
|
-
Popular implementations like https://safe.global/[Safe] (formerly Gnosis Safe) have become the standard for securing valuable assets. Multisigs provide enhanced security through collective authorization, customizable controls for ownership and thresholds, and the ability to rotate signers without changing the account address.
|
|
6
|
-
|
|
7
|
-
== Beyond Standard Signature Verification
|
|
8
|
-
|
|
9
|
-
As discussed in the xref:accounts.adoc#signature_validation[accounts section], the standard approach for smart contracts to verify signatures is https://eips.ethereum.org/EIPS/eip-1271[ERC-1271], which defines an `isValidSignature(hash, signature)`. However, it is limited in two important ways:
|
|
10
|
-
|
|
11
|
-
1. It assumes the signer has an EVM address
|
|
12
|
-
2. It treats the signer as a single identity
|
|
13
|
-
|
|
14
|
-
This becomes problematic when implementing multisig accounts where:
|
|
15
|
-
|
|
16
|
-
* You may want to use signers that don't have EVM addresses (like keys from hardware devices)
|
|
17
|
-
* Each signer needs to be individually verified rather than treated as a collective identity
|
|
18
|
-
* You need a threshold system to determine when enough valid signatures are present
|
|
19
|
-
|
|
20
|
-
The https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/SignatureChecker.sol[SignatureChecker] library is useful for verifying EOA and ERC-1271 signatures, but it's not designed for more complex arrangements like threshold-based multisigs.
|
|
21
|
-
|
|
22
|
-
== ERC-7913 Signers
|
|
23
|
-
|
|
24
|
-
https://eips.ethereum.org/EIPS/eip-7913[ERC-7913] extends the concept of signer representation to include keys that don't have EVM addresses, addressing this limitation. OpenZeppelin implements this standard through three contracts:
|
|
25
|
-
|
|
26
|
-
=== SignerERC7913
|
|
27
|
-
|
|
28
|
-
The xref:api:utils.adoc#SignerERC7913[`SignerERC7913`] contract allows a single ERC-7913 formatted signer to control an account. The signer is represented as a `bytes` object that concatenates a verifier address and a key: `verifier || key`.
|
|
29
|
-
|
|
30
|
-
[source,solidity]
|
|
31
|
-
----
|
|
32
|
-
// contracts/MyAccountERC7913.sol
|
|
33
|
-
// SPDX-License-Identifier: MIT
|
|
34
|
-
|
|
35
|
-
pragma solidity ^0.8.24;
|
|
36
|
-
|
|
37
|
-
import {Account} from "@openzeppelin/community-contracts/account/Account.sol";
|
|
38
|
-
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
|
|
39
|
-
import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
|
|
40
|
-
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
|
|
41
|
-
import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/signers/ERC7739.sol";
|
|
42
|
-
import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";
|
|
43
|
-
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
|
|
44
|
-
import {SignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/signers/SignerERC7913.sol";
|
|
45
|
-
|
|
46
|
-
contract MyAccountERC7913 is Account, SignerERC7913, ERC7739, ERC7821, ERC721Holder, ERC1155Holder, Initializable {
|
|
47
|
-
constructor() EIP712("MyAccount7913", "1") {}
|
|
48
|
-
|
|
49
|
-
function initialize(bytes memory signer) public initializer {
|
|
50
|
-
_setSigner(signer);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function setSigner(bytes memory signer) public onlyEntryPointOrSelf {
|
|
54
|
-
_setSigner(signer);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/// @dev Allows the entry point as an authorized executor.
|
|
58
|
-
function _erc7821AuthorizedExecutor(
|
|
59
|
-
address caller,
|
|
60
|
-
bytes32 mode,
|
|
61
|
-
bytes calldata executionData
|
|
62
|
-
) internal view virtual override returns (bool) {
|
|
63
|
-
return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
----
|
|
67
|
-
|
|
68
|
-
WARNING: Leaving an account uninitialized may leave it unusable since no public key was associated with it.
|
|
69
|
-
|
|
70
|
-
=== MultiSignerERC7913
|
|
71
|
-
|
|
72
|
-
The xref:api:utils/cryptography.adoc#MultiSignerERC7913[`MultiSignerERC7913`] contract extends this concept to support multiple signers with a threshold-based signature verification system.
|
|
73
|
-
|
|
74
|
-
[source,solidity]
|
|
75
|
-
----
|
|
76
|
-
// contracts/MyAccountMultiSigner.sol
|
|
77
|
-
// SPDX-License-Identifier: MIT
|
|
78
|
-
|
|
79
|
-
pragma solidity ^0.8.27;
|
|
80
|
-
|
|
81
|
-
import {Account} from "@openzeppelin/community-contracts/account/Account.sol";
|
|
82
|
-
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
|
|
83
|
-
import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
|
|
84
|
-
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
|
|
85
|
-
import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/signers/ERC7739.sol";
|
|
86
|
-
import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";
|
|
87
|
-
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
|
|
88
|
-
import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/signers/MultiSignerERC7913.sol";
|
|
89
|
-
|
|
90
|
-
contract MyAccountMultiSigner is
|
|
91
|
-
Account,
|
|
92
|
-
MultiSignerERC7913,
|
|
93
|
-
ERC7739,
|
|
94
|
-
ERC7821,
|
|
95
|
-
ERC721Holder,
|
|
96
|
-
ERC1155Holder,
|
|
97
|
-
Initializable
|
|
98
|
-
{
|
|
99
|
-
constructor() EIP712("MyAccountMultiSigner", "1") {}
|
|
100
|
-
|
|
101
|
-
function initialize(bytes[] memory signers, uint256 threshold) public initializer {
|
|
102
|
-
_addSigners(signers);
|
|
103
|
-
_setThreshold(threshold);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {
|
|
107
|
-
_addSigners(signers);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {
|
|
111
|
-
_removeSigners(signers);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {
|
|
115
|
-
_setThreshold(threshold);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/// @dev Allows the entry point as an authorized executor.
|
|
119
|
-
function _erc7821AuthorizedExecutor(
|
|
120
|
-
address caller,
|
|
121
|
-
bytes32 mode,
|
|
122
|
-
bytes calldata executionData
|
|
123
|
-
) internal view virtual override returns (bool) {
|
|
124
|
-
return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
----
|
|
128
|
-
|
|
129
|
-
This implementation is ideal for standard multisig setups where each signer has equal authority, and a fixed number of approvals is required.
|
|
130
|
-
|
|
131
|
-
The `MultiSignerERC7913` contract provides several key features for managing multi-signature accounts. It maintains a set of authorized signers and implements a threshold-based system that requires a minimum number of signatures to approve operations. The contract includes an internal interface for managing signers, allowing for the addition and removal of authorized parties.
|
|
132
|
-
|
|
133
|
-
NOTE: `MultiSignerERC7913` safeguards to ensure that the threshold remains achievable based on the current number of active signers, preventing situations where operations could become impossible to execute.
|
|
134
|
-
|
|
135
|
-
The contract also provides public functions for querying signer information: xref:api:utils/cryptography.adoc#MultiSignerERC7913-isSigner-bytes-[`isSigner(bytes memory signer)`] to check if a given signer is authorized, xref:api:utils/cryptography.adoc#MultiSignerERC7913-getSigners-uint64-uint64-[`getSigners(uint64 start, uint64 end)`] to retrieve a paginated list of authorized signers, and xref:api:utils/cryptography.adoc#MultiSignerERC7913-getSignerCount[`getSignerCount()`] to get the total number of signers. These functions are useful when validating signatures, implementing customized access control logic, or building user interfaces that need to display signer information.
|
|
136
|
-
|
|
137
|
-
=== MultiSignerERC7913Weighted
|
|
138
|
-
|
|
139
|
-
For more sophisticated governance structures, the xref:api:utils/cryptography.adoc#MultiSignerERC7913Weighted[`MultiSignerERC7913Weighted`] contract extends `MultiSignerERC7913` by assigning different weights to each signer.
|
|
140
|
-
|
|
141
|
-
[source,solidity]
|
|
142
|
-
----
|
|
143
|
-
// contracts/MyAccountMultiSignerWeighted.sol
|
|
144
|
-
// SPDX-License-Identifier: MIT
|
|
145
|
-
|
|
146
|
-
pragma solidity ^0.8.27;
|
|
147
|
-
|
|
148
|
-
import {Account} from "@openzeppelin/community-contracts/account/Account.sol";
|
|
149
|
-
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
|
|
150
|
-
import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
|
|
151
|
-
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
|
|
152
|
-
import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/signers/ERC7739.sol";
|
|
153
|
-
import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";
|
|
154
|
-
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
|
|
155
|
-
import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";
|
|
156
|
-
|
|
157
|
-
contract MyAccountMultiSignerWeighted is
|
|
158
|
-
Account,
|
|
159
|
-
MultiSignerERC7913Weighted,
|
|
160
|
-
ERC7739,
|
|
161
|
-
ERC7821,
|
|
162
|
-
ERC721Holder,
|
|
163
|
-
ERC1155Holder,
|
|
164
|
-
Initializable
|
|
165
|
-
{
|
|
166
|
-
constructor() EIP712("MyAccountMultiSignerWeighted", "1") {}
|
|
167
|
-
|
|
168
|
-
function initialize(bytes[] memory signers, uint256[] memory weights, uint256 threshold) public initializer {
|
|
169
|
-
_addSigners(signers);
|
|
170
|
-
_setSignerWeights(signers, weights);
|
|
171
|
-
_setThreshold(threshold);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {
|
|
175
|
-
_addSigners(signers);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {
|
|
179
|
-
_removeSigners(signers);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {
|
|
183
|
-
_setThreshold(threshold);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function setSignerWeights(bytes[] memory signers, uint256[] memory weights) public onlyEntryPointOrSelf {
|
|
187
|
-
_setSignerWeights(signers, weights);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/// @dev Allows the entry point as an authorized executor.
|
|
191
|
-
function _erc7821AuthorizedExecutor(
|
|
192
|
-
address caller,
|
|
193
|
-
bytes32 mode,
|
|
194
|
-
bytes calldata executionData
|
|
195
|
-
) internal view virtual override returns (bool) {
|
|
196
|
-
return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
----
|
|
200
|
-
|
|
201
|
-
This implementation is perfect for scenarios where different signers should have varying levels of authority, such as:
|
|
202
|
-
|
|
203
|
-
* Board members with different voting powers
|
|
204
|
-
* Organizational structures with hierarchical decision-making
|
|
205
|
-
* Hybrid governance systems combining core team and community members
|
|
206
|
-
* Execution setups like "social recovery" where you trust particular guardians more than others
|
|
207
|
-
|
|
208
|
-
The `MultiSignerERC7913Weighted` contract extends `MultiSignerERC7913` with a weighting system. Each signer can have a custom weight, and operations require the total weight of signing participants to meet or exceed the threshold. Signers without explicit weights default to a weight of 1.
|
|
209
|
-
|
|
210
|
-
NOTE: When setting up a weighted multisig, ensure the threshold value matches the scale used for signer weights. For example, if signers have weights like 1, 2, or 3, then a threshold of 4 would require at least two signers (e.g., one with weight 1 and one with weight 3).
|
|
211
|
-
|
|
212
|
-
== Setting Up a Multisig Account
|
|
213
|
-
|
|
214
|
-
To create a multisig account, you need to:
|
|
215
|
-
|
|
216
|
-
1. Define your signers
|
|
217
|
-
2. Determine your threshold
|
|
218
|
-
3. Initialize your account with these parameters
|
|
219
|
-
|
|
220
|
-
The example below demonstrates setting up a 2-of-3 multisig account with different types of signers:
|
|
221
|
-
|
|
222
|
-
[source,solidity]
|
|
223
|
-
----
|
|
224
|
-
// Example setup code
|
|
225
|
-
function setupMultisigAccount() external {
|
|
226
|
-
// Create signers using different types of keys
|
|
227
|
-
bytes memory ecdsaSigner = alice; // EOA address (20 bytes)
|
|
228
|
-
|
|
229
|
-
// P256 signer with format: verifier || pubKey
|
|
230
|
-
bytes memory p256Signer = abi.encodePacked(
|
|
231
|
-
p256Verifier,
|
|
232
|
-
bobP256PublicKeyX,
|
|
233
|
-
bobP256PublicKeyY
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
// RSA signer with format: verifier || pubKey
|
|
237
|
-
bytes memory rsaSigner = abi.encodePacked(
|
|
238
|
-
rsaVerifier,
|
|
239
|
-
abi.encode(charlieRSAPublicKeyE, charlieRSAPublicKeyN)
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
// Create array of signers
|
|
243
|
-
bytes[] memory signers = new bytes[](3);
|
|
244
|
-
signers[0] = ecdsaSigner;
|
|
245
|
-
signers[1] = p256Signer;
|
|
246
|
-
signers[2] = rsaSigner;
|
|
247
|
-
|
|
248
|
-
// Set threshold to 2 (2-of-3 multisig)
|
|
249
|
-
uint256 threshold = 2;
|
|
250
|
-
|
|
251
|
-
// Initialize the account
|
|
252
|
-
myMultisigAccount.initialize(signers, threshold);
|
|
253
|
-
}
|
|
254
|
-
----
|
|
255
|
-
|
|
256
|
-
For a weighted multisig, you would also specify weights:
|
|
257
|
-
|
|
258
|
-
[source,solidity]
|
|
259
|
-
----
|
|
260
|
-
// Example setup for weighted multisig
|
|
261
|
-
function setupWeightedMultisigAccount() external {
|
|
262
|
-
// Create array of signers (same as above)
|
|
263
|
-
bytes[] memory signers = new bytes[](3);
|
|
264
|
-
signers[0] = ecdsaSigner;
|
|
265
|
-
signers[1] = p256Signer;
|
|
266
|
-
signers[2] = rsaSigner;
|
|
267
|
-
|
|
268
|
-
// Assign weights to signers (Alice:1, Bob:2, Charlie:3)
|
|
269
|
-
uint256[] memory weights = new uint256[](3);
|
|
270
|
-
weights[0] = 1;
|
|
271
|
-
weights[1] = 2;
|
|
272
|
-
weights[2] = 3;
|
|
273
|
-
|
|
274
|
-
// Set threshold to 4 (requires at least Bob+Charlie or all three)
|
|
275
|
-
uint256 threshold = 4;
|
|
276
|
-
|
|
277
|
-
// Initialize the weighted account
|
|
278
|
-
myWeightedMultisigAccount.initialize(signers, weights, threshold);
|
|
279
|
-
}
|
|
280
|
-
----
|
|
281
|
-
|
|
282
|
-
IMPORTANT: The xref:api:utils/cryptography.adoc#MultiSignerERC7913-_validateReachableThreshold--[`_validateReachableThreshold`] function ensures that the sum of weights for all active signers meets or exceeds the threshold. Any customization built on top of the multisigner contracts must ensure the threshold is always reachable.
|
|
283
|
-
|
|
284
|
-
For multisig accounts, the signature is a complex structure that contains both the signers and their individual signatures. The format follows ERC-7913's specification and must be properly encoded.
|
|
285
|
-
|
|
286
|
-
=== Signature Format
|
|
287
|
-
|
|
288
|
-
The multisig signature is encoded as:
|
|
289
|
-
|
|
290
|
-
[source,solidity]
|
|
291
|
-
----
|
|
292
|
-
abi.encode(
|
|
293
|
-
bytes[] signers, // Array of signers sorted by `keccak256`
|
|
294
|
-
bytes[] signatures // Array of signatures corresponding to each signer
|
|
295
|
-
)
|
|
296
|
-
----
|
|
297
|
-
|
|
298
|
-
Where:
|
|
299
|
-
|
|
300
|
-
* `signers` is an array of the signers participating in this particular signature
|
|
301
|
-
* `signatures` is an array of the individual signatures corresponding to each signer
|
|
302
|
-
|
|
303
|
-
[NOTE]
|
|
304
|
-
====
|
|
305
|
-
To avoid duplicate signers, the contract uses `keccak256` to generate a unique id for each signer. When providing a multisignature, the `signers` array should be sorted in ascending order by `keccak256`, and the `signatures` array must match the order of their corresponding signers.
|
|
306
|
-
====
|
|
@@ -1,31 +0,0 @@
|
|
|
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 ERC-20 or ERC-721 token standards, and that's why you're here. Head to our specialized guides to learn more about these:
|
|
28
|
-
|
|
29
|
-
* xref:erc20.adoc[ERC-20]: the most widespread token standard for fungible assets, albeit somewhat limited by its simplicity.
|
|
30
|
-
* xref:erc721.adoc[ERC-721]: the de-facto solution for non-fungible tokens, often used for collectibles and games.
|
|
31
|
-
* xref:erc1155.adoc[ERC-1155]: 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.
|