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,210 +0,0 @@
|
|
|
1
|
-
= Adding cross-chain support to contracts
|
|
2
|
-
|
|
3
|
-
If your contract is targeting to be used in the context of multichain operations, you may need specific tools to identify and process these cross-chain operations.
|
|
4
|
-
|
|
5
|
-
OpenZeppelin provides the xref:api:crosschain.adoc#CrossChainEnabled[`CrossChainEnabled`] abstract contract, that includes dedicated internal functions.
|
|
6
|
-
|
|
7
|
-
In this guide, we will go through an example use case: _how to build an upgradeable & mintable ERC20 token controlled by a governor present on a foreign chain_.
|
|
8
|
-
|
|
9
|
-
== Starting point, our ERC20 contract
|
|
10
|
-
|
|
11
|
-
Let's start with a small ERC20 contract, that we bootstrapped using the https://wizard.openzeppelin.com/[OpenZeppelin Contracts Wizard], and extended with an owner that has the ability to mint. Note that for demonstration purposes we have not used the built-in `Ownable` contract.
|
|
12
|
-
|
|
13
|
-
[source,solidity]
|
|
14
|
-
----
|
|
15
|
-
// SPDX-License-Identifier: MIT
|
|
16
|
-
pragma solidity ^0.8.4;
|
|
17
|
-
|
|
18
|
-
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
|
19
|
-
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
20
|
-
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
21
|
-
|
|
22
|
-
contract MyToken is Initializable, ERC20Upgradeable, UUPSUpgradeable {
|
|
23
|
-
address public owner;
|
|
24
|
-
|
|
25
|
-
modifier onlyOwner() {
|
|
26
|
-
require(owner == _msgSender(), "Not authorized");
|
|
27
|
-
_;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
31
|
-
constructor() initializer {}
|
|
32
|
-
|
|
33
|
-
function initialize(address initialOwner) initializer public {
|
|
34
|
-
__ERC20_init("MyToken", "MTK");
|
|
35
|
-
__UUPSUpgradeable_init();
|
|
36
|
-
|
|
37
|
-
owner = initialOwner;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function mint(address to, uint256 amount) public onlyOwner {
|
|
41
|
-
_mint(to, amount);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
----
|
|
48
|
-
|
|
49
|
-
This token is mintable and upgradeable by the owner of the contract.
|
|
50
|
-
|
|
51
|
-
== Preparing our contract for cross-chain operations.
|
|
52
|
-
|
|
53
|
-
Let's now imagine that this contract is going to live on one chain, but we want the minting and the upgrading to be performed by a xref:governance.adoc[`governor`] contract on another chain.
|
|
54
|
-
|
|
55
|
-
For example, we could have our token on xDai, with our governor on mainnet, or we could have our token on mainnet, with our governor on optimism
|
|
56
|
-
|
|
57
|
-
In order to do that, we will start by adding xref:api:crosschain.adoc#CrossChainEnabled[`CrossChainEnabled`] to our contract. You will notice that the contract is now abstract. This is because `CrossChainEnabled` is an abstract contract: it is not tied to any particular chain and it deals with cross-chain interactions in an abstract way. This is what enables us to easily reuse the code for different chains. We will specialize it later by inheriting from a chain-specific implementation of the abstraction.
|
|
58
|
-
|
|
59
|
-
```diff
|
|
60
|
-
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
61
|
-
+import "@openzeppelin/contracts-upgradeable/crosschain/CrossChainEnabled.sol";
|
|
62
|
-
|
|
63
|
-
-contract MyToken is Initializable, ERC20Upgradeable, UUPSUpgradeable {
|
|
64
|
-
+abstract contract MyTokenCrossChain is Initializable, ERC20Upgradeable, UUPSUpgradeable, CrossChainEnabled {
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Once that is done, we can use the `onlyCrossChainSender` modifier, provided by `CrossChainEnabled` in order to protect the minting and upgrading operations.
|
|
68
|
-
|
|
69
|
-
```diff
|
|
70
|
-
- function mint(address to, uint256 amount) public onlyOwner {
|
|
71
|
-
+ function mint(address to, uint256 amount) public onlyCrossChainSender(owner) {
|
|
72
|
-
|
|
73
|
-
- function _authorizeUpgrade(address newImplementation) internal override onlyOwner {
|
|
74
|
-
+ function _authorizeUpgrade(address newImplementation) internal override onlyCrossChainSender(owner) {
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
This change will effectively restrict the mint and upgrade operations to the `owner` on the remote chain.
|
|
78
|
-
|
|
79
|
-
== Specializing for a specific chain
|
|
80
|
-
|
|
81
|
-
Once the abstract cross-chain version of our token is ready we can easily specialize it for the chain we want, or more precisely for the bridge system that we want to rely on.
|
|
82
|
-
|
|
83
|
-
This is done using one of the many `CrossChainEnabled` implementations.
|
|
84
|
-
|
|
85
|
-
For example, if our token is on xDai, and our governor on mainnet, we can use the https://docs.tokenbridge.net/amb-bridge/about-amb-bridge[AMB] bridge available on xDai at https://blockscout.com/xdai/mainnet/address/0x75Df5AF045d91108662D8080fD1FEFAd6aA0bb59[0x75Df5AF045d91108662D8080fD1FEFAd6aA0bb59]
|
|
86
|
-
|
|
87
|
-
[source,solidity]
|
|
88
|
-
----
|
|
89
|
-
[...]
|
|
90
|
-
|
|
91
|
-
import "@openzeppelin/contracts-upgradeable/crosschain/amb/CrossChainEnabledAMB.sol";
|
|
92
|
-
|
|
93
|
-
contract MyTokenXDAI is
|
|
94
|
-
MyTokenCrossChain,
|
|
95
|
-
CrossChainEnabledAMB(0x75Df5AF045d91108662D8080fD1FEFAd6aA0bb59)
|
|
96
|
-
{}
|
|
97
|
-
----
|
|
98
|
-
|
|
99
|
-
If the token is on Ethereum mainnet, and our governor on Optimism, we use the Optimism https://community.optimism.io/docs/protocol/protocol-2.0/#l1crossdomainmessenger[CrossDomainMessenger] available on mainnet at https://etherscan.io/address/0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1[0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1].
|
|
100
|
-
|
|
101
|
-
[source,solidity]
|
|
102
|
-
----
|
|
103
|
-
[...]
|
|
104
|
-
|
|
105
|
-
import "@openzeppelin/contracts-upgradeable/crosschain/optimismCrossChainEnabledOptimism.sol";
|
|
106
|
-
|
|
107
|
-
contract MyTokenOptimism is
|
|
108
|
-
MyTokenCrossChain,
|
|
109
|
-
CrossChainEnabledOptimism(0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1)
|
|
110
|
-
{}
|
|
111
|
-
----
|
|
112
|
-
|
|
113
|
-
== Mixing cross domain addresses is dangerous
|
|
114
|
-
|
|
115
|
-
When designing a contract with cross-chain support, it is essential to understand possible fallbacks and the security assumption that are being made.
|
|
116
|
-
|
|
117
|
-
In this guide, we are particularly focusing on restricting access to a specific caller. This is usually done (as shown above) using `msg.sender` or `_msgSender()`. However, when going cross-chain, it is not just that simple. Even without considering possible bridge issues, it is important to keep in mind that the same address can correspond to very different entities when considering a multi-chain space. EOA wallets can only execute operations if the wallet's private-key signs the transaction. To our knowledge this is the case in all EVM chains, so a cross-chain message coming from such a wallet is arguably equivalent to a non-cross-chain message by the same wallet. The situation is however very different for smart contracts.
|
|
118
|
-
|
|
119
|
-
Due to the way smart contract addresses are computed, and the fact that smart contracts on different chains live independent lives, you could have two very different contracts live at the same address on different chains. You could imagine two multisig wallets with different signers using the same address on different chains. You could also see a very basic smart wallet live on one chain at the same address as a full-fledged governor on another chain. Therefore, you should be careful that whenever you give permissions to a specific address, you control with chain this address can act from.
|
|
120
|
-
|
|
121
|
-
== Going further with access control
|
|
122
|
-
|
|
123
|
-
In the previous example, we have both an `onlyOwner()` modifier and the `onlyCrossChainSender(owner)` mechanism. We didn't use the xref:access-control.adoc#ownership-and-ownable[`Ownable`] pattern because the ownership transfer mechanism in includes is not designed to work with the owner being a cross-chain entity. Unlike xref:access-control.adoc#ownership-and-ownable[`Ownable`], xref:access-control.adoc#role-based-access-control[`AccessControl`] is more effective at capturing the nuances and can effectively be used to build cross-chain-aware contracts.
|
|
124
|
-
|
|
125
|
-
Using xref:api:access.adoc#AccessControlCrossChain[`AccessControlCrossChain`] includes both the xref:api:access.adoc#AccessControl[`AccessControl`] core and the xref:api:crosschain.adoc#CrossChainEnabled[`CrossChainEnabled`] abstraction. It also includes some binding to make role management compatible with cross-chain operations.
|
|
126
|
-
|
|
127
|
-
In the case of the `mint` function, the caller must have the `MINTER_ROLE` when the call originates from the same chain. If the caller is on a remote chain, then the caller should not have the `MINTER_ROLE`, but the "aliased" version (`MINTER_ROLE ^ CROSSCHAIN_ALIAS`). This mitigates the danger described in the previous section by strictly separating local accounts from remote accounts from a different chain. See the xref:api:access.adoc#AccessControlCrossChain[`AccessControlCrossChain`] documentation for more details.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
```diff
|
|
131
|
-
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
|
132
|
-
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
133
|
-
+import "@openzeppelin/contracts-upgradeable/access/AccessControlCrossChainUpgradeable.sol";
|
|
134
|
-
|
|
135
|
-
-abstract contract MyTokenCrossChain is Initializable, ERC20Upgradeable, UUPSUpgradeable, CrossChainEnabled {
|
|
136
|
-
+abstract contract MyTokenCrossChain is Initializable, ERC20Upgradeable, UUPSUpgradeable, AccessControlCrossChainUpgradeable {
|
|
137
|
-
|
|
138
|
-
- address public owner;
|
|
139
|
-
- modifier onlyOwner() {
|
|
140
|
-
- require(owner == _msgSender(), "Not authorized");
|
|
141
|
-
- _;
|
|
142
|
-
- }
|
|
143
|
-
|
|
144
|
-
+ bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
|
|
145
|
-
+ bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");
|
|
146
|
-
|
|
147
|
-
function initialize(address initialOwner) initializer public {
|
|
148
|
-
__ERC20_init("MyToken", "MTK");
|
|
149
|
-
__UUPSUpgradeable_init();
|
|
150
|
-
+ __AccessControl_init();
|
|
151
|
-
+ _grantRole(_crossChainRoleAlias(DEFAULT_ADMIN_ROLE), initialOwner); // initialOwner is on a remote chain
|
|
152
|
-
- owner = initialOwner;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
- function mint(address to, uint256 amount) public onlyCrossChainSender(owner) {
|
|
156
|
-
+ function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
|
|
157
|
-
|
|
158
|
-
- function _authorizeUpgrade(address newImplementation) internal override onlyCrossChainSender(owner) {
|
|
159
|
-
+ function _authorizeUpgrade(address newImplementation) internal override onlyRole(UPGRADER_ROLE) {
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
This results in the following, final, code:
|
|
163
|
-
|
|
164
|
-
[source,solidity]
|
|
165
|
-
----
|
|
166
|
-
// SPDX-License-Identifier: MIT
|
|
167
|
-
pragma solidity ^0.8.4;
|
|
168
|
-
|
|
169
|
-
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
|
170
|
-
import "@openzeppelin/contracts-upgradeable/access/AccessControlCrossChainUpgradeable.sol";
|
|
171
|
-
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
172
|
-
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
173
|
-
|
|
174
|
-
abstract contract MyTokenCrossChain is Initializable, ERC20Upgradeable, AccessControlCrossChainUpgradeable, UUPSUpgradeable {
|
|
175
|
-
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
|
|
176
|
-
bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");
|
|
177
|
-
|
|
178
|
-
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
179
|
-
constructor() initializer {}
|
|
180
|
-
|
|
181
|
-
function initialize(address initialOwner) initializer public {
|
|
182
|
-
__ERC20_init("MyToken", "MTK");
|
|
183
|
-
__AccessControl_init();
|
|
184
|
-
__UUPSUpgradeable_init();
|
|
185
|
-
|
|
186
|
-
_grantRole(_crossChainRoleAlias(DEFAULT_ADMIN_ROLE), initialOwner); // initialOwner is on a remote chain
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
|
|
190
|
-
_mint(to, amount);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function _authorizeUpgrade(address newImplementation) internal onlyRole(UPGRADER_ROLE) override {
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
import "@openzeppelin/contracts-upgradeable/crosschain/amb/CrossChainEnabledAMB.sol";
|
|
198
|
-
|
|
199
|
-
contract MyTokenXDAI is
|
|
200
|
-
MyTokenCrossChain,
|
|
201
|
-
CrossChainEnabledAMB(0x75Df5AF045d91108662D8080fD1FEFAd6aA0bb59)
|
|
202
|
-
{}
|
|
203
|
-
|
|
204
|
-
import "@openzeppelin/contracts-upgradeable/crosschain/optimismCrossChainEnabledOptimism.sol";
|
|
205
|
-
|
|
206
|
-
contract MyTokenOptimism is
|
|
207
|
-
MyTokenCrossChain,
|
|
208
|
-
CrossChainEnabledOptimism(0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1)
|
|
209
|
-
{}
|
|
210
|
-
----
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
= Crowdsales
|
|
2
|
-
|
|
3
|
-
All crowdsale-related contracts were removed from the OpenZeppelin Contracts library on the https://forum.openzeppelin.com/t/openzeppelin-contracts-v3-0-beta-release/2256[v3.0.0 release] due to both a decline in their usage and the complexity associated with migrating them to Solidity v0.6.
|
|
4
|
-
|
|
5
|
-
They are however still available on the v2.5 release of OpenZeppelin Contracts, which you can install by running:
|
|
6
|
-
|
|
7
|
-
```console
|
|
8
|
-
$ npm install @openzeppelin/contracts@v2.5
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Refer to the https://docs.openzeppelin.com/contracts/2.x/crowdsales[v2.x documentation] when working with them.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
= Drafts
|
|
2
|
-
|
|
3
|
-
All draft contracts were either moved into a different directory or removed from the OpenZeppelin Contracts library on the https://forum.openzeppelin.com/t/openzeppelin-contracts-v3-0-beta-release/2256[v3.0.0 release].
|
|
4
|
-
|
|
5
|
-
* `ERC20Migrator`: removed.
|
|
6
|
-
* xref:api:token/ERC20.adoc#ERC20Snapshot[`ERC20Snapshot`]: moved to `token/ERC20`.
|
|
7
|
-
* `ERC20Detailed` and `ERC1046`: removed.
|
|
8
|
-
* `TokenVesting`: removed. Pending a replacement that is being discussed in https://github.com/OpenZeppelin/openzeppelin-contracts/issues/1214[`#1214`].
|
|
9
|
-
* xref:api:utils.adoc#Counters[`Counters`]: moved to xref:api:utils.adoc[`utils`].
|
|
10
|
-
* xref:api:utils.adoc#Strings[`Strings`]: moved to xref:api:utils.adoc[`utils`].
|
|
11
|
-
* xref:api:utils.adoc#SignedSafeMath[`SignedSafeMath`]: moved to xref:api:utils.adoc[`utils`].
|
|
12
|
-
|
|
13
|
-
Removed contracts are still available on the v2.5 release of OpenZeppelin Contracts, which you can install by running:
|
|
14
|
-
|
|
15
|
-
```console
|
|
16
|
-
$ npm install @openzeppelin/contracts@v2.5
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Refer to the xref:2.x@contracts:api:drafts.adoc[v2.x documentation] when working with them.
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
= ERC1155
|
|
2
|
-
|
|
3
|
-
ERC1155 is a novel token standard that aims to take the best from previous standards to create a xref:tokens.adoc#different-kinds-of-tokens[*fungibility-agnostic*] and *gas-efficient* xref:tokens.adoc#but_first_coffee_a_primer_on_token_contracts[token contract].
|
|
4
|
-
|
|
5
|
-
TIP: ERC1155 draws ideas from all of xref:erc20.adoc[ERC20], xref:erc721.adoc[ERC721], and xref:erc777.adoc[ERC777]. If you're unfamiliar with those standards, head to their guides before moving on.
|
|
6
|
-
|
|
7
|
-
[[multi-token-standard]]
|
|
8
|
-
== Multi Token Standard
|
|
9
|
-
|
|
10
|
-
The distinctive feature of ERC1155 is that it uses a single smart contract to represent multiple tokens at once. This is why its xref:api:token/ERC1155.adoc#IERC1155-balanceOf-address-uint256-[`balanceOf`] function differs from ERC20's and ERC777's: it has an additional `id` argument for the identifier of the token that you want to query the balance of.
|
|
11
|
-
|
|
12
|
-
This is similar to how ERC721 does things, but in that standard a token `id` has no concept of balance: each token is non-fungible and exists or doesn't. The ERC721 xref:api:token/ERC721.adoc#IERC721-balanceOf-address-[`balanceOf`] function refers to _how many different tokens_ an account has, not how many of each. On the other hand, in ERC1155 accounts have a distinct balance for each token `id`, and non-fungible tokens are implemented by simply minting a single one of them.
|
|
13
|
-
|
|
14
|
-
This approach leads to massive gas savings for projects that require multiple tokens. Instead of deploying a new contract for each token type, a single ERC1155 token contract can hold the entire system state, reducing deployment costs and complexity.
|
|
15
|
-
|
|
16
|
-
[[batch-operations]]
|
|
17
|
-
== Batch Operations
|
|
18
|
-
|
|
19
|
-
Because all state is held in a single contract, it is possible to operate over multiple tokens in a single transaction very efficiently. The standard provides two functions, xref:api:token/ERC1155.adoc#IERC1155-balanceOfBatch-address---uint256---[`balanceOfBatch`] and xref:api:token/ERC1155.adoc#IERC1155-safeBatchTransferFrom-address-address-uint256---uint256---bytes-[`safeBatchTransferFrom`], that make querying multiple balances and transferring multiple tokens simpler and less gas-intensive.
|
|
20
|
-
|
|
21
|
-
In the spirit of the standard, we've also included batch operations in the non-standard functions, such as xref:api:token/ERC1155.adoc#ERC1155-_mintBatch-address-uint256---uint256---bytes-[`_mintBatch`].
|
|
22
|
-
|
|
23
|
-
== Constructing an ERC1155 Token Contract
|
|
24
|
-
|
|
25
|
-
We'll use ERC1155 to track multiple items in our game, which will each have their own unique attributes. We mint all items to the deployer of the contract, which we can later transfer to players. Players are free to keep their tokens or trade them with other people as they see fit, as they would any other asset on the blockchain!
|
|
26
|
-
|
|
27
|
-
For simplicity we will mint all items in the constructor but you could add minting functionality to the contract to mint on demand to players.
|
|
28
|
-
|
|
29
|
-
TIP: For an overview of minting mechanisms check out xref:erc20-supply.adoc[Creating ERC20 Supply].
|
|
30
|
-
|
|
31
|
-
Here's what a contract for tokenized items might look like:
|
|
32
|
-
|
|
33
|
-
[source,solidity]
|
|
34
|
-
----
|
|
35
|
-
// contracts/GameItems.sol
|
|
36
|
-
// SPDX-License-Identifier: MIT
|
|
37
|
-
pragma solidity ^0.8.0;
|
|
38
|
-
|
|
39
|
-
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
|
|
40
|
-
|
|
41
|
-
contract GameItems is ERC1155 {
|
|
42
|
-
uint256 public constant GOLD = 0;
|
|
43
|
-
uint256 public constant SILVER = 1;
|
|
44
|
-
uint256 public constant THORS_HAMMER = 2;
|
|
45
|
-
uint256 public constant SWORD = 3;
|
|
46
|
-
uint256 public constant SHIELD = 4;
|
|
47
|
-
|
|
48
|
-
constructor() ERC1155("https://game.example/api/item/{id}.json") {
|
|
49
|
-
_mint(msg.sender, GOLD, 10**18, "");
|
|
50
|
-
_mint(msg.sender, SILVER, 10**27, "");
|
|
51
|
-
_mint(msg.sender, THORS_HAMMER, 1, "");
|
|
52
|
-
_mint(msg.sender, SWORD, 10**9, "");
|
|
53
|
-
_mint(msg.sender, SHIELD, 10**9, "");
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
----
|
|
57
|
-
|
|
58
|
-
Note that for our Game Items, Gold is a fungible token whilst Thor's Hammer is a non-fungible token as we minted only one.
|
|
59
|
-
|
|
60
|
-
The xref:api:token/ERC1155.adoc#ERC1155[`ERC1155`] contract includes the optional extension xref:api:token/ERC1155.adoc#IERC1155MetadataURI[`IERC1155MetadataURI`]. That's where the xref:api:token/ERC1155.adoc#IERC1155MetadataURI-uri-uint256-[`uri`] function comes from: we use it to retrieve the metadata uri.
|
|
61
|
-
|
|
62
|
-
Also note that, unlike ERC20, ERC1155 lacks a `decimals` field, since each token is distinct and cannot be partitioned.
|
|
63
|
-
|
|
64
|
-
Once deployed, we will be able to query the deployer’s balance:
|
|
65
|
-
[source,javascript]
|
|
66
|
-
----
|
|
67
|
-
> gameItems.balanceOf(deployerAddress,3)
|
|
68
|
-
1000000000
|
|
69
|
-
----
|
|
70
|
-
|
|
71
|
-
We can transfer items to player accounts:
|
|
72
|
-
[source,javascript]
|
|
73
|
-
----
|
|
74
|
-
> gameItems.safeTransferFrom(deployerAddress, playerAddress, 2, 1, "0x0")
|
|
75
|
-
> gameItems.balanceOf(playerAddress, 2)
|
|
76
|
-
1
|
|
77
|
-
> gameItems.balanceOf(deployerAddress, 2)
|
|
78
|
-
0
|
|
79
|
-
----
|
|
80
|
-
|
|
81
|
-
We can also batch transfer items to player accounts and get the balance of batches:
|
|
82
|
-
[source,javascript]
|
|
83
|
-
----
|
|
84
|
-
> gameItems.safeBatchTransferFrom(deployerAddress, playerAddress, [0,1,3,4], [50,100,1,1], "0x0")
|
|
85
|
-
> gameItems.balanceOfBatch([playerAddress,playerAddress,playerAddress,playerAddress,playerAddress], [0,1,2,3,4])
|
|
86
|
-
[50,100,1,1,1]
|
|
87
|
-
----
|
|
88
|
-
|
|
89
|
-
The metadata uri can be obtained:
|
|
90
|
-
|
|
91
|
-
[source,javascript]
|
|
92
|
-
----
|
|
93
|
-
> gameItems.uri(2)
|
|
94
|
-
"https://game.example/api/item/{id}.json"
|
|
95
|
-
----
|
|
96
|
-
|
|
97
|
-
The `uri` can include the string `++{id}++` which clients must replace with the actual token ID, in lowercase hexadecimal (with no 0x prefix) and leading zero padded to 64 hex characters.
|
|
98
|
-
|
|
99
|
-
For token ID `2` and uri `++https://game.example/api/item/{id}.json++` clients would replace `++{id}++` with `0000000000000000000000000000000000000000000000000000000000000002` to retrieve JSON at `https://game.example/api/item/0000000000000000000000000000000000000000000000000000000000000002.json`.
|
|
100
|
-
|
|
101
|
-
The JSON document for token ID 2 might look something like:
|
|
102
|
-
|
|
103
|
-
[source,json]
|
|
104
|
-
----
|
|
105
|
-
{
|
|
106
|
-
"name": "Thor's hammer",
|
|
107
|
-
"description": "Mjölnir, the legendary hammer of the Norse god of thunder.",
|
|
108
|
-
"image": "https://game.example/item-id-8u5h2m.png",
|
|
109
|
-
"strength": 20
|
|
110
|
-
}
|
|
111
|
-
----
|
|
112
|
-
|
|
113
|
-
For more information about the metadata JSON Schema, check out the https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md#erc-1155-metadata-uri-json-schema[ERC-1155 Metadata URI JSON Schema].
|
|
114
|
-
|
|
115
|
-
NOTE: You'll notice that the item's information is included in the metadata, but that information isn't on-chain! So a game developer could change the underlying metadata, changing the rules of the game!
|
|
116
|
-
|
|
117
|
-
TIP: If you'd like to put all item information on-chain, you can extend ERC721 to do so (though it will be rather costly) by providing a xref:utilities.adoc#base64[`Base64`] Data URI with the JSON schema encoded. You could also leverage IPFS to store the URI information, but these techniques are out of the scope of this overview guide
|
|
118
|
-
|
|
119
|
-
[[sending-to-contracts]]
|
|
120
|
-
== Sending Tokens to Contracts
|
|
121
|
-
|
|
122
|
-
A key difference when using xref:api:token/ERC1155.adoc#IERC1155-safeTransferFrom-address-address-uint256-uint256-bytes-[`safeTransferFrom`] is that token transfers to other contracts may revert with the following message:
|
|
123
|
-
|
|
124
|
-
[source,text]
|
|
125
|
-
----
|
|
126
|
-
ERC1155: transfer to non ERC1155Receiver implementer
|
|
127
|
-
----
|
|
128
|
-
|
|
129
|
-
This is a good thing! It means that the recipient contract has not registered itself as aware of the ERC1155 protocol, so transfers to it are disabled to *prevent tokens from being locked forever*. As an example, https://etherscan.io/token/0xa74476443119A942dE498590Fe1f2454d7D4aC0d?a=0xa74476443119A942dE498590Fe1f2454d7D4aC0d[the Golem contract currently holds over 350k `GNT` tokens], worth multiple tens of thousands of dollars, and lacks methods to get them out of there. This has happened to virtually every ERC20-backed project, usually due to user error.
|
|
130
|
-
|
|
131
|
-
In order for our contract to receive ERC1155 tokens we can inherit from the convenience contract xref:api:token/ERC1155.adoc#ERC1155Holder[`ERC1155Holder`] which handles the registering for us. Though we need to remember to implement functionality to allow tokens to be transferred out of our contract:
|
|
132
|
-
|
|
133
|
-
[source,solidity]
|
|
134
|
-
----
|
|
135
|
-
// contracts/MyContract.sol
|
|
136
|
-
// SPDX-License-Identifier: MIT
|
|
137
|
-
pragma solidity ^0.8.0;
|
|
138
|
-
|
|
139
|
-
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
|
|
140
|
-
|
|
141
|
-
contract MyContract is ERC1155Holder {
|
|
142
|
-
}
|
|
143
|
-
----
|
|
144
|
-
|
|
145
|
-
We can also implement more complex scenarios using the xref:api:token/ERC1155.adoc#IERC1155Receiver-onERC1155Received-address-address-uint256-uint256-bytes-[`onERC1155Received`] and xref:api:token/ERC1155.adoc#IERC1155Receiver-onERC1155BatchReceived-address-address-uint256---uint256---bytes-[`onERC1155BatchReceived`] functions.
|
|
146
|
-
|
|
147
|
-
[[Presets]]
|
|
148
|
-
== Preset ERC1155 contract
|
|
149
|
-
A preset ERC1155 is available, https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.7/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol[`ERC1155PresetMinterPauser`]. It is preset to allow for token minting (create) - including batch minting, stop all token transfers (pause) and allow holders to burn (destroy) their tokens. The contract uses xref:access-control.adoc[Access Control] to control access to the minting and pausing functionality. The account that deploys the contract will be granted the minter and pauser roles, as well as the default admin role.
|
|
150
|
-
|
|
151
|
-
This contract is ready to deploy without having to write any Solidity code. It can be used as-is for quick prototyping and testing, but is also suitable for production environments.
|
|
152
|
-
|
|
153
|
-
NOTE: Contract presets are now deprecated in favor of https://wizard.openzeppelin.com[Contracts Wizard] as a more powerful alternative.
|
package/lib/openzeppelin-contracts-upgradeable.git/docs/modules/ROOT/pages/erc20-supply.adoc
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
= Creating ERC20 Supply
|
|
2
|
-
|
|
3
|
-
In this guide you will learn how to create an ERC20 token with a custom supply mechanism. We will showcase two idiomatic ways to use OpenZeppelin Contracts for this purpose that you will be able to apply to your smart contract development practice.
|
|
4
|
-
|
|
5
|
-
The standard interface implemented by tokens built on Ethereum is called ERC20, and Contracts includes a widely used implementation of it: the aptly named xref:api:token/ERC20.adoc[`ERC20`] contract. This contract, like the standard itself, is quite simple and bare-bones. In fact, if you try to deploy an instance of `ERC20` as-is it will be quite literally useless... it will have no supply! What use is a token with no supply?
|
|
6
|
-
|
|
7
|
-
The way that supply is created is not defined in the ERC20 document. Every token is free to experiment with its own mechanisms, ranging from the most decentralized to the most centralized, from the most naive to the most researched, and more.
|
|
8
|
-
|
|
9
|
-
[[fixed-supply]]
|
|
10
|
-
== Fixed Supply
|
|
11
|
-
|
|
12
|
-
Let's say we want a token with a fixed supply of 1000, initially allocated to the account that deploys the contract. If you've used Contracts v1, you may have written code like the following:
|
|
13
|
-
|
|
14
|
-
[source,solidity]
|
|
15
|
-
----
|
|
16
|
-
contract ERC20FixedSupply is ERC20 {
|
|
17
|
-
constructor() {
|
|
18
|
-
totalSupply += 1000;
|
|
19
|
-
balances[msg.sender] += 1000;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
----
|
|
23
|
-
|
|
24
|
-
Starting with Contracts v2 this pattern is not only discouraged, but disallowed. The variables `totalSupply` and `balances` are now private implementation details of `ERC20`, and you can't directly write to them. Instead, there is an internal xref:api:token/ERC20.adoc#ERC20-_mint-address-uint256-[`_mint`] function that will do exactly this:
|
|
25
|
-
|
|
26
|
-
[source,solidity]
|
|
27
|
-
----
|
|
28
|
-
contract ERC20FixedSupply is ERC20 {
|
|
29
|
-
constructor() ERC20("Fixed", "FIX") {
|
|
30
|
-
_mint(msg.sender, 1000);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
----
|
|
34
|
-
|
|
35
|
-
Encapsulating state like this makes it safer to extend contracts. For instance, in the first example we had to manually keep the `totalSupply` in sync with the modified balances, which is easy to forget. In fact, we omitted something else that is also easily forgotten: the `Transfer` event that is required by the standard, and which is relied on by some clients. The second example does not have this bug, because the internal `_mint` function takes care of it.
|
|
36
|
-
|
|
37
|
-
[[rewarding-miners]]
|
|
38
|
-
== Rewarding Miners
|
|
39
|
-
|
|
40
|
-
The internal xref:api:token/ERC20.adoc#ERC20-_mint-address-uint256-[`_mint`] function is the key building block that allows us to write ERC20 extensions that implement a supply mechanism.
|
|
41
|
-
|
|
42
|
-
The mechanism we will implement is a token reward for the miners that produce Ethereum blocks. In Solidity we can access the address of the current block's miner in the global variable `block.coinbase`. We will mint a token reward to this address whenever someone calls the function `mintMinerReward()` on our token. The mechanism may sound silly, but you never know what kind of dynamic this might result in, and it's worth analyzing and experimenting with!
|
|
43
|
-
|
|
44
|
-
[source,solidity]
|
|
45
|
-
----
|
|
46
|
-
contract ERC20WithMinerReward is ERC20 {
|
|
47
|
-
constructor() ERC20("Reward", "RWD") {}
|
|
48
|
-
|
|
49
|
-
function mintMinerReward() public {
|
|
50
|
-
_mint(block.coinbase, 1000);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
----
|
|
54
|
-
|
|
55
|
-
As we can see, `_mint` makes it super easy to do this correctly.
|
|
56
|
-
|
|
57
|
-
[[modularizing-the-mechanism]]
|
|
58
|
-
== Modularizing the Mechanism
|
|
59
|
-
|
|
60
|
-
There is one supply mechanism already included in Contracts: `ERC20PresetMinterPauser`. This is a generic mechanism in which a set of accounts is assigned the `minter` role, granting them the permission to call a `mint` function, an external version of `_mint`.
|
|
61
|
-
|
|
62
|
-
This can be used for centralized minting, where an externally owned account (i.e. someone with a pair of cryptographic keys) decides how much supply to create and for whom. There are very legitimate use cases for this mechanism, such as https://medium.com/reserve-currency/why-another-stablecoin-866f774afede#3aea[traditional asset-backed stablecoins].
|
|
63
|
-
|
|
64
|
-
The accounts with the minter role don't need to be externally owned, though, and can just as well be smart contracts that implement a trustless mechanism. We can in fact implement the same behavior as the previous section.
|
|
65
|
-
|
|
66
|
-
[source,solidity]
|
|
67
|
-
----
|
|
68
|
-
contract MinerRewardMinter {
|
|
69
|
-
ERC20PresetMinterPauser _token;
|
|
70
|
-
|
|
71
|
-
constructor(ERC20PresetMinterPauser token) {
|
|
72
|
-
_token = token;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function mintMinerReward() public {
|
|
76
|
-
_token.mint(block.coinbase, 1000);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
----
|
|
80
|
-
|
|
81
|
-
This contract, when initialized with an `ERC20PresetMinterPauser` instance, and granted the `minter` role for that contract, will result in exactly the same behavior implemented in the previous section. What is interesting about using `ERC20PresetMinterPauser` is that we can easily combine multiple supply mechanisms by assigning the role to multiple contracts, and moreover that we can do this dynamically.
|
|
82
|
-
|
|
83
|
-
TIP: To learn more about roles and permissioned systems, head to our xref:access-control.adoc[Access Control guide].
|
|
84
|
-
|
|
85
|
-
[[automating-the-reward]]
|
|
86
|
-
== Automating the Reward
|
|
87
|
-
|
|
88
|
-
So far our supply mechanisms were triggered manually, but `ERC20` also allows us to extend the core functionality of the token through the xref:api:token/ERC20.adoc#ERC20-_beforeTokenTransfer-address-address-uint256-[`_beforeTokenTransfer`] hook (see xref:extending-contracts.adoc#using-hooks[Using Hooks]).
|
|
89
|
-
|
|
90
|
-
Adding to the supply mechanism from previous sections, we can use this hook to mint a miner reward for every token transfer that is included in the blockchain.
|
|
91
|
-
|
|
92
|
-
[source,solidity]
|
|
93
|
-
----
|
|
94
|
-
contract ERC20WithAutoMinerReward is ERC20 {
|
|
95
|
-
constructor() ERC20("Reward", "RWD") {}
|
|
96
|
-
|
|
97
|
-
function _mintMinerReward() internal {
|
|
98
|
-
_mint(block.coinbase, 1000);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function _beforeTokenTransfer(address from, address to, uint256 value) internal virtual override {
|
|
102
|
-
if (!(from == address(0) && to == block.coinbase)) {
|
|
103
|
-
_mintMinerReward();
|
|
104
|
-
}
|
|
105
|
-
super._beforeTokenTransfer(from, to, value);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
----
|
|
109
|
-
|
|
110
|
-
[[wrapping-up]]
|
|
111
|
-
== Wrapping Up
|
|
112
|
-
|
|
113
|
-
We've seen two ways to implement ERC20 supply mechanisms: internally through `_mint`, and externally through `ERC20PresetMinterPauser`. Hopefully this has helped you understand how to use OpenZeppelin Contracts and some of the design principles behind it, and you can apply them to your own smart contracts.
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
= ERC20
|
|
2
|
-
|
|
3
|
-
An ERC20 token contract keeps track of xref:tokens.adoc#different-kinds-of-tokens[_fungible_ tokens]: any one token is exactly equal to any other token; no tokens have special rights or behavior associated with them. This makes ERC20 tokens useful for things like a *medium of exchange currency*, *voting rights*, *staking*, and more.
|
|
4
|
-
|
|
5
|
-
OpenZeppelin Contracts provides many ERC20-related contracts. On the xref:api:token/ERC20.adoc[`API reference`] you'll find detailed information on their properties and usage.
|
|
6
|
-
|
|
7
|
-
[[constructing-an-erc20-token-contract]]
|
|
8
|
-
== Constructing an ERC20 Token Contract
|
|
9
|
-
|
|
10
|
-
Using Contracts, we can easily create our own ERC20 token contract, which will be used to track _Gold_ (GLD), an internal currency in a hypothetical game.
|
|
11
|
-
|
|
12
|
-
Here's what our GLD token might look like.
|
|
13
|
-
|
|
14
|
-
[source,solidity]
|
|
15
|
-
----
|
|
16
|
-
// contracts/GLDToken.sol
|
|
17
|
-
// SPDX-License-Identifier: MIT
|
|
18
|
-
pragma solidity ^0.8.0;
|
|
19
|
-
|
|
20
|
-
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
21
|
-
|
|
22
|
-
contract GLDToken is ERC20 {
|
|
23
|
-
constructor(uint256 initialSupply) ERC20("Gold", "GLD") {
|
|
24
|
-
_mint(msg.sender, initialSupply);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
----
|
|
28
|
-
|
|
29
|
-
Our contracts are often used via https://solidity.readthedocs.io/en/latest/contracts.html#inheritance[inheritance], and here we're reusing xref:api:token/ERC20.adoc#erc20[`ERC20`] for both the basic standard implementation and the xref:api:token/ERC20.adoc#ERC20-name--[`name`], xref:api:token/ERC20.adoc#ERC20-symbol--[`symbol`], and xref:api:token/ERC20.adoc#ERC20-decimals--[`decimals`] optional extensions. Additionally, we're creating an `initialSupply` of tokens, which will be assigned to the address that deploys the contract.
|
|
30
|
-
|
|
31
|
-
TIP: For a more complete discussion of ERC20 supply mechanisms, see xref:erc20-supply.adoc[Creating ERC20 Supply].
|
|
32
|
-
|
|
33
|
-
That's it! Once deployed, we will be able to query the deployer's balance:
|
|
34
|
-
|
|
35
|
-
[source,javascript]
|
|
36
|
-
----
|
|
37
|
-
> GLDToken.balanceOf(deployerAddress)
|
|
38
|
-
1000000000000000000000
|
|
39
|
-
----
|
|
40
|
-
|
|
41
|
-
We can also xref:api:token/ERC20.adoc#IERC20-transfer-address-uint256-[transfer] these tokens to other accounts:
|
|
42
|
-
|
|
43
|
-
[source,javascript]
|
|
44
|
-
----
|
|
45
|
-
> GLDToken.transfer(otherAddress, 300000000000000000000)
|
|
46
|
-
> GLDToken.balanceOf(otherAddress)
|
|
47
|
-
300000000000000000000
|
|
48
|
-
> GLDToken.balanceOf(deployerAddress)
|
|
49
|
-
700000000000000000000
|
|
50
|
-
----
|
|
51
|
-
|
|
52
|
-
[[a-note-on-decimals]]
|
|
53
|
-
== A Note on `decimals`
|
|
54
|
-
|
|
55
|
-
Often, you'll want to be able to divide your tokens into arbitrary amounts: say, if you own `5 GLD`, you may want to send `1.5 GLD` to a friend, and keep `3.5 GLD` to yourself. Unfortunately, Solidity and the EVM do not support this behavior: only integer (whole) numbers can be used, which poses an issue. You may send `1` or `2` tokens, but not `1.5`.
|
|
56
|
-
|
|
57
|
-
To work around this, xref:api:token/ERC20.adoc#ERC20[`ERC20`] provides a xref:api:token/ERC20.adoc#ERC20-decimals--[`decimals`] field, which is used to specify how many decimal places a token has. To be able to transfer `1.5 GLD`, `decimals` must be at least `1`, since that number has a single decimal place.
|
|
58
|
-
|
|
59
|
-
How can this be achieved? It's actually very simple: a token contract can use larger integer values, so that a balance of `50` will represent `5 GLD`, a transfer of `15` will correspond to `1.5 GLD` being sent, and so on.
|
|
60
|
-
|
|
61
|
-
It is important to understand that `decimals` is _only used for display purposes_. All arithmetic inside the contract is still performed on integers, and it is the different user interfaces (wallets, exchanges, etc.) that must adjust the displayed values according to `decimals`. The total token supply and balance of each account are not specified in `GLD`: you need to divide by `10 ** decimals` to get the actual `GLD` amount.
|
|
62
|
-
|
|
63
|
-
You'll probably want to use a `decimals` value of `18`, just like Ether and most ERC20 token contracts in use, unless you have a very special reason not to. When minting tokens or transferring them around, you will be actually sending the number `num GLD * (10 ** decimals)`.
|
|
64
|
-
|
|
65
|
-
NOTE: By default, `ERC20` uses a value of `18` for `decimals`. To use a different value, you will need to override the `decimals()` function in your contract.
|
|
66
|
-
|
|
67
|
-
```solidity
|
|
68
|
-
function decimals() public view virtual override returns (uint8) {
|
|
69
|
-
return 16;
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
So if you want to send `5` tokens using a token contract with 18 decimals, the method to call will actually be:
|
|
74
|
-
|
|
75
|
-
```solidity
|
|
76
|
-
transfer(recipient, 5 * (10 ** 18));
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
[[Presets]]
|
|
80
|
-
== Preset ERC20 contract
|
|
81
|
-
A preset ERC20 is available, https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.7/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol[`ERC20PresetMinterPauser`]. It is preset to allow for token minting (create), stop all token transfers (pause) and allow holders to burn (destroy) their tokens. The contract uses xref:access-control.adoc[Access Control] to control access to the minting and pausing functionality. The account that deploys the contract will be granted the minter and pauser roles, as well as the default admin role.
|
|
82
|
-
|
|
83
|
-
This contract is ready to deploy without having to write any Solidity code. It can be used as-is for quick prototyping and testing, but is also suitable for production environments.
|
|
84
|
-
|
|
85
|
-
NOTE: Contract presets are now deprecated in favor of https://wizard.openzeppelin.com[Contracts Wizard] as a more powerful alternative.
|