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,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.
|
|
@@ -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.
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
= ERC721
|
|
2
|
-
|
|
3
|
-
We've discussed how you can make a _fungible_ token using xref:erc20.adoc[ERC20], but what if not all tokens are alike? This comes up in situations like *real estate*, *voting rights*, or *collectibles*, where some items are valued more than others, due to their usefulness, rarity, etc. ERC721 is a standard for representing ownership of xref:tokens.adoc#different-kinds-of-tokens[_non-fungible_ tokens], that is, where each token is unique.
|
|
4
|
-
|
|
5
|
-
ERC721 is a more complex standard than ERC20, with multiple optional extensions, and is split across a number of contracts. The OpenZeppelin Contracts provide flexibility regarding how these are combined, along with custom useful extensions. Check out the xref:api:token/ERC721.adoc[API Reference] to learn more about these.
|
|
6
|
-
|
|
7
|
-
== Constructing an ERC721 Token Contract
|
|
8
|
-
|
|
9
|
-
We'll use ERC721 to track items in our game, which will each have their own unique attributes. Whenever one is to be awarded to a player, it will be minted and sent to them. Players are free to keep their token or trade it with other people as they see fit, as they would any other asset on the blockchain! Please note any account can call `awardItem` to mint items. To restrict what accounts can mint items we can add xref:access-control.adoc[Access Control].
|
|
10
|
-
|
|
11
|
-
Here's what a contract for tokenized items might look like:
|
|
12
|
-
|
|
13
|
-
[source,solidity]
|
|
14
|
-
----
|
|
15
|
-
// contracts/GameItem.sol
|
|
16
|
-
// SPDX-License-Identifier: MIT
|
|
17
|
-
pragma solidity ^0.8.0;
|
|
18
|
-
|
|
19
|
-
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
|
|
20
|
-
import "@openzeppelin/contracts/utils/Counters.sol";
|
|
21
|
-
|
|
22
|
-
contract GameItem is ERC721URIStorage {
|
|
23
|
-
using Counters for Counters.Counter;
|
|
24
|
-
Counters.Counter private _tokenIds;
|
|
25
|
-
|
|
26
|
-
constructor() ERC721("GameItem", "ITM") {}
|
|
27
|
-
|
|
28
|
-
function awardItem(address player, string memory tokenURI)
|
|
29
|
-
public
|
|
30
|
-
returns (uint256)
|
|
31
|
-
{
|
|
32
|
-
uint256 newItemId = _tokenIds.current();
|
|
33
|
-
_mint(player, newItemId);
|
|
34
|
-
_setTokenURI(newItemId, tokenURI);
|
|
35
|
-
|
|
36
|
-
_tokenIds.increment();
|
|
37
|
-
return newItemId;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
----
|
|
41
|
-
|
|
42
|
-
The xref:api:token/ERC721.adoc#ERC721URIStorage[`ERC721URIStorage`] contract is an implementation of ERC721 that includes the metadata standard extensions (xref:api:token/ERC721.adoc#IERC721Metadata[`IERC721Metadata`]) as well as a mechanism for per-token metadata. That's where the xref:api:token/ERC721.adoc#ERC721-_setTokenURI-uint256-string-[`_setTokenURI`] method comes from: we use it to store an item's metadata.
|
|
43
|
-
|
|
44
|
-
Also note that, unlike ERC20, ERC721 lacks a `decimals` field, since each token is distinct and cannot be partitioned.
|
|
45
|
-
|
|
46
|
-
New items can be created:
|
|
47
|
-
|
|
48
|
-
[source,javascript]
|
|
49
|
-
----
|
|
50
|
-
> gameItem.awardItem(playerAddress, "https://game.example/item-id-8u5h2m.json")
|
|
51
|
-
Transaction successful. Transaction hash: 0x...
|
|
52
|
-
Events emitted:
|
|
53
|
-
- Transfer(0x0000000000000000000000000000000000000000, playerAddress, 7)
|
|
54
|
-
----
|
|
55
|
-
|
|
56
|
-
And the owner and metadata of each item queried:
|
|
57
|
-
|
|
58
|
-
[source,javascript]
|
|
59
|
-
----
|
|
60
|
-
> gameItem.ownerOf(7)
|
|
61
|
-
playerAddress
|
|
62
|
-
> gameItem.tokenURI(7)
|
|
63
|
-
"https://game.example/item-id-8u5h2m.json"
|
|
64
|
-
----
|
|
65
|
-
|
|
66
|
-
This `tokenURI` should resolve to a JSON document that might look something like:
|
|
67
|
-
|
|
68
|
-
[source,json]
|
|
69
|
-
----
|
|
70
|
-
{
|
|
71
|
-
"name": "Thor's hammer",
|
|
72
|
-
"description": "Mjölnir, the legendary hammer of the Norse god of thunder.",
|
|
73
|
-
"image": "https://game.example/item-id-8u5h2m.png",
|
|
74
|
-
"strength": 20
|
|
75
|
-
}
|
|
76
|
-
----
|
|
77
|
-
|
|
78
|
-
For more information about the `tokenURI` metadata JSON Schema, check out the https://eips.ethereum.org/EIPS/eip-721[ERC721 specification].
|
|
79
|
-
|
|
80
|
-
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!
|
|
81
|
-
|
|
82
|
-
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 tokenURI information, but these techniques are out of the scope of this overview guide.
|
|
83
|
-
|
|
84
|
-
[[Presets]]
|
|
85
|
-
== Preset ERC721 contract
|
|
86
|
-
A preset ERC721 is available, https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.7/contracts/token/ERC721/presets/ERC721PresetMinterPauserAutoId.sol[`ERC721PresetMinterPauserAutoId`]. It is preconfigured with token minting (creation) with token ID and URI auto generation, the ability to stop all token transfers (pause), and it allows 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.
|
|
87
|
-
|
|
88
|
-
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.
|
|
89
|
-
|
|
90
|
-
NOTE: Contract presets are now deprecated in favor of https://wizard.openzeppelin.com[Contracts Wizard] as a more powerful alternative.
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
= ERC777
|
|
2
|
-
|
|
3
|
-
Like xref:erc20.adoc[ERC20], ERC777 is a standard for xref:tokens.adoc#different-kinds-of-tokens[_fungible_ tokens], and is focused around allowing more complex interactions when trading tokens. More generally, it brings tokens and Ether closer together by providing the equivalent of a `msg.value` field, but for tokens.
|
|
4
|
-
|
|
5
|
-
The standard also brings multiple quality-of-life improvements, such as getting rid of the confusion around `decimals`, minting and burning with proper events, among others, but its killer feature is *receive hooks*. A hook is simply a function in a contract that is called when tokens are sent to it, meaning *accounts and contracts can react to receiving tokens*.
|
|
6
|
-
|
|
7
|
-
This enables a lot of interesting use cases, including atomic purchases using tokens (no need to do `approve` and `transferFrom` in two separate transactions), rejecting reception of tokens (by reverting on the hook call), redirecting the received tokens to other addresses (similarly to how xref:api:payment#PaymentSplitter[`PaymentSplitter`] does it), among many others.
|
|
8
|
-
|
|
9
|
-
Furthermore, since contracts are required to implement these hooks in order to receive tokens, _no tokens can get stuck in a contract that is unaware of the ERC777 protocol_, as has happened countless times when using ERC20s.
|
|
10
|
-
|
|
11
|
-
== What If I Already Use ERC20?
|
|
12
|
-
|
|
13
|
-
The standard has you covered! The ERC777 standard is *backwards compatible with ERC20*, meaning you can interact with these tokens as if they were ERC20, using the standard functions, while still getting all of the niceties, including send hooks. See the https://eips.ethereum.org/EIPS/eip-777#backward-compatibility[EIP's Backwards Compatibility section] to learn more.
|
|
14
|
-
|
|
15
|
-
== Constructing an ERC777 Token Contract
|
|
16
|
-
|
|
17
|
-
We will replicate the `GLD` example of the xref:erc20.adoc#constructing-an-erc20-token-contract[ERC20 guide], this time using ERC777. As always, check out the xref:api:token/ERC777.adoc[`API reference`] to learn more about the details of each function.
|
|
18
|
-
|
|
19
|
-
[source,solidity]
|
|
20
|
-
----
|
|
21
|
-
// contracts/GLDToken.sol
|
|
22
|
-
// SPDX-License-Identifier: MIT
|
|
23
|
-
pragma solidity ^0.8.0;
|
|
24
|
-
|
|
25
|
-
import "@openzeppelin/contracts/token/ERC777/ERC777.sol";
|
|
26
|
-
|
|
27
|
-
contract GLDToken is ERC777 {
|
|
28
|
-
constructor(uint256 initialSupply, address[] memory defaultOperators)
|
|
29
|
-
ERC777("Gold", "GLD", defaultOperators)
|
|
30
|
-
{
|
|
31
|
-
_mint(msg.sender, initialSupply, "", "");
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
----
|
|
35
|
-
|
|
36
|
-
In this case, we'll be extending from the xref:api:token/ERC777.adoc#ERC777[`ERC777`] contract, which provides an implementation with compatibility support for ERC20. The API is quite similar to that of xref:api:token/ERC777.adoc#ERC777[`ERC777`], and we'll once again make use of xref:api:token/ERC777.adoc#ERC777-_mint-address-address-uint256-bytes-bytes-[`_mint`] to assign the `initialSupply` to the deployer account. Unlike xref:api:token/ERC20.adoc#ERC20-_mint-address-uint256-[ERC20's `_mint`], this one includes some extra parameters, but you can safely ignore those for now.
|
|
37
|
-
|
|
38
|
-
You'll notice both xref:api:token/ERC777.adoc#IERC777-name--[`name`] and xref:api:token/ERC777.adoc#IERC777-symbol--[`symbol`] are assigned, but not xref:api:token/ERC777.adoc#ERC777-decimals--[`decimals`]. The ERC777 specification makes it mandatory to include support for these functions (unlike ERC20, where it is optional and we had to include xref:api:token/ERC20.adoc#ERC20Detailed[`ERC20Detailed`]), but also mandates that `decimals` always returns a fixed value of `18`, so there's no need to set it ourselves. For a review of ``decimals``'s role and importance, refer back to our xref:erc20.adoc#a-note-on-decimals[ERC20 guide].
|
|
39
|
-
|
|
40
|
-
Finally, we'll need to set the xref:api:token/ERC777.adoc#IERC777-defaultOperators--[`defaultOperators`]: special accounts (usually other smart contracts) that will be able to transfer tokens on behalf of their holders. If you're not planning on using operators in your token, you can simply pass an empty array. _Stay tuned for an upcoming in-depth guide on ERC777 operators!_
|
|
41
|
-
|
|
42
|
-
That's it for a basic token contract! We can now deploy it, and use the same xref:api:token/ERC777.adoc#IERC777-balanceOf-address-[`balanceOf`] method to query the deployer's balance:
|
|
43
|
-
|
|
44
|
-
[source,javascript]
|
|
45
|
-
----
|
|
46
|
-
> GLDToken.balanceOf(deployerAddress)
|
|
47
|
-
1000
|
|
48
|
-
----
|
|
49
|
-
|
|
50
|
-
To move tokens from one account to another, we can use both xref:api:token/ERC777.adoc#ERC777-transfer-address-uint256-[``ERC20``'s `transfer`] method, or the new xref:api:token/ERC777.adoc#ERC777-send-address-uint256-bytes-[``ERC777``'s `send`], which fulfills a very similar role, but adds an optional `data` field:
|
|
51
|
-
|
|
52
|
-
[source,javascript]
|
|
53
|
-
----
|
|
54
|
-
> GLDToken.transfer(otherAddress, 300)
|
|
55
|
-
> GLDToken.send(otherAddress, 300, "")
|
|
56
|
-
> GLDToken.balanceOf(otherAddress)
|
|
57
|
-
600
|
|
58
|
-
> GLDToken.balanceOf(deployerAddress)
|
|
59
|
-
400
|
|
60
|
-
----
|
|
61
|
-
|
|
62
|
-
== Sending Tokens to Contracts
|
|
63
|
-
|
|
64
|
-
A key difference when using xref:api:token/ERC777.adoc#ERC777-send-address-uint256-bytes-[`send`] is that token transfers to other contracts may revert with the following message:
|
|
65
|
-
|
|
66
|
-
[source,text]
|
|
67
|
-
----
|
|
68
|
-
ERC777: token recipient contract has no implementer for ERC777TokensRecipient
|
|
69
|
-
----
|
|
70
|
-
|
|
71
|
-
This is a good thing! It means that the recipient contract has not registered itself as aware of the ERC777 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.
|
|
72
|
-
|
|
73
|
-
_An upcoming guide will cover how a contract can register itself as a recipient, send and receive hooks, and other advanced features of ERC777!_
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
= Extending Contracts
|
|
2
|
-
|
|
3
|
-
Most of the OpenZeppelin Contracts are expected to be used via https://solidity.readthedocs.io/en/latest/contracts.html#inheritance[inheritance]: you will _inherit_ from them when writing your own contracts.
|
|
4
|
-
|
|
5
|
-
This is the commonly found `is` syntax, like in `contract MyToken is ERC20`.
|
|
6
|
-
|
|
7
|
-
[NOTE]
|
|
8
|
-
====
|
|
9
|
-
Unlike ``contract``s, Solidity ``library``s are not inherited from and instead rely on the https://solidity.readthedocs.io/en/latest/contracts.html#using-for[`using for`] syntax.
|
|
10
|
-
|
|
11
|
-
OpenZeppelin Contracts has some ``library``s: most are in the xref:api:utils.adoc[Utils] directory.
|
|
12
|
-
====
|
|
13
|
-
|
|
14
|
-
== Overriding
|
|
15
|
-
|
|
16
|
-
Inheritance is often used to add the parent contract's functionality to your own contract, but that's not all it can do. You can also _change_ how some parts of the parent behave using _overrides_.
|
|
17
|
-
|
|
18
|
-
For example, imagine you want to change xref:api:access.adoc#AccessControl[`AccessControl`] so that xref:api:access.adoc#AccessControl-revokeRole-bytes32-address-[`revokeRole`] can no longer be called. This can be achieved using overrides:
|
|
19
|
-
|
|
20
|
-
```solidity
|
|
21
|
-
// contracts/ModifiedAccessControl.sol
|
|
22
|
-
// SPDX-License-Identifier: MIT
|
|
23
|
-
pragma solidity ^0.8.0;
|
|
24
|
-
|
|
25
|
-
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
26
|
-
|
|
27
|
-
contract ModifiedAccessControl is AccessControl {
|
|
28
|
-
// Override the revokeRole function
|
|
29
|
-
function revokeRole(bytes32, address) public override {
|
|
30
|
-
revert("ModifiedAccessControl: cannot revoke roles");
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The old `revokeRole` is then replaced by our override, and any calls to it will immediately revert. We cannot _remove_ the function from the contract, but reverting on all calls is good enough.
|
|
36
|
-
|
|
37
|
-
=== Calling `super`
|
|
38
|
-
|
|
39
|
-
Sometimes you want to _extend_ a parent's behavior, instead of outright changing it to something else. This is where `super` comes in.
|
|
40
|
-
|
|
41
|
-
The `super` keyword will let you call functions defined in a parent contract, even if they are overridden. This mechanism can be used to add additional checks to a function, emit events, or otherwise add functionality as you see fit.
|
|
42
|
-
|
|
43
|
-
TIP: For more information on how overrides work, head over to the https://solidity.readthedocs.io/en/latest/contracts.html#index-17[official Solidity documentation].
|
|
44
|
-
|
|
45
|
-
Here is a modified version of xref:api:access.adoc#AccessControl[`AccessControl`] where xref:api:access.adoc#AccessControl-revokeRole-bytes32-address-[`revokeRole`] cannot be used to revoke the `DEFAULT_ADMIN_ROLE`:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
```solidity
|
|
49
|
-
// contracts/ModifiedAccessControl.sol
|
|
50
|
-
// SPDX-License-Identifier: MIT
|
|
51
|
-
pragma solidity ^0.8.0;
|
|
52
|
-
|
|
53
|
-
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
54
|
-
|
|
55
|
-
contract ModifiedAccessControl is AccessControl {
|
|
56
|
-
function revokeRole(bytes32 role, address account) public override {
|
|
57
|
-
require(
|
|
58
|
-
role != DEFAULT_ADMIN_ROLE,
|
|
59
|
-
"ModifiedAccessControl: cannot revoke default admin role"
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
super.revokeRole(role, account);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
The `super.revokeRole` statement at the end will invoke ``AccessControl``'s original version of `revokeRole`, the same code that would've run if there were no overrides in place.
|
|
68
|
-
|
|
69
|
-
[[using-hooks]]
|
|
70
|
-
== Using Hooks
|
|
71
|
-
|
|
72
|
-
Sometimes, in order to extend a parent contract you will need to override multiple related functions, which leads to code duplication and increased likelihood of bugs.
|
|
73
|
-
|
|
74
|
-
For example, consider implementing safe xref:api:token/ERC20.adoc#ERC20[`ERC20`] transfers in the style of xref:api:token/ERC721.adoc#IERC721Receiver[`IERC721Receiver`]. You may think overriding xref:api:token/ERC20.adoc#ERC20-transfer-address-uint256-[`transfer`] and xref:api:token/ERC20.adoc#ERC20-transferFrom-address-address-uint256-[`transferFrom`] would be enough, but what about xref:api:token/ERC20.adoc#ERC20-_transfer-address-address-uint256-[`_transfer`] and xref:api:token/ERC20.adoc#ERC20-_mint-address-uint256-[`_mint`]? To prevent you from having to deal with these details, we introduced **hooks**.
|
|
75
|
-
|
|
76
|
-
Hooks are simply functions that are called before or after some action takes place. They provide a centralized point to _hook into_ and extend the original behavior.
|
|
77
|
-
|
|
78
|
-
Here's how you would implement the `IERC721Receiver` pattern in `ERC20`, using the xref:api:token/ERC20.adoc#ERC20-_beforeTokenTransfer-address-address-uint256-[`_beforeTokenTransfer`] hook:
|
|
79
|
-
|
|
80
|
-
```solidity
|
|
81
|
-
pragma solidity ^0.8.0;
|
|
82
|
-
|
|
83
|
-
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
84
|
-
|
|
85
|
-
contract ERC20WithSafeTransfer is ERC20 {
|
|
86
|
-
function _beforeTokenTransfer(address from, address to, uint256 amount)
|
|
87
|
-
internal virtual override
|
|
88
|
-
{
|
|
89
|
-
super._beforeTokenTransfer(from, to, amount);
|
|
90
|
-
|
|
91
|
-
require(_validRecipient(to), "ERC20WithSafeTransfer: invalid recipient");
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function _validRecipient(address to) private view returns (bool) {
|
|
95
|
-
...
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
...
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Using hooks this way leads to cleaner and safer code, without having to rely on a deep understanding of the parent's internals.
|
|
103
|
-
|
|
104
|
-
=== Rules of Hooks
|
|
105
|
-
|
|
106
|
-
There's a few guidelines you should follow when writing code that uses hooks in order to prevent issues. They are very simple, but do make sure you follow them:
|
|
107
|
-
|
|
108
|
-
1. Whenever you override a parent's hook, re-apply the `virtual` attribute to the hook. That will allow child contracts to add more functionality to the hook.
|
|
109
|
-
2. **Always** call the parent's hook in your override using `super`. This will make sure all hooks in the inheritance tree are called: contracts like xref:api:token/ERC20.adoc#ERC20Pausable[`ERC20Pausable`] rely on this behavior.
|
|
110
|
-
|
|
111
|
-
```solidity
|
|
112
|
-
contract MyToken is ERC20 {
|
|
113
|
-
function _beforeTokenTransfer(address from, address to, uint256 amount)
|
|
114
|
-
internal virtual override // Add virtual here!
|
|
115
|
-
{
|
|
116
|
-
super._beforeTokenTransfer(from, to, amount); // Call parent hook
|
|
117
|
-
...
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
That's it! Enjoy simpler code using hooks!
|
|
122
|
-
|
|
123
|
-
== Security
|
|
124
|
-
|
|
125
|
-
The maintainers of OpenZeppelin Contracts are mainly concerned with the correctness and security of the code as published in the library, and the combinations of base contracts with the official extensions from the library.
|
|
126
|
-
|
|
127
|
-
Custom overrides, and those of hooks in particular, may break some important assumptions and introduce vulnerabilities in otherwise secure code. While we try to ensure the contracts remain secure in the face of a wide range of potential customizations, this is done in a best-effort manner. While we try to document all important assumptions, this should not be relied upon. Custom overrides should be carefully reviewed and checked against the source code of the contract they are customizing so as to fully understand their impact and guarantee their security.
|
|
128
|
-
|
|
129
|
-
The way functions interact internally should not be assumed to stay stable across releases of the library. For example, a function that is used in one context in a particular release may not be used in the same context in the next release. Contracts that override functions should revalidate their assumptions when updating the version of OpenZeppelin Contracts they are built on.
|