@zero-tech/ztoken
Advanced tools
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
| # MeowToken Contract | ||
| The MeowToken is both a general purpose ERC20 token and a token designed for usage in Meow DAO's. | ||
| Many copies of this token may be deployed in the future (one for each DAO) and as such the token contract needs to be safe and easy to use. | ||
| ## Intended Usage | ||
| A MeowToken is used to represent ownership of a DAO inside of Meow. | ||
| Users who own a MeowToken have privileges granted by the DAO. | ||
| One of these privileges may be voting rights on proposals. | ||
| The weight of a users vote is determined by the quantity of tokens they own versus the total supply of tokens. | ||
| Token will also be used in `zNS` system developed by Zero and will be the main asset for purchasing Root Domains | ||
| through staking on the `zNS` platform. | ||
| ## Specification | ||
| This is a list of feature specifications, it will attempt to describe each fundamental feature and any requirements around them. | ||
| ### ERC20 Token | ||
| The token needs to implement the [ERC20 Token Standard](https://eips.ethereum.org/EIPS/eip-20). | ||
| ### Transfer | ||
| A user who owns MeowTokens should be able to transfer their tokens to another account or wallet. | ||
| ### Upgradable | ||
| The original token contract named `ZeroToken` was deployed as a Transparent Upgradeable Proxy. | ||
| When changing to `MeowToken`, contract has been upgraded twice to achieve the final stage and remove | ||
| some unnecessary functionality and to change the name and symbol of the token. After the final upgrade | ||
| contract stops being upgradeable through `renounceOwnership()` method on it's `ProxyAdmin` contract. | ||
| Even though MeowToken stays a Transparent Proxy, it will be impossible to upgrade, since it will have no owner | ||
| who is the only entity that can upgrade the contract. So, effectively, MeowToken is not upgradeable | ||
| after the ownerhip of it's `ProxyAdmin` is renounced. | ||
| ### Bulk Transfer | ||
| The ability to transfer tokens from one account to many accounts with a single transaction is required to save on gas. | ||
| Besides that a new feature is added where transferring tokens to the address of the token contract itself | ||
| will burn these tokens from the `totalSupply`. This should be clearly stated in the docs and UI and some | ||
| measures should be added that warn people about the fact that they are burning tokens if specifying the incorrect address. | ||
| ### Ownable | ||
| The contract was previously own-able, but the current implementation aim to remove ownership methods and after the upgrade will happen on the mainnet the renounceOwnership() method will be called |
| # Upgrade Process for MEOW Token | ||
| ## Ethereum Mainnet | ||
| 1. [test step] Send a single approval transaction to populate state of the existing token. | ||
| 2. [upgrade step] Deploy new implementation contract `MeowToken.sol` using script `scripts/02_deployMeowImpl.ts` | ||
| 3. [upgrade step] Create a proposal in OpenZeppelin Defender to upgrade the token proxy contract to the newly deployed implementation. Proposal will go through the multisig. | ||
| 4. [test step] Run the test script `scripts/03_confirmValues.ts` to test 4 main things: | ||
| 1. `transferBulk()` works as expected moving funds from existing token holder to other wallets | ||
| 2. `transferFromBulk()` works as expected moving funds from existing token holder to other wallets while using recent (post upgrade) approvals | ||
| 3. `transferFromBulk()` works as expected moving funds from existing token holder to other wallets while using previous (pre-upgrade) approval created in the step #1 | ||
| 4. both `transferBulk()` and `transferFromBulk()` burn the amount of tokens sent to the address of the Token Proxy contract from the `totalSupply` | ||
| 5. [upgrade step] Once token functionality is validated after the upgrade, we proceed to "remove the token upgradability" by: | ||
| 1. Calling the `ProxyAdmin.renounceOwnership()` to remove the ability to call `upgrade` for any account in the future. | ||
| 6. (Alternative to step 5!) Call the current `ProxyAdmin.changeProxyAdmin()` to some other dead address that is not owned by anyone and is not the zero address, therefore removing the need for the new `ProxyAdmin` altogether. | ||
| > Q: Which of the approaches between #5 and #6 is better? If #6 is better, which address should we use that is safe to assume will never be owned by anyone? | ||
| > It can't be 0x0 address. Can it be 0xdead or some other? | ||
| ## Ethereum Sepolia Testnet Run | ||
| For this run we performed the same steps as for Mainnet, except we deployed the original `ZeroToken` first so we have a token to upgrade. Additionally, a mint of tokens occurs to the main account that is used in tests so we have funds to transfer back and forth. | ||
| You can find the scripts in the `scripts/` root directory. | ||
| ## Running the Scripts | ||
| To run any of the scripts files you must first include the used private keys in a `.env` file at the root of this repository that will link to the account(s) used in ownership and token transfers. | ||
| ``` | ||
| # .env | ||
| PRIVATE_KEY=<private key for mainnet account> | ||
| PRIVATE_KEY_A=<private key for test account A> | ||
| PRIVATE_KEY_B=<private key for test account B> | ||
| PRIVATE_KEY_C=<private key for test account C> | ||
| PRIVATE_KEY_D=<private key for test account D> | ||
| ``` | ||
| Then you can run the scripts using the terminal command below. By default, hardhat is the network that's used and scripts may fail if they expect certain state to exist, such as the ZERO contract already being deployed. | ||
| You can specify the network using the `--network <network-name>` argument. | ||
| ```bash | ||
| $ yarn hardhat run scripts/<script-name> [--network <network-name>] | ||
| ``` | ||
| For example, running on the Sepolia test network would first require the deployment of ZERO and minting of tokens | ||
| ``` | ||
| yarn hardhat run scripts/01_deployZero.ts --network sepolia | ||
| ``` | ||
| Then you would also run the script to perform transactions and write out the values. | ||
| ``` | ||
| yarn hardhat run scripts/03_confirmValues.ts --network sepolia | ||
| ``` | ||
| After this runs successfully it will generate a `preUpgradeTokenValues.json` file located at the root of this repository. Once you've completed these two steps, you can modify the address of the ZERO token in the upgrade script `scripts/04_upgradeZero.ts` to be the newly deployed address and then run it similar to the above. | ||
| Before running `03_confirmValues` again, you must also change some variable names internally. This includes the token address, token name, and output file name. When this is run a `postUpgradeTokenValues.json` will be generated. Use this to confirm that transfers work as expected, and that total supply of the MEOW token is reduced by the expected amount after performing a transfer to the token contract address. |
+2
-2
| # Zero Token Contracts Documentation | ||
| Here you will find documentation around the Zero Token Contract set. | ||
| Here you will find documentation around the Meow Token Contract set. | ||
| For information in specific contracts please view these files: | ||
| - [zToken Contract](./ztoken.md) | ||
| - [Meow Token Contract](./meow-token.md) | ||
| - [Merkle Token Vesting Contract](./merklevesting.md) | ||
| - [Merkle Token Airdrop Contract](./merkleairdrop.md) |
+17
-27
| { | ||
| "name": "@zero-tech/ztoken", | ||
| "version": "1.0.1", | ||
| "version": "2.0.0", | ||
| "license": "MIT", | ||
@@ -9,15 +9,2 @@ "files": [ | ||
| ], | ||
| "types": "./lib/cjs/types/index.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "import": { | ||
| "types": "./lib/esm/types/index.d.ts", | ||
| "default": "./lib/esm/index.mjs" | ||
| }, | ||
| "require": { | ||
| "types": "./lib/cjs/types/index.d.ts", | ||
| "default": "./lib/cjs/index.js" | ||
| } | ||
| } | ||
| }, | ||
| "scripts": { | ||
@@ -27,6 +14,7 @@ "build-hh": "yarn run clean-hh && yarn run compile", | ||
| "compile": "hardhat compile", | ||
| "typechain": "hardhat typechain", | ||
| "hardhat": "hardhat", | ||
| "merkle": "hardhat merkle", | ||
| "test": "hardhat test --show-stack-traces", | ||
| "coverage": "yarn run build && hardhat coverage --temp artifacts --network hardhat", | ||
| "coverage": "yarn run build && hardhat coverage --temp artifacts --network hardhat --solcoverjs ./.solcover.js ", | ||
| "fix": "yarn run fix:contracts && yarn run fix:ts", | ||
@@ -39,5 +27,3 @@ "fix:contracts": "prettier --write ./contracts/**/*.sol", | ||
| "clean": "rm -rf ./lib", | ||
| "build": "npm run clean && npm run build:esm && npm run build:cjs", | ||
| "build:esm": "tsc -p ./tsconfig.esm.json && mv lib/esm/index.js lib/esm/index.mjs", | ||
| "build:cjs": "tsc -p ./tsconfig.cjs.json" | ||
| "build": "yarn run clean && yarn run compile" | ||
| }, | ||
@@ -49,6 +35,8 @@ "devDependencies": { | ||
| "@nomiclabs/hardhat-ethers": "2.2.2", | ||
| "@nomiclabs/hardhat-etherscan": "^3.0.0", | ||
| "@nomiclabs/hardhat-waffle": "2.0.1", | ||
| "@nomiclabs/hardhat-etherscan": "^3.0.0", | ||
| "@openzeppelin/contracts": "4.8.2", | ||
| "@openzeppelin/contracts-upgradeable": "4.8.2", | ||
| "@openzeppelin/contracts": "4.9.3", | ||
| "@openzeppelin/contracts-upgradeable": "4.9.3", | ||
| "@openzeppelin/contracts-400": "npm:@openzeppelin/contracts@4.0.0", | ||
| "@openzeppelin/contracts-upgradeable-400": "npm:@openzeppelin/contracts-upgradeable@4.0.0", | ||
| "@openzeppelin/hardhat-upgrades": "^1.26.0", | ||
@@ -59,7 +47,9 @@ "@openzeppelin/upgrades-core": "1.10.0", | ||
| "@types/chai": "4.2.0", | ||
| "@types/chai-as-promised": "^7.1.6", | ||
| "@types/mocha": "9.1.0", | ||
| "@types/node": "^18.15.11", | ||
| "@typescript-eslint/eslint-plugin": "4.16.1", | ||
| "@typescript-eslint/parser": "4.16.1", | ||
| "@types/node": "^20.8.4", | ||
| "@typescript-eslint/eslint-plugin": "^6.8.0", | ||
| "@typescript-eslint/parser": "^6.8.0", | ||
| "chai": "4.3.3", | ||
| "chai-as-promised": "^7.1.1", | ||
| "cli-interact": "0.1.9", | ||
@@ -72,4 +62,4 @@ "csv-parser": "3.0.0", | ||
| "ethereumjs-util": "7.0.10", | ||
| "ethers": "5.5.1", | ||
| "hardhat": "2.13.0", | ||
| "hardhat-ignore-warnings": "^0.2.9", | ||
| "ipfs-http-client": "50.1.1", | ||
@@ -82,3 +72,3 @@ "lodash": "4.17.15", | ||
| "solhint-plugin-prettier": "0.0.5", | ||
| "solidity-coverage": "0.7.16", | ||
| "solidity-coverage": "0.8.5", | ||
| "ts-generator": "0.1.1", | ||
@@ -89,2 +79,2 @@ "ts-node": "10.9.1", | ||
| } | ||
| } | ||
| } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
| # Modified Open Zeppelin Contracts | ||
| These contracts are slightly modified versions of the base Open Zeppelin contracts. | ||
| They are based on `@openzeppelin/contracts-upgradeable` version `4.0.0` | ||
| This document serves as a complete list of changes: | ||
| ## ERC20Upgradeable | ||
| - `_balances` is now internal (was private) | ||
| - `_allowances` is now internal (was private) | ||
| ## ERC20PauseableUpgradeable | ||
| - `_updateAccountSnapshot` is now internal (was private) | ||
| - `_updateTotalSupplySnapshot` is now internal (was private) | ||
Sorry, the diff of this file is not supported yet
| # zToken Contract | ||
| The zToken is both a general purpose ERC20 token and a token designed for usage in Zer0 DAO's. | ||
| Many copies of this token may be deployed in the future (one for each DAO) and as such the token contract needs to be safe and easy to use. | ||
| ## Intended Usage | ||
| A zToken is used to represent ownership of a DAO inside of Zer0. | ||
| Users who own a zToken have privileges granted by the DAO. | ||
| One of these privileges may be voting rights on proposals. | ||
| The weight of a users vote is determined by the quantity of tokens they own versus the total supply of tokens. | ||
| ## Specification | ||
| This is a list of feature specifications, it will attempt to describe each fundamental feature and any requirements around them. | ||
| ### ERC20 Token | ||
| The token needs to implement the [ERC20 Token Standard](https://eips.ethereum.org/EIPS/eip-20). | ||
| ### Transfer | ||
| A user who owns zTokens should be able to transfer their tokens to another account or wallet. | ||
| ### Pauseable | ||
| The zToken administrator (owner of the zToken contract) should be able to freeze and unfreeze token transactions. | ||
| Freezing of token transactions will prevent: | ||
| - Tokens from being transferred | ||
| - Tokens from being bought or sold | ||
| - New tokens from being created | ||
| ### Upgradable | ||
| It is likely that additional functionality may be required of a zToken in the future. | ||
| Therefore the zToken contracts should be upgradable to allow for functionality improvements without a token migration. | ||
| ### Balance Snapshotting | ||
| Voting on a zDAO proposal may not require tokens to be ‘spent’ or ‘locked’ thus allowing a user to vote and then transfer their tokens before the vote has passed. | ||
| As such, the weight of a users vote must not change during the duration of a proposal. If it were changeable then it would be possible for a user to vote on a proposal, transfer their tokens, then vote a second time on the same proposal. | ||
| To prevent this balance snapshotting must be implemented, which will snapshot a users balances when a snapshot is taken. zDAO can therefore use a users token balance at the start time of a proposal to determine voting weight. | ||
| Authorized users, such as the owner, or "snapshotters" are allowed to call a `snapshot` method which will take a snapshot of user balances. | ||
| This `snapshot` method returns the taken snapshot id which can be used to retrieve the balances at that snapshot. | ||
| ### Bulk Transfer | ||
| The ability to transfer tokens from one account to many accounts with a single transaction is required to save on gas. | ||
| ### Ownable | ||
| The owner of the token contract has the ability to mint and burn tokens. | ||
| The intended owner of this token is a Zer0 DAO. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
84224
28.57%24
20%43
10.26%