├── .dockerignore ├── .env.ci ├── .env.tpl ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── ci.yml │ ├── release.yml │ └── slither.yml ├── .gitignore ├── .husky └── commit-msg ├── .prettierrc ├── .solcover.js ├── .solhint.json ├── .solhintignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── DEPLOY.md ├── Dockerfile ├── README.md ├── codechecks.yml ├── commitlint.config.js ├── contracts ├── Core │ ├── BlockManager.sol │ ├── BondManager.sol │ ├── CollectionManager.sol │ ├── RewardManager.sol │ ├── StakeManager.sol │ ├── StateManager.sol │ ├── VoteManager.sol │ ├── interface │ │ ├── IBlockManager.sol │ │ ├── IBondManager.sol │ │ ├── ICollectionManager.sol │ │ ├── IRewardManager.sol │ │ ├── IStakeManager.sol │ │ └── IVoteManager.sol │ ├── parameters │ │ ├── ACL.sol │ │ ├── Governance.sol │ │ ├── child │ │ │ ├── BlockManagerParams.sol │ │ │ ├── BondManagerParams.sol │ │ │ ├── CollectionManagerParams.sol │ │ │ ├── RandomNoManagerParams.sol │ │ │ ├── RewardManagerParams.sol │ │ │ ├── StakeManagerParams.sol │ │ │ └── VoteManagerParams.sol │ │ └── interfaces │ │ │ ├── IBlockManagerParams.sol │ │ │ ├── IBondManagerParams.sol │ │ │ ├── ICollectionManagerParams.sol │ │ │ ├── IRandomNoManagerParams.sol │ │ │ ├── IRewardManagerParams.sol │ │ │ ├── IStakeManagerParams.sol │ │ │ └── IVoteManagerParams.sol │ └── storage │ │ ├── BlockStorage.sol │ │ ├── BondStorage.sol │ │ ├── CollectionStorage.sol │ │ ├── Constants.sol │ │ ├── StakeStorage.sol │ │ └── VoteStorage.sol ├── Delegator.sol ├── IDelegator.sol ├── Initializable.sol ├── Pause.sol ├── lib │ ├── MerklePosAware.sol │ ├── Random.sol │ └── Structs.sol ├── mocks │ ├── InitializableMock.sol │ └── MerklePosAwareTest.sol ├── randomNumber │ ├── IRandomNoClient.sol │ ├── IRandomNoProvider.sol │ ├── RandomNoManager.sol │ └── RandomNoStorage.sol └── tokenization │ ├── IStakedToken.sol │ ├── IStakedTokenFactory.sol │ ├── RAZOR.sol │ ├── StakedToken.sol │ └── StakedTokenFactory.sol ├── deploy ├── 001_deploy_governance.js ├── 002_deploy_block_manager.js ├── 003_deploy_collection_manager.js ├── 004_deploy_stake_manager.js ├── 005_deploy_reward_manager.js ├── 006_deploy_vote_manager.js ├── 007_deploy_delegator.js ├── 008_deploy_razor.js ├── 009_deploy_staked_token_factory.js ├── 010_deploy_random_no_manager.js └── 011_deploy_bond_manager.js ├── deployed ├── matic_mumbai_testnet │ └── addresses.json └── skale │ └── addresses.json ├── docker-compose.yml ├── docker ├── deploy.sh ├── entrypoint.sh └── hardhat_node.sh ├── docs ├── CHANGELOG.md ├── CONTRIBUTING.md ├── DEPLOY.md ├── README.md ├── api-reference.md ├── architecture.md ├── core-concepts.md ├── data-models.md ├── documentation-plan.md ├── guides │ ├── bonds.md │ ├── delegation.md │ ├── staking.md │ └── voting.md ├── project-structure.md └── setup-and-installation.md ├── hardhat.config.js ├── migrations ├── migrationHelpers.js ├── postDeployment.js └── src │ ├── 10_deploy_random_no_manager.js │ ├── 11_deploy_bond_manager.js │ ├── 1_deploy_governance.js │ ├── 2_deploy_block_manager.js │ ├── 3_deploy_collection_manager.js │ ├── 4_deploy_stake_manager.js │ ├── 5_deploy_reward_manager.js │ ├── 6_deploy_vote_manager.js │ ├── 7_deploy_delegator.js │ ├── 8_deploy_razor.js │ ├── 9_deploy_staked_token_factory.js │ └── postDeploymentSetup.js ├── package.json ├── scenarios └── scenarios.js ├── scripts ├── deploy.sh ├── gasAnalyze.js └── gasCompare.js ├── slither.config.json ├── tenderly.yaml ├── test ├── ACL.js ├── AssignCollectionsRandomly.js ├── BlockManager.js ├── BondManager.js ├── CollectionManager.js ├── Delegator.js ├── Governance.js ├── Initializable.js ├── MerklePosAware.spec.js ├── PostDeployment.js ├── RandomNoManager.js ├── StakeManager.js ├── VoteManager.js └── helpers │ ├── InternalEngine.js │ ├── MerklePosAware.js │ ├── constants.js │ ├── testHelpers.js │ ├── testSetup.js │ └── utils.js └── yarn.lock /.dockerignore: -------------------------------------------------------------------------------- 1 | artifacts 2 | cache 3 | node_modules 4 | test 5 | *.log 6 | abi 7 | .circleci 8 | .github 9 | deployed 10 | deployments 11 | scripts -------------------------------------------------------------------------------- /.env.ci: -------------------------------------------------------------------------------- 1 | # Seed phrase from which accounts are derived (Do not use this in production) 2 | MNEMONIC=square include clarify skin garden tube tide eight eternal grit hybrid library 3 | 4 | # Ethereum Network 5 | NETWORK=local 6 | 7 | # Network type 8 | NETWORK_TYPE=TESTNET 9 | 10 | # Provider HOST & PORT for deployment 11 | PROVIDER_HOST=127.0.0.1 12 | PROVIDER_PORT=8545 13 | 14 | # Schelling Coin Address (if want to re-use already deployed instance) 15 | RAZOR_ADDRESS= 16 | 17 | DELEGATOR_ADDRESS= 18 | 19 | # List of Stakers 20 | STAKER_ADDRESSES=0x1D68ad204637173b2d8656B7972c57dcE41Bc80e,0x9FF5085aa345C019cDF2A427B02Bd6746DeF549B,0xc4695904751Ad8414c75798d6Ff2579f55e61522,0x40d57C3F5c3BAbac3033E2D50AB7C6886A595F46,0xa2B827aCF6073f5D9e2350cbf0646Ba2535a5B0C 21 | SEED_AMOUNT=1000000000000000000000000 -------------------------------------------------------------------------------- /.env.tpl: -------------------------------------------------------------------------------- 1 | # Environment where you deploying contracts 2 | ENV= 3 | # Seed phrase from which accounts are derived 4 | MNEMONIC= 5 | 6 | # Ethereum Network 7 | NETWORK= 8 | 9 | # Network type can be either MAINNET or TESTNET 10 | NETWORK_TYPE= 11 | 12 | # Provider HOST & PORT for deployment 13 | PROVIDER_HOST= 14 | PROVIDER_PORT= 15 | 16 | # Provider URL for deployment 17 | PROVIDER_URL= 18 | 19 | # Schelling Coin Address (if want to reuse already deployed instance) 20 | RAZOR_ADDRESS= 21 | 22 | DELEGATOR_ADDRESS= 23 | 24 | # List of Stakers 25 | STAKER_ADDRESSES= 26 | SEED_AMOUNT= 27 | 28 | #Tenderly SLUG 29 | TENDERLY_SLUG= -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage/ 2 | scripts/ 3 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb-base", 3 | "globals": { 4 | "artifacts": true, 5 | "web3": true, 6 | "assert": true, 7 | "it": true, 8 | "before": true, 9 | "beforeEach": true, 10 | "after": true, 11 | "afterEach": true, 12 | "describe": true, 13 | "expect": true, 14 | "ethers": true 15 | }, 16 | "rules": { 17 | "no-unused-expressions": "off", 18 | "func-names": "off", 19 | "no-else-return": "off", 20 | "no-mixed-operators": "off", 21 | "no-param-reassign": "off", 22 | "no-underscore-dangle" : "off", // This is added as stakers address is stored in _address in struct 23 | "no-plusplus": "off", 24 | "no-shadow": "off", 25 | "import/no-extraneous-dependencies": "off", 26 | "space-before-function-paren": [ 27 | 1, 28 | { 29 | "anonymous": "always", 30 | "named": "never" 31 | } 32 | ], 33 | "max-len": [ 34 | "error", 35 | 160 36 | ], 37 | "prefer-arrow-callback": "off", 38 | "no-restricted-syntax": "off", 39 | "no-await-in-loop": "off", 40 | "comma-dangle": [ 41 | "error", 42 | { 43 | "arrays": "always-multiline", 44 | "objects": "always-multiline", 45 | "imports": "always-multiline", 46 | "exports": "always-multiline", 47 | "functions": "never" 48 | } 49 | ] 50 | } 51 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - develop 8 | - "release*" 9 | pull_request: 10 | types: [opened, synchronize] 11 | 12 | jobs: 13 | install_dependencies: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v3 18 | with: 19 | token: ${{ secrets.GITHUB_TOKEN }} 20 | fetch-depth: 0 21 | - uses: actions/setup-node@v3 22 | with: 23 | node-version: 16 24 | - name: Install dependencies 25 | run: | 26 | npm install 27 | npm run cp-ci-env 28 | - uses: bissolli/gh-action-persist-workspace@v1 29 | with: 30 | action: persist 31 | 32 | test: 33 | runs-on: ubuntu-latest 34 | needs: install_dependencies 35 | steps: 36 | - uses: bissolli/gh-action-persist-workspace@v1 37 | with: 38 | action: retrieve 39 | - name: Run tests 40 | run: | 41 | CI=true npm run test 42 | 43 | scenarios: 44 | runs-on: ubuntu-latest 45 | needs: install_dependencies 46 | steps: 47 | - uses: bissolli/gh-action-persist-workspace@v1 48 | with: 49 | action: retrieve 50 | - name: Run scenarios 51 | run: | 52 | CI=true npm run scenarios 53 | 54 | lint: 55 | runs-on: ubuntu-latest 56 | needs: install_dependencies 57 | steps: 58 | - uses: bissolli/gh-action-persist-workspace@v1 59 | with: 60 | action: retrieve 61 | - name: Run Lint 62 | run: npm run lint 63 | 64 | coverage: 65 | runs-on: ubuntu-latest 66 | needs: install_dependencies 67 | steps: 68 | - uses: bissolli/gh-action-persist-workspace@v1 69 | with: 70 | action: retrieve 71 | - name: Run Coverage 72 | run: npm run coverage 73 | - name: Upload coverage to Coveralls 74 | uses: coverallsapp/github-action@v2 75 | with: 76 | github-token: ${{ secrets.GITHUB_TOKEN }} 77 | 78 | slither: 79 | runs-on: ubuntu-latest 80 | needs: install_dependencies 81 | steps: 82 | - uses: bissolli/gh-action-persist-workspace@v1 83 | with: 84 | action: retrieve 85 | - name: Run Slither 86 | uses: crytic/slither-action@v0.3.0 87 | id: slither 88 | with: 89 | node-version: 16 90 | sarif: results.sarif 91 | fail-on: high 92 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Package 2 | 3 | on: 4 | push: 5 | tags: 6 | - v* 7 | jobs: 8 | publish-npm-package: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: 13 | persist-credentials: false 14 | - uses: actions/setup-node@v3 15 | with: 16 | node-version: "20" 17 | registry-url: "https://registry.npmjs.org" 18 | - run: yarn cp-ci-env 19 | - run: | 20 | PKG_VERSION=$(node -p "require('./package.json').version") 21 | TAG_VERSION=${GITHUB_REF#refs/tags/v} 22 | if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then 23 | echo "Package version ($PKG_VERSION) does not match tag version ($TAG_VERSION)" 24 | exit 1 25 | fi 26 | - run: yarn install 27 | - run: yarn run hardhat export-abi 28 | - run: npm publish 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.RAZORNETWORKBOT }} 31 | NODE_AUTH_TOKEN: ${{ secrets.RAZORDEPLOYER }} 32 | -------------------------------------------------------------------------------- /.github/workflows/slither.yml: -------------------------------------------------------------------------------- 1 | name: Slither Analysis 2 | on: [push] 3 | jobs: 4 | analyze: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - uses: crytic/slither-action@v0.4.0 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | artifacts/ 2 | build/ 3 | coverage/ 4 | coverage.json 5 | cache/ 6 | deployed/mumbai/abi 7 | abi 8 | .env 9 | .env.mumbai 10 | .env.local 11 | node_modules/ 12 | .DS_Store 13 | .previous-deployment-addresses 14 | .contract-deployment.tmp.json 15 | .post-deployment-test.tmp.json 16 | deployments 17 | deployed/local 18 | deployments 19 | gasReporterOutput.json 20 | .vscode/ 21 | 22 | package-lock.json 23 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no -- commitlint --edit "" 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "overrides": [ 3 | { 4 | "files": "*.sol", 5 | "options": { 6 | "printWidth": 140, 7 | "explicitTypes": "always" 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | file: 'test/*.js', 3 | norpc: true, 4 | copyPackages: ['openzeppelin-solidity'], 5 | skipFiles: ['Migrations.sol'], 6 | istanbulReporter: ['html', 'lcov', 'text'], 7 | providerOptions: { 8 | total_accounts: 20, 9 | default_balance_ether: '1000000000000000000', 10 | gasLimit: 0xfffffffffff, 11 | }, 12 | mocha: { 13 | enableTimeouts: true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": [ 4 | "prettier" 5 | ], 6 | "rules": { 7 | "avoid-suicide": "error", 8 | "compiler-version": ["error", "^0.8.0"], 9 | "const-name-snakecase": "error", 10 | "contract-name-camelcase": "warn", 11 | "event-name-camelcase": "error", 12 | "func-name-mixedcase": "error", 13 | "func-visibility": ["error", { "ignoreConstructors": true }], 14 | "imports-on-top": "warn", 15 | "mark-callable-contracts": "off", 16 | "max-line-length": ["warn", 127], 17 | "no-unused-vars": "error", 18 | "not-rely-on-time" : "off", 19 | "ordering": "error", 20 | "prettier/prettier": "error", 21 | "private-vars-leading-underscore": "error", 22 | "quotes": ["error","double"], 23 | "reentrancy": "error", 24 | "var-name-mixedcase": "error", 25 | "visibility-modifier-order": "error", 26 | "reason-string": "error" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.solhintignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.0.1](https://github.com/razor-network/contracts/compare/v1.0.0...v1.0.1) (2022-04-04) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * **release:** explicitly export abis before publish ([1931444](https://github.com/razor-network/contracts/commit/1931444e8ea05491c38685a81e826330748105db)) 7 | 8 | # [1.0.0](https://github.com/razor-network/contracts/compare/v0.3.0...v1.0.0) (2022-04-04) 9 | 10 | 11 | ### Bug Fixes 12 | 13 | * increase footer max line length ([26d09e7](https://github.com/razor-network/contracts/commit/26d09e79170515e5efe51282e5c4bf6ad273c1e7)) 14 | 15 | 16 | ### chore 17 | 18 | * **release:** dummy commit to trigger release ([2ecb956](https://github.com/razor-network/contracts/commit/2ecb95696b99ff09dbda7f4fbf9832dd6ea06a8a)) 19 | 20 | 21 | * Merge pull request #783 from razor-network/next ([b789199](https://github.com/razor-network/contracts/commit/b789199b162f3a763b04329a593bd2b109f81ea5)), closes [#783](https://github.com/razor-network/contracts/issues/783) 22 | 23 | 24 | ### BREAKING CHANGES 25 | 26 | * Release 27 | * **release:** Release 28 | 29 | # [0.3.0](https://github.com/razor-network/contracts/compare/v0.2.1...v0.3.0) (2022-04-04) 30 | 31 | 32 | ### Bug Fixes 33 | 34 | * clean up docgen ([#743](https://github.com/razor-network/contracts/issues/743)) ([2bba861](https://github.com/razor-network/contracts/commit/2bba86197e01a1f8873b8cc9cffdc93829fce359)) 35 | * dispute 'disputeCollectionIdShouldBePresent()' is successful if empty array is passed ([#763](https://github.com/razor-network/contracts/issues/763)) ([d029654](https://github.com/razor-network/contracts/commit/d02965414e5931a28fa4b6aa56404d33f9b84f59)) 36 | * fixed delegator migration ([#775](https://github.com/razor-network/contracts/issues/775)) ([ca349e4](https://github.com/razor-network/contracts/commit/ca349e4ce6be76d63e644414d4f13e58ee46c815)) 37 | * fixed scenarios ([#761](https://github.com/razor-network/contracts/issues/761)) ([2ec3d73](https://github.com/razor-network/contracts/commit/2ec3d73bf4792e5af1744e63cca390cdb59fb2f1)) 38 | * only propose revealed assets of epoch ([#726](https://github.com/razor-network/contracts/issues/726)) ([2c14622](https://github.com/razor-network/contracts/commit/2c1462220fcb1d9cbf9143da6e82f4ef4d242b27)) 39 | * optmized for calls in loop : slither warning ([#745](https://github.com/razor-network/contracts/issues/745)) ([b1f4236](https://github.com/razor-network/contracts/commit/b1f423648b7e3366cdb3377bcfee30f752e555f9)) 40 | * removed require statement from BlockManager ([#740](https://github.com/razor-network/contracts/issues/740)) ([af10f62](https://github.com/razor-network/contracts/commit/af10f6219662c03440d353b22106c13c19e13bec)) 41 | * stakerReward being updated properly ([#770](https://github.com/razor-network/contracts/issues/770)) ([1e19b51](https://github.com/razor-network/contracts/commit/1e19b51fe13ff9642d2970ff3e4b3ef9283209ea)) 42 | 43 | 44 | ### Features 45 | 46 | * add docgen to the project from natspec ([#731](https://github.com/razor-network/contracts/issues/731)) ([4fd81ca](https://github.com/razor-network/contracts/commit/4fd81ca7233de0f231177e42c046d5b47b7bee9c)) 47 | * added require length check in propose ([#765](https://github.com/razor-network/contracts/issues/765)) ([2535e59](https://github.com/razor-network/contracts/commit/2535e5961d34f4cbd98c9b831f0fd9d6e2de2d97)) 48 | * removed redundant roles ([#754](https://github.com/razor-network/contracts/issues/754)) ([cb79103](https://github.com/razor-network/contracts/commit/cb79103b8df851f4958b9aa467b9252f31a73f19)) 49 | * removed uncessary slither warnigns for timestamp ([#755](https://github.com/razor-network/contracts/issues/755)) ([c43731d](https://github.com/razor-network/contracts/commit/c43731d60a252a47393af070ae7687a2f4cfe5d4)) 50 | * staker can now claim commission ([#758](https://github.com/razor-network/contracts/issues/758)) ([6469129](https://github.com/razor-network/contracts/commit/64691296e5f3420cd6309e26fa17c26c31300647)) 51 | 52 | ## [0.2.1](https://github.com/razor-network/contracts/compare/v0.2.0...v0.2.1) (2022-02-23) 53 | 54 | 55 | ### Bug Fixes 56 | 57 | * disable body check on commits ([b351303](https://github.com/razor-network/contracts/commit/b35130307a7a5a6b90518d0a8ced0171ade58c1a)) 58 | * disable commit body length ([78ca858](https://github.com/razor-network/contracts/commit/78ca85807514ca904102adff743b394609c0979f)) 59 | * Fix readme ([69c008d](https://github.com/razor-network/contracts/commit/69c008de5dac294135942f5fe11352e59d14fc99)) 60 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | How to contribute 2 | =================== 3 | 4 | The preferred way to contribute is to fork the main repository on GitHub, then submit a “pull request” (PR). 5 | 6 | Create an account on GitHub if you do not already have one. 7 | 8 | Fork the project repository: click on the ‘Fork’ button near the top of the page. This creates a copy of the code under your account on the GitHub user account. For more details on how to fork a repository see this guide. 9 | 10 | Clone your fork of the repo from your GitHub account to your local disk: 11 | 12 | ``` 13 | $ git clone git@github.com:YourLogin/contracts.git 14 | $ cd contracts 15 | ``` 16 | Install the development dependencies: 17 | ``` 18 | $ npm i 19 | ``` 20 | for more details about installation, see the Readme. 21 | 22 | Add the upstream remote. This saves a reference to the main contracts repository, which you can use to keep your repository synchronized with the latest changes: 23 | ``` 24 | $ git remote add upstream git@github.com:razor-network/contracts.git 25 | ``` 26 | You should now have a working installation, and your git repository properly configured. The next steps now describe the process of modifying code and submitting a PR: 27 | 28 | Synchronize your master branch with the upstream master branch: 29 | ``` 30 | $ git checkout master 31 | $ git pull upstream master 32 | ``` 33 | Create a feature branch to hold your development changes: 34 | ``` 35 | $ git checkout -b my_feature 36 | ``` 37 | and start making changes. Always use a feature branch. It’s good practice to never work on the master branch! 38 | 39 | Develop the feature on your feature branch on your computer, using Git to do the version control. When you’re done editing, add changed files using git add and then git commit: 40 | ``` 41 | $ git add modified_files 42 | $ git commit 43 | ``` 44 | to record your changes in Git, then push the changes to your GitHub account with: 45 | ``` 46 | $ git push -u origin my_feature 47 | ``` 48 | Follow these instructions to create a pull request from your fork. This will send an email to the committers. You may want to consider sending an email to the mailing list for more visibility. 49 | 50 | It is often helpful to keep your local feature branch synchronized with the latest changes of the main repository: 51 | ``` 52 | $ git fetch upstream 53 | $ git merge upstream/master 54 | ``` 55 | Subsequently, you might need to solve the conflicts. You can refer to the Git documentation related to resolving merge conflict using the command line. 56 | 57 | Learning git: 58 | --- 59 | 60 | The Git documentation and http://try.github.io are excellent resources to get started with git, and understanding all of the commands shown here. 61 | -------------------------------------------------------------------------------- /DEPLOY.md: -------------------------------------------------------------------------------- 1 | ## hardhat-deploy in a nutshell 2 | 3 | **hardhat-deploy** allows you to write `deploy scripts` in the `deploy` folder. Each of these files that look as follows will be executed in turn when you execute the following task: `hardhat --network deploy` 4 | 5 | Note: `hre.deployments.deploy` function will by default only deploy a contract if the contract code has changed, making it easier to write idempotent scripts. 6 | 7 | ### An example of a deploy script : 8 | 9 | ``` 10 | module.exports = async ({ 11 | getNamedAccounts, 12 | deployments, 13 | getChainId, 14 | getUnnamedAccounts, 15 | }) => { 16 | const {deploy} = deployments; 17 | const {deployer} = await getNamedAccounts(); 18 | 19 | // the following will only deploy "GenericMetaTxProcessor" if the contract was never deployed or if the code changed since last deployment 20 | await deploy('GenericMetaTxProcessor', { 21 | from: deployer, 22 | gasLimit: 4000000, 23 | args: [], 24 | }); 25 | }; 26 | 27 | ``` 28 | 29 | As you can see the HRE passed in has 4 new fields : 30 | 31 | - `getNamedAccounts` is a function that returns a promise to an object whose keys are names and values are addresses. It is parsed from the `namedAccounts` configuration. 32 | - `getUnnamedAccounts` is a function that return a promise to an array of accounts which were not named (see `namedAccounts` ). It is useful for tests where you want to be sure that the account has no speicifc role in the system (no token given, no admin access, etc...). 33 | - `getChainId` is a function which return a promise for the chainId, as convenience 34 | - `deployments` is an object which contains functions to access past deployments or to save new ones, as well as helpers functions. 35 | 36 | `deployments` contains for example the `deploy` function that allows you to deploy contract and save them. 37 | 38 | ### **1. namedAccounts (ability to name addresses)** 39 | 40 | --- 41 | 42 | This plugin extends the `HardhatConfig`'s object with an optional `namedAccounts` field. 43 | 44 | `namedAccounts` allows you to associate names to addresses and have them configured per chain. 45 | This allows you to have meaningful names in your tests. 46 | 47 | ``` 48 | { 49 | namedAccounts: { 50 | deployer: { 51 | default: 0, // here this will by default take the first account as deployer 52 | 1: 0, // similarly on mainnet it will take the first account as deployer. Note though that depending on how hardhat network are configured, the account 0 on one network can be different than on another 53 | 4: '0xA296a3d5F026953e17F472B497eC29a5631FB51B', // but for rinkeby it will be a specific address 54 | "goerli": '0x84b9514E013710b9dD0811c9Fe46b837a4A0d8E0', //it can also specify a specific netwotk name (specified in hardhat.config.js) 55 | }, 56 | feeCollector:{ 57 | default: 1, // here this will by default take the second account as feeCollector (so in the test this will be a different account than the deployer) 58 | 1: '0xa5610E1f289DbDe94F3428A9df22E8B518f65751', // on the mainnet the feeCollector could be a multi sig 59 | 4: '0xa250ac77360d4e837a13628bC828a2aDf7BabfB3', // on rinkeby it could be another account 60 | } 61 | } 62 | } 63 | 64 | ``` 65 | 66 | --- 67 | 68 | Furthermore you can also ensure these scripts are executed in test’s too by calling `await deployments.fixture(['MyContract'])` in your test. 69 | This is optimised, so if multiple tests use the same contract, the deployment will be executed once and each test will start with the exact same state. 70 | 71 | This is a huge benefit for testing since you are not required to replicate the deployment procedure in your tests. 72 | 73 | You can even group deploy scripts in different sub folder and ensure they are executed in their logical order. 74 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16-alpine 2 | COPY . /usr/src/app 3 | WORKDIR /usr/src/app 4 | 5 | RUN apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python \ 6 | && apk add --update make gcc musl musl-dev g++ libc-dev bash linux-headers jq \ 7 | && npm install 8 | 9 | COPY $PWD/docker/entrypoint.sh /usr/local/bin 10 | COPY $PWD/docker/hardhat_node.sh /usr/local/bin 11 | COPY $PWD/docker/deploy.sh /usr/local/bin 12 | ENTRYPOINT ["/bin/sh", "/usr/local/bin/entrypoint.sh"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Razor network - Contracts 2 | 3 | [![CircleCI](https://circleci.com/gh/razor-network/contracts/tree/master.svg?style=svg)](https://circleci.com/gh/razor-network/contracts/tree/master) 4 | [![Coverage Status](https://coveralls.io/repos/github/razor-network/contracts/badge.svg?branch=master)](https://coveralls.io/github/razor-network/contracts?branch=master) 5 | 6 | These are the contracts for Razor network. 7 | 8 | ## Prerequisites : 9 | #### npm 10 | You'll need npm to install the required packages. 11 | To install npm , go to this [link](https://www.npmjs.com/get-npm) 12 | 13 | # Development 14 | Create a `.env` file from `.env.tpl` and set the environment variables accordingly. 15 | ##### Running tests 16 | Run `npm run test` 17 | 18 | ##### Test Coverage 19 | Run `npm run coverage` 20 | 21 | ##### Test Lint 22 | Run `npm run lint` 23 | 24 | ##### prettify code 25 | Run `npm run lint:sol:fix` 26 | 27 | # Deployment 28 | 29 | ##### Using Docker 30 | The easiest way to get a local hardhat instance with deployed contracts is to run a docker container. 31 | `$ docker-compose up` 32 | 33 | ##### Local Deployment using hardhat 34 | 1. Create a copy of local environment `.env.local` from `.env.tpl` and set the environment variables accordingly 35 | 2. Run hardhat node (`npx hardhat node`) 36 | 3. Run command `deploy:local` 37 | 4. Use tenderly to track local transactions: https://github.com/Tenderly/tenderly-cli#export 38 | 39 | ##### Polygon Mumbai Testnet Deployment 40 | 1. Create a copy of local environment `.env.mumbai` from `.env.tpl` and set the environment variables accordingly 41 | 2. Run command `deploy:mumbai` 42 | 43 | 44 | # Addresses 45 | We are currently live on Polygon Mumbai Testnet. 46 | 47 | Deployed contract addresses can be found [here](deployed/mumbai/addresses.json) 48 | 49 | # tenderly 50 | ``` 51 | npx hardhat node 52 | npm run deploy:local 53 | npm run deploy:mumbai 54 | npx hardhat test --network localhost 55 | tenderly export --export-network hardhat 0x4c30a90c6d2370abaef047fbac5a3f2dd43a9490caae7c79ec700eee600db024 56 | 57 | ``` 58 | 59 | # gas Prices across networks 60 | ``` 61 | npm run gas 62 | ``` 63 | -------------------------------------------------------------------------------- /codechecks.yml: -------------------------------------------------------------------------------- 1 | checks: 2 | - name: eth-gas-reporter/codechecks 3 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'body-max-line-length': [0, 'always', 200], 5 | 'footer-max-line-length': [0, 'always', 2000], 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /contracts/Core/StateManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "./storage/Constants.sol"; 5 | 6 | /** @title StateManager 7 | * @notice StateManager manages the state of the network 8 | */ 9 | 10 | contract StateManager is Constants { 11 | /** 12 | * @notice a check to ensure the epoch value sent in the function is of the currect epoch 13 | */ 14 | modifier checkEpoch(uint32 epoch) { 15 | // slither-disable-next-line incorrect-equality 16 | require(epoch == getEpoch(), "incorrect epoch"); 17 | _; 18 | } 19 | 20 | /** 21 | * @notice a check to ensure the function was called in the state specified 22 | */ 23 | modifier checkState(State state, uint8 buffer) { 24 | // slither-disable-next-line incorrect-equality 25 | require(state == getState(buffer), "incorrect state"); 26 | _; 27 | } 28 | 29 | /** 30 | * @notice a check to ensure the function was not called in the state specified 31 | */ 32 | modifier notState(State state, uint8 buffer) { 33 | // slither-disable-next-line incorrect-equality 34 | require(state != getState(buffer), "incorrect state"); 35 | _; 36 | } 37 | 38 | /** @notice a check to ensure the epoch value sent in the function is of the currect epoch 39 | * and was called in the state specified 40 | */ 41 | modifier checkEpochAndState( 42 | State state, 43 | uint32 epoch, 44 | uint8 buffer 45 | ) { 46 | // slither-disable-next-line incorrect-equality 47 | require(epoch == getEpoch(), "incorrect epoch"); 48 | // slither-disable-next-line incorrect-equality 49 | require(state == getState(buffer), "incorrect state"); 50 | _; 51 | } 52 | 53 | /** 54 | * @return the value of current epoch 55 | */ 56 | function getEpoch() public view returns (uint32) { 57 | return (uint32(block.timestamp) / (EPOCH_LENGTH)); 58 | } 59 | 60 | /** 61 | * @return the value of current state 62 | */ 63 | function getState(uint8 buffer) public view returns (State) { 64 | uint8 lowerLimit = buffer; 65 | 66 | uint16 upperLimit = EPOCH_LENGTH / NUM_STATES - buffer; 67 | // slither-disable-next-line timestamp,weak-prng 68 | if (block.timestamp % (EPOCH_LENGTH / NUM_STATES) > upperLimit || block.timestamp % (EPOCH_LENGTH / NUM_STATES) < lowerLimit) { 69 | return State.Buffer; 70 | } 71 | // slither-disable-next-line timestamp,weak-prng 72 | uint8 state = uint8(((block.timestamp) / (EPOCH_LENGTH / NUM_STATES)) % (NUM_STATES)); 73 | return State(state); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /contracts/Core/interface/IBlockManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "../../lib/Structs.sol"; 5 | 6 | interface IBlockManager { 7 | /** 8 | * @notice if the proposed staker, whose block is valid and has the lowest iteration, does not call claimBlockReward() 9 | * then in commit state, the staker who commits first will confirm this block and will receive the block reward inturn 10 | * @param stakerId id of the staker that is confirming the block 11 | */ 12 | function confirmPreviousEpochBlock(uint32 stakerId) external; 13 | 14 | /** 15 | * @notice return the struct of the confirmed block 16 | * @param epoch in which this block was confirmed 17 | * @return _block : struct of the confirmed block 18 | */ 19 | function getBlock(uint32 epoch) external view returns (Structs.Block memory _block); 20 | 21 | /** 22 | * @notice this is to check whether a block was confirmed in a particular epoch or not 23 | * @param epoch for which this check is being done 24 | * @return true or false. true if a block has been confirmed, else false 25 | */ 26 | function isBlockConfirmed(uint32 epoch) external view returns (bool); 27 | } 28 | -------------------------------------------------------------------------------- /contracts/Core/interface/IBondManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IBondManager { 5 | function occurrenceRecalculation() external; 6 | 7 | function databondCollectionsReset() external; 8 | 9 | function getDatabondCollections() external view returns (uint16[] memory); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/Core/interface/ICollectionManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../../lib/Structs.sol"; 4 | import "../storage/Constants.sol"; 5 | 6 | interface ICollectionManager { 7 | /** 8 | * @notice Creates a Multiple Jobs in the network. 9 | * @dev Jobs are not directly reported by staker but just stores the URL and its corresponding details 10 | * @param mulJobs multiple jobs that are to be created 11 | */ 12 | function createMulJob(Structs.Job[] memory mulJobs) external returns (uint16[] memory); 13 | 14 | /** 15 | * @notice Creates a collection in the network. 16 | * @dev Collections are to be reported by staker by querying the URLs in each job assigned in the collection 17 | * and aggregating them based on the aggregation method specified in the collection 18 | * @param tolerance specifies the percentage by which the staker's value can deviate from the value decided by the network 19 | * @param power is used to specify the decimal shifts required on the result of a Collection 20 | * @param occurrence how often the collection needs to be reported upon 21 | * @param aggregationMethod specifies the aggregation method to be used by the stakers 22 | * @param jobIDs an array that holds which jobs should the stakers query for the stakers to report for the collection 23 | * @param name of the collection 24 | */ 25 | function createCollection( 26 | uint32 tolerance, 27 | int8 power, 28 | uint16 occurrence, 29 | uint32 aggregationMethod, 30 | uint16[] memory jobIDs, 31 | string calldata name 32 | ) external returns (uint16); 33 | 34 | /** 35 | * @notice Updates a Job in the network. 36 | * @param jobID the job id for which the details need to change 37 | * @param weight specifies the weight the result of each job carries 38 | * @param power is used to specify the decimal shifts required on the result of a Job query 39 | * @param selectorType defines the selectorType of the URL. Can be JSON/XHTML 40 | * @param selector of the URL 41 | * @param url to be used for retrieving the data 42 | */ 43 | function updateJob( 44 | uint16 jobID, 45 | uint8 weight, 46 | int8 power, 47 | Constants.JobSelectorType selectorType, 48 | string calldata selector, 49 | string calldata url 50 | ) external; 51 | 52 | /** @notice Updates a Collection in the network. 53 | * @param collectionID the collection id for which the details need to change 54 | * @param tolerance specifies the percentage by which the staker's value can deviate from the value decided by the network 55 | * @param aggregationMethod specifies the aggregation method to be used by the stakers 56 | * @param power is used to specify the decimal shifts required on the result of a Collection 57 | * @param jobIDs an array that holds which jobs should the stakers query for the stakers to report for the collection 58 | */ 59 | function updateCollection( 60 | uint16 collectionID, 61 | uint32 tolerance, 62 | uint32 aggregationMethod, 63 | int8 power, 64 | uint16[] memory jobIDs 65 | ) external; 66 | 67 | function setResult( 68 | uint32 epoch, 69 | uint16[] memory ids, 70 | uint256[] memory medians 71 | ) external; 72 | 73 | function setCollectionOccurrence(uint16 collectionId, uint16 occurrence) external; 74 | 75 | /** 76 | * @notice Sets the status of the collection in the network. 77 | * @param assetStatus the status that needs to be set for the collection 78 | * @param id the collection id for which the status needs to change 79 | */ 80 | function setCollectionStatus(bool assetStatus, uint16 id) external; 81 | 82 | /** 83 | * @param id the id of the collection 84 | * @return status of the collection 85 | */ 86 | function getCollectionStatus(uint16 id) external view returns (bool); 87 | 88 | /** 89 | * @return total number of active collections 90 | */ 91 | function getNumActiveCollections() external view returns (uint16); 92 | 93 | /** 94 | * @return ids of active collections 95 | */ 96 | function getActiveCollections() external view returns (uint16[] memory); 97 | 98 | /** 99 | * @param id the id of the collection 100 | * @return power of the collection 101 | */ 102 | function getCollectionPower(uint16 id) external view returns (int8); 103 | 104 | /** 105 | * @return total number of collections 106 | */ 107 | function getNumCollections() external view returns (uint16); 108 | 109 | /** 110 | * @return total number of jobs 111 | */ 112 | function getNumJobs() external view returns (uint16); 113 | 114 | /** 115 | * @param i the leafId of the collection 116 | * @return tolerance of the collection 117 | */ 118 | function getCollectionTolerance(uint16 i) external view returns (uint32); 119 | 120 | /** 121 | * @param leafId, the leafId of the collection 122 | * @return the id of the collection 123 | */ 124 | function getCollectionIdFromLeafId(uint16 leafId) external view returns (uint16); 125 | 126 | /** 127 | * @param _name the name of the collection in bytes32 128 | * @return collection ID 129 | */ 130 | function getCollectionID(bytes32 _name) external view returns (uint16); 131 | 132 | /** 133 | * @notice returns the result of the collection based on the name sent by the client 134 | * @param _name the name of the collection in bytes32 135 | * @return result of the collection 136 | * @return power of the resultant collection 137 | */ 138 | function getResult(bytes32 _name) external view returns (uint256, int8); 139 | 140 | /** 141 | * @notice returns the result of the collection based on the id sent by the client 142 | * @param _id the id of the collection 143 | * @return result of the collection 144 | * @return power of the resultant collection 145 | */ 146 | function getResultFromID(uint16 _id) external view returns (uint256, int8); 147 | } 148 | -------------------------------------------------------------------------------- /contracts/Core/interface/IRewardManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "../../lib/Structs.sol"; 5 | 6 | interface IRewardManager { 7 | /** 8 | * @notice gives penalty to stakers for failing to reveal or 9 | * reveal value deviations 10 | * @param stakerId The id of staker currently in consideration 11 | * @param epoch the epoch value 12 | */ 13 | function givePenalties(uint32 epoch, uint32 stakerId) external; 14 | 15 | /** 16 | * @notice The function gives block reward for one valid proposer in the 17 | * previous epoch by increasing stake of staker 18 | * called from confirmBlock function of BlockManager contract. Commission 19 | * from the delegator's pool is given out to the staker from the block reward 20 | * @param stakerId The ID of the staker 21 | */ 22 | function giveBlockReward(uint32 epoch, uint32 stakerId) external; 23 | 24 | /** 25 | * @notice The function gives out penalties to stakers during commit. 26 | * The penalties are given for inactivity, failing to reveal 27 | * , deviation from the median value of particular asset 28 | * @param stakerId The staker id 29 | * @param epoch The Epoch value in consideration 30 | */ 31 | function giveInactivityPenalties(uint32 epoch, uint32 stakerId) external; 32 | } 33 | -------------------------------------------------------------------------------- /contracts/Core/interface/IStakeManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "../../lib/Structs.sol"; 5 | import "../storage/Constants.sol"; 6 | 7 | interface IStakeManager { 8 | /** 9 | * @notice External function for setting stake of the staker 10 | * Used by RewardManager 11 | * @param _epoch The epoch in which stake changes 12 | * @param _id of the staker 13 | * @param reason the reason for stake to change 14 | * @param prevStake previous stake of the staker 15 | * @param _stake updated stake of the staker 16 | */ 17 | function setStakerStake( 18 | uint32 _epoch, 19 | uint32 _id, 20 | Constants.StakeChanged reason, 21 | uint256 prevStake, 22 | uint256 _stake 23 | ) external; 24 | 25 | /** 26 | * @notice The function is used by the Votemanager reveal function and BlockManager FinalizeDispute 27 | * to penalise the staker who lost his secret or who got disputed and make his stake less by "slashPenaltyAmount" and 28 | * transfer to bounty hunter half the "slashPenaltyAmount" of the staker 29 | * @param epoch The epoch in which staker is slashed 30 | * @param stakerId The ID of the staker who is penalised 31 | * @param bountyHunter The address of the bounty hunter 32 | */ 33 | function slash( 34 | uint32 epoch, 35 | uint32 stakerId, 36 | address bountyHunter 37 | ) external; 38 | 39 | /** 40 | * @notice External function for setting age of the staker 41 | * Used by RewardManager 42 | * @param _epoch The epoch in which age changes 43 | * @param _id of the staker 44 | * @param _age the updated new age 45 | * @param reason the reason for age change 46 | */ 47 | function setStakerAge( 48 | uint32 _epoch, 49 | uint32 _id, 50 | uint32 _age, 51 | Constants.AgeChanged reason 52 | ) external; 53 | 54 | /** 55 | * @notice External function for setting stakerReward of the staker 56 | * Used by RewardManager 57 | * @param _epoch The epoch in which stakerReward changes 58 | * @param _id of the staker 59 | * @param reason the reason for stakerReward to change 60 | * @param prevStakerReward previous stakerReward of the staker 61 | * @param _stakerReward updated stakerReward of the staker 62 | */ 63 | function setStakerReward( 64 | uint32 _epoch, 65 | uint32 _id, 66 | Constants.StakerRewardChanged reason, 67 | uint256 prevStakerReward, 68 | uint256 _stakerReward 69 | ) external; 70 | 71 | /** 72 | * @notice External function for setting epochFirstStakedOrLastPenalized of the staker 73 | * Used by RewardManager 74 | * @param _epoch The epoch in which staker first staked or was last penalized 75 | * @param _id of the staker 76 | */ 77 | function setStakerEpochFirstStakedOrLastPenalized(uint32 _epoch, uint32 _id) external; 78 | 79 | /** 80 | * @notice remove all funds in case of emergency 81 | */ 82 | function escape(address _address) external; 83 | 84 | /** 85 | * @notice event being thrown after every successful sRZR transfer taking place 86 | * @param from sender 87 | * @param to recepient 88 | * @param amount srzr amount being transferred 89 | * @param stakerId the id of the staker whose sRZR is involved in the transfer 90 | */ 91 | function srzrTransfer( 92 | address from, 93 | address to, 94 | uint256 amount, 95 | uint32 stakerId 96 | ) external; 97 | 98 | /** 99 | * @param _address Address of the staker 100 | * @return The staker ID 101 | */ 102 | function getStakerId(address _address) external view returns (uint32); 103 | 104 | /** 105 | * @param _id The staker ID 106 | * @return staker The Struct of staker information 107 | */ 108 | function getStaker(uint32 _id) external view returns (Structs.Staker memory staker); 109 | 110 | /** 111 | * @return The number of stakers in the razor network 112 | */ 113 | function getNumStakers() external view returns (uint32); 114 | 115 | /** 116 | * @param stakerId ID of the staker 117 | * @return influence of staker 118 | */ 119 | function getInfluence(uint32 stakerId) external view returns (uint256); 120 | 121 | /** 122 | * @param stakerId ID of the staker 123 | * @return stake of staker 124 | */ 125 | function getStake(uint32 stakerId) external view returns (uint256); 126 | 127 | /** 128 | * @param stakerId ID of the staker 129 | * @return epochFirstStakedOrLastPenalized of staker 130 | */ 131 | function getEpochFirstStakedOrLastPenalized(uint32 stakerId) external view returns (uint32); 132 | 133 | /** 134 | * @return length of maturities array 135 | */ 136 | function maturitiesLength() external view returns (uint32); 137 | } 138 | -------------------------------------------------------------------------------- /contracts/Core/interface/IVoteManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "../../lib/Structs.sol"; 5 | 6 | interface IVoteManager { 7 | /** 8 | * @notice stores the salt calculated in block manager 9 | * @param _salt the hash of the last epoch and medians of the block 10 | */ 11 | function storeSalt(bytes32 _salt) external; 12 | 13 | /** 14 | * @notice stores the depth of a valid merkle tree. Depth of the merkle tree sent by the stakers should match with this 15 | * for a valid commit/reveal 16 | * @param _depth depth of the merkle tree 17 | */ 18 | function storeDepth(uint256 _depth) external; 19 | 20 | /** 21 | * @notice returns vote value of a collection reported by a particular staker 22 | * @param epoch in which the staker reveal this value 23 | * @param stakerId id of the staker 24 | * @param leafId seq position of collection in merkle tree 25 | * @return vote value 26 | */ 27 | function getVoteValue( 28 | uint32 epoch, 29 | uint32 stakerId, 30 | uint16 leafId 31 | ) external view returns (uint256); 32 | 33 | /** 34 | * @notice returns vote weight of the value of the collection reported 35 | * @param epoch in which the staker reveal this value 36 | * @param leafId seq position of collection in merkle tree 37 | * @param voteValue one of the values of the collection being reported 38 | * @return vote weight of the vote 39 | */ 40 | function getVoteWeight( 41 | uint32 epoch, 42 | uint16 leafId, 43 | uint256 voteValue 44 | ) external view returns (uint256); 45 | 46 | /** 47 | * @notice returns snapshot of influence of the staker when they revealed 48 | * @param epoch when the snapshot was taken 49 | * @param stakerId id of the staker 50 | * @return influence of the staker 51 | */ 52 | function getInfluenceSnapshot(uint32 epoch, uint32 stakerId) external view returns (uint256); 53 | 54 | /** 55 | * @notice returns snapshot of stake of the staker when they revealed 56 | * @param epoch when the snapshot was taken 57 | * @param stakerId id of the staker 58 | * @return stake of the staker 59 | */ 60 | function getStakeSnapshot(uint32 epoch, uint32 stakerId) external view returns (uint256); 61 | 62 | /** 63 | * @notice returns the total influence revealed of the collection 64 | * @param epoch when asset was being revealed 65 | * @param leafId seq position of collection in merkle tree 66 | * @return total influence revealed of the collection 67 | */ 68 | function getTotalInfluenceRevealed(uint32 epoch, uint16 leafId) external view returns (uint256); 69 | 70 | /** 71 | * @notice returns the epoch a staker last revealed their votes 72 | * @param stakerId id of the staker 73 | * @return epoch last revealed 74 | */ 75 | function getEpochLastRevealed(uint32 stakerId) external view returns (uint32); 76 | 77 | /** 78 | * @notice returns the epoch a staker last committed their votes 79 | * @param stakerId id of the staker 80 | * @return epoch last committed 81 | */ 82 | function getEpochLastCommitted(uint32 stakerId) external view returns (uint32); 83 | 84 | /** 85 | * @return the salt 86 | */ 87 | function getSalt() external view returns (bytes32); 88 | } 89 | -------------------------------------------------------------------------------- /contracts/Core/parameters/ACL.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "@openzeppelin/contracts/access/AccessControl.sol"; 5 | 6 | contract ACL is AccessControl { 7 | /** 8 | * @dev the deployer of the network is given to the default admin role which gives other roles to contracts 9 | */ 10 | constructor() { 11 | _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /contracts/Core/parameters/child/BlockManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../interfaces/IBlockManagerParams.sol"; 4 | import "../ACL.sol"; 5 | import "../../storage/Constants.sol"; 6 | 7 | abstract contract BlockManagerParams is ACL, IBlockManagerParams, Constants { 8 | /// @notice maximum number of best proposed blocks to be considered for dispute 9 | uint8 public maxAltBlocks = 5; 10 | uint8 public buffer = 5; 11 | /// @notice reward given to staker whose block is confirmed 12 | uint256 public blockReward = 100 * (10**18); 13 | /// @notice minimum amount of stake required to participate 14 | uint256 public minStake = 20000 * (10**18); 15 | 16 | /// @inheritdoc IBlockManagerParams 17 | function setMaxAltBlocks(uint8 _maxAltBlocks) external override onlyRole(GOVERNANCE_ROLE) { 18 | // slither-disable-next-line events-maths 19 | maxAltBlocks = _maxAltBlocks; 20 | } 21 | 22 | function setBufferLength(uint8 _bufferLength) external override onlyRole(GOVERNANCE_ROLE) { 23 | // slither-disable-next-line events-maths 24 | buffer = _bufferLength; 25 | } 26 | 27 | /// @inheritdoc IBlockManagerParams 28 | function setBlockReward(uint256 _blockReward) external override onlyRole(GOVERNANCE_ROLE) { 29 | // slither-disable-next-line events-maths 30 | blockReward = _blockReward; 31 | } 32 | 33 | /// @inheritdoc IBlockManagerParams 34 | function setMinStake(uint256 _minStake) external override onlyRole(GOVERNANCE_ROLE) { 35 | // slither-disable-next-line events-maths 36 | minStake = _minStake; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/Core/parameters/child/BondManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../interfaces/IBondManagerParams.sol"; 4 | import "../ACL.sol"; 5 | import "../../storage/Constants.sol"; 6 | 7 | abstract contract BondManagerParams is ACL, IBondManagerParams, Constants { 8 | uint8 public buffer = 5; 9 | /// @notice deposit need to be sent per job 10 | uint256 public depositPerJob = 500_000 * (10**18); 11 | /// @notice minimum bond to be paid 12 | uint256 public minBond = 100_000 * (10**18); 13 | /// @notice the number of epochs for which a staker cant update job/collection they have created 14 | uint16 public epochLimitForUpdateBond = 5; 15 | // slither-disable-next-line constable-states 16 | uint8 public maxJobs = 6; 17 | // slither-disable-next-line constable-states 18 | uint8 public minJobs = 2; 19 | /// @notice the number of epochs for which the RAZORs are locked after initiating withdraw 20 | uint16 public withdrawLockPeriod = 1; 21 | 22 | /// @inheritdoc IBondManagerParams 23 | function setDepositPerJob(uint256 _depositPerJob) external override onlyRole(GOVERNANCE_ROLE) { 24 | // slither-reason: Disabled across all params childs 25 | // as they are being called by governance contract only 26 | // and their before setting, we are emitting event 27 | // slither-disable-next-line events-maths 28 | depositPerJob = _depositPerJob; 29 | } 30 | 31 | function setMinBond(uint256 _minBond) external override onlyRole(GOVERNANCE_ROLE) { 32 | // slither-reason: Disabled across all params childs 33 | // as they are being called by governance contract only 34 | // and their before setting, we are emitting event 35 | // slither-disable-next-line events-maths 36 | minBond = _minBond; 37 | } 38 | 39 | function setMinJobs(uint8 _minJobs) external override onlyRole(GOVERNANCE_ROLE) { 40 | // slither-reason: Disabled across all params childs 41 | // as they are being called by governance contract only 42 | // and their before setting, we are emitting event 43 | // slither-disable-next-line events-maths 44 | minJobs = _minJobs; 45 | } 46 | 47 | function setMaxJobs(uint8 _maxJobs) external override onlyRole(GOVERNANCE_ROLE) { 48 | // slither-reason: Disabled across all params childs 49 | // as they are being called by governance contract only 50 | // and their before setting, we are emitting event 51 | // slither-disable-next-line events-maths 52 | maxJobs = _maxJobs; 53 | } 54 | 55 | function setEpochLimitForUpdateBond(uint16 _epochLimitForUpdateBond) external override onlyRole(GOVERNANCE_ROLE) { 56 | // slither-reason: Disabled across all params childs 57 | // as they are being called by governance contract only 58 | // and their before setting, we are emitting event 59 | // slither-disable-next-line events-maths 60 | epochLimitForUpdateBond = _epochLimitForUpdateBond; 61 | } 62 | 63 | function setBufferLength(uint8 _bufferLength) external override onlyRole(GOVERNANCE_ROLE) { 64 | // slither-reason: Disabled across all params childs 65 | // as they are being called by governance contract only 66 | // and their before setting, we are emitting event 67 | // slither-disable-next-line events-maths 68 | buffer = _bufferLength; 69 | } 70 | 71 | function setWithdrawLockPeriod(uint16 _withdrawLockPeriod) external override onlyRole(GOVERNANCE_ROLE) { 72 | // slither-disable-next-line events-maths 73 | withdrawLockPeriod = _withdrawLockPeriod; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /contracts/Core/parameters/child/CollectionManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../interfaces/ICollectionManagerParams.sol"; 4 | import "../ACL.sol"; 5 | import "../../storage/Constants.sol"; 6 | 7 | abstract contract CollectionManagerParams is ACL, ICollectionManagerParams, Constants { 8 | uint8 public buffer = 5; 9 | /// @notice maximum percentage deviation allowed from medians for all collections 10 | uint32 public maxTolerance = 1_000_000; 11 | 12 | /// @inheritdoc ICollectionManagerParams 13 | function setMaxTolerance(uint32 _maxTolerance) external override onlyRole(GOVERNANCE_ROLE) { 14 | // slither-reason: Disabled across all params childs 15 | // as they are being called by governance contract only 16 | // and their before setting, we are emitting event 17 | // slither-disable-next-line events-maths 18 | maxTolerance = _maxTolerance; 19 | } 20 | 21 | function setBufferLength(uint8 _bufferLength) external override onlyRole(GOVERNANCE_ROLE) { 22 | // slither-reason: Disabled across all params childs 23 | // as they are being called by governance contract only 24 | // and their before setting, we are emitting event 25 | // slither-disable-next-line events-maths 26 | buffer = _bufferLength; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/Core/parameters/child/RandomNoManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../interfaces/IRandomNoManagerParams.sol"; 4 | import "../ACL.sol"; 5 | import "../../storage/Constants.sol"; 6 | 7 | abstract contract RandomNoManagerParams is ACL, IRandomNoManagerParams, Constants { 8 | uint8 public buffer = 5; 9 | 10 | function setBufferLength(uint8 _bufferLength) external override onlyRole(GOVERNANCE_ROLE) { 11 | // slither-reason: Disabled across all params childs 12 | // as they are being called by governance contract only 13 | // and their before setting, we are emitting event 14 | // slither-disable-next-line events-maths 15 | buffer = _bufferLength; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/Core/parameters/child/RewardManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../interfaces/IRewardManagerParams.sol"; 4 | import "../ACL.sol"; 5 | import "../../storage/Constants.sol"; 6 | 7 | abstract contract RewardManagerParams is ACL, IRewardManagerParams, Constants { 8 | /// @notice percentage stake penalty to be given out for inactivity 9 | uint32 public penaltyNotRevealNum = 1000; 10 | /// @notice percentage age penalty to be given out for inactivity 11 | uint32 public penaltyAgeNotRevealNum = 100_000; 12 | /// @notice maximum age a staker can have 13 | uint32 public maxAge = 100 * 10000; 14 | /// @notice reward given to staker whose block is confirmed 15 | uint256 public blockReward = 100 * (10**18); 16 | /// @notice maximum percentage deviation allowed from medians for all collections 17 | uint32 public maxTolerance = 1_000_000; 18 | /// @notice maximum commission stakers can charge from delegators on their profits 19 | uint8 public maxCommission = 20; 20 | 21 | /// @inheritdoc IRewardManagerParams 22 | function setPenaltyNotRevealNum(uint32 _penaltyNotRevealNumerator) external override onlyRole(GOVERNANCE_ROLE) { 23 | // slither-disable-next-line events-maths 24 | penaltyNotRevealNum = _penaltyNotRevealNumerator; 25 | } 26 | 27 | /// @inheritdoc IRewardManagerParams 28 | function setPenaltyAgeNotRevealNum(uint32 _penaltyAgeNotRevealNumerator) external override onlyRole(GOVERNANCE_ROLE) { 29 | // slither-disable-next-line events-maths 30 | penaltyAgeNotRevealNum = _penaltyAgeNotRevealNumerator; 31 | } 32 | 33 | /// @inheritdoc IRewardManagerParams 34 | function setBlockReward(uint256 _blockReward) external override onlyRole(GOVERNANCE_ROLE) { 35 | // slither-disable-next-line events-maths 36 | blockReward = _blockReward; 37 | } 38 | 39 | /// @inheritdoc IRewardManagerParams 40 | function setMaxAge(uint32 _maxAge) external override onlyRole(GOVERNANCE_ROLE) { 41 | // slither-disable-next-line events-maths 42 | maxAge = _maxAge; 43 | } 44 | 45 | /// @inheritdoc IRewardManagerParams 46 | function setMaxTolerance(uint32 _maxTolerance) external override onlyRole(GOVERNANCE_ROLE) { 47 | // slither-reason: Disabled across all params childs 48 | // as they are being called by governance contract only 49 | // and their before setting, we are emitting event 50 | // slither-disable-next-line events-maths 51 | maxTolerance = _maxTolerance; 52 | } 53 | 54 | /// @inheritdoc IRewardManagerParams 55 | function setMaxCommission(uint8 _maxCommission) external override onlyRole(GOVERNANCE_ROLE) { 56 | // slither-disable-next-line events-maths 57 | maxCommission = _maxCommission; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /contracts/Core/parameters/child/StakeManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../interfaces/IStakeManagerParams.sol"; 4 | import "../ACL.sol"; 5 | import "../../storage/Constants.sol"; 6 | 7 | abstract contract StakeManagerParams is ACL, IStakeManagerParams, Constants { 8 | struct SlashNums { 9 | // percent bounty from staker's stake to be received by the bounty hunter 10 | uint32 bounty; 11 | // percent RAZOR burn from staker's stake 12 | uint32 burn; 13 | // percent from staker's stake to be kept by staker 14 | uint32 keep; 15 | } 16 | /// @notice a boolean, if true, the default admin role can remove all the funds incase of emergency 17 | bool public escapeHatchEnabled = true; 18 | 19 | uint8 public buffer = 5; 20 | /// @notice the number of epochs for which the sRZRs are locked for calling unstake() 21 | uint16 public unstakeLockPeriod = 1; 22 | /// @notice the number of epochs for which the RAZORs are locked after initiating withdraw 23 | uint16 public withdrawLockPeriod = 1; 24 | /// @notice the number of epochs where staker/delegator needs to initiate withdraw 25 | uint16 public withdrawInitiationPeriod = 5; 26 | /** 27 | * @notice percentage stake penalty from the locked amount for extending unstake lock 28 | * incase withdrawInitiationPeriod was missed 29 | */ 30 | uint32 public resetUnstakeLockPenalty = 100_000; 31 | /// @notice maximum commission stakers can charge from delegators on their profits 32 | uint8 public maxCommission = 20; 33 | /// @notice maximum commission change a staker can do 34 | uint8 public deltaCommission = 3; 35 | /// @notice the number of epochs for which a staker cant change commission once set/change 36 | uint16 public epochLimitForUpdateCommission = 100; 37 | /// @notice slashing params being used if staker is slashed. Slash Penalty = bounty + burned + kept == 100% 38 | SlashNums public slashNums = SlashNums(500_000, 9_500_000, 0); 39 | /// @notice minimum amount of stake required to participate 40 | uint256 public minStake = 20000 * (10**18); 41 | /// @notice minimum amount of stake required to become a staker 42 | uint256 public minSafeRazor = 10000 * (10**18); 43 | 44 | /// @inheritdoc IStakeManagerParams 45 | function setSlashParams( 46 | uint32 _bounty, 47 | uint32 _burn, 48 | uint32 _keep 49 | ) external override onlyRole(GOVERNANCE_ROLE) { 50 | require(_bounty + _burn + _keep <= BASE_DENOMINATOR, "params sum exceeds denominator"); 51 | // slither-disable-next-line events-maths 52 | slashNums = SlashNums(_bounty, _burn, _keep); 53 | } 54 | 55 | /// @inheritdoc IStakeManagerParams 56 | function setDeltaCommission(uint8 _deltaCommission) external override onlyRole(GOVERNANCE_ROLE) { 57 | // slither-disable-next-line events-maths 58 | deltaCommission = _deltaCommission; 59 | } 60 | 61 | /// @inheritdoc IStakeManagerParams 62 | function setEpochLimitForUpdateCommission(uint16 _epochLimitForUpdateCommission) external override onlyRole(GOVERNANCE_ROLE) { 63 | // slither-disable-next-line events-maths 64 | epochLimitForUpdateCommission = _epochLimitForUpdateCommission; 65 | } 66 | 67 | /// @inheritdoc IStakeManagerParams 68 | function setUnstakeLockPeriod(uint16 _unstakeLockPeriod) external override onlyRole(GOVERNANCE_ROLE) { 69 | // slither-disable-next-line events-maths 70 | unstakeLockPeriod = _unstakeLockPeriod; 71 | } 72 | 73 | /// @inheritdoc IStakeManagerParams 74 | function setWithdrawLockPeriod(uint16 _withdrawLockPeriod) external override onlyRole(GOVERNANCE_ROLE) { 75 | // slither-disable-next-line events-maths 76 | withdrawLockPeriod = _withdrawLockPeriod; 77 | } 78 | 79 | /// @inheritdoc IStakeManagerParams 80 | function setWithdrawInitiationPeriod(uint16 _withdrawInitiationPeriod) external override onlyRole(GOVERNANCE_ROLE) { 81 | // slither-disable-next-line events-maths 82 | withdrawInitiationPeriod = _withdrawInitiationPeriod; 83 | } 84 | 85 | /// @inheritdoc IStakeManagerParams 86 | function setResetUnstakeLockPenalty(uint32 _resetUnstakeLockPenalty) external override onlyRole(GOVERNANCE_ROLE) { 87 | // slither-disable-next-line events-maths 88 | resetUnstakeLockPenalty = _resetUnstakeLockPenalty; 89 | } 90 | 91 | /// @inheritdoc IStakeManagerParams 92 | function setMinStake(uint256 _minStake) external override onlyRole(GOVERNANCE_ROLE) { 93 | // slither-disable-next-line events-maths 94 | minStake = _minStake; 95 | } 96 | 97 | /// @inheritdoc IStakeManagerParams 98 | function setMinSafeRazor(uint256 _minSafeRazor) external override onlyRole(GOVERNANCE_ROLE) { 99 | require(_minSafeRazor <= minStake, "minSafeRazor beyond minStake"); 100 | // slither-disable-next-line events-maths 101 | minSafeRazor = _minSafeRazor; 102 | } 103 | 104 | /// @inheritdoc IStakeManagerParams 105 | function setMaxCommission(uint8 _maxCommission) external override onlyRole(GOVERNANCE_ROLE) { 106 | // slither-disable-next-line events-maths 107 | maxCommission = _maxCommission; 108 | } 109 | 110 | /// @inheritdoc IStakeManagerParams 111 | function disableEscapeHatch() external override onlyRole(GOVERNANCE_ROLE) { 112 | // slither-disable-next-line events-maths 113 | escapeHatchEnabled = false; 114 | } 115 | 116 | function setBufferLength(uint8 _bufferLength) external override onlyRole(GOVERNANCE_ROLE) { 117 | // slither-reason: Disabled across all params childs 118 | // as they are being called by governance contract only 119 | // and their before setting, we are emitting event 120 | // slither-disable-next-line events-maths 121 | buffer = _bufferLength; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /contracts/Core/parameters/child/VoteManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../interfaces/IVoteManagerParams.sol"; 4 | import "../ACL.sol"; 5 | import "../../storage/Constants.sol"; 6 | 7 | abstract contract VoteManagerParams is ACL, IVoteManagerParams, Constants { 8 | uint8 public buffer = 5; 9 | /// @notice maximum number of collections that can be assigned to the staker 10 | uint16 public toAssign = 3; 11 | /// @notice minimum amount of stake required to participate 12 | uint256 public minStake = 20000 * (10**18); 13 | 14 | /// @inheritdoc IVoteManagerParams 15 | function setMinStake(uint256 _minStake) external override onlyRole(GOVERNANCE_ROLE) { 16 | // slither-disable-next-line events-maths 17 | minStake = _minStake; 18 | } 19 | 20 | /// @inheritdoc IVoteManagerParams 21 | function setToAssign(uint16 _toAssign) external override onlyRole(GOVERNANCE_ROLE) { 22 | // slither-disable-next-line events-maths 23 | toAssign = _toAssign; 24 | } 25 | 26 | function setBufferLength(uint8 _bufferLength) external override onlyRole(GOVERNANCE_ROLE) { 27 | // slither-reason: Disabled across all params childs 28 | // as they are being called by governance contract only 29 | // and their before setting, we are emitting event 30 | // slither-disable-next-line events-maths 31 | buffer = _bufferLength; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/Core/parameters/interfaces/IBlockManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IBlockManagerParams { 5 | /** 6 | * @notice changing the maximum number of best proposed blocks to be considered for dispute 7 | * @dev can be called only by the the address that has the governance role 8 | * @param _maxAltBlocks updated value to be set for maxAltBlocks 9 | */ 10 | function setMaxAltBlocks(uint8 _maxAltBlocks) external; 11 | 12 | /** 13 | * @notice changing the block reward given out to stakers 14 | * @dev can be called only by the the address that has the governance role 15 | * @param _blockReward updated value to be set for blockReward 16 | */ 17 | function setBlockReward(uint256 _blockReward) external; 18 | 19 | /** 20 | * @notice changing minimum amount that to be staked for participation 21 | * @dev can be called only by the the address that has the governance role 22 | * @param _minStake updated value to be set for minStake 23 | */ 24 | function setMinStake(uint256 _minStake) external; 25 | 26 | /** 27 | * @notice changing buffer length between the states 28 | * @dev can be called only by the the address that has the governance role 29 | * @param _bufferLength updated value to be set for buffer 30 | */ 31 | function setBufferLength(uint8 _bufferLength) external; 32 | } 33 | -------------------------------------------------------------------------------- /contracts/Core/parameters/interfaces/IBondManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IBondManagerParams { 5 | /** 6 | * @notice changing the maximum percentage deviation allowed from medians for all collections 7 | * @dev can be called only by the the address that has the governance role 8 | * @param _depositPerJob updated value for maxTolerance 9 | */ 10 | function setDepositPerJob(uint256 _depositPerJob) external; 11 | 12 | /** 13 | * @notice changing buffer length between the states 14 | * @dev can be called only by the the address that has the governance role 15 | * @param _bufferLength updated value to be set for buffer 16 | */ 17 | function setBufferLength(uint8 _bufferLength) external; 18 | 19 | function setMinBond(uint256 _minBond) external; 20 | 21 | function setEpochLimitForUpdateBond(uint16 _epochLimitForUpdateBond) external; 22 | 23 | function setWithdrawLockPeriod(uint16 _withdrawLockPeriod) external; 24 | 25 | function setMinJobs(uint8 _minJobs) external; 26 | 27 | function setMaxJobs(uint8 _maxJobs) external; 28 | } 29 | -------------------------------------------------------------------------------- /contracts/Core/parameters/interfaces/ICollectionManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface ICollectionManagerParams { 5 | /** 6 | * @notice changing the maximum percentage deviation allowed from medians for all collections 7 | * @dev can be called only by the the address that has the governance role 8 | * @param _maxTolerance updated value for maxTolerance 9 | */ 10 | function setMaxTolerance(uint32 _maxTolerance) external; 11 | 12 | /** 13 | * @notice changing buffer length between the states 14 | * @dev can be called only by the the address that has the governance role 15 | * @param _bufferLength updated value to be set for buffer 16 | */ 17 | function setBufferLength(uint8 _bufferLength) external; 18 | } 19 | -------------------------------------------------------------------------------- /contracts/Core/parameters/interfaces/IRandomNoManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IRandomNoManagerParams { 5 | /** 6 | * @notice changing buffer length between the states 7 | * @dev can be called only by the the address that has the governance role 8 | * @param _bufferLength updated value to be set for buffer 9 | */ 10 | function setBufferLength(uint8 _bufferLength) external; 11 | } 12 | -------------------------------------------------------------------------------- /contracts/Core/parameters/interfaces/IRewardManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IRewardManagerParams { 5 | /** 6 | * @notice changing the percentage stake penalty to be given out for inactivity 7 | * @dev can be called only by the the address that has the governance role 8 | * @param _penaltyNotRevealNumerator updated value to be set for penaltyNotRevealNumerator 9 | */ 10 | function setPenaltyNotRevealNum(uint32 _penaltyNotRevealNumerator) external; 11 | 12 | /** 13 | * @notice changing the percentage age penalty to be given out for inactivity 14 | * @dev can be called only by the the address that has the governance role 15 | * @param _penaltyAgeNotRevealNumerator updated value to be set for penaltyAgeNotRevealNumerator 16 | */ 17 | function setPenaltyAgeNotRevealNum(uint32 _penaltyAgeNotRevealNumerator) external; 18 | 19 | /** 20 | * @notice changing the block reward given out to stakers 21 | * @dev can be called only by the the address that has the governance role 22 | * @param _blockReward updated value to be set for blockReward 23 | */ 24 | function setBlockReward(uint256 _blockReward) external; 25 | 26 | /** 27 | * @notice changing the maximum age a staker can have 28 | * @dev can be called only by the the address that has the governance role 29 | * @param _maxAge updated value to be set for maxAge 30 | */ 31 | function setMaxAge(uint32 _maxAge) external; 32 | 33 | /** 34 | * @notice changing the maximum percentage deviation allowed from medians for all collections 35 | * @dev can be called only by the the address that has the governance role 36 | * @param _maxTolerance updated value for maxTolerance 37 | */ 38 | function setMaxTolerance(uint32 _maxTolerance) external; 39 | 40 | /** 41 | * @notice changing maximum commission stakers can charge from delegators on their profits 42 | * @dev can be called only by the the address that has the governance role 43 | * @param _maxCommission updated value to be set for maxCommission 44 | */ 45 | function setMaxCommission(uint8 _maxCommission) external; 46 | } 47 | -------------------------------------------------------------------------------- /contracts/Core/parameters/interfaces/IStakeManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IStakeManagerParams { 5 | /** 6 | * @notice changing slashing parameters 7 | * @dev can be called only by the the address that has the governance role 8 | * @param _bounty updated percent value to be set for bounty 9 | * @param _burn updated percent value to be set for burn 10 | * @param _keep updated percent value to be set for keep 11 | */ 12 | function setSlashParams( 13 | uint32 _bounty, 14 | uint32 _burn, 15 | uint32 _keep 16 | ) external; 17 | 18 | /** 19 | * @notice changing the number of epochs for which the RAZORs are locked after initiating withdraw 20 | * @dev can be called only by the the address that has the governance role 21 | * @param _withdrawLockPeriod updated value to be set for withdrawLockPeriod 22 | */ 23 | function setWithdrawLockPeriod(uint16 _withdrawLockPeriod) external; 24 | 25 | /** 26 | * @notice changing the number of epochs for which the sRZRs are locked for calling unstake() 27 | * @dev can be called only by the the address that has the governance role 28 | * @param _unstakeLockPeriod updated value to be set for unstakeLockPeriod 29 | */ 30 | function setUnstakeLockPeriod(uint16 _unstakeLockPeriod) external; 31 | 32 | /** 33 | * @notice changing the number of epochs where staker/delegator needs to initiate withdraw 34 | * @dev can be called only by the the address that has the governance role 35 | * @param _withdrawInitiationPeriod updated value to be set for withdrawInitiationPeriod 36 | */ 37 | function setWithdrawInitiationPeriod(uint16 _withdrawInitiationPeriod) external; 38 | 39 | /** 40 | * @notice changing percentage stake penalty from the locked amount for extending unstake lock 41 | * incase withdrawInitiationPeriod was missed 42 | * @dev can be called only by the the address that has the governance role 43 | * @param _resetUnstakePenalty updated value to be set for resetUnstakePenalty 44 | */ 45 | function setResetUnstakeLockPenalty(uint32 _resetUnstakePenalty) external; 46 | 47 | /** 48 | * @notice changing minimum amount that to be staked for participation 49 | * @dev can be called only by the the address that has the governance role 50 | * @param _minStake updated value to be set for minStake 51 | */ 52 | function setMinStake(uint256 _minStake) external; 53 | 54 | /** 55 | * @notice changing minimum amount that to be staked to become a staker 56 | * @dev can be called only by the the address that has the governance role 57 | * @param _minSafeRazor updated value to be set for minSafeRazor 58 | */ 59 | function setMinSafeRazor(uint256 _minSafeRazor) external; 60 | 61 | /** 62 | * @notice changing maximum commission stakers can charge from delegators on their profits 63 | * @dev can be called only by the the address that has the governance role 64 | * @param _maxCommission updated value to be set for maxCommission 65 | */ 66 | function setMaxCommission(uint8 _maxCommission) external; 67 | 68 | /** 69 | * @notice changing maximum commission change a staker can do 70 | * @dev can be called only by the the address that has the governance role 71 | * @param _deltaCommission updated value to be set for deltaCommission 72 | */ 73 | function setDeltaCommission(uint8 _deltaCommission) external; 74 | 75 | /** 76 | * @notice changing the number of epochs for which a staker cant change commission once set/change 77 | * @dev can be called only by the the address that has the governance role 78 | * @param _epochLimitForUpdateCommission updated value to be set for epochLimitForUpdateCommission 79 | */ 80 | function setEpochLimitForUpdateCommission(uint16 _epochLimitForUpdateCommission) external; 81 | 82 | /** 83 | * @notice sets escape hatch to false permanently 84 | * @dev can be called only by the the address that has the governance role 85 | */ 86 | function disableEscapeHatch() external; 87 | 88 | /** 89 | * @notice changing buffer length between the states 90 | * @dev can be called only by the the address that has the governance role 91 | * @param _bufferLength updated value to be set for buffer 92 | */ 93 | function setBufferLength(uint8 _bufferLength) external; 94 | } 95 | -------------------------------------------------------------------------------- /contracts/Core/parameters/interfaces/IVoteManagerParams.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IVoteManagerParams { 5 | /** 6 | * @notice changing minimum amount that to be staked for participation 7 | * @dev can be called only by the the address that has the governance role 8 | * @param _minStake updated value to be set for minStake 9 | */ 10 | function setMinStake(uint256 _minStake) external; 11 | 12 | /** 13 | * @notice changing maximum number of collections that can be assigned to the staker 14 | * @dev can be called only by the the address that has the governance role 15 | * @param _toAssign updated value to be set for toAssign 16 | */ 17 | function setToAssign(uint16 _toAssign) external; 18 | 19 | /** 20 | * @notice changing buffer length between the states 21 | * @dev can be called only by the the address that has the governance role 22 | * @param _bufferLength updated value to be set for buffer 23 | */ 24 | function setBufferLength(uint8 _bufferLength) external; 25 | } 26 | -------------------------------------------------------------------------------- /contracts/Core/storage/BlockStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../../lib/Structs.sol"; 4 | 5 | contract BlockStorage { 6 | /// @notice mapping of epoch -> address -> dispute 7 | mapping(uint32 => mapping(address => Structs.Dispute)) public disputes; 8 | /// @notice mapping of epoch -> blockId -> block 9 | mapping(uint32 => mapping(uint32 => Structs.Block)) public proposedBlocks; 10 | /// @notice mapping of epoch->blockId 11 | mapping(uint32 => uint32[]) public sortedProposedBlockIds; 12 | /// @notice mapping of stakerId->epoch 13 | mapping(uint32 => uint32) public epochLastProposed; 14 | /// @notice total number of proposed blocks in an epoch 15 | // slither-disable-next-line constable-states 16 | uint32 public numProposedBlocks; 17 | /// @notice block index that is to be confirmed if not disputed 18 | // slither-disable-next-line constable-states 19 | int8 public blockIndexToBeConfirmed; // Index in sortedProposedBlockIds 20 | /// @notice mapping of epoch -> blocks 21 | mapping(uint32 => Structs.Block) public blocks; 22 | } 23 | -------------------------------------------------------------------------------- /contracts/Core/storage/BondStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../../lib/Structs.sol"; 4 | 5 | contract BondStorage { 6 | mapping(uint32 => Structs.DataBond) public databonds; 7 | mapping(uint32 => mapping(address => Structs.Lock)) public bondLocks; 8 | 9 | uint16[] public databondCollections; 10 | uint32 public numDataBond; 11 | } 12 | -------------------------------------------------------------------------------- /contracts/Core/storage/CollectionStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "../../lib/Structs.sol"; 5 | 6 | contract CollectionStorage { 7 | /// @notice mapping for JobID -> Job Info 8 | mapping(uint16 => Structs.Job) public jobs; 9 | /// @notice mapping for CollectionID -> Collection Info 10 | mapping(uint16 => Structs.Collection) public collections; 11 | 12 | /// @notice mapping for leafId -> collectionid 13 | mapping(uint16 => uint16) public leafIdToCollectionIdRegistry; 14 | 15 | /// @notice mapping for name of collection in bytes32 -> collectionid 16 | mapping(bytes32 => uint16) public ids; 17 | 18 | /// @notice number of active collections in the network 19 | uint16 public numActiveCollections; 20 | /// @notice number of collections in the network 21 | uint16 public numCollections; 22 | /// @notice number of jobs in the network 23 | uint16 public numJobs; 24 | } 25 | -------------------------------------------------------------------------------- /contracts/Core/storage/Constants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | contract Constants { 5 | enum State { 6 | Commit, 7 | Reveal, 8 | Propose, 9 | Dispute, 10 | Confirm, 11 | Buffer 12 | } 13 | 14 | enum StakeChanged { 15 | BlockReward, 16 | InactivityPenalty, 17 | Slashed 18 | } 19 | 20 | enum StakerRewardChanged { 21 | StakerRewardAdded, 22 | StakerRewardClaimed 23 | } 24 | 25 | enum AgeChanged { 26 | InactivityPenalty, 27 | VotingRewardOrPenalty 28 | } 29 | 30 | enum JobSelectorType { 31 | JSON, 32 | XHTML 33 | } 34 | 35 | uint8 public constant NUM_STATES = 5; 36 | 37 | uint16 public constant EPOCH_LENGTH = 1200; 38 | 39 | // slither-disable-next-line too-many-digits 40 | address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD; 41 | uint32 public constant BASE_DENOMINATOR = 10_000_000; 42 | // keccak256("BLOCK_CONFIRMER_ROLE") 43 | bytes32 public constant BLOCK_CONFIRMER_ROLE = 0x18797bc7973e1dadee1895be2f1003818e30eae3b0e7a01eb9b2e66f3ea2771f; 44 | 45 | // keccak256("STAKE_MODIFIER_ROLE") 46 | bytes32 public constant STAKE_MODIFIER_ROLE = 0xdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc804; 47 | 48 | // keccak256("REWARD_MODIFIER_ROLE") 49 | bytes32 public constant REWARD_MODIFIER_ROLE = 0xcabcaf259dd9a27f23bd8a92bacd65983c2ebf027c853f89f941715905271a8d; 50 | 51 | // keccak256("COLLECTION_MODIFIER_ROLE") 52 | bytes32 public constant COLLECTION_MODIFIER_ROLE = 0xa3a75e7cd2b78fcc3ae2046ab93bfa4ac0b87ed7ea56646a312cbcb73eabd294; 53 | 54 | // keccak256("VOTE_MODIFIER_ROLE") 55 | bytes32 public constant VOTE_MODIFIER_ROLE = 0x912208965b92edeb3eb82a612c87b38b5e844f7539cb396f0d08ec012e511b07; 56 | 57 | // keccak256("DELEGATOR_MODIFIER_ROLE") 58 | bytes32 public constant DELEGATOR_MODIFIER_ROLE = 0x6b7da7a33355c6e035439beb2ac6a052f1558db73f08690b1c9ef5a4e8389597; 59 | 60 | // keccak256("REGISTRY_MODIFIER_ROLE") 61 | bytes32 public constant REGISTRY_MODIFIER_ROLE = 0xca51085219bef34771da292cb24ee4fcf0ae6bdba1a62c17d1fb7d58be802883; 62 | 63 | // keccak256("SECRETS_MODIFIER_ROLE") 64 | bytes32 public constant SECRETS_MODIFIER_ROLE = 0x46aaf8a125792dfff6db03d74f94fe1acaf55c8cab22f65297c15809c364465c; 65 | 66 | // keccak256("PAUSE_ROLE") 67 | bytes32 public constant PAUSE_ROLE = 0x139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d; 68 | 69 | // keccak256("GOVERNANCE_ROLE") 70 | bytes32 public constant GOVERNANCE_ROLE = 0x71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1; 71 | 72 | // keccak256("STOKEN_ROLE") 73 | bytes32 public constant STOKEN_ROLE = 0xce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc; 74 | 75 | // keccak256("SALT_MODIFIER_ROLE") 76 | bytes32 public constant SALT_MODIFIER_ROLE = 0xf31dda80d37c96a1a0852ace387dda52a75487d7d4eb74895e749ede3e0987b4; 77 | 78 | // keccak256("DEPTH_MODIFIER_ROLE)") 79 | bytes32 public constant DEPTH_MODIFIER_ROLE = 0x91f5d9ea80c4d04985e669bc72870410b28b57afdf61c0d50d377766d86a3748; 80 | 81 | // keccak256("ESCAPE_HATCH_ROLE") 82 | bytes32 public constant ESCAPE_HATCH_ROLE = 0x518d8c39717318f051dfb836a4ebe5b3c34aa2cb7fce26c21a89745422ba8043; 83 | 84 | // keccak256("OCCURRENCE_MODIFIER_ROLE") 85 | bytes32 public constant OCCURRENCE_MODIFIER_ROLE = 0x35ed6c1cb451e31b9dd4f1d325602da07694e1747843e6b55ab1527fd8835fb5; 86 | 87 | // keccak256("RESET_DATABOND_ROLE") 88 | bytes32 public constant RESET_DATABOND_ROLE = 0x3e99a7fb3946972656cbde0e63ef530dd7750472272e07c65aa9f473a99f5c5d; 89 | 90 | // keccak256("COLLECTION_CONFIRMER_ROLE") 91 | bytes32 public constant COLLECTION_CONFIRMER_ROLE = 0xa1d2ec18e7ea6241ef0566da3d2bc59cc059592990e56680abdc7031155a0c28; 92 | } 93 | -------------------------------------------------------------------------------- /contracts/Core/storage/StakeStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "../../lib/Structs.sol"; 5 | 6 | contract StakeStorage { 7 | enum LockType { 8 | Unstake, 9 | Withdraw 10 | } 11 | /// @notice total number of stakers 12 | // slither-disable-next-line constable-states 13 | uint32 public numStakers; 14 | /// @notice total number of bounties given out 15 | // slither-disable-next-line constable-states 16 | uint32 public bountyCounter; 17 | 18 | /// @notice mapping of staker address -> staker id info 19 | mapping(address => uint32) public stakerIds; 20 | /// @notice mapping of staker id -> staker info 21 | mapping(uint32 => Structs.Staker) public stakers; 22 | /// @notice mapping of staker/delegator address -> staker sRZR address -> LockType -> Lock info 23 | mapping(address => mapping(address => mapping(LockType => Structs.Lock))) public locks; 24 | /// @notice mapping of bounty id -> bounty lock info 25 | mapping(uint32 => Structs.BountyLock) public bountyLocks; 26 | /// @notice maturity calculation for each index = [math.floor(math.sqrt(i*10000)/2) for i in range(1,100)] 27 | uint16[101] public maturities = [ 28 | 50, 29 | 70, 30 | 86, 31 | 100, 32 | 111, 33 | 122, 34 | 132, 35 | 141, 36 | 150, 37 | 158, 38 | 165, 39 | 173, 40 | 180, 41 | 187, 42 | 193, 43 | 200, 44 | 206, 45 | 212, 46 | 217, 47 | 223, 48 | 229, 49 | 234, 50 | 239, 51 | 244, 52 | 250, 53 | 254, 54 | 259, 55 | 264, 56 | 269, 57 | 273, 58 | 278, 59 | 282, 60 | 287, 61 | 291, 62 | 295, 63 | 300, 64 | 304, 65 | 308, 66 | 312, 67 | 316, 68 | 320, 69 | 324, 70 | 327, 71 | 331, 72 | 335, 73 | 339, 74 | 342, 75 | 346, 76 | 350, 77 | 353, 78 | 357, 79 | 360, 80 | 364, 81 | 367, 82 | 370, 83 | 374, 84 | 377, 85 | 380, 86 | 384, 87 | 387, 88 | 390, 89 | 393, 90 | 396, 91 | 400, 92 | 403, 93 | 406, 94 | 409, 95 | 412, 96 | 415, 97 | 418, 98 | 421, 99 | 424, 100 | 427, 101 | 430, 102 | 433, 103 | 435, 104 | 438, 105 | 441, 106 | 444, 107 | 447, 108 | 450, 109 | 452, 110 | 455, 111 | 458, 112 | 460, 113 | 463, 114 | 466, 115 | 469, 116 | 471, 117 | 474, 118 | 476, 119 | 479, 120 | 482, 121 | 484, 122 | 487, 123 | 489, 124 | 492, 125 | 494, 126 | 497, 127 | 500, 128 | 502 129 | ]; 130 | } 131 | -------------------------------------------------------------------------------- /contracts/Core/storage/VoteStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "../../lib/Structs.sol"; 5 | 6 | contract VoteStorage { 7 | /// @notice mapping of stakerid -> commitment 8 | mapping(uint32 => Structs.Commitment) public commitments; 9 | 10 | // Epoch needs to be brought back due to AAR, each epoch would have different set of assets revealed 11 | /// @notice mapping of epoch -> stakerid -> assetid -> vote 12 | mapping(uint32 => mapping(uint32 => mapping(uint16 => uint256))) public votes; 13 | 14 | /// @notice mapping of epoch -> assetid -> weight 15 | mapping(uint32 => mapping(uint16 => uint256)) public totalInfluenceRevealed; 16 | 17 | /// @notice mapping of epoch -> assetid -> voteValue -> weight 18 | mapping(uint32 => mapping(uint16 => mapping(uint256 => uint256))) public voteWeights; 19 | 20 | /// @notice mapping of epoch-> stakerid->influence 21 | mapping(uint32 => mapping(uint32 => uint256)) public influenceSnapshot; 22 | 23 | /// @notice mapping of epoch-> stakerid->stake 24 | mapping(uint32 => mapping(uint32 => uint256)) public stakeSnapshot; 25 | 26 | /// @notice mapping of stakerid=> epochLastRevealed 27 | mapping(uint32 => uint32) public epochLastRevealed; 28 | 29 | /// @notice hash of last epoch and its block medians 30 | bytes32 public salt; 31 | 32 | /// @notice depth of a valid merkle tree 33 | uint256 public depth; // uint32 possible, pack if opp arise 34 | } 35 | -------------------------------------------------------------------------------- /contracts/Delegator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "./Core/StateManager.sol"; 5 | import "./Core/interface/ICollectionManager.sol"; 6 | import "./IDelegator.sol"; 7 | import "./randomNumber/IRandomNoClient.sol"; 8 | import "./Core/parameters/ACL.sol"; 9 | import "./Core/storage/Constants.sol"; 10 | import "./Pause.sol"; 11 | 12 | /** @title Delegator 13 | * @notice Delegator acts as a bridge between the client and the protocol 14 | */ 15 | 16 | contract Delegator is ACL, StateManager, Pause, IDelegator { 17 | ICollectionManager public collectionManager; 18 | IRandomNoClient public randomNoManager; 19 | 20 | /// @inheritdoc IDelegator 21 | function updateAddress(address newDelegateAddress, address newRandomNoManagerAddress) external override onlyRole(DEFAULT_ADMIN_ROLE) { 22 | require(newDelegateAddress != address(0x0) && newRandomNoManagerAddress != address(0x0), "Zero Address check"); 23 | collectionManager = ICollectionManager(newDelegateAddress); 24 | randomNoManager = IRandomNoClient(newRandomNoManagerAddress); 25 | } 26 | 27 | /// @inheritdoc IDelegator 28 | function register() external override whenNotPaused returns (bytes32) { 29 | return randomNoManager.register(); 30 | } 31 | 32 | /// @inheritdoc IDelegator 33 | function getActiveCollections() external view override whenNotPaused returns (uint16[] memory) { 34 | return collectionManager.getActiveCollections(); 35 | } 36 | 37 | /// @inheritdoc IDelegator 38 | function getCollectionStatus(uint16 _id) external view override whenNotPaused returns (bool) { 39 | return collectionManager.getCollectionStatus(_id); 40 | } 41 | 42 | /// @inheritdoc IDelegator 43 | function getCollectionID(bytes32 _hname) external view override whenNotPaused returns (uint16) { 44 | return collectionManager.getCollectionID(_hname); 45 | } 46 | 47 | /// @inheritdoc IDelegator 48 | function getResult(bytes32 _name) external view override whenNotPaused returns (uint256, int8) { 49 | return collectionManager.getResult(_name); 50 | } 51 | 52 | /// @inheritdoc IDelegator 53 | function getResultFromID(uint16 _id) external view override whenNotPaused returns (uint256, int8) { 54 | return collectionManager.getResultFromID(_id); 55 | } 56 | 57 | /// @inheritdoc IDelegator 58 | function getRandomNumber(bytes32 requestId) external view override whenNotPaused returns (uint256) { 59 | return randomNoManager.getRandomNumber(requestId); 60 | } 61 | 62 | /// @inheritdoc IDelegator 63 | function getGenericRandomNumberOfLastEpoch() external view override whenNotPaused returns (uint256) { 64 | return randomNoManager.getGenericRandomNumberOfLastEpoch(); 65 | } 66 | 67 | /// @inheritdoc IDelegator 68 | function getGenericRandomNumber(uint32 _epoch) external view override whenNotPaused returns (uint256) { 69 | return randomNoManager.getGenericRandomNumber(_epoch); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /contracts/IDelegator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IDelegator { 5 | /** 6 | * @dev updates the address of the Collection Manager contract from where the delegator will fetch 7 | * results of the oracle 8 | * @param newDelegateAddress address of the Collection Manager 9 | * @param newRandomNoManagerAddress address of the Random Number Manager 10 | */ 11 | function updateAddress(address newDelegateAddress, address newRandomNoManagerAddress) external; 12 | 13 | /** 14 | * @notice Allows Client to register for random number 15 | * Per request a rquest id is generated, which is binded to one epoch 16 | * this epoch is current epoch if Protocol is in commit state, or epoch + 1 if in any other state 17 | * @return requestId : unique request id 18 | */ 19 | function register() external returns (bytes32); 20 | 21 | /** 22 | * @dev using the hash of collection name, clients can query collection id with respect to its hash 23 | * @param _name bytes32 hash of the collection name 24 | * @return collection ID 25 | */ 26 | function getCollectionID(bytes32 _name) external view returns (uint16); 27 | 28 | /** 29 | * @dev using the hash of collection name, clients can query the result of that collection 30 | * @param _name bytes32 hash of the collection name 31 | * @return result of the collection and its power 32 | */ 33 | function getResult(bytes32 _name) external view returns (uint256, int8); 34 | 35 | /** 36 | * @dev using the collection id, clients can query the result of the collection 37 | * @param _id collection ID 38 | * @return result of the collection and its power 39 | */ 40 | function getResultFromID(uint16 _id) external view returns (uint256, int8); 41 | 42 | /** 43 | * @return ids of active collections in the oracle 44 | */ 45 | function getActiveCollections() external view returns (uint16[] memory); 46 | 47 | /** 48 | * @dev using the collection id, clients can query the status of collection 49 | * @param _id collection ID 50 | * @return status of the collection 51 | */ 52 | function getCollectionStatus(uint16 _id) external view returns (bool); 53 | 54 | /** 55 | * @notice Allows client to pull random number once available 56 | * Random no is generated from secret of that epoch and request id, its unique per requestid 57 | * @param requestId : A unique id per request 58 | */ 59 | function getRandomNumber(bytes32 requestId) external view returns (uint256); 60 | 61 | /** 62 | * @notice Fetch generic random number of last epoch 63 | * @return random number 64 | */ 65 | function getGenericRandomNumberOfLastEpoch() external view returns (uint256); 66 | 67 | /** 68 | * @dev using epoch, clients can query random number generated of the epoch 69 | * @param _epoch epoch 70 | * @return random number 71 | */ 72 | function getGenericRandomNumber(uint32 _epoch) external view returns (uint256); 73 | } 74 | -------------------------------------------------------------------------------- /contracts/Initializable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | // solhint-disable-next-line compiler-version 4 | pragma solidity ^0.8.0; 5 | 6 | /** 7 | * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed 8 | * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an 9 | * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer 10 | * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. 11 | * 12 | * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as 13 | * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. 14 | * 15 | * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure 16 | * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. 17 | * 18 | * Forked from OZ's (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/b9125001f0a1c44d596ca3a47536f1a467e3a29d/contracts/proxy/utils/Initializable.sol) 19 | */ 20 | 21 | abstract contract Initializable { 22 | /** 23 | * @dev Indicates that the contract has been initialized. 24 | */ 25 | bool private _initialized; 26 | 27 | /** 28 | * @dev Indicates that the contract is in the process of being initialized. 29 | */ 30 | bool private _initializing; 31 | 32 | /** 33 | * @dev Modifier to protect an initializer function from being invoked twice. 34 | */ 35 | modifier initializer() { 36 | require(_initializing || !_initialized, "contract already initialized"); 37 | 38 | bool isTopLevelCall = !_initializing; 39 | if (isTopLevelCall) { 40 | _initializing = true; 41 | _initialized = true; 42 | } 43 | 44 | _; 45 | 46 | if (isTopLevelCall) { 47 | _initializing = false; 48 | } 49 | } 50 | 51 | modifier initialized() { 52 | require(_initialized, "Contract should be initialized"); 53 | _; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /contracts/Pause.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "@openzeppelin/contracts/security/Pausable.sol"; 4 | import "./Core/parameters/ACL.sol"; 5 | import "./Core/storage/Constants.sol"; 6 | 7 | contract Pause is Pausable, ACL, Constants { 8 | function pause() external onlyRole(PAUSE_ROLE) { 9 | Pausable._pause(); 10 | } 11 | 12 | function unpause() external onlyRole(PAUSE_ROLE) { 13 | Pausable._unpause(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /contracts/lib/MerklePosAware.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | /** 6 | * @dev These functions deal with verification of Merkle trees (hash trees), 7 | */ 8 | library MerklePosAware { 9 | function verifyMultiple( 10 | bytes32[][] memory proofs, 11 | bytes32 root, 12 | bytes32[] memory leaves, 13 | uint16[] memory leafId, 14 | uint256 depth, 15 | uint16 maxAssets 16 | ) internal pure returns (bool) { 17 | for (uint256 i = 0; i < proofs.length; i++) { 18 | if (!verify(proofs[i], root, leaves[i], leafId[i], depth, maxAssets)) return false; 19 | } 20 | return true; 21 | } 22 | 23 | /** 24 | * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree 25 | * defined by `root`. For this, a `proof` must be provided, containing 26 | * sibling hashes on the branch from the leaf to the root of the tree. Each 27 | * pair of leaves and each pair of pre-images are assumed to be sorted. 28 | */ 29 | function verify( 30 | bytes32[] memory proof, 31 | bytes32 root, 32 | bytes32 leaf, 33 | uint16 leafId, 34 | uint256 depth, 35 | uint16 maxAssets 36 | ) internal pure returns (bool) { 37 | bytes32 computedHash = leaf; 38 | bytes memory seq = bytes(getSequence(leafId, depth)); 39 | 40 | uint256 lastNode = maxAssets; 41 | uint256 myNode = leafId + 1; 42 | uint256 j = depth; 43 | uint256 i = 0; 44 | while (j > 0) { 45 | bytes32 proofElement = proof[i]; 46 | j--; 47 | // check proof if my node is not last node and number of nodes on level is not odd 48 | if (!(lastNode % 2 == 1 && lastNode == myNode)) { 49 | // 0x30 is 0, 0x31 is 1 50 | if (seq[j] == 0x30) { 51 | computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); 52 | } else { 53 | computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); 54 | } 55 | i++; 56 | } 57 | 58 | myNode = myNode / 2 + (myNode % 2); 59 | lastNode = lastNode / 2 + (lastNode % 2); 60 | } 61 | 62 | return computedHash == root; 63 | } 64 | 65 | function getSequence(uint256 leafId, uint256 depth) internal pure returns (bytes memory) { 66 | bytes memory output = new bytes(depth); 67 | for (uint8 i = 0; i < depth; i++) { 68 | output[depth - 1 - i] = (leafId % 2 == 1) ? bytes1("1") : bytes1("0"); 69 | leafId /= 2; 70 | } 71 | return output; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /contracts/lib/Random.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | library Random { 5 | // pseudo random number generator based on hash. returns 0 -> max-1 6 | // slither ignore reason : Internal library 7 | // slither-disable-next-line dead-code 8 | function prng(uint256 max, bytes32 randHash) internal pure returns (uint256) { 9 | uint256 sum = uint256(randHash); 10 | return (sum % max); 11 | } 12 | 13 | // pseudo random hash generator based on hashes. 14 | // slither ignore reason : Internal library 15 | // slither-disable-next-line dead-code 16 | function prngHash(bytes32 seed, bytes32 salt) internal pure returns (bytes32) { 17 | bytes32 prngHashVal = keccak256(abi.encodePacked(seed, salt)); 18 | return (prngHashVal); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/lib/Structs.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | library Structs { 5 | struct Commitment { 6 | uint32 epoch; 7 | bytes32 commitmentHash; 8 | } 9 | struct Staker { 10 | // Slot 1 11 | bool acceptDelegation; 12 | bool isSlashed; 13 | uint8 commission; 14 | uint32 id; 15 | uint32 age; 16 | address _address; 17 | // Slot 2 18 | address tokenAddress; 19 | uint32 epochFirstStakedOrLastPenalized; 20 | uint32 epochCommissionLastUpdated; 21 | // Slot 3 22 | uint256 stake; 23 | uint256 stakerReward; 24 | } 25 | 26 | struct Lock { 27 | uint256 amount; //amount in sRZR/RZR 28 | uint256 unlockAfter; // Can be made uint32 later if packing is possible 29 | } 30 | 31 | struct BountyLock { 32 | uint32 redeemAfter; 33 | address bountyHunter; 34 | uint256 amount; //amount in RZR 35 | } 36 | 37 | struct Block { 38 | bool valid; 39 | uint32 proposerId; 40 | uint16[] ids; 41 | uint256 iteration; 42 | uint256 biggestStake; 43 | uint256[] medians; 44 | } 45 | 46 | struct Dispute { 47 | uint16 collectionId; 48 | uint256 lastVisitedValue; 49 | uint256 accWeight; 50 | uint256 median; 51 | } 52 | 53 | struct Job { 54 | uint16 id; 55 | uint8 selectorType; // 0-1 56 | uint8 weight; // 1-100 57 | int8 power; 58 | string name; 59 | string selector; 60 | string url; 61 | } 62 | 63 | struct Collection { 64 | bool active; 65 | uint16 id; 66 | uint16 occurrence; 67 | int8 power; 68 | uint32 epochLastReported; 69 | uint32 tolerance; 70 | uint32 aggregationMethod; 71 | uint16[] jobIDs; 72 | string name; 73 | uint256 result; 74 | } 75 | 76 | struct AssignedAsset { 77 | uint16 leafId; 78 | uint256 value; 79 | } 80 | 81 | struct MerkleTree { 82 | Structs.AssignedAsset[] values; 83 | bytes32[][] proofs; 84 | bytes32 root; 85 | } 86 | 87 | struct DataBond { 88 | bool active; 89 | uint16 collectionId; 90 | uint16 desiredOccurrence; 91 | uint32 id; 92 | uint32 epochBondLastUpdated; 93 | address bondCreator; 94 | uint16[] jobIds; 95 | uint256 bond; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /contracts/mocks/InitializableMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import "../Initializable.sol"; 6 | 7 | /** 8 | * @title InitializableMock 9 | * @dev This contract is a mock to test initializable functionality 10 | */ 11 | contract InitializableMock is Initializable { 12 | bool public initializerRan; 13 | 14 | function initializeNested() external initializer { 15 | initialize(); 16 | } 17 | 18 | function initialize() public initializer { 19 | initializerRan = true; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/mocks/MerklePosAwareTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../lib/MerklePosAware.sol"; 4 | 5 | contract MerklePosAwareTest { 6 | function verifyMultiple( 7 | bytes32[][] memory proofs, 8 | bytes32 root, 9 | bytes32[] memory leaves, 10 | uint16[] memory leafId, 11 | uint256 depth, 12 | uint16 maxAssets 13 | ) external pure returns (bool) { 14 | return MerklePosAware.verifyMultiple(proofs, root, leaves, leafId, depth, maxAssets); 15 | } 16 | 17 | function getSequence(uint256 leafId, uint256 depth) external pure returns (bytes memory) { 18 | return MerklePosAware.getSequence(leafId, depth); 19 | } 20 | //function getSequence(uint256 leafId, uint256 depth) external 21 | 22 | // function verify( 23 | // bytes32[] memory proof, 24 | // bytes32 root, 25 | // bytes32 leaf, 26 | // uint16 leafId, 27 | // uint256 depth, 28 | // uint16 maxAssets 29 | // ) external pure returns (bool) { 30 | // return MerklePosAware.verify(proof, root, leaf, leafId, depth, maxAssets); 31 | // } 32 | 33 | // function getSequence(uint256 leafId, uint256 depth) external pure returns (string memory) { 34 | // return string(MerklePosAware.getSequence(leafId, depth)); 35 | // } 36 | } 37 | -------------------------------------------------------------------------------- /contracts/randomNumber/IRandomNoClient.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IRandomNoClient { 5 | /** 6 | * @notice Allows Client to register for random number 7 | * Per request a rquest id is generated, which is binded to one epoch 8 | * this epoch is current epoch if Protocol is in commit state, or epoch + 1 if in any other state 9 | * @return requestId : unique request id 10 | */ 11 | function register() external returns (bytes32); 12 | 13 | /** 14 | * @notice Allows client to pull random number once available 15 | * Random no is generated from secret of that epoch and request id, its unique per requestid 16 | * @param requestId : A unique id per request 17 | */ 18 | function getRandomNumber(bytes32 requestId) external view returns (uint256); 19 | 20 | /** 21 | * @notice Allows client to get generic random number of last epoch 22 | * @return random number 23 | */ 24 | function getGenericRandomNumberOfLastEpoch() external view returns (uint256); 25 | 26 | /** 27 | * @notice Allows client to get generic random number of any epoch 28 | * @param epoch random no of which epoch 29 | * @return random number 30 | */ 31 | function getGenericRandomNumber(uint32 epoch) external view returns (uint256); 32 | } 33 | -------------------------------------------------------------------------------- /contracts/randomNumber/IRandomNoProvider.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IRandomNoProvider { 5 | /** 6 | * @notice Called by BlockManager in ClaimBlockReward or ConfirmBlockLastEpoch 7 | * @param epoch current epoch 8 | * @param _secret hash of encoded rando secret from stakers 9 | */ 10 | function provideSecret(uint32 epoch, bytes32 _secret) external; 11 | } 12 | -------------------------------------------------------------------------------- /contracts/randomNumber/RandomNoManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | import "../Core/parameters/child/RandomNoManagerParams.sol"; 4 | import "../Core/parameters/ACL.sol"; 5 | import "./IRandomNoClient.sol"; 6 | import "./IRandomNoProvider.sol"; 7 | import "../Initializable.sol"; 8 | import "../lib/Random.sol"; 9 | import "../Core/StateManager.sol"; 10 | import "./RandomNoStorage.sol"; 11 | 12 | /** 13 | * @title : RandomNoManager 14 | * @notice : Allows clients to register for random no, and pull it once available 15 | */ 16 | 17 | contract RandomNoManager is Initializable, StateManager, RandomNoStorage, RandomNoManagerParams, IRandomNoClient, IRandomNoProvider { 18 | event RandomNumberAvailable(uint32 indexed epoch); 19 | 20 | /** 21 | * @param blockManagerAddress The address of the BlockManager Contract 22 | */ 23 | function initialize(address blockManagerAddress) external initializer onlyRole(DEFAULT_ADMIN_ROLE) { 24 | grantRole(SECRETS_MODIFIER_ROLE, blockManagerAddress); 25 | } 26 | 27 | /// @inheritdoc IRandomNoClient 28 | function register() external override initialized returns (bytes32 requestId) { 29 | uint32 epoch = getEpoch(); 30 | nonce[msg.sender] = nonce[msg.sender] + 1; 31 | requestId = keccak256(abi.encodePacked(nonce[msg.sender], msg.sender)); 32 | requests[requestId] = epoch + 1; 33 | } 34 | 35 | /// @inheritdoc IRandomNoProvider 36 | function provideSecret(uint32 epoch, bytes32 _secret) external override initialized onlyRole(SECRETS_MODIFIER_ROLE) { 37 | /// @dev this require is added for extra assurance to clients, 38 | /// to give them assurance that once secret is set for epoch, it cant be changed 39 | /// as admin could always override this SECRETS_MODIFIER_ROLE role 40 | require(secrets[epoch] == 0x0, "Secret already set"); 41 | secrets[epoch] = _secret; 42 | emit RandomNumberAvailable(epoch); 43 | } 44 | 45 | /// @inheritdoc IRandomNoClient 46 | function getRandomNumber(bytes32 requestId) external view override returns (uint256) { 47 | uint32 epochOfRequest = requests[requestId]; 48 | return _generateRandomNumber(epochOfRequest, requestId); 49 | } 50 | 51 | /// @inheritdoc IRandomNoClient 52 | function getGenericRandomNumberOfLastEpoch() external view override returns (uint256) { 53 | uint32 epoch = getEpoch(); 54 | return _generateRandomNumber(epoch - 1, 0); 55 | } 56 | 57 | /// @inheritdoc IRandomNoClient 58 | function getGenericRandomNumber(uint32 epoch) external view override returns (uint256) { 59 | return _generateRandomNumber(epoch, 0); 60 | } 61 | 62 | function _generateRandomNumber(uint32 epoch, bytes32 requestId) internal view returns (uint256) { 63 | bytes32 secret = secrets[epoch]; 64 | if (secret == 0x0) { 65 | revert("Random Number not genarated yet"); 66 | } else { 67 | return uint256(Random.prngHash(secret, requestId)); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /contracts/randomNumber/RandomNoStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | contract RandomNoStorage { 5 | /// @notice mapping of client address => nonce 6 | mapping(address => uint32) public nonce; 7 | /// @notice mapping of requestId => epoch 8 | mapping(bytes32 => uint32) public requests; 9 | /// @notice mapping of epoch => secrets 10 | mapping(uint32 => bytes32) public secrets; 11 | } 12 | -------------------------------------------------------------------------------- /contracts/tokenization/IStakedToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 6 | 7 | /** 8 | * @dev Interface of the ERC20 standard as defined in the EIP. 9 | */ 10 | interface IStakedToken is IERC20 { 11 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 12 | * the total supply. 13 | * 14 | * Emits a {Transfer} event with `from` set to the zero address. 15 | * 16 | * Requirements: 17 | * 18 | * - `account` cannot be the zero address. 19 | */ 20 | function mint( 21 | address account, 22 | uint256 amount, 23 | uint256 razorDeposited 24 | ) external returns (bool); 25 | 26 | /** 27 | * @dev Destroys `amount` tokens from `account`, reducing the 28 | * total supply. 29 | * 30 | * Emits a {Transfer} event with `to` set to the zero address. 31 | * 32 | * Requirements: 33 | * 34 | * - `account` cannot be the zero address. 35 | * - `account` must have at least `amount` tokens. 36 | */ 37 | function burn(address account, uint256 amount) external returns (bool); 38 | 39 | /// @notice Used in withdraw 40 | // At any time via calling this one can find out how much RZR was deposited for this much sRZR 41 | function getRZRDeposited(address delegator, uint256 sAmount) external view returns (uint256); 42 | } 43 | -------------------------------------------------------------------------------- /contracts/tokenization/IStakedTokenFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | interface IStakedTokenFactory { 5 | /** 6 | * @dev a factory contract where the sRZR for a new staker is being deployed 7 | * @param stakeManagerAddress address of the stake Manager contract 8 | * @param stakedID id of the staker whom the sRZR is being deployed 9 | */ 10 | function createStakedToken(address stakeManagerAddress, uint32 stakedID) external returns (address); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/tokenization/RAZOR.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | /** 7 | * @title RAZOR 8 | * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator. 9 | * Note they can later distribute these tokens as they wish using `transfer` and other 10 | * `ERC20` functions. 11 | */ 12 | 13 | contract RAZOR is ERC20 { 14 | /** 15 | * @dev Constructor that gives msg.sender all of existing tokens. 16 | */ 17 | constructor(uint256 initialSupply) ERC20("RAZOR", "RAZOR") { 18 | _mint(msg.sender, initialSupply); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/tokenization/StakedToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | import "./IStakedToken.sol"; 6 | import "../Core/interface/IStakeManager.sol"; 7 | 8 | contract StakedToken is ERC20, IStakedToken { 9 | address private _owner; 10 | uint32 public stakerID; 11 | IStakeManager public stakeManager; 12 | 13 | /** 14 | * @notice Mapping to store the amount of RZR delegated or staked by user 15 | * hence at any time we can calculate gain = (current Rel * sRZRamount) - ((razorDeposited/balOfsRZR()) * sRZRamount) 16 | * razorDeposited/balOfsRZR() indicates, for 1 sRZR, how much you had put in 17 | */ 18 | 19 | mapping(address => uint256) public razorDeposited; 20 | 21 | modifier onlyOwner() { 22 | require(_owner == msg.sender, "Ownable: caller is not the owner"); 23 | _; 24 | } 25 | 26 | /** 27 | * @dev unique ERC20 sToken contract is deployed for every new staker that stakes into the protocol 28 | * @param stakeManagerAddress address of the stake manager contract 29 | * @param _stakerID the id of staker for whom the sToken is being deployed 30 | */ 31 | constructor(address stakeManagerAddress, uint32 _stakerID) ERC20("sRZR", "sRZR") { 32 | require(stakeManagerAddress != address(0), "zero Address Check"); 33 | _owner = stakeManagerAddress; 34 | stakeManager = IStakeManager(stakeManagerAddress); 35 | stakerID = _stakerID; 36 | } 37 | 38 | /// @inheritdoc IStakedToken 39 | function mint( 40 | address account, 41 | uint256 amount, 42 | uint256 _razorDeposited 43 | ) external override onlyOwner returns (bool) { 44 | razorDeposited[account] = razorDeposited[account] + _razorDeposited; 45 | _mint(account, amount); 46 | return true; 47 | } 48 | 49 | /// @inheritdoc IStakedToken 50 | function burn(address account, uint256 amount) external override onlyOwner returns (bool) { 51 | _burn(account, amount); 52 | return true; 53 | } 54 | 55 | /// @inheritdoc IStakedToken 56 | function getRZRDeposited(address user, uint256 sAmount) public view override returns (uint256) { 57 | require(balanceOf(user) >= sAmount, "Amount Exceeds Balance"); 58 | return ((sAmount * razorDeposited[user]) / balanceOf(user)); 59 | } 60 | 61 | /** 62 | * @dev an internal function that handles the amount os razor deposited based on sRZR token transfer. 63 | * If sRZR is transferred from to another account, razor deposited should also be transferred 64 | * @param from address from where sRZR is being transferred from 65 | * @param to address where sRZR is being transferred to 66 | * @param amount amount sRZR being transferred 67 | */ 68 | function _beforeTokenTransfer( 69 | address from, 70 | address to, 71 | uint256 amount 72 | ) internal virtual override { 73 | //mint : addition, would happen in case of delegate or stake 74 | //burn : subtraction, would happeen when staker calls withdraw 75 | //transfer : add and sub 76 | 77 | // Mint case is handled up only 78 | 79 | if (to == address(0)) { 80 | //Burn 81 | uint256 propotionalRazorContribution = getRZRDeposited(from, amount); 82 | razorDeposited[from] = razorDeposited[from] - propotionalRazorContribution; 83 | } else if (from != address(0)) { 84 | uint256 propotionalRazorContribution = getRZRDeposited(from, amount); 85 | razorDeposited[from] = razorDeposited[from] - propotionalRazorContribution; 86 | razorDeposited[to] = razorDeposited[to] + propotionalRazorContribution; 87 | } 88 | 89 | stakeManager.srzrTransfer(from, to, amount, stakerID); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /contracts/tokenization/StakedTokenFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.0; 3 | 4 | import "./StakedToken.sol"; 5 | import "./IStakedTokenFactory.sol"; 6 | 7 | contract StakedTokenFactory is IStakedTokenFactory { 8 | /// @inheritdoc IStakedTokenFactory 9 | function createStakedToken(address stakeManagerAddress, uint32 stakerID) external override returns (address) { 10 | require(stakeManagerAddress != address(0x0), "zero address check"); 11 | StakedToken sToken = new StakedToken(stakeManagerAddress, stakerID); 12 | return address(sToken); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /deploy/001_deploy_governance.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH } = require('../migrations/migrationHelpers'); 2 | 3 | const deployGovernance = async () => { 4 | await deployContractHH('Governance'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployGovernance(); 9 | }; 10 | module.exports.tags = ['Governance']; 11 | -------------------------------------------------------------------------------- /deploy/002_deploy_block_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH } = require('../migrations/migrationHelpers'); 2 | 3 | const deployBlockManager = async () => { 4 | await deployContractHH('BlockManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployBlockManager(); 9 | }; 10 | module.exports.tags = ['BlockManager']; 11 | -------------------------------------------------------------------------------- /deploy/003_deploy_collection_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH } = require('../migrations/migrationHelpers'); 2 | 3 | const deployCollectionManager = async () => { 4 | await deployContractHH('CollectionManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployCollectionManager(); 9 | }; 10 | module.exports.tags = ['CollectionManager']; 11 | -------------------------------------------------------------------------------- /deploy/004_deploy_stake_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH } = require('../migrations/migrationHelpers'); 2 | 3 | const deployStakeManager = async () => { 4 | await deployContractHH('StakeManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployStakeManager(); 9 | }; 10 | module.exports.tags = ['StakeManager']; 11 | -------------------------------------------------------------------------------- /deploy/005_deploy_reward_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH } = require('../migrations/migrationHelpers'); 2 | 3 | const deployRewardManager = async () => { 4 | await deployContractHH('RewardManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployRewardManager(); 9 | }; 10 | module.exports.tags = ['RewardManager']; 11 | -------------------------------------------------------------------------------- /deploy/006_deploy_vote_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH } = require('../migrations/migrationHelpers'); 2 | 3 | const deployVoteManager = async () => { 4 | await deployContractHH('VoteManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployVoteManager(); 9 | }; 10 | module.exports.tags = ['VoteManager']; 11 | -------------------------------------------------------------------------------- /deploy/007_deploy_delegator.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH, readOldDeploymentFile, appendDeploymentFile } = require('../migrations/migrationHelpers'); 2 | 3 | const { DELEGATOR_ADDRESS } = process.env; 4 | 5 | const deployDelegator = async () => { 6 | if (DELEGATOR_ADDRESS === '' || !DELEGATOR_ADDRESS) { 7 | await deployContractHH('Delegator'); 8 | } else { 9 | const { Delegator } = await readOldDeploymentFile(); 10 | 11 | if (DELEGATOR_ADDRESS !== Delegator) { 12 | throw Error('Delegator instance address is different than what was deployed previously'); 13 | } 14 | // eslint-disable-next-line no-console 15 | console.log('Re-using Delegator instance deployed at', Delegator); 16 | await appendDeploymentFile({ Delegator }); 17 | } 18 | }; 19 | 20 | module.exports = async () => { 21 | await deployDelegator(); 22 | }; 23 | module.exports.tags = ['Delegator']; 24 | -------------------------------------------------------------------------------- /deploy/008_deploy_razor.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH, readOldDeploymentFile, appendDeploymentFile } = require('../migrations/migrationHelpers'); 2 | 3 | const { NETWORK, RAZOR_ADDRESS } = process.env; 4 | const { BigNumber } = ethers; 5 | const initialSupply = (BigNumber.from(10).pow(BigNumber.from(27))); 6 | 7 | const deployRAZOR = async () => { 8 | if (NETWORK !== 'mainnet' && RAZOR_ADDRESS === '') { 9 | await deployContractHH('RAZOR', [initialSupply]); 10 | } else { 11 | const { RAZOR } = await readOldDeploymentFile(); 12 | 13 | if (RAZOR !== RAZOR_ADDRESS) { 14 | throw Error('Razor instance address is different than that is deployed previously'); 15 | } 16 | 17 | // eslint-disable-next-line no-console 18 | console.log('Re-using Razor instance deployed at', RAZOR); 19 | await appendDeploymentFile({ RAZOR }); 20 | } 21 | }; 22 | 23 | module.exports = async () => { 24 | await deployRAZOR(); 25 | }; 26 | module.exports.tags = ['RAZOR']; 27 | -------------------------------------------------------------------------------- /deploy/009_deploy_staked_token_factory.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH } = require('../migrations/migrationHelpers'); 2 | 3 | const deployStakedTokenFactory = async () => { 4 | await deployContractHH('StakedTokenFactory'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployStakedTokenFactory(); 9 | }; 10 | module.exports.tags = ['StakedTokenFactory']; 11 | -------------------------------------------------------------------------------- /deploy/010_deploy_random_no_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH } = require('../migrations/migrationHelpers'); 2 | 3 | const deployRandomNoManager = async () => { 4 | await deployContractHH('RandomNoManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployRandomNoManager(); 9 | }; 10 | module.exports.tags = ['RandomNoManager']; 11 | -------------------------------------------------------------------------------- /deploy/011_deploy_bond_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContractHH } = require('../migrations/migrationHelpers'); 2 | 3 | const deployBondManager = async () => { 4 | await deployContractHH('BondManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployBondManager(); 9 | }; 10 | module.exports.tags = ['BondManager']; 11 | -------------------------------------------------------------------------------- /deployed/matic_mumbai_testnet/addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "Structs": "0x2E4D1a4fC693ef3af903BB46Ea098eaa9102CE3f", 3 | "Random": "0x2CCc74005be81213c9322EE56AAE2273525101c2", 4 | "Parameters": "0xcCb4043db41D6aDaFc770FBC706c9E3194524287", 5 | "BlockManager": "0x2e19aB0b134Ae1917A44C3C3338fA774cCB4c079", 6 | "AssetManager": "0xD62408a3aECD9aC97878B216979790b3C3b543c4", 7 | "StakeManager": "0x70C55e9f008f66fB67F508b02fdcac81916826e6", 8 | "RewardManager": "0x312cc7E1aAb93Bc23FD696330cDFc79410A28018", 9 | "VoteManager": "0x6e83e9C80B34eB41e8FE252c075B5713558Cc0bc", 10 | "Delegator": "0x18132674b03967F0c790e2C3D630A4bAAed76ef0", 11 | "RAZOR": "0x34A8759E4024A9A217014DB7Ee046498A16f08f0", 12 | "Faucet": "0x03844fa76b4fC2ea97ef3467122B0F15d5543EE2" 13 | } 14 | -------------------------------------------------------------------------------- /deployed/skale/addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "Governance": "0x3B055a1d062900bD50DaF21bC0816bA84e13f29A", 3 | "BlockManager": "0xEF9e5017F4d7Dc807b606C3F941ca96e17152cA1", 4 | "CollectionManager": "0xCDe8Bc40cB9FE65BFa07B80fCDf0208b4Eb188ED", 5 | "StakeManager": "0x536c79271E7F9E5E851aeA9503A1b3D2B1D57b5e", 6 | "RewardManager": "0xf75E3E1bcd70cF1bfeffA529935A8C951D8A92a6", 7 | "VoteManager": "0x1FBd5F4dE69f2802354e7db87a74356c21A4d6e5", 8 | "Delegator": "0x713f5C70cD2C8590e88bF917DF7F4Cc1eB6e821F", 9 | "RAZOR": "0xDc342De801De342EdE013C7E6e7a78Fa4f548041", 10 | "StakedTokenFactory": "0xB72acbE1Ec81BbD614bF50516cb319630cEb98D6", 11 | "RandomNoManager": "0x49d990C1236f7525D2aE06Cdb8Dd20ac796cF84B" 12 | } 13 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" # optional since v1.27.0 2 | services: 3 | contracts: 4 | build: . 5 | ports: 6 | - "8545:8545" 7 | volumes: 8 | - type: bind 9 | source: ./deployed 10 | target: /usr/src/app/deployed -------------------------------------------------------------------------------- /docker/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ENV=$1 4 | 5 | # Exit immediately if a command exits with a non-zero status. 6 | set -e 7 | 8 | cd /usr/src/app; 9 | 10 | # Copy address from previous deployment, if it exists 11 | if [[ -f "deployed/$ENV/addresses.json" ]] 12 | then 13 | cp deployed/$ENV/addresses.json .previous-deployment-addresses 14 | rm -rf deployed/$ENV 15 | fi 16 | 17 | cp .env.$ENV .env 18 | 19 | echo "Deploying contracts on network $ENV" 20 | npx hardhat --network $ENV deploy 21 | npx hardhat run migrations/postDeployment.js --network $ENV 22 | 23 | mkdir -p deployed/$ENV 24 | cp -r artifacts deployed/$ENV/abi 25 | cat .contract-deployment.tmp.json | jq '.' > deployed/$ENV/addresses.json 26 | rm -rf .contract-deployment.tmp.json 27 | 28 | if [[ -f "./.previous-deployment-addresses" ]] 29 | then 30 | rm -rf .previous-deployment-addresses 31 | fi 32 | 33 | echo "Done" 34 | -------------------------------------------------------------------------------- /docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # turn on bash's job control 4 | set -m 5 | 6 | # Start the first process 7 | /usr/local/bin/hardhat_node.sh & 8 | status=$? 9 | if [ $status -ne 0 ]; then 10 | echo "Failed to start my_first_process: $status" 11 | exit $status 12 | fi 13 | 14 | # Start the second process 15 | /usr/local/bin/deploy.sh local -D 16 | status=$? 17 | if [ $status -ne 0 ]; then 18 | echo "Failed to start my_second_process: $status" 19 | exit $status 20 | fi 21 | 22 | # Naive check runs checks once a minute to see if either of the processes exited. 23 | # This illustrates part of the heavy lifting you need to do if you want to run 24 | # more than one service in a container. The container exits with an error 25 | # if it detects that either of the processes has exited. 26 | # Otherwise it loops forever, waking up every 60 seconds 27 | 28 | while sleep 60; do 29 | ps aux |grep /usr/local/bin/hardhat_node.sh |grep -q -v grep 30 | PROCESS_STATUS=$? 31 | # If the greps above find anything, they exit with 0 status 32 | # If they are not both 0, then something is wrong 33 | if [ $PROCESS_STATUS -ne 0 ]; then 34 | echo "Hardhat Process has exited." 35 | exit 1 36 | fi 37 | done 38 | 39 | # now we bring the primary process back into the foreground 40 | # and leave it there 41 | fg %1 -------------------------------------------------------------------------------- /docker/hardhat_node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd /usr/src/app; 4 | 5 | npx hardhat node; 6 | # Keep node alive 7 | set -e 8 | if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ]; then 9 | set -- node "$@" 10 | fi 11 | 12 | exec "$@" 13 | 14 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.0.1](https://github.com/razor-network/contracts/compare/v1.0.0...v1.0.1) (2022-04-04) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * **release:** explicitly export abis before publish ([1931444](https://github.com/razor-network/contracts/commit/1931444e8ea05491c38685a81e826330748105db)) 7 | 8 | # [1.0.0](https://github.com/razor-network/contracts/compare/v0.3.0...v1.0.0) (2022-04-04) 9 | 10 | 11 | ### Bug Fixes 12 | 13 | * increase footer max line length ([26d09e7](https://github.com/razor-network/contracts/commit/26d09e79170515e5efe51282e5c4bf6ad273c1e7)) 14 | 15 | 16 | ### chore 17 | 18 | * **release:** dummy commit to trigger release ([2ecb956](https://github.com/razor-network/contracts/commit/2ecb95696b99ff09dbda7f4fbf9832dd6ea06a8a)) 19 | 20 | 21 | * Merge pull request #783 from razor-network/next ([b789199](https://github.com/razor-network/contracts/commit/b789199b162f3a763b04329a593bd2b109f81ea5)), closes [#783](https://github.com/razor-network/contracts/issues/783) 22 | 23 | 24 | ### BREAKING CHANGES 25 | 26 | * Release 27 | * **release:** Release 28 | 29 | # [0.3.0](https://github.com/razor-network/contracts/compare/v0.2.1...v0.3.0) (2022-04-04) 30 | 31 | 32 | ### Bug Fixes 33 | 34 | * clean up docgen ([#743](https://github.com/razor-network/contracts/issues/743)) ([2bba861](https://github.com/razor-network/contracts/commit/2bba86197e01a1f8873b8cc9cffdc93829fce359)) 35 | * dispute 'disputeCollectionIdShouldBePresent()' is successful if empty array is passed ([#763](https://github.com/razor-network/contracts/issues/763)) ([d029654](https://github.com/razor-network/contracts/commit/d02965414e5931a28fa4b6aa56404d33f9b84f59)) 36 | * fixed delegator migration ([#775](https://github.com/razor-network/contracts/issues/775)) ([ca349e4](https://github.com/razor-network/contracts/commit/ca349e4ce6be76d63e644414d4f13e58ee46c815)) 37 | * fixed scenarios ([#761](https://github.com/razor-network/contracts/issues/761)) ([2ec3d73](https://github.com/razor-network/contracts/commit/2ec3d73bf4792e5af1744e63cca390cdb59fb2f1)) 38 | * only propose revealed assets of epoch ([#726](https://github.com/razor-network/contracts/issues/726)) ([2c14622](https://github.com/razor-network/contracts/commit/2c1462220fcb1d9cbf9143da6e82f4ef4d242b27)) 39 | * optmized for calls in loop : slither warning ([#745](https://github.com/razor-network/contracts/issues/745)) ([b1f4236](https://github.com/razor-network/contracts/commit/b1f423648b7e3366cdb3377bcfee30f752e555f9)) 40 | * removed require statement from BlockManager ([#740](https://github.com/razor-network/contracts/issues/740)) ([af10f62](https://github.com/razor-network/contracts/commit/af10f6219662c03440d353b22106c13c19e13bec)) 41 | * stakerReward being updated properly ([#770](https://github.com/razor-network/contracts/issues/770)) ([1e19b51](https://github.com/razor-network/contracts/commit/1e19b51fe13ff9642d2970ff3e4b3ef9283209ea)) 42 | 43 | 44 | ### Features 45 | 46 | * add docgen to the project from natspec ([#731](https://github.com/razor-network/contracts/issues/731)) ([4fd81ca](https://github.com/razor-network/contracts/commit/4fd81ca7233de0f231177e42c046d5b47b7bee9c)) 47 | * added require length check in propose ([#765](https://github.com/razor-network/contracts/issues/765)) ([2535e59](https://github.com/razor-network/contracts/commit/2535e5961d34f4cbd98c9b831f0fd9d6e2de2d97)) 48 | * removed redundant roles ([#754](https://github.com/razor-network/contracts/issues/754)) ([cb79103](https://github.com/razor-network/contracts/commit/cb79103b8df851f4958b9aa467b9252f31a73f19)) 49 | * removed uncessary slither warnigns for timestamp ([#755](https://github.com/razor-network/contracts/issues/755)) ([c43731d](https://github.com/razor-network/contracts/commit/c43731d60a252a47393af070ae7687a2f4cfe5d4)) 50 | * staker can now claim commission ([#758](https://github.com/razor-network/contracts/issues/758)) ([6469129](https://github.com/razor-network/contracts/commit/64691296e5f3420cd6309e26fa17c26c31300647)) 51 | 52 | ## [0.2.1](https://github.com/razor-network/contracts/compare/v0.2.0...v0.2.1) (2022-02-23) 53 | 54 | 55 | ### Bug Fixes 56 | 57 | * disable body check on commits ([b351303](https://github.com/razor-network/contracts/commit/b35130307a7a5a6b90518d0a8ced0171ade58c1a)) 58 | * disable commit body length ([78ca858](https://github.com/razor-network/contracts/commit/78ca85807514ca904102adff743b394609c0979f)) 59 | * Fix readme ([69c008d](https://github.com/razor-network/contracts/commit/69c008de5dac294135942f5fe11352e59d14fc99)) 60 | -------------------------------------------------------------------------------- /docs/DEPLOY.md: -------------------------------------------------------------------------------- 1 | ## hardhat-deploy in a nutshell 2 | 3 | **hardhat-deploy** allows you to write `deploy scripts` in the `deploy` folder. Each of these files that look as follows will be executed in turn when you execute the following task: `hardhat --network deploy` 4 | 5 | Note: `hre.deployments.deploy` function will by default only deploy a contract if the contract code has changed, making it easier to write idempotent scripts. 6 | 7 | ### An example of a deploy script : 8 | 9 | ``` 10 | module.exports = async ({ 11 | getNamedAccounts, 12 | deployments, 13 | getChainId, 14 | getUnnamedAccounts, 15 | }) => { 16 | const {deploy} = deployments; 17 | const {deployer} = await getNamedAccounts(); 18 | 19 | // the following will only deploy "GenericMetaTxProcessor" if the contract was never deployed or if the code changed since last deployment 20 | await deploy('GenericMetaTxProcessor', { 21 | from: deployer, 22 | gasLimit: 4000000, 23 | args: [], 24 | }); 25 | }; 26 | 27 | ``` 28 | 29 | As you can see the HRE passed in has 4 new fields : 30 | 31 | - `getNamedAccounts` is a function that returns a promise to an object whose keys are names and values are addresses. It is parsed from the `namedAccounts` configuration. 32 | - `getUnnamedAccounts` is a function that return a promise to an array of accounts which were not named (see `namedAccounts` ). It is useful for tests where you want to be sure that the account has no speicifc role in the system (no token given, no admin access, etc...). 33 | - `getChainId` is a function which return a promise for the chainId, as convenience 34 | - `deployments` is an object which contains functions to access past deployments or to save new ones, as well as helpers functions. 35 | 36 | `deployments` contains for example the `deploy` function that allows you to deploy contract and save them. 37 | 38 | ### **1. namedAccounts (ability to name addresses)** 39 | 40 | --- 41 | 42 | This plugin extends the `HardhatConfig`'s object with an optional `namedAccounts` field. 43 | 44 | `namedAccounts` allows you to associate names to addresses and have them configured per chain. 45 | This allows you to have meaningful names in your tests. 46 | 47 | ``` 48 | { 49 | namedAccounts: { 50 | deployer: { 51 | default: 0, // here this will by default take the first account as deployer 52 | 1: 0, // similarly on mainnet it will take the first account as deployer. Note though that depending on how hardhat network are configured, the account 0 on one network can be different than on another 53 | 4: '0xA296a3d5F026953e17F472B497eC29a5631FB51B', // but for rinkeby it will be a specific address 54 | "goerli": '0x84b9514E013710b9dD0811c9Fe46b837a4A0d8E0', //it can also specify a specific netwotk name (specified in hardhat.config.js) 55 | }, 56 | feeCollector:{ 57 | default: 1, // here this will by default take the second account as feeCollector (so in the test this will be a different account than the deployer) 58 | 1: '0xa5610E1f289DbDe94F3428A9df22E8B518f65751', // on the mainnet the feeCollector could be a multi sig 59 | 4: '0xa250ac77360d4e837a13628bC828a2aDf7BabfB3', // on rinkeby it could be another account 60 | } 61 | } 62 | } 63 | 64 | ``` 65 | 66 | --- 67 | 68 | Furthermore you can also ensure these scripts are executed in test’s too by calling `await deployments.fixture(['MyContract'])` in your test. 69 | This is optimised, so if multiple tests use the same contract, the deployment will be executed once and each test will start with the exact same state. 70 | 71 | This is a huge benefit for testing since you are not required to replicate the deployment procedure in your tests. 72 | 73 | You can even group deploy scripts in different sub folder and ensure they are executed in their logical order. 74 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Oracle Contracts Documentation 2 | 3 | Welcome to the Oracle Contracts documentation. This documentation provides comprehensive information about the Oracle Contracts system, its architecture, and how to work with it. 4 | 5 | ## Documentation Structure 6 | 7 | ### Core Documentation 8 | - [Project Structure](project-structure.md) - Directory layout and file purposes 9 | - [Architecture Overview](architecture.md) - System design and component interactions 10 | - [Setup & Installation](setup-and-installation.md) - Environment setup and deployment steps 11 | - [API Reference](api-reference.md) - Contract interfaces and endpoints 12 | - [Data Models](data-models.md) - Data structures and schemas 13 | - [Core Concepts](core-concepts.md) - Fundamental concepts and terminology 14 | - [Contributing](contributing.md) - Development workflow and guidelines 15 | 16 | ### Detailed Guides 17 | - [Staking Guide](guides/staking.md) - Participate through staking 18 | - [Voting Guide](guides/voting.md) - Consensus participation 19 | - [Bonds Guide](guides/bonds.md) - Data bond management 20 | - [Delegation Guide](guides/delegation.md) - Delegate tokens to stakers 21 | 22 | ## Getting Started 23 | 24 | 1. **New to Oracle Contracts?** 25 | - Start with [Core Concepts](core-concepts.md) 26 | - Review the [Architecture Overview](architecture.md) 27 | - Follow the [Setup Guide](setup-and-installation.md) 28 | 29 | 2. **Want to Develop?** 30 | - Check the [Project Structure](project-structure.md) 31 | - Read the [API Reference](api-reference.md) 32 | - Follow the [Contributing Guide](contributing.md) 33 | 34 | 3. **Ready to Participate?** 35 | - Follow the [Staking Guide](guides/staking.md) 36 | - Learn about [Voting](guides/voting.md) 37 | - Understand [Delegation](guides/delegation.md) 38 | 39 | ## Quick Links 40 | 41 | - [Documentation Plan](documentation-plan.md) 42 | - [GitHub Repository](https://github.com/razor-network/oracle-contracts) 43 | - [Change Log](../CHANGELOG.md) 44 | 45 | ## Getting Help 46 | 47 | If you need help or have questions: 48 | 1. Check the [Project Structure](project-structure.md) to find relevant files 49 | 2. Review the [Core Concepts](core-concepts.md) guide 50 | 3. Consult the [API Reference](api-reference.md) 51 | 4. See the [Contributing Guide](contributing.md) for development questions 52 | 5. Open an issue on GitHub for bugs or feature requests 53 | 54 | ## Contributing to Documentation 55 | 56 | See our [Contributing Guide](contributing.md) for information about improving this documentation. 57 | 58 | ## Documentation Updates 59 | 60 | This documentation is actively maintained. For the latest updates: 61 | 1. Check the [Documentation Plan](documentation-plan.md) for upcoming changes 62 | 2. Review the [Change Log](../CHANGELOG.md) for recent updates 63 | 3. Submit improvements through pull requests 64 | -------------------------------------------------------------------------------- /docs/architecture.md: -------------------------------------------------------------------------------- 1 | # System Architecture 2 | 3 | ## Overview 4 | 5 | The Oracle Contracts system is a decentralized oracle network that enables reliable off-chain data reporting and aggregation on blockchain networks. The system uses a sophisticated architecture of smart contracts to manage data collection, stake-based validation, and reward distribution. 6 | 7 | ```mermaid 8 | graph TD 9 | A[Client Applications] --> B[Oracle Network] 10 | B --> C[Core Contracts] 11 | C --> D[Data Sources] 12 | 13 | subgraph Core Contracts 14 | E[Block Manager] 15 | F[Collection Manager] 16 | G[Stake Manager] 17 | H[Vote Manager] 18 | I[Bond Manager] 19 | J[Reward Manager] 20 | end 21 | 22 | subgraph Data Flow 23 | K[Jobs] 24 | L[Collections] 25 | M[Results] 26 | end 27 | ``` 28 | 29 | ## Core Components 30 | 31 | ### 1. Collection Management System 32 | The Collection Manager is the primary interface for data management: 33 | - **Jobs**: Individual data sources with specific URLs and parsing instructions 34 | - **Collections**: Groups of related jobs with defined aggregation methods 35 | - **Results**: Aggregated and validated data points 36 | 37 | ```mermaid 38 | graph LR 39 | A[Jobs] -->|Grouped into| B[Collections] 40 | B -->|Reported by| C[Stakers] 41 | C -->|Validated through| D[Consensus] 42 | D -->|Produces| E[Final Results] 43 | ``` 44 | 45 | ### 2. Stake Management System 46 | Manages staker participation and security: 47 | - Stake allocation and tracking 48 | - Slashing conditions 49 | - Delegation mechanisms 50 | 51 | ### 3. Block Management System 52 | Handles the epoch-based progression of the oracle: 53 | - Block confirmation process 54 | - Epoch transitions 55 | - Result finalization 56 | 57 | ```mermaid 58 | stateDiagram-v2 59 | [*] --> Commit 60 | Commit --> Reveal 61 | Reveal --> Propose 62 | Propose --> Confirm 63 | Confirm --> [*] 64 | ``` 65 | 66 | ### 4. Vote Management System 67 | Coordinates the consensus process: 68 | - Vote collection and tracking 69 | - Dispute resolution 70 | - Result finalization 71 | 72 | ### 5. Bond Management System 73 | Handles data bond management: 74 | - Collection assignments 75 | - Bond calculations 76 | - Occurrence tracking 77 | 78 | ### 6. Reward Management System 79 | Manages incentive distribution: 80 | - Block rewards 81 | - Staking rewards 82 | - Penalty management 83 | 84 | ## Data Flow 85 | 86 | ```mermaid 87 | sequenceDiagram 88 | participant Client 89 | participant Oracle 90 | participant Staker 91 | participant DataSource 92 | 93 | Client->>Oracle: Request Data 94 | Oracle->>Staker: Assign Collection 95 | Staker->>DataSource: Query Jobs 96 | DataSource->>Staker: Return Data 97 | Staker->>Oracle: Submit Results 98 | Oracle->>Oracle: Consensus Process 99 | Oracle->>Client: Return Validated Data 100 | ``` 101 | 102 | ## Security Model 103 | 104 | The system employs multiple security mechanisms: 105 | 106 | 1. **Staking**: Participants must stake tokens to participate 107 | 2. **Consensus**: Multi-stage validation process 108 | 3. **Slashing**: Penalties for malicious behavior 109 | 4. **Bonding**: Collection-specific security deposits 110 | 111 | ## Network States 112 | 113 | The oracle network operates in distinct states: 114 | 115 | ```mermaid 116 | stateDiagram-v2 117 | [*] --> Active 118 | Active --> Paused: Emergency 119 | Paused --> Active: Resolution 120 | Active --> Upgraded: Protocol Update 121 | Upgraded --> Active: Migration Complete 122 | ``` 123 | 124 | ## Smart Contract Architecture 125 | 126 | ```mermaid 127 | classDiagram 128 | class IBlockManager { 129 | +confirmPreviousEpochBlock() 130 | +getBlock() 131 | +isBlockConfirmed() 132 | } 133 | class ICollectionManager { 134 | +createCollection() 135 | +updateCollection() 136 | +setResult() 137 | +getResult() 138 | } 139 | class IStakeManager { 140 | +stake() 141 | +unstake() 142 | +delegate() 143 | } 144 | class IBondManager { 145 | +occurrenceRecalculation() 146 | +getDatabondCollections() 147 | } 148 | class IVoteManager { 149 | +vote() 150 | +reveal() 151 | +dispute() 152 | } 153 | class IRewardManager { 154 | +distributeRewards() 155 | +calculateRewards() 156 | } 157 | ``` 158 | 159 | ## Deployment Architecture 160 | 161 | The system supports deployment across multiple networks: 162 | 163 | ```mermaid 164 | graph TD 165 | A[Deployment Manager] -->|Deploy| B[Network 1] 166 | A -->|Deploy| C[Network 2] 167 | A -->|Deploy| D[Network N] 168 | 169 | subgraph Network 1 170 | B1[Core Contracts] 171 | B2[Governance] 172 | B3[Token Contracts] 173 | end 174 | ``` 175 | 176 | ## Integration Points 177 | 178 | ### External Interfaces 179 | 1. **Client Integration** 180 | - Direct contract calls 181 | - Event monitoring 182 | - Result verification 183 | 184 | 2. **Data Source Integration** 185 | - URL-based data fetching 186 | - Multiple selector types (JSON/XHTML) 187 | - Custom aggregation methods 188 | 189 | ### Internal Communication 190 | 1. **Inter-Contract Communication** 191 | - Strict access control 192 | - State synchronization 193 | - Event-based updates 194 | 195 | ## Scalability Considerations 196 | 197 | The system is designed with several scalability features: 198 | 199 | 1. **Horizontal Scaling** 200 | - Multiple collections can be processed in parallel 201 | - Independent staker operations 202 | - Distributed data sourcing 203 | 204 | 2. **Vertical Scaling** 205 | - Configurable epoch lengths 206 | - Adjustable collection parameters 207 | - Flexible aggregation methods 208 | 209 | ## Future Architecture Considerations 210 | 211 | 1. **Planned Improvements** 212 | - Layer 2 integration 213 | - Cross-chain communication 214 | - Enhanced data verification methods 215 | 216 | 2. **Expansion Areas** 217 | - Additional data source types 218 | - New consensus mechanisms 219 | - Advanced reward systems 220 | 221 | ## Related Documentation 222 | - [Setup and Installation](setup-and-installation.md) 223 | - [API Reference](api-reference.md) 224 | - [Data Models](data-models.md) 225 | - [Core Concepts](core-concepts.md) -------------------------------------------------------------------------------- /docs/core-concepts.md: -------------------------------------------------------------------------------- 1 | # Core Concepts 2 | 3 | This document explains the fundamental concepts and terminology used in the Oracle Contracts system. 4 | 5 | ## Staking System 6 | 7 | ### Staking and Delegation 8 | The system uses a Proof of Stake (PoS) consensus mechanism where participants can: 9 | 10 | 1. **Direct Staking** 11 | - Participants can stake RAZOR tokens directly 12 | - Minimum safe amount required for staking 13 | - Stakers receive sRZR (Staked RAZOR) tokens representing their stake 14 | - Stakers can run nodes and participate in oracle operations 15 | 16 | 2. **Delegation** 17 | - Users can delegate their RAZOR tokens to existing stakers 18 | - Delegators receive sRZR tokens proportional to their delegation 19 | - Stakers can set commission rates for delegation 20 | - Helps achieve decentralization without requiring everyone to run nodes 21 | 22 | ```mermaid 23 | graph TD 24 | A[RAZOR Tokens] -->|Stake| B[Direct Staking] 25 | A -->|Delegate| C[Delegation] 26 | B -->|Receive| D[sRZR Tokens] 27 | C -->|Receive| D 28 | D -->|Represent| E[Stake Position] 29 | ``` 30 | 31 | ### Stake Management 32 | The system includes sophisticated stake management features: 33 | 34 | 1. **Staking Operations** 35 | - Stake: Lock RAZOR tokens and receive sRZR 36 | - Unstake: Lock sRZR tokens for withdrawal 37 | - Withdraw: Claim unstaked RAZOR tokens 38 | - Lock periods for security 39 | 40 | 2. **Maturity and Influence** 41 | - Stakers gain maturity over time 42 | - Influence = Maturity × Stake 43 | - Higher influence means more weight in consensus 44 | 45 | ## Oracle Operations 46 | 47 | ### Data Collection System 48 | 49 | 1. **Jobs** 50 | - Individual data sources 51 | - Specific URLs and parsing instructions 52 | - Power (decimal adjustment) settings 53 | - Weight in aggregation 54 | 55 | 2. **Collections** 56 | - Groups of related jobs 57 | - Aggregation methods 58 | - Tolerance levels for deviation 59 | - Update frequency (occurrence) 60 | 61 | ```mermaid 62 | graph LR 63 | A[Jobs] -->|Group Into| B[Collections] 64 | B -->|Assigned to| C[Stakers] 65 | C -->|Report| D[Results] 66 | D -->|Validate| E[Consensus] 67 | ``` 68 | 69 | ### Consensus Mechanism 70 | 71 | The system operates in epochs with distinct states: 72 | 73 | 1. **Epoch States** 74 | ```mermaid 75 | stateDiagram-v2 76 | [*] --> Commit 77 | Commit --> Reveal 78 | Reveal --> Propose 79 | Propose --> Confirm 80 | Confirm --> [*] 81 | ``` 82 | 83 | 2. **State Functions** 84 | - Commit: Submit hashed values 85 | - Reveal: Reveal actual values 86 | - Propose: Select block proposer 87 | - Confirm: Finalize results 88 | 89 | ## Security Model 90 | 91 | ### Slashing Conditions 92 | The system enforces security through penalties: 93 | 94 | 1. **Slashing Components** 95 | - Bounty: Reward for identifying violations 96 | - Burn: Tokens removed from circulation 97 | - Keep: Tokens retained by the system 98 | 99 | 2. **Penalty Triggers** 100 | - Invalid data reporting 101 | - Malicious behavior 102 | - Inactivity 103 | - Protocol violations 104 | 105 | ```mermaid 106 | graph TD 107 | A[Violation Detected] -->|Triggers| B[Slashing] 108 | B -->|Distributes| C[Bounty] 109 | B -->|Removes| D[Burn] 110 | B -->|Retains| E[Keep] 111 | ``` 112 | 113 | ### Bond Management 114 | 115 | 1. **Data Bonds** 116 | - Collateral for data reporting 117 | - Collection-specific assignments 118 | - Occurrence tracking 119 | - Risk management 120 | 121 | 2. **Bond Calculations** 122 | - Based on stake amount 123 | - Adjusted by collection value 124 | - Influenced by reporting history 125 | 126 | ## Reward System 127 | 128 | ### Reward Distribution 129 | 130 | 1. **Types of Rewards** 131 | - Block rewards for proposers 132 | - Staking rewards for participation 133 | - Commission for delegation service 134 | - Bounties for security enforcement 135 | 136 | 2. **Distribution Factors** 137 | - Stake amount 138 | - Participation rate 139 | - Age and maturity 140 | - Commission rates 141 | 142 | ```mermaid 143 | graph TD 144 | A[Rewards] -->|Block| B[Proposers] 145 | A -->|Stake| C[Stakers] 146 | A -->|Commission| D[Delegators] 147 | A -->|Bounty| E[Enforcers] 148 | ``` 149 | 150 | ## Governance 151 | 152 | ### Parameter Management 153 | 154 | 1. **Configurable Parameters** 155 | - Minimum stake amounts 156 | - Lock periods 157 | - Commission limits 158 | - Slashing ratios 159 | - Reward rates 160 | 161 | 2. **Access Control** 162 | - Role-based permissions 163 | - Admin functions 164 | - Emergency controls 165 | - Upgrade mechanisms 166 | 167 | ## Token Economics 168 | 169 | ### RAZOR Token 170 | 171 | 1. **Utility** 172 | - Staking requirement 173 | - Transaction fees 174 | - Governance participation 175 | - Value capture 176 | 177 | 2. **sRZR Token** 178 | - Represents staked position 179 | - Transferable stake claims 180 | - Delegation tracking 181 | - Reward distribution 182 | 183 | ```mermaid 184 | graph LR 185 | A[RAZOR] -->|Stake| B[sRZR] 186 | B -->|Represents| C[Stake Position] 187 | C -->|Earns| D[Rewards] 188 | D -->|Claimed in| A 189 | ``` 190 | 191 | ## Related Documentation 192 | - [Architecture Overview](architecture.md) 193 | - [Setup Guide](setup-and-installation.md) 194 | - [API Reference](api-reference.md) 195 | - [Contributing Guidelines](contributing.md) -------------------------------------------------------------------------------- /docs/documentation-plan.md: -------------------------------------------------------------------------------- 1 | # Documentation Plan for Oracle Contracts 2 | 3 | ## Completed Tasks 4 | 5 | ### Phase 1: Project Setup & Structure ✓ 6 | 1. Create documentation directory structure 7 | - Created all core documentation files 8 | - Set up guides folder 9 | - Established consistent formatting 10 | 11 | 2. Create initial README and navigation ✓ 12 | - Main README with project overview 13 | - Documentation index for easy navigation 14 | - Cross-referencing strategy 15 | 16 | ### Phase 2: Core Architecture Documentation ✓ 17 | 1. Document System Architecture 18 | - High-level system overview 19 | - Component relationships 20 | - Core contract interactions 21 | - Mermaid diagrams for system visualization 22 | 23 | 2. Document Core Components 24 | - Block management system 25 | - Bond management system 26 | - Collection management system 27 | - Reward distribution 28 | - Stake management 29 | - Vote management 30 | - Random number generation 31 | 32 | ### Phase 3: Technical Documentation ✓ 33 | 1. API Reference Documentation 34 | - Interface documentation 35 | - Function signatures 36 | - Events documentation 37 | - Error codes 38 | 39 | 2. Data Models Documentation 40 | - Contract storage structures 41 | - State variables 42 | - Struct definitions 43 | - Relationship diagrams 44 | 45 | ### Phase 4: Process & Workflow Documentation ✓ 46 | 1. Setup & Installation Guide 47 | - Development environment setup 48 | - Dependencies and prerequisites 49 | - Build and deployment steps 50 | - Configuration options 51 | 52 | 2. Contributing Guidelines 53 | - Development workflow 54 | - Code style guidelines 55 | - Testing requirements 56 | - Pull request process 57 | 58 | ### Phase 5: Conceptual Documentation ✓ 59 | 1. Core Concepts Guide 60 | - Oracle system fundamentals 61 | - Consensus mechanism 62 | - Tokenomics 63 | - Governance model 64 | 65 | 2. User Guides 66 | - Staking guide 67 | - Voting procedures 68 | - Bond management 69 | - Delegation process 70 | 71 | ## Related Documentation 72 | - [Architecture Overview](architecture.md) 73 | - [Setup Guide](setup-and-installation.md) 74 | - [API Reference](api-reference.md) 75 | - [Core Concepts](core-concepts.md) -------------------------------------------------------------------------------- /docs/guides/delegation.md: -------------------------------------------------------------------------------- 1 | # Delegation Guide 2 | 3 | This guide explains how to participate in the Oracle Network through delegation. 4 | 5 | ## Overview 6 | 7 | Delegation allows users to participate in the network without running a node by delegating their RAZOR tokens to active stakers. Delegators earn rewards while stakers manage the operational aspects. 8 | 9 | ## Delegation Process 10 | 11 | ### 1. Prerequisites 12 | 13 | Before delegating: 14 | - Have RAZOR tokens 15 | - Research stakers 16 | - Understand commission rates 17 | - Consider lock periods 18 | 19 | ### 2. Choosing a Staker 20 | 21 | Factors to consider: 22 | - Performance history 23 | - Commission rate 24 | - Total stake 25 | - Age/maturity 26 | - Uptime record 27 | 28 | ```mermaid 29 | graph TD 30 | A[Choose Staker] --> B{Evaluation} 31 | B --> C[Performance] 32 | B --> D[Commission] 33 | B --> E[Stake Size] 34 | B --> F[Maturity] 35 | B --> G[Uptime] 36 | ``` 37 | 38 | ### 3. Delegating Tokens 39 | 40 | ```solidity 41 | function delegate(uint32 stakerId, uint256 amount) 42 | ``` 43 | 44 | Process: 45 | 1. Approve RAZOR tokens 46 | 2. Select staker 47 | 3. Specify amount 48 | 4. Execute delegation 49 | 50 | ```mermaid 51 | sequenceDiagram 52 | participant Delegator 53 | participant StakeManager 54 | participant Staker 55 | participant RAZOR 56 | 57 | Delegator->>RAZOR: Approve Tokens 58 | Delegator->>StakeManager: Delegate 59 | StakeManager->>Staker: Increase Stake 60 | StakeManager->>Delegator: Issue sRZR 61 | ``` 62 | 63 | ## Reward System 64 | 65 | ### 1. Reward Distribution 66 | 67 | How rewards work: 68 | - Staker earns rewards 69 | - Commission deducted 70 | - Remainder distributed 71 | - Based on delegation share 72 | 73 | ### 2. Commission Structure 74 | 75 | Understanding fees: 76 | - Base commission rate 77 | - Maximum limits 78 | - Update frequency 79 | - Calculation method 80 | 81 | ```mermaid 82 | graph LR 83 | A[Total Rewards] -->|Minus Commission| B[Net Rewards] 84 | B -->|Proportional| C[Delegator Share] 85 | A -->|Commission %| D[Staker Share] 86 | ``` 87 | 88 | ## Managing Delegation 89 | 90 | ### 1. Monitoring Performance 91 | 92 | Track: 93 | - Reward earnings 94 | - Staker performance 95 | - Network participation 96 | - Commission changes 97 | 98 | ### 2. Unstaking Process 99 | 100 | ```solidity 101 | function unstake(uint32 stakerId, uint256 sAmount) 102 | ``` 103 | 104 | Steps: 105 | 1. Initiate unstake 106 | 2. Wait lock period 107 | 3. Initiate withdrawal 108 | 4. Complete withdrawal 109 | 110 | ```mermaid 111 | stateDiagram-v2 112 | [*] --> Delegated 113 | Delegated --> Unstaking: Unstake 114 | Unstaking --> Withdrawing: Lock Period 115 | Withdrawing --> Withdrawn: Claim 116 | Withdrawn --> [*] 117 | ``` 118 | 119 | ## Risk Management 120 | 121 | ### 1. Staker Risks 122 | 123 | Potential issues: 124 | - Poor performance 125 | - Commission changes 126 | - Slashing events 127 | - Inactivity 128 | 129 | ### 2. Network Risks 130 | 131 | Consider: 132 | - Market conditions 133 | - Protocol changes 134 | - Technical issues 135 | - Economic factors 136 | 137 | ### 3. Mitigation Strategies 138 | 139 | Best practices: 140 | - Diversify delegations 141 | - Monitor actively 142 | - Plan exit strategy 143 | - Stay informed 144 | 145 | ## Advanced Topics 146 | 147 | ### 1. Delegation Strategy 148 | 149 | Optimization: 150 | - Timing entries 151 | - Size management 152 | - Staker selection 153 | - Exit planning 154 | 155 | ### 2. Reward Optimization 156 | 157 | Maximizing returns: 158 | - Commission comparison 159 | - Performance tracking 160 | - Compound strategy 161 | - Tax efficiency 162 | 163 | ### 3. Portfolio Management 164 | 165 | Balancing: 166 | - Risk levels 167 | - Return targets 168 | - Lock periods 169 | - Liquidity needs 170 | 171 | ## Troubleshooting 172 | 173 | ### Common Issues 174 | 175 | 1. **Delegation Problems** 176 | - Insufficient balance 177 | - Staker not accepting 178 | - Wrong parameters 179 | - Technical issues 180 | 181 | 2. **Reward Issues** 182 | - Distribution delays 183 | - Calculation errors 184 | - Commission changes 185 | - Network issues 186 | 187 | 3. **Withdrawal Problems** 188 | - Lock periods 189 | - Gas costs 190 | - Timing issues 191 | - Technical errors 192 | 193 | ## Best Practices 194 | 195 | ### 1. Due Diligence 196 | - Research stakers 197 | - Check history 198 | - Verify commission 199 | - Monitor performance 200 | 201 | ### 2. Risk Management 202 | - Start small 203 | - Diversify 204 | - Monitor regularly 205 | - Plan exits 206 | 207 | ### 3. Record Keeping 208 | - Track delegations 209 | - Monitor rewards 210 | - Document changes 211 | - Tax implications 212 | 213 | ## Tools and Resources 214 | 215 | ### 1. Analysis Tools 216 | - Staker metrics 217 | - Performance tracking 218 | - Reward calculator 219 | - Risk assessment 220 | 221 | ### 2. Monitoring Tools 222 | - Network status 223 | - Staker performance 224 | - Reward tracking 225 | - Commission changes 226 | 227 | ## Related Documentation 228 | - [Core Concepts](../core-concepts.md) 229 | - [API Reference](../api-reference.md) 230 | - [Architecture](../architecture.md) 231 | - [Staking Guide](staking.md) -------------------------------------------------------------------------------- /docs/guides/staking.md: -------------------------------------------------------------------------------- 1 | # Staking Guide 2 | 3 | This guide explains how to participate in the Oracle Network through staking RAZOR tokens. 4 | 5 | ## Overview 6 | 7 | Staking is the primary mechanism for participating in the Oracle Network. By staking RAZOR tokens, participants: 8 | - Secure the network 9 | - Earn rewards 10 | - Participate in data reporting 11 | - Gain voting rights 12 | 13 | ## Staking Process 14 | 15 | ### 1. Prerequisites 16 | 17 | Before staking, ensure you have: 18 | - RAZOR tokens in your wallet 19 | - Minimum required stake amount 20 | - ETH for transaction fees 21 | 22 | ### 2. Direct Staking 23 | 24 | ```solidity 25 | // 1. Approve RAZOR tokens 26 | IERC20(razorAddress).approve(stakeManager, amount); 27 | 28 | // 2. Stake tokens 29 | stakeManager.stake(currentEpoch, amount); 30 | ``` 31 | 32 | When you stake: 33 | 1. Your RAZOR tokens are locked in the contract 34 | 2. You receive sRZR tokens representing your stake 35 | 3. Your staker ID is assigned 36 | 4. You can start participating in oracle operations 37 | 38 | ### 3. Stake Management 39 | 40 | #### Adding More Stake 41 | ```solidity 42 | stakeManager.stake(currentEpoch, additionalAmount); 43 | ``` 44 | 45 | #### Checking Your Stake 46 | ```solidity 47 | uint256 stake = stakeManager.getStake(stakerId); 48 | uint256 influence = stakeManager.getInfluence(stakerId); 49 | ``` 50 | 51 | #### Understanding Maturity 52 | - Stake maturity increases over time 53 | - Higher maturity = more influence 54 | - Influence = Stake × Maturity 55 | - Maturity resets on penalties 56 | 57 | ## Unstaking Process 58 | 59 | ### 1. Initiate Unstake 60 | ```solidity 61 | stakeManager.unstake(stakerId, sRZRAmount); 62 | ``` 63 | 64 | ### 2. Wait Lock Period 65 | - Must wait `unstakeLockPeriod` epochs 66 | - Lock prevents quick withdrawals 67 | - Ensures network security 68 | 69 | ### 3. Initiate Withdrawal 70 | ```solidity 71 | stakeManager.initiateWithdraw(stakerId); 72 | ``` 73 | 74 | ### 4. Complete Withdrawal 75 | ```solidity 76 | stakeManager.unlockWithdraw(stakerId); 77 | ``` 78 | 79 | ## Rewards 80 | 81 | ### Types of Rewards 82 | 1. Block Rewards 83 | - For proposing valid blocks 84 | - Based on stake size 85 | 86 | 2. Reporting Rewards 87 | - For accurate data reporting 88 | - Based on participation 89 | 90 | 3. Age Rewards 91 | - For long-term staking 92 | - Based on maturity 93 | 94 | ### Claiming Rewards 95 | ```solidity 96 | stakeManager.claimStakerReward(); 97 | ``` 98 | 99 | ## Security Considerations 100 | 101 | ### 1. Slashing Conditions 102 | - Invalid data reporting 103 | - Malicious behavior 104 | - Inactivity 105 | - Protocol violations 106 | 107 | ### 2. Slashing Penalties 108 | - Loss of stake 109 | - Reset of maturity 110 | - Temporary exclusion 111 | 112 | ### 3. Best Practices 113 | - Monitor your node 114 | - Maintain uptime 115 | - Report accurately 116 | - Stay informed 117 | 118 | ## Node Operation 119 | 120 | ### 1. Setup Requirements 121 | - Reliable hardware 122 | - Stable internet 123 | - Regular maintenance 124 | - Security measures 125 | 126 | ### 2. Monitoring 127 | - Watch performance 128 | - Check rewards 129 | - Monitor slashing 130 | - Track influence 131 | 132 | ## Advanced Topics 133 | 134 | ### 1. Commission Management 135 | ```solidity 136 | // Set delegation acceptance 137 | stakeManager.setDelegationAcceptance(true); 138 | 139 | // Update commission rate 140 | stakeManager.updateCommission(newRate); 141 | ``` 142 | 143 | ### 2. Lock Extensions 144 | ```solidity 145 | // Reset unstake lock if needed 146 | stakeManager.resetUnstakeLock(stakerId); 147 | ``` 148 | 149 | ### 3. Influence Optimization 150 | - Balance stake size 151 | - Maintain uptime 152 | - Avoid penalties 153 | - Build maturity 154 | 155 | ## Troubleshooting 156 | 157 | ### Common Issues 158 | 159 | 1. **Failed Stake** 160 | - Insufficient balance 161 | - Not approved 162 | - Below minimum 163 | 164 | 2. **Failed Unstake** 165 | - Existing locks 166 | - Wrong timing 167 | - Invalid amount 168 | 169 | 3. **Failed Withdrawal** 170 | - Lock period active 171 | - Wrong timing 172 | - System paused 173 | 174 | ## Best Practices 175 | 176 | 1. **Risk Management** 177 | - Start small 178 | - Increase gradually 179 | - Monitor performance 180 | - Maintain reserves 181 | 182 | 2. **Operational Excellence** 183 | - Regular monitoring 184 | - Quick response 185 | - Stay updated 186 | - Community engagement 187 | 188 | 3. **Long-term Strategy** 189 | - Build maturity 190 | - Optimize influence 191 | - Plan upgrades 192 | - Network participation 193 | 194 | ## Related Documentation 195 | - [Core Concepts](../core-concepts.md) 196 | - [API Reference](../api-reference.md) 197 | - [Architecture](../architecture.md) -------------------------------------------------------------------------------- /docs/guides/voting.md: -------------------------------------------------------------------------------- 1 | # Voting Guide 2 | 3 | This guide explains how to participate in the Oracle Network's consensus process through voting. 4 | 5 | ## Overview 6 | 7 | The Oracle Network uses a commit-reveal voting scheme to ensure fair and tamper-resistant data reporting. Stakers participate in multiple phases: 8 | 1. Commit Phase - Submit encrypted votes 9 | 2. Reveal Phase - Reveal actual values 10 | 3. Dispute Phase - Challenge incorrect values 11 | 4. Resolution Phase - Finalize results 12 | 13 | ## Voting Process 14 | 15 | ### 1. Commit Phase 16 | 17 | During the commit phase, stakers: 18 | 1. Query assigned data sources 19 | 2. Aggregate results 20 | 3. Create a Merkle tree of values 21 | 4. Submit the Merkle root as commitment 22 | 23 | ```mermaid 24 | sequenceDiagram 25 | participant Staker 26 | participant DataSource 27 | participant Network 28 | 29 | Staker->>DataSource: Query Data 30 | DataSource->>Staker: Return Values 31 | Staker->>Staker: Aggregate Results 32 | Staker->>Staker: Build Merkle Tree 33 | Staker->>Network: Submit Commitment 34 | ``` 35 | 36 | #### Creating a Commitment 37 | ```solidity 38 | struct Commitment { 39 | uint32 epoch; 40 | bytes32 commitmentHash; 41 | } 42 | ``` 43 | 44 | Key considerations: 45 | - Use secure random salt 46 | - Include all assigned collections 47 | - Meet depth requirements 48 | - Submit within timeframe 49 | 50 | ### 2. Reveal Phase 51 | 52 | During the reveal phase, stakers: 53 | 1. Reveal original values 54 | 2. Provide Merkle proofs 55 | 3. Validate other reveals 56 | 4. Build consensus 57 | 58 | ```mermaid 59 | sequenceDiagram 60 | participant Staker 61 | participant Network 62 | participant Validators 63 | 64 | Staker->>Network: Reveal Values 65 | Staker->>Network: Submit Proofs 66 | Network->>Validators: Validate Reveals 67 | Validators->>Network: Confirm Valid 68 | ``` 69 | 70 | #### Vote Weight Calculation 71 | Vote weight depends on: 72 | - Staker's influence (stake × maturity) 73 | - Accuracy history 74 | - Participation rate 75 | - Value deviation 76 | 77 | ### 3. Dispute Phase 78 | 79 | Disputes can be raised when: 80 | - Values deviate significantly 81 | - Proofs are invalid 82 | - Rules are violated 83 | 84 | ```mermaid 85 | stateDiagram-v2 86 | [*] --> ValidReveal 87 | ValidReveal --> Disputed: Challenge 88 | Disputed --> Resolution 89 | Resolution --> Slashed: Invalid 90 | Resolution --> Confirmed: Valid 91 | ``` 92 | 93 | #### Dispute Resolution 94 | 1. Challenge submission 95 | 2. Evidence verification 96 | 3. Stake implications 97 | 4. Result adjustment 98 | 99 | ### 4. Finalization 100 | 101 | Results are finalized when: 102 | 1. Sufficient votes received 103 | 2. Consensus achieved 104 | 3. Dispute period passed 105 | 4. Block confirmed 106 | 107 | ## Best Practices 108 | 109 | ### 1. Data Collection 110 | - Use reliable data sources 111 | - Implement proper error handling 112 | - Validate input data 113 | - Handle edge cases 114 | 115 | ### 2. Vote Submission 116 | - Meet timing requirements 117 | - Verify commitments 118 | - Double-check values 119 | - Monitor gas costs 120 | 121 | ### 3. Security 122 | - Secure salt generation 123 | - Safe key management 124 | - Network monitoring 125 | - Backup procedures 126 | 127 | ## Advanced Topics 128 | 129 | ### 1. Influence Optimization 130 | - Maintain high uptime 131 | - Build maturity 132 | - Avoid slashing 133 | - Strategic staking 134 | 135 | ### 2. Merkle Tree Management 136 | ```solidity 137 | struct MerkleTree { 138 | AssignedAsset[] values; 139 | bytes32[][] proofs; 140 | bytes32 root; 141 | } 142 | ``` 143 | 144 | Key aspects: 145 | - Proper construction 146 | - Proof verification 147 | - Tree balancing 148 | - Depth requirements 149 | 150 | ### 3. Dispute Strategies 151 | When to dispute: 152 | - Clear violations 153 | - Significant deviations 154 | - Provable cases 155 | - Economic viability 156 | 157 | ## Error Handling 158 | 159 | ### Common Issues 160 | 161 | 1. **Failed Commits** 162 | - Invalid format 163 | - Wrong timing 164 | - Gas issues 165 | - Tree depth mismatch 166 | 167 | 2. **Failed Reveals** 168 | - Invalid proofs 169 | - Wrong values 170 | - Timing issues 171 | - Gas limitations 172 | 173 | 3. **Dispute Problems** 174 | - Insufficient evidence 175 | - Wrong procedure 176 | - Timing constraints 177 | - Economic factors 178 | 179 | ## Monitoring and Analytics 180 | 181 | ### 1. Performance Metrics 182 | - Vote success rate 183 | - Dispute involvement 184 | - Consensus participation 185 | - Reward efficiency 186 | 187 | ### 2. Network Statistics 188 | - Total influence 189 | - Vote distribution 190 | - Value convergence 191 | - Dispute frequency 192 | 193 | ### 3. Economic Analysis 194 | - Reward projections 195 | - Slashing risk 196 | - Gas optimization 197 | - ROI calculations 198 | 199 | ## Tools and Resources 200 | 201 | ### 1. Development Tools 202 | - Test networks 203 | - Simulation tools 204 | - Monitoring systems 205 | - Analytics platforms 206 | 207 | ### 2. Reference Materials 208 | - Technical specifications 209 | - API documentation 210 | - Example implementations 211 | - Best practices 212 | 213 | ## Related Documentation 214 | - [Core Concepts](../core-concepts.md) 215 | - [API Reference](../api-reference.md) 216 | - [Architecture](../architecture.md) 217 | - [Staking Guide](staking.md) -------------------------------------------------------------------------------- /docs/project-structure.md: -------------------------------------------------------------------------------- 1 | # Project Structure 2 | 3 | This document provides an overview of the project's directory structure and explains the purpose of key files. 4 | 5 | ## Directory Structure 6 | 7 | ``` 8 | oracle-contracts/ 9 | ├── contracts/ # Smart contract source files 10 | │ ├── Core/ # Core contract implementations 11 | │ │ ├── interface/ # Contract interfaces 12 | │ │ ├── parameters/ # Contract parameters 13 | │ │ └── storage/ # Storage contracts 14 | │ ├── lib/ # Utility libraries 15 | │ ├── mocks/ # Mock contracts for testing 16 | │ ├── randomNumber/ # Random number generation 17 | │ └── tokenization/ # Token-related contracts 18 | ├── deploy/ # Deployment scripts 19 | ├── deployed/ # Deployment addresses 20 | ├── docker/ # Docker configuration 21 | ├── migrations/ # Migration scripts 22 | ├── scenarios/ # Test scenarios 23 | ├── scripts/ # Utility scripts 24 | └── test/ # Test files 25 | ``` 26 | 27 | ## Key Files and Their Purpose 28 | 29 | ### Root Directory Files 30 | 31 | - `hardhat.config.js` - Hardhat configuration including network settings, compiler options, and task definitions 32 | - `package.json` - Project dependencies and scripts 33 | - `.env.tpl` - Template for environment variables 34 | - `.solhint.json` - Solidity linting rules 35 | - `.prettierrc` - Code formatting rules 36 | - `codechecks.yml` - Code quality checks configuration 37 | 38 | ### Contract Files 39 | 40 | #### Core Contracts 41 | 42 | ``` 43 | contracts/Core/ 44 | ├── BlockManager.sol # Manages epoch blocks and confirmations 45 | ├── BondManager.sol # Handles data bond creation and management 46 | ├── CollectionManager.sol # Manages data collections and jobs 47 | ├── RewardManager.sol # Distributes rewards to participants 48 | ├── StakeManager.sol # Handles staking and delegation 49 | └── VoteManager.sol # Manages voting and consensus 50 | ``` 51 | 52 | #### Interfaces 53 | 54 | ``` 55 | contracts/Core/interface/ 56 | ├── IBlockManager.sol # Block management interface 57 | ├── IBondManager.sol # Bond management interface 58 | ├── ICollectionManager.sol # Collection management interface 59 | ├── IRewardManager.sol # Reward distribution interface 60 | ├── IStakeManager.sol # Stake management interface 61 | └── IVoteManager.sol # Vote management interface 62 | ``` 63 | 64 | #### Parameters 65 | 66 | ``` 67 | contracts/Core/parameters/ 68 | ├── ACL.sol # Access control settings 69 | ├── Governance.sol # Governance parameters 70 | └── child/ # Individual parameter contracts 71 | ├── BlockManagerParams.sol 72 | ├── BondManagerParams.sol 73 | ├── CollectionManagerParams.sol 74 | ├── RandomNoManagerParams.sol 75 | ├── RewardManagerParams.sol 76 | ├── StakeManagerParams.sol 77 | └── VoteManagerParams.sol 78 | ``` 79 | 80 | #### Storage 81 | 82 | ``` 83 | contracts/Core/storage/ 84 | ├── BlockStorage.sol # Block-related storage 85 | ├── BondStorage.sol # Bond-related storage 86 | ├── CollectionStorage.sol # Collection-related storage 87 | ├── Constants.sol # System constants 88 | ├── StakeStorage.sol # Stake-related storage 89 | └── VoteStorage.sol # Vote-related storage 90 | ``` 91 | 92 | ### Libraries 93 | 94 | ``` 95 | contracts/lib/ 96 | ├── MerklePosAware.sol # Merkle tree utilities 97 | ├── Random.sol # Random number utilities 98 | └── Structs.sol # Common data structures 99 | ``` 100 | 101 | ### Deployment 102 | 103 | ``` 104 | deploy/ 105 | ├── 001_deploy_governance.js # Governance deployment 106 | ├── 002_deploy_block_manager.js # Block manager deployment 107 | ├── 003_deploy_collection_manager.js # Collection manager deployment 108 | └── ... # Additional deployment scripts 109 | ``` 110 | 111 | ### Testing 112 | 113 | ``` 114 | test/ 115 | ├── helpers/ # Test helper functions 116 | │ ├── constants.js # Test constants 117 | │ ├── InternalEngine.js # Test engine 118 | │ └── testSetup.js # Test setup utilities 119 | ├── ACL.js # Access control tests 120 | ├── BlockManager.js # Block manager tests 121 | └── ... # Additional test files 122 | ``` 123 | 124 | ## File Categories and Their Uses 125 | 126 | ### For Smart Contract Development 127 | - `contracts/Core/` - Main contract implementations 128 | - `contracts/Core/interface/` - Contract interfaces 129 | - `contracts/lib/` - Reusable libraries 130 | - `test/` - Contract tests 131 | 132 | ### For Deployment 133 | - `deploy/` - Deployment scripts 134 | - `deployed/` - Network addresses 135 | - `migrations/` - Migration scripts 136 | - `.env.tpl` - Environment configuration 137 | 138 | ### For Testing 139 | - `test/` - Test files 140 | - `test/helpers/` - Test utilities 141 | - `scenarios/` - Complex test scenarios 142 | 143 | ### For Development Tools 144 | - `scripts/` - Utility scripts 145 | - `docker/` - Container configuration 146 | - `.solhint.json` - Linting rules 147 | - `.prettierrc` - Formatting rules 148 | 149 | ## Common Development Workflows 150 | 151 | ### 1. Contract Development 152 | Key files: 153 | - `contracts/Core/` for implementations 154 | - `contracts/Core/interface/` for interfaces 155 | - `test/` for tests 156 | - `.solhint.json` for linting rules 157 | 158 | ### 2. Deployment Process 159 | Key files: 160 | - `deploy/` for deployment scripts 161 | - `.env` for configuration 162 | - `hardhat.config.js` for network settings 163 | - `deployed/` for addresses 164 | 165 | ### 3. Testing 166 | Key files: 167 | - `test/` for test files 168 | - `test/helpers/` for utilities 169 | - `scenarios/` for complex tests 170 | - `contracts/mocks/` for mock contracts 171 | 172 | ## Related Documentation 173 | - [Architecture Overview](architecture.md) 174 | - [Setup Guide](setup-and-installation.md) 175 | - [Contributing Guidelines](contributing.md) -------------------------------------------------------------------------------- /docs/setup-and-installation.md: -------------------------------------------------------------------------------- 1 | # Setup and Installation Guide 2 | 3 | This guide will walk you through the process of setting up the Oracle Contracts development environment and deploying the contracts to various networks. 4 | 5 | ## Prerequisites 6 | 7 | - Node.js >= 16 8 | - Git 9 | - Yarn or npm 10 | - Access to an Ethereum node (local or remote) 11 | 12 | ## Environment Setup 13 | 14 | 1. Clone the repository: 15 | ```bash 16 | git clone https://github.com/razor-network/contracts.git 17 | cd contracts 18 | ``` 19 | 20 | 2. Install dependencies: 21 | ```bash 22 | yarn install 23 | # or 24 | npm install 25 | ``` 26 | 27 | 3. Set up environment variables: 28 | ```bash 29 | cp .env.tpl .env 30 | ``` 31 | 32 | Edit `.env` with your configuration: 33 | ``` 34 | MNEMONIC=your mnemonic phrase 35 | INFURA_PROJECT_ID=your infura project id 36 | ETHERSCAN_API_KEY=your etherscan api key 37 | ``` 38 | 39 | ## Development Environment 40 | 41 | ### Local Development 42 | 43 | 1. Start a local Hardhat node: 44 | ```bash 45 | npm run start:local 46 | ``` 47 | 48 | 2. In a new terminal, deploy contracts to local network: 49 | ```bash 50 | npm run deploy 51 | ``` 52 | 53 | ### Running Tests 54 | 55 | 1. Run the full test suite: 56 | ```bash 57 | npm test 58 | ``` 59 | 60 | 2. Run specific test scenarios: 61 | ```bash 62 | npm run scenarios 63 | ``` 64 | 65 | 3. Generate coverage report: 66 | ```bash 67 | npm run coverage 68 | ``` 69 | 70 | Coverage requirements: 71 | - Statements: 90% 72 | - Branches: 60% 73 | - Functions: 85% 74 | - Lines: 86% 75 | 76 | ### Code Quality 77 | 78 | 1. Run linting: 79 | ```bash 80 | # Run all linters 81 | npm run lint 82 | 83 | # Fix linting issues 84 | npm run lint:fix 85 | 86 | # Run specific linters 87 | npm run lint:sol # Solidity files 88 | npm run lint:js # JavaScript files 89 | ``` 90 | 91 | ## Deployment 92 | 93 | ### Network Configuration 94 | 95 | The system supports deployment to multiple networks. Configure network settings in `hardhat.config.js`: 96 | 97 | ```javascript 98 | networks: { 99 | mainnet: { 100 | url: `https://mainnet.infura.io/v3/${process.env.INFURA_PROJECT_ID}`, 101 | accounts: { 102 | mnemonic: process.env.MNEMONIC 103 | } 104 | }, 105 | rinkeby: { 106 | url: `https://rinkeby.infura.io/v3/${process.env.INFURA_PROJECT_ID}`, 107 | accounts: { 108 | mnemonic: process.env.MNEMONIC 109 | } 110 | } 111 | } 112 | ``` 113 | 114 | ### Named Accounts 115 | 116 | Configure named accounts in `hardhat.config.js` for different networks: 117 | 118 | ```javascript 119 | namedAccounts: { 120 | deployer: { 121 | default: 0, 122 | 1: 0, // mainnet 123 | 4: '0xA296a3d5F026953e17F472B497eC29a5631FB51B', // rinkeby 124 | }, 125 | feeCollector: { 126 | default: 1, 127 | 1: '0xa5610E1f289DbDe94F3428A9df22E8B518f65751', // mainnet 128 | 4: '0xa250ac77360d4e837a13628bC828a2aDf7BabfB3', // rinkeby 129 | } 130 | } 131 | ``` 132 | 133 | ### Deployment Process 134 | 135 | 1. Deploy to a specific network: 136 | ```bash 137 | npx hardhat --network deploy 138 | ``` 139 | 140 | 2. Verify contracts on Etherscan: 141 | ```bash 142 | npx hardhat --network etherscan-verify 143 | ``` 144 | 145 | ### Deployment Scripts 146 | 147 | Deployment scripts in the `deploy/` folder are executed in sequence: 148 | 149 | 1. `001_deploy_governance.js` - Deploys governance contract 150 | 2. `002_deploy_block_manager.js` - Deploys block manager 151 | 3. `003_deploy_collection_manager.js` - Deploys collection manager 152 | 4. `004_deploy_stake_manager.js` - Deploys stake manager 153 | 5. `005_deploy_reward_manager.js` - Deploys reward manager 154 | 6. `006_deploy_vote_manager.js` - Deploys vote manager 155 | 7. `007_deploy_delegator.js` - Deploys delegator 156 | 8. `008_deploy_razor.js` - Deploys RAZOR token 157 | 9. `009_deploy_staked_token_factory.js` - Deploys staked token factory 158 | 10. `010_deploy_random_no_manager.js` - Deploys random number manager 159 | 11. `011_deploy_bond_manager.js` - Deploys bond manager 160 | 161 | ## Gas Analysis 162 | 163 | 1. Generate gas usage report: 164 | ```bash 165 | npm run gas 166 | ``` 167 | 168 | 2. Compare gas usage between versions: 169 | ```bash 170 | npm run gasCompare 171 | ``` 172 | 173 | ## Troubleshooting 174 | 175 | ### Common Issues 176 | 177 | 1. **Compilation Errors** 178 | - Ensure Node.js version >= 16 179 | - Clear hardhat cache: `npx hardhat clean` 180 | - Rebuild: `npm run compile` 181 | 182 | 2. **Deployment Failures** 183 | - Check network configuration 184 | - Verify account has sufficient funds 185 | - Ensure correct environment variables 186 | 187 | 3. **Test Failures** 188 | - Run with `--verbose` flag for detailed output 189 | - Check test coverage for specific components 190 | 191 | ### Support 192 | 193 | For additional support: 194 | 1. Check [GitHub Issues](https://github.com/razor-network/contracts/issues) 195 | 2. Review [Core Concepts](core-concepts.md) 196 | 3. Consult [API Reference](api-reference.md) 197 | 198 | ## Next Steps 199 | 200 | - Review [Architecture Documentation](architecture.md) 201 | - Understand [Core Concepts](core-concepts.md) 202 | - Explore [API Reference](api-reference.md) 203 | - Learn about [Contributing](contributing.md) -------------------------------------------------------------------------------- /hardhat.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | const dotenv = require('dotenv'); 3 | 4 | const dotenvResult = dotenv.config(); 5 | 6 | if (dotenvResult.error) { 7 | throw dotenvResult.error; 8 | } 9 | 10 | require('hardhat-deploy'); 11 | require('@nomiclabs/hardhat-ethers'); 12 | require('hardhat-gas-reporter'); 13 | require('solidity-coverage'); 14 | require('hardhat-abi-exporter'); 15 | require('@tenderly/hardhat-tenderly'); 16 | require('@nomiclabs/hardhat-etherscan'); 17 | require('@primitivefi/hardhat-dodoc'); 18 | 19 | const { 20 | PROVIDER_HOST, 21 | PROVIDER_PORT, 22 | PROVIDER_URL, 23 | NETWORK, 24 | MNEMONIC, 25 | CMC_KEY, 26 | ETHERSCAN_KEY, 27 | TENDERLY_SLUG, 28 | } = process.env; 29 | 30 | // Ref - https://chainid.network/chains.json 31 | const ENV_CHAIN_IDS = { 32 | mainnet: 1, 33 | goerli: 5, 34 | mumbai: 80001, 35 | skale: 132333505628089, 36 | }; 37 | 38 | module.exports = { 39 | defaultNetwork: 'hardhat', 40 | solidity: { 41 | compilers: [ 42 | { 43 | version: '0.8.4', 44 | settings: { 45 | optimizer: { 46 | enabled: true, 47 | runs: 3000, 48 | }, 49 | }, 50 | }, 51 | ], 52 | overrides: { 53 | 'contracts/Core/BlockManager.sol': { 54 | version: '0.8.4', 55 | settings: { 56 | optimizer: { 57 | enabled: true, 58 | runs: 200, 59 | }, 60 | }, 61 | }, 62 | 'contracts/Core/StakeManager.sol': { 63 | version: '0.8.4', 64 | settings: { 65 | optimizer: { 66 | enabled: true, 67 | runs: 1300, 68 | }, 69 | }, 70 | }, 71 | }, 72 | }, 73 | networks: { 74 | local: { 75 | url: `http://${PROVIDER_HOST}:${PROVIDER_PORT}`, 76 | chainId: 31337, 77 | logger: console, 78 | mining: { 79 | auto: true, 80 | interval: 2000, 81 | }, 82 | }, 83 | mumbai: { 84 | url: PROVIDER_URL || '', 85 | accounts: { mnemonic: MNEMONIC }, 86 | chainId: ENV_CHAIN_IDS[NETWORK], 87 | timeout: 300000, 88 | }, 89 | skale: { 90 | url: PROVIDER_URL || '', 91 | accounts: { mnemonic: MNEMONIC }, 92 | chainId: ENV_CHAIN_IDS[NETWORK], 93 | timeout: 300000, 94 | }, 95 | hardhat: { 96 | saveDeployments: false, 97 | }, 98 | }, 99 | etherscan: { 100 | apiKey: ETHERSCAN_KEY, 101 | }, 102 | gasReporter: { 103 | noColors: true, // Colors on terminal corrupts the output. 104 | coinmarketcap: CMC_KEY, 105 | currency: 'USD', 106 | }, 107 | abiExporter: { 108 | path: './abi', 109 | clear: true, 110 | flat: true, 111 | spacing: 2, 112 | }, 113 | tenderly: { 114 | username: 'razor', 115 | project: TENDERLY_SLUG, 116 | }, 117 | mocha: { 118 | timeout: 50000, 119 | }, 120 | dodoc: { 121 | runOnCompile: false, 122 | }, 123 | namedAccounts: { 124 | deployer: 0, 125 | tokenOwner: 1, 126 | }, 127 | paths: { 128 | sources: './contracts', 129 | }, 130 | }; 131 | -------------------------------------------------------------------------------- /migrations/postDeployment.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | const postDeploymentSetup = require('./src/postDeploymentSetup'); 3 | 4 | async function main() { 5 | await postDeploymentSetup(); 6 | } 7 | 8 | main() 9 | .then(() => process.exit(0)) 10 | .catch((error) => { 11 | console.error(error); 12 | process.exit(1); 13 | }); 14 | -------------------------------------------------------------------------------- /migrations/src/10_deploy_random_no_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContract } = require('../migrationHelpers'); 2 | 3 | const deployRandomNoManager = async () => { 4 | await deployContract('RandomNoManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployRandomNoManager(); 9 | }; 10 | -------------------------------------------------------------------------------- /migrations/src/11_deploy_bond_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContract } = require('../migrationHelpers'); 2 | 3 | const deployBondManager = async () => { 4 | await deployContract('BondManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployBondManager(); 9 | }; 10 | -------------------------------------------------------------------------------- /migrations/src/1_deploy_governance.js: -------------------------------------------------------------------------------- 1 | const { deployContract } = require('../migrationHelpers'); 2 | 3 | const deployGovernance = async () => { 4 | await deployContract('Governance'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployGovernance(); 9 | }; 10 | -------------------------------------------------------------------------------- /migrations/src/2_deploy_block_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContract } = require('../migrationHelpers'); 2 | 3 | const deployBlockManager = async () => { 4 | await deployContract('BlockManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployBlockManager(); 9 | }; 10 | -------------------------------------------------------------------------------- /migrations/src/3_deploy_collection_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContract } = require('../migrationHelpers'); 2 | 3 | const deployCollectionManager = async () => { 4 | await deployContract('CollectionManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployCollectionManager(); 9 | }; 10 | -------------------------------------------------------------------------------- /migrations/src/4_deploy_stake_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContract } = require('../migrationHelpers'); 2 | 3 | const deployStakeManager = async () => { 4 | await deployContract('StakeManager', [], []); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployStakeManager(); 9 | }; 10 | -------------------------------------------------------------------------------- /migrations/src/5_deploy_reward_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContract } = require('../migrationHelpers'); 2 | 3 | const deployRewardManager = async () => { 4 | await deployContract('RewardManager', [], []); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployRewardManager(); 9 | }; 10 | -------------------------------------------------------------------------------- /migrations/src/6_deploy_vote_manager.js: -------------------------------------------------------------------------------- 1 | const { deployContract } = require('../migrationHelpers'); 2 | 3 | const deployVoteManager = async () => { 4 | await deployContract('VoteManager'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployVoteManager(); 9 | }; 10 | -------------------------------------------------------------------------------- /migrations/src/7_deploy_delegator.js: -------------------------------------------------------------------------------- 1 | const { DELEGATOR_ADDRESS } = process.env; 2 | const { deployContract, readOldDeploymentFile, appendDeploymentFile } = require('../migrationHelpers'); 3 | 4 | const deployDelegator = async () => { 5 | if (DELEGATOR_ADDRESS === '' || !DELEGATOR_ADDRESS) { 6 | await deployContract('Delegator'); 7 | } else { 8 | const { Delegator } = await readOldDeploymentFile(); 9 | 10 | if (DELEGATOR_ADDRESS !== Delegator) { 11 | throw Error('Delegator instance address is different than that is deployed previously'); 12 | } 13 | 14 | // eslint-disable-next-line no-console 15 | console.log('Re-using Delegator instance deployed at', Delegator); 16 | await appendDeploymentFile({ Delegator }); 17 | } 18 | }; 19 | 20 | module.exports = async () => { 21 | await deployDelegator(); 22 | }; 23 | -------------------------------------------------------------------------------- /migrations/src/8_deploy_razor.js: -------------------------------------------------------------------------------- 1 | const { NETWORK, RAZOR_ADDRESS } = process.env; 2 | const { 3 | deployContract, 4 | appendDeploymentFile, 5 | readOldDeploymentFile, 6 | } = require('../migrationHelpers'); 7 | 8 | const { BigNumber } = ethers; 9 | const initialSupply = (BigNumber.from(10).pow(BigNumber.from(27))); 10 | const deployRAZOR = async () => { 11 | if (NETWORK !== 'mainnet' && RAZOR_ADDRESS === '') { 12 | await deployContract('RAZOR', [], [initialSupply]); 13 | } else { 14 | const { RAZOR } = await readOldDeploymentFile(); 15 | 16 | if (RAZOR !== RAZOR_ADDRESS) { 17 | throw Error('Razor instance address is different than that is deployed previously'); 18 | } 19 | 20 | // eslint-disable-next-line no-console 21 | console.log('Re-using Razor instance deployed at', RAZOR); 22 | await appendDeploymentFile({ RAZOR }); 23 | } 24 | }; 25 | 26 | module.exports = async () => { 27 | await deployRAZOR(); 28 | }; 29 | -------------------------------------------------------------------------------- /migrations/src/9_deploy_staked_token_factory.js: -------------------------------------------------------------------------------- 1 | const { deployContract } = require('../migrationHelpers'); 2 | 3 | const deployStakedTokenFactory = async () => { 4 | await deployContract('StakedTokenFactory'); 5 | }; 6 | 7 | module.exports = async () => { 8 | await deployStakedTokenFactory(); 9 | }; 10 | -------------------------------------------------------------------------------- /migrations/src/postDeploymentSetup.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | const { 3 | getdeployedContractInstance, 4 | readDeploymentFile, 5 | getJobs, 6 | getCollections, 7 | waitForConfirmState, 8 | postDeploymentInitialiseContracts, 9 | postDeploymentGrantRoles, 10 | } = require('../migrationHelpers'); 11 | 12 | const { BigNumber } = ethers; 13 | const { 14 | NETWORK, 15 | NETWORK_TYPE, 16 | SEED_AMOUNT, 17 | STAKER_ADDRESSES, 18 | } = process.env; 19 | 20 | module.exports = async () => { 21 | const MINING_INTERVAL = 2000; 22 | 23 | const { 24 | CollectionManager: collectionManagerAddress, 25 | StakeManager: stakeManagerAddress, 26 | RAZOR: RAZORAddress, 27 | } = await readDeploymentFile(); 28 | 29 | const { contractInstance: collectionManager } = await getdeployedContractInstance('CollectionManager', collectionManagerAddress); 30 | const { contractInstance: stakeManager } = await getdeployedContractInstance('StakeManager', stakeManagerAddress); 31 | const { contractInstance: RAZOR } = await getdeployedContractInstance('RAZOR', RAZORAddress); 32 | 33 | const pendingTransactions = []; 34 | const stakerAddressList = STAKER_ADDRESSES.split(','); 35 | 36 | // Only transfer tokens in testnets 37 | if (NETWORK_TYPE === 'TESTNET') { 38 | // Add new instance of StakeManager contract & Deployer address as Minter 39 | 40 | for (let i = 0; i < stakerAddressList.length; i++) { 41 | const tx = await RAZOR.transfer(stakerAddressList[i], SEED_AMOUNT); 42 | pendingTransactions.push(tx); 43 | } 44 | } 45 | 46 | if (NETWORK === 'local' || NETWORK === 'hardhat') { 47 | // Set interval mining to 2 seconds. This is to enable using razor-go with interval mining without affecting hardhat config. 48 | await ethers.provider.send('evm_setAutomine', [false]); 49 | await ethers.provider.send('evm_setIntervalMining', [MINING_INTERVAL]); 50 | } 51 | 52 | // Initialise Contracts and Grant Roles 53 | await postDeploymentInitialiseContracts('deploy'); 54 | await postDeploymentGrantRoles('deploy'); 55 | 56 | console.log('Waiting for post-deployment setup transactions to get confirmed'); 57 | for (let i = 0; i < pendingTransactions.length; i++) { 58 | pendingTransactions[i].wait(); 59 | } 60 | 61 | const jobs = await getJobs(); 62 | const jobsOverride = []; 63 | const collections = await getCollections(); 64 | for (let i = 0; i < jobs.length; i++) { 65 | jobsOverride.push({ 66 | id: 0, 67 | selectorType: jobs[i].selectorType, 68 | weight: jobs[i].weight, 69 | power: jobs[i].power, 70 | name: jobs[i].name, 71 | selector: jobs[i].selector, 72 | url: jobs[i].url, 73 | }); 74 | } 75 | console.log('Creating Jobs'); 76 | await collectionManager.createMulJob(jobsOverride); 77 | 78 | console.log('Creating Collections'); 79 | console.log('Waiting for Confirm state : 4.......'); 80 | const numStates = await stakeManager.NUM_STATES(); 81 | const stateLength = (BigNumber.from(await stakeManager.EPOCH_LENGTH())).div(numStates); 82 | 83 | for (let i = 0; i < collections.length; i++) { 84 | await waitForConfirmState(numStates, stateLength); 85 | collections[i].occurrence = 1; 86 | await collectionManager.createCollection( 87 | collections[i].tolerance, 88 | collections[i].power, 89 | collections[i].occurrence, 90 | collections[i].aggregationMethod, 91 | collections[i].jobIDs, 92 | collections[i].name 93 | ); 94 | console.log(`Collection Created : ${collections[i].name}`); 95 | } 96 | console.log('Contracts deployed successfully & initial setup is done'); 97 | }; 98 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@razor-network/contracts", 3 | "version": "1.0.1", 4 | "description": "These are the contracts for Razor network testnet", 5 | "author": "Razor Network", 6 | "private": false, 7 | "files": [ 8 | "abi/**/*", 9 | "contracts/**/*" 10 | ], 11 | "scripts": { 12 | "cp-ci-env": "cp .env.ci .env", 13 | "compile": "npx hardhat compile", 14 | "codechecks": "npx codechecks", 15 | "coverage": "hardhat coverage && npm run coverage:check", 16 | "coverage:check": "istanbul check-coverage --statements 90 --branches 60 --functions 85 --lines 86", 17 | "start:local": "./node_modules/.bin/hardhat node", 18 | "deploy": "./scripts/deploy.sh", 19 | "lint": "npm run lint:sol && npm run lint:js", 20 | "lint:fix": "npm run lint:js:fix && npm run lint:sol:fix", 21 | "lint:js": "eslint \"**/*.js\"", 22 | "lint:js:fix": "eslint --fix . \"**/*.js\"", 23 | "lint:sol": "solhint 'contracts/**/*.sol'", 24 | "lint:sol:fix": "prettier 'contracts/**/*.sol' -w", 25 | "test": "hardhat test", 26 | "scenarios": "hardhat test scenarios/scenarios.js", 27 | "gas": "CI=true npm run test && node scripts/gasAnalyze.js", 28 | "gasCompare": "node scripts/gasCompare.js", 29 | "postinstall": "husky install", 30 | "prepack": "pinst --disable", 31 | "postpack": "pinst --enable" 32 | }, 33 | "release": { 34 | "plugins": [ 35 | "@semantic-release/release-notes-generator", 36 | "@semantic-release/changelog", 37 | "@semantic-release/npm", 38 | "@semantic-release/git", 39 | "@semantic-release/github" 40 | ] 41 | }, 42 | "repository": { 43 | "type": "git", 44 | "url": "https://github.com/razor-network/contracts.git" 45 | }, 46 | "license": "ISC", 47 | "bugs": { 48 | "url": "https://github.com/razor-network/contracts/issues" 49 | }, 50 | "homepage": "https://github.com/razor-network/contracts#readme", 51 | "dependencies": { 52 | "@openzeppelin/contracts": "4.7.3", 53 | "@primitivefi/hardhat-dodoc": "^0.1.3", 54 | "@semantic-release/changelog": "^6.0.1", 55 | "@semantic-release/git": "^10.0.1", 56 | "fs": "^0.0.1-security", 57 | "hardhat": "^2.11.0", 58 | "hardhat-abi-exporter": "^2.3.0", 59 | "hardhat-deploy": "^0.11.4", 60 | "json-to-markdown-table": "^1.0.0", 61 | "jsonfile": "^6.1.0", 62 | "semantic-release": "^19.0.2" 63 | }, 64 | "devDependencies": { 65 | "@codechecks/client": "^0.1.11", 66 | "@commitlint/cli": "^16.2.1", 67 | "@commitlint/config-conventional": "^16.2.1", 68 | "@nomiclabs/hardhat-ethers": "^2.0.6", 69 | "@nomiclabs/hardhat-etherscan": "^2.1.6", 70 | "@tenderly/hardhat-tenderly": "^1.0.12", 71 | "axios": "^0.24.0", 72 | "chai": "^4.3.4", 73 | "coveralls": "^3.1.1", 74 | "dotenv": "10.0.0", 75 | "elliptic": "^6.5.4", 76 | "eslint": "^7.32.0", 77 | "eslint-config-airbnb-base": "^14.2.1", 78 | "eslint-config-prettier": "^8.3.0", 79 | "eslint-plugin-import": "^2.24.2", 80 | "ethers": "^5.6.8", 81 | "get-json": "^1.0.1", 82 | "hardhat-gas-reporter": "1.0.4", 83 | "husky": "^7.0.4", 84 | "pinst": "^3.0.0", 85 | "prettier": "^2.3.2", 86 | "prettier-plugin-solidity": "^1.0.0-beta.17", 87 | "solhint": "~3.3.6", 88 | "solhint-plugin-prettier": "^0.0.5", 89 | "solidity-coverage": "^0.8.0" 90 | }, 91 | "engines": { 92 | "node": ">=16" 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export $(grep -v -e '^#' -e '^MNEMONIC' .env | xargs -0) 3 | # Exit immediately if a command exits with a non-zero status. 4 | set -e 5 | echo "Starting deployment for $ENV environment" 6 | # Copy address from previous deployment, if it exists 7 | if [[ -f "deployed/$ENV/addresses.json" ]] 8 | then 9 | echo "Previous addresses" 10 | cat deployed/$ENV/addresses.json 11 | cp deployed/$ENV/addresses.json .previous-deployment-addresses 12 | rm -rf deployed/$ENV 13 | fi 14 | 15 | echo "Deploying contracts on network $NETWORK" 16 | npx hardhat --network $NETWORK deploy --show-stack-traces 17 | npx hardhat run migrations/postDeployment.js --network $NETWORK --show-stack-traces 18 | 19 | mkdir -p deployed/$ENV 20 | cp -r artifacts deployed/$ENV/abi 21 | cat .contract-deployment.tmp.json | jq '.' > deployed/$ENV/addresses.json 22 | rm -rf .contract-deployment.tmp.json 23 | 24 | if [[ -f "./.previous-deployment-addresses" ]] 25 | then 26 | rm -rf .previous-deployment-addresses 27 | fi 28 | 29 | echo "Done" 30 | -------------------------------------------------------------------------------- /scripts/gasCompare.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const markdown = require('json-to-markdown-table'); 3 | 4 | let arguments = process.argv 5 | 6 | let getFileData = (filePath) => { 7 | 8 | try{ 9 | const fileData = fs.readFileSync(filePath); 10 | const response = JSON.parse(fileData) 11 | return response.info.methods; 12 | 13 | } catch (err) { 14 | console.log(err); 15 | return 16 | } 17 | 18 | } 19 | //method to calculate maximum value 20 | 21 | let calculateMaximumValue = (numbers) => { 22 | if(numbers.length===0){ 23 | return 0 24 | } 25 | 26 | return numbers[numbers.length-1]; 27 | 28 | } 29 | let calculateMinimumValue = (numbers) => { 30 | if(numbers.length===0){ 31 | return 0 32 | } 33 | 34 | return numbers[0]; 35 | 36 | } 37 | //method to compare gas values before and after. 38 | 39 | let compareValue = (gas_usage_current,gas_usage_master) => { 40 | 41 | if(gas_usage_current === gas_usage_master){ 42 | return 0 //no change ; 43 | } 44 | else{ 45 | return ((gas_usage_current-gas_usage_master)/gas_usage_master)*100 46 | 47 | } 48 | } 49 | // method to compare the gas Consumption. 50 | 51 | let gasCompare = async () => { 52 | let coloumn = ['Contract','Method','Current(Maximum)','Master(Maximum)','Change%(Maximum)','Diff(Maximum)','Current(Minimum)','Master(Minimum)','Diff(Minimum)','Change%(Minimum)']; 53 | let gasChangeData = []; 54 | const gasDataI = getFileData(arguments[2]); 55 | const gasDataII = getFileData(arguments[3]); 56 | for(i in gasDataI){ 57 | if(i in gasDataII){ 58 | let changeMaximum = compareValue(calculateMaximumValue(gasDataI[i].gasData),calculateMaximumValue(gasDataII[i].gasData)); 59 | let changeMinimum = compareValue(calculateMinimumValue(gasDataI[i].gasData),calculateMinimumValue(gasDataII[i].gasData)); 60 | let diffMaximum = calculateMaximumValue(gasDataI[i].gasData)-calculateMaximumValue(gasDataII[i].gasData); 61 | let diffMinimum = calculateMinimumValue(gasDataI[i].gasData)-calculateMinimumValue(gasDataII[i].gasData); 62 | if(calculateMaximumValue(gasDataI[i].gasData) && changeMaximum!=0) 63 | { 64 | let obj = {'Contract': gasDataI[i].contract, 65 | 'Method':gasDataI[i].method, 66 | 'Current(Maximum)':calculateMaximumValue(gasDataI[i].gasData), 67 | 'Master(Maximum)' :calculateMaximumValue(gasDataII[i].gasData), 68 | 'Change%(Maximum)': changeMaximum > 0 ? '+' + changeMaximum.toFixed(2).toString() :'-' + Math.abs(changeMaximum.toFixed(2)), 69 | 'Diff(Maximum)' : diffMaximum > 0 ? '+' + diffMaximum.toFixed(2).toString() :'-' + Math.abs(diffMaximum.toFixed(2)), 70 | 'Current(Minimum)':calculateMinimumValue(gasDataI[i].gasData), 71 | 'Master(Minimum)' :calculateMinimumValue(gasDataII[i].gasData), 72 | 'Diff(Minimum)' : diffMinimum > 0 ? '+' + diffMinimum.toFixed(2).toString() :'-' + Math.abs(diffMinimum.toFixed(2)), 73 | 'Change%(Minimum)':changeMinimum > 0 ? '+' + changeMinimum.toFixed(2).toString() :'-' + Math.abs(changeMinimum.toFixed(2)), 74 | } 75 | gasChangeData.push(obj); 76 | } 77 | } 78 | } 79 | 80 | let markdownString = markdown(gasChangeData, coloumn); 81 | 82 | if (gasChangeData.length !== 0) { 83 | // Write the markdown to a file called gasCompareOutput.json 84 | fs.writeFileSync('gasCompareOutput.md', markdownString); 85 | } else { 86 | console.log("No changes found in gas Consumption"); 87 | } 88 | } 89 | 90 | gasCompare(); 91 | -------------------------------------------------------------------------------- /slither.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "detectors_to_exclude": "solc-version,conformance-to-solidity-naming-conventions", 3 | "filter_paths": "node_modules" 4 | } 5 | -------------------------------------------------------------------------------- /tenderly.yaml: -------------------------------------------------------------------------------- 1 | account_id: "" 2 | exports: 3 | hardhat: 4 | project_slug: razor/razor-network 5 | rpc_address: 127.0.0.1:8545 6 | protocol: "" 7 | forked_network: "" 8 | chain_config: 9 | homestead_block: 0 10 | eip150_block: 0 11 | eip150_hash: "0x0000000000000000000000000000000000000000000000000000000000000000" 12 | eip155_block: 0 13 | eip158_block: 0 14 | byzantium_block: 0 15 | constantinople_block: 0 16 | petersburg_block: 0 17 | istanbul_block: 0 18 | berlin_block: 0 19 | localhost: 20 | chain_config: 21 | berlin_block: 0 22 | byzantium_block: 0 23 | constantinople_block: 0 24 | eip150_block: 0 25 | eip150_hash: "0x0000000000000000000000000000000000000000000000000000000000000000" 26 | eip155_block: 0 27 | eip158_block: 0 28 | homestead_block: 0 29 | istanbul_block: 0 30 | petersburg_block: 0 31 | forked_network: "" 32 | project_slug: razor/razor-network 33 | protocol: "" 34 | rpc_address: 127.0.0.1:8545 35 | project_slug: "" 36 | -------------------------------------------------------------------------------- /test/Initializable.js: -------------------------------------------------------------------------------- 1 | const { assert } = require('chai'); 2 | const { 3 | assertRevert, 4 | } = require('./helpers/testHelpers'); 5 | 6 | let mock; 7 | 8 | describe('Initializable', function () { 9 | beforeEach('deploying', async function () { 10 | const InitializableMock = await ethers.getContractFactory('InitializableMock'); 11 | mock = await InitializableMock.deploy(); 12 | }); 13 | 14 | it('initializer has not run', async function () { 15 | assert.isFalse(await mock.initializerRan()); 16 | }); 17 | 18 | it('initializer has run', async function () { 19 | await mock.initialize(); 20 | assert.isTrue(await mock.initializerRan()); 21 | }); 22 | 23 | it('initializer does not run again', async function () { 24 | await mock.initialize(); 25 | await assertRevert(mock.initialize(), 'contract already initialized'); 26 | }); 27 | 28 | it('initializer has run after nested initialization', async function () { 29 | await mock.initializeNested(); 30 | assert.isTrue(await mock.initializerRan()); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /test/MerklePosAware.spec.js: -------------------------------------------------------------------------------- 1 | const { expect, assert } = require('chai'); 2 | const { createMerkle, getProofPath } = require('./helpers/MerklePosAware'); 3 | 4 | describe('Unit tests', function () { 5 | let Merkle; 6 | 7 | before(async function () { 8 | // const Governance = await ethers.getContractFactory('Governance'); 9 | Merkle = (await ( 10 | await ethers.getContractFactory('MerklePosAwareTest') 11 | ).deploy()); 12 | }); 13 | 14 | describe('MerklePosAware', function () { 15 | it('Tree from 1 nodes to 11 nodes', async function () { 16 | const maxNodes = 11; 17 | const votes = []; 18 | const randomHash = '0x26700e13983fefbd9cf16da2ed70fa5c679beb55062a4803121a869731e308d2'; 19 | for (let i = 1; i <= maxNodes; i++) { 20 | votes.push(i * 100); 21 | } 22 | for (let i = 1; i <= maxNodes; i++) { 23 | const votesThisItr = votes.slice(0, i); 24 | const tree = await createMerkle(votesThisItr); 25 | const proofs = []; 26 | const leafId = []; 27 | const leaves = []; 28 | const depth = Math.ceil(Math.log2(i)); 29 | for (let j = 0; j < i; j++) { 30 | const tree = await createMerkle(votesThisItr); 31 | proofs.push(await getProofPath(tree, j)); 32 | leaves.push(ethers.utils.solidityKeccak256(['uint256'], [votes[j]])); 33 | leafId.push(j); 34 | } 35 | // console.log('asdasd', proofs, tree[0][0], leaves, medianIndex, depth); 36 | expect(await Merkle.verifyMultiple(proofs, randomHash, leaves, leafId, depth, i)).to.be.false; 37 | expect(await Merkle.verifyMultiple(proofs, tree[0][0], leaves, leafId, depth, i)).to.be.true; 38 | } 39 | }); 40 | it('Tests for getSequence', async function () { 41 | const maxNodes = 100; 42 | for (let i = 2; i <= maxNodes; i++) { 43 | const depth = Math.ceil(Math.log2(i)); 44 | for (let j = 0; j < i; j++) { 45 | let output = ''; 46 | let leafId = j; 47 | for (let k = 0; k < depth; k++) { 48 | if (leafId % 2 === 1) { 49 | output = `1${output}`; 50 | } else { 51 | output = `0${output}`; 52 | } 53 | leafId = Math.floor(leafId / 2); 54 | } 55 | const asciiOutput = String(await Merkle.getSequence(j, depth)); 56 | let binary = ''; 57 | const arr = asciiOutput.split('3'); 58 | for (let k = 1; k < arr.length; k++) { 59 | binary += arr[k]; 60 | } 61 | assert(binary === output, 'incorrect sequence'); 62 | } 63 | } 64 | }).timeout(400000); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /test/helpers/MerklePosAware.js: -------------------------------------------------------------------------------- 1 | const { utils } = require('ethers'); 2 | 3 | const createMerkle = async (values) => { 4 | let tree = []; 5 | const leafs = []; 6 | // Hash all values 7 | for (let i = 0; i < values.length; i++) { 8 | leafs.push(utils.solidityKeccak256(['uint256'], [values[i]])); 9 | } 10 | 11 | let level = leafs; 12 | let nextLevel = []; 13 | tree.push(level); 14 | 15 | while (level.length !== 1) { 16 | for (let i = 0; i < level.length; i += 2) { 17 | if (i + 1 < level.length) { 18 | nextLevel.push(utils.solidityKeccak256(['bytes32', 'bytes32'], [level[i], level[i + 1]])); 19 | } else nextLevel.push(level[i]); 20 | } 21 | level = nextLevel; 22 | tree.push(level); 23 | nextLevel = []; 24 | } 25 | tree = tree.reverse(); 26 | return tree; 27 | }; 28 | 29 | const getProofPath = async (tree, leafId) => { 30 | let index = leafId; 31 | const compactProofPath = []; 32 | for (let currentLevel = tree.length - 1; currentLevel > 0; currentLevel--) { 33 | const currentLevelNodes = tree[currentLevel]; 34 | const currentLevelCount = currentLevelNodes.length; 35 | 36 | // if this is an odd end node to be promoted up, skip to avoid proofs with null values 37 | if (index === currentLevelCount - 1 && currentLevelCount % 2 === 1) { 38 | index = Math.floor(index / 2); 39 | // eslint-disable-next-line no-continue 40 | continue; 41 | } 42 | 43 | const nodes = { left: '0', right: '0' }; 44 | if (index % 2) { 45 | // the index is the right node 46 | nodes.left = currentLevelNodes[index - 1]; 47 | nodes.right = currentLevelNodes[index]; 48 | compactProofPath.push(nodes.left); 49 | } else { 50 | nodes.left = currentLevelNodes[index]; 51 | nodes.right = currentLevelNodes[index + 1]; 52 | compactProofPath.push(nodes.right); 53 | } 54 | 55 | index = Math.floor(index / 2); // set index to the parent index 56 | } 57 | return compactProofPath; 58 | }; 59 | 60 | module.exports = { 61 | createMerkle, 62 | getProofPath, 63 | }; 64 | -------------------------------------------------------------------------------- /test/helpers/constants.js: -------------------------------------------------------------------------------- 1 | const { BigNumber } = ethers; 2 | 3 | const DEFAULT_ADMIN_ROLE_HASH = '0x0000000000000000000000000000000000000000000000000000000000000000'; 4 | const ONE_ETHER = BigNumber.from(10).pow(BigNumber.from(18)); 5 | 6 | const EPOCH_LENGTH = BigNumber.from(1200); 7 | const BASE_DENOMINATOR = BigNumber.from(10000000); 8 | const NUM_BLOCKS = 10; 9 | const NUM_STATES = BigNumber.from(5); 10 | const STATE_LENGTH = BigNumber.from(240); 11 | const GRACE_PERIOD = 0; 12 | const UNSTAKE_LOCK_PERIOD = 1; 13 | const WITHDRAW_LOCK_PERIOD = 1; 14 | const WITHDRAW_INITIATION_PERIOD = 5; 15 | const MATURITIES = [50, 70, 86, 100, 111, 122, 132, 141, 150, 158, 16 | 165, 173, 180, 187, 193, 200, 206, 212, 217, 223, 17 | 229, 234, 239, 244, 250, 254, 259, 264, 269, 273, 18 | 278, 282, 287, 291, 295, 300, 304, 308, 312, 316, 19 | 320, 324, 327, 331, 335, 339, 342, 346, 350, 353, 20 | 357, 360, 364, 367, 370, 374, 377, 380, 384, 387, 21 | 390, 393, 396, 400, 403, 406, 409, 412, 415, 418, 22 | 421, 424, 427, 430, 433, 435, 438, 441, 444, 447, 23 | 450, 452, 455, 458, 460, 463, 466, 469, 471, 474, 24 | 476, 479, 482, 484, 487, 489, 492, 494, 497]; 25 | 26 | // keccak256("BLOCK_CONFIRMER_ROLE") 27 | const BLOCK_CONFIRMER_ROLE = '0x18797bc7973e1dadee1895be2f1003818e30eae3b0e7a01eb9b2e66f3ea2771f'; 28 | 29 | // keccak256("STAKE_MODIFIER_ROLE") 30 | const STAKE_MODIFIER_ROLE = '0xdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc804'; 31 | 32 | // keccak256("REWARD_MODIFIER_ROLE") 33 | const REWARD_MODIFIER_ROLE = '0xcabcaf259dd9a27f23bd8a92bacd65983c2ebf027c853f89f941715905271a8d'; 34 | 35 | // keccak256("COLLECTION_MODIFIER_ROLE") 36 | const COLLECTION_MODIFIER_ROLE = '0xa3a75e7cd2b78fcc3ae2046ab93bfa4ac0b87ed7ea56646a312cbcb73eabd294'; 37 | 38 | // keccak256("VOTE_MODIFIER_ROLE") 39 | const VOTE_MODIFIER_ROLE = '0x912208965b92edeb3eb82a612c87b38b5e844f7539cb396f0d08ec012e511b07'; 40 | 41 | // keccak256("DELEGATOR_MODIFIER_ROLE") 42 | const DELEGATOR_MODIFIER_ROLE = '0x6b7da7a33355c6e035439beb2ac6a052f1558db73f08690b1c9ef5a4e8389597'; 43 | 44 | // keccak256("REGISTRY_MODIFIER_ROLE") 45 | const REGISTRY_MODIFIER_ROLE = '0xca51085219bef34771da292cb24ee4fcf0ae6bdba1a62c17d1fb7d58be802883'; 46 | 47 | // keccak256("GOVERNER_ROLE") 48 | const GOVERNER_ROLE = '0x704c992d358ec8f6051d88e5bd9f92457afedcbc3e2d110fcd019b5eda48e52e'; 49 | 50 | // keccak256("GOVERNANCE_ROLE") 51 | const GOVERNANCE_ROLE = '0x71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1'; 52 | 53 | // keccak256("PAUSE_ROLE") 54 | const PAUSE_ROLE = '0x139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d'; 55 | 56 | // keccak256("SALT_MODIFER_ROLE") 57 | const SALT_MODIFIER_ROLE = '0xf31dda80d37c96a1a0852ace387dda52a75487d7d4eb74895e749ede3e0987b4'; 58 | 59 | // keccak256("SECRETS_MODIFIER_ROLE") 60 | const SECRETS_MODIFIER_ROLE = '0x46aaf8a125792dfff6db03d74f94fe1acaf55c8cab22f65297c15809c364465c'; 61 | 62 | // keccak256("DEPTH_MODIFIER_ROLE") 63 | const DEPTH_MODIFIER_ROLE = '0x91f5d9ea80c4d04985e669bc72870410b28b57afdf61c0d50d377766d86a3748'; 64 | 65 | const ESCAPE_HATCH_ROLE = '0x518d8c39717318f051dfb836a4ebe5b3c34aa2cb7fce26c21a89745422ba8043'; 66 | 67 | // keccak256("STOKEN_ROLE") 68 | const STOKEN_ROLE = '0xce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc'; 69 | 70 | // keccak256("OCCURRENCE_MODIFIER_ROLE") 71 | const OCCURRENCE_MODIFIER_ROLE = '0x35ed6c1cb451e31b9dd4f1d325602da07694e1747843e6b55ab1527fd8835fb5'; 72 | 73 | // keccak256("RESET_DATABOND_ROLE") 74 | const RESET_DATABOND_ROLE = '0x3e99a7fb3946972656cbde0e63ef530dd7750472272e07c65aa9f473a99f5c5d'; 75 | 76 | // keccak256("COLLECTION_CONFIRMER_ROLE") 77 | const COLLECTION_CONFIRMER_ROLE = '0xa1d2ec18e7ea6241ef0566da3d2bc59cc059592990e56680abdc7031155a0c28'; 78 | 79 | const BURN_ADDRESS = '0x000000000000000000000000000000000000dEaD'; 80 | 81 | const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; 82 | 83 | module.exports = { 84 | DEFAULT_ADMIN_ROLE_HASH, 85 | BLOCK_CONFIRMER_ROLE, 86 | STAKE_MODIFIER_ROLE, 87 | SECRETS_MODIFIER_ROLE, 88 | REWARD_MODIFIER_ROLE, 89 | COLLECTION_MODIFIER_ROLE, 90 | VOTE_MODIFIER_ROLE, 91 | DELEGATOR_MODIFIER_ROLE, 92 | REGISTRY_MODIFIER_ROLE, 93 | GOVERNER_ROLE, 94 | SALT_MODIFIER_ROLE, 95 | DEPTH_MODIFIER_ROLE, 96 | BASE_DENOMINATOR, 97 | GOVERNANCE_ROLE, 98 | PAUSE_ROLE, 99 | EPOCH_LENGTH, 100 | NUM_BLOCKS, 101 | NUM_STATES, 102 | ONE_ETHER, 103 | STATE_LENGTH, 104 | GRACE_PERIOD, 105 | UNSTAKE_LOCK_PERIOD, 106 | WITHDRAW_LOCK_PERIOD, 107 | WITHDRAW_INITIATION_PERIOD, 108 | ESCAPE_HATCH_ROLE, 109 | OCCURRENCE_MODIFIER_ROLE, 110 | RESET_DATABOND_ROLE, 111 | COLLECTION_CONFIRMER_ROLE, 112 | MATURITIES, 113 | ZERO_ADDRESS, 114 | BURN_ADDRESS, 115 | STOKEN_ROLE, 116 | }; 117 | -------------------------------------------------------------------------------- /test/helpers/testHelpers.js: -------------------------------------------------------------------------------- 1 | const { assert } = require('chai'); 2 | const { BigNumber } = require('ethers'); 3 | const { ethers } = require('hardhat'); 4 | const { EPOCH_LENGTH, STATE_LENGTH } = require('./constants'); 5 | const { getEpoch, toBigNumber } = require('./utils'); 6 | 7 | /** 8 | * Function to assert that two BigNumber instances are equal. 9 | * @param actualBN BigNumber amount you received 10 | * @param expectedBN BigNumber amount you expected to receive 11 | * @param log Log reason if we fail the assertion 12 | */ 13 | const assertBNEqual = (actualBN, expectedBN, log) => { 14 | assert.strictEqual(actualBN.toString(), expectedBN.toString(), log); 15 | }; 16 | 17 | /** 18 | * Function to assert that the firstBN parameter is less than secondBN parameter 19 | * @param lesserBN smaller BigNumber amount 20 | * @param greaterBN greater BigNumber amount 21 | */ 22 | const assertBNLessThan = (lesserBN, greaterBN) => { 23 | assert.ok(lesserBN.lt(greaterBN), `${lesserBN.toString()} is not less than ${greaterBN.toString()}`); 24 | }; 25 | 26 | /** 27 | * Convenience method to assert that two BigNumber instances are NOT equal. 28 | * @param actualBN The BigNumber instance you received 29 | * @param expectedBN The BigNumber amount you expected NOT to receive 30 | * @param log Log reason if we fail the assertion 31 | */ 32 | const assertBNNotEqual = (actualBN, expectedBN, log) => { 33 | assert.notStrictEqual(actualBN.toString(), expectedBN.toString(), log); 34 | }; 35 | 36 | /** 37 | * Function to check if two arrays/objects which contain nested BigNumber are equal. 38 | * @param actual What you received 39 | * @param expected The shape you expected 40 | */ 41 | const assertDeepEqual = (actual, expected, context) => { 42 | // Check if it's a value type we can assert on straight away. 43 | if (BigNumber.isBigNumber(actual) || BigNumber.isBigNumber(expected)) { 44 | assertBNEqual(actual, expected, context); 45 | } else if ( 46 | typeof expected === 'string' 47 | || typeof actual === 'string' 48 | || typeof expected === 'number' 49 | || typeof actual === 'number' 50 | || typeof expected === 'boolean' 51 | || typeof actual === 'boolean' 52 | ) { 53 | assert.strictEqual(actual, expected, context); 54 | } else if (Array.isArray(expected)) { 55 | // Otherwise dig through the deeper object and recurse 56 | for (let i = 0; i < expected.length; i++) { 57 | assertDeepEqual(actual[i], expected[i], `(array index: ${i}) `); 58 | } 59 | } else { 60 | for (const key of Object.keys(expected)) { 61 | assertDeepEqual(actual[key], expected[key], `(key: ${key}) `); 62 | } 63 | } 64 | }; 65 | 66 | /** 67 | * Function to check whether transaction is getting reverted with reason as expected. 68 | * @param promise Transaction promise 69 | * @param reason Reason for revert 70 | */ 71 | const assertRevert = async (promise, reason) => { 72 | let errorEncountered = false; 73 | try { 74 | await promise; 75 | } catch (error) { 76 | assert.include(error.message, 'revert'); 77 | if (reason) { 78 | assert.include(error.message, reason); 79 | } 80 | errorEncountered = true; 81 | } 82 | assert.strictEqual(errorEncountered, true, 'Transaction did not revert as expected'); 83 | }; 84 | 85 | const waitNBlocks = async (n) => { 86 | await Promise.all( 87 | [...Array(n).keys()].map(() => ethers.provider.send('evm_mine')) 88 | ); 89 | }; 90 | 91 | const mineAdvance = async (n) => { 92 | n = toBigNumber(n); 93 | const blockNumber = toBigNumber(await ethers.provider.getBlockNumber()); 94 | if (n.gt(blockNumber)) { 95 | const diff = n.sub(blockNumber); 96 | await waitNBlocks(diff.toNumber()); 97 | } 98 | }; 99 | 100 | const mineBlock = () => ethers.provider.send('evm_mine'); 101 | 102 | // Mines to the next Epoch from which ever block it is in the current Epoch 103 | const mineToNextEpoch = async () => { 104 | const currentBlockNumber = await ethers.provider.getBlockNumber(); 105 | const currentBlock = await ethers.provider.getBlock(currentBlockNumber); 106 | const currentTimestamp = currentBlock.timestamp; 107 | const currentEpoch = await getEpoch(); 108 | const nextEpochBlockTimestamp = (currentEpoch + 1) * EPOCH_LENGTH.toNumber(); // currentBlocktimestamp + epochLength 109 | const diff = nextEpochBlockTimestamp - currentTimestamp; 110 | await ethers.provider.send('evm_increaseTime', [diff + 5]); 111 | await ethers.provider.send('evm_mine'); 112 | }; 113 | 114 | // Mines to the next state in the current epoch 115 | const mineToNextState = async () => { 116 | const currentBlockNumber = await ethers.provider.getBlockNumber(); 117 | const currentBlock = await ethers.provider.getBlock(currentBlockNumber); 118 | const currentTimestamp = toBigNumber(currentBlock.timestamp); 119 | const temp = currentTimestamp.div(STATE_LENGTH).add('1'); 120 | const nextStateBlockNum = temp.mul(STATE_LENGTH); 121 | const diff = nextStateBlockNum.sub(currentTimestamp); 122 | await ethers.provider.send('evm_increaseTime', [diff.toNumber() + 5]); 123 | await ethers.provider.send('evm_mine'); 124 | }; 125 | 126 | const restoreSnapshot = async (id) => { 127 | await ethers.provider.send('evm_revert', [id]); 128 | await mineBlock(); 129 | }; 130 | 131 | const takeSnapshot = async () => { 132 | const result = await ethers.provider.send('evm_snapshot'); 133 | 134 | await mineBlock(); 135 | 136 | return result; 137 | }; 138 | 139 | module.exports = { 140 | assertRevert, 141 | assertDeepEqual, 142 | assertBNEqual, 143 | assertBNLessThan, 144 | assertBNNotEqual, 145 | waitNBlocks, 146 | mineAdvance, 147 | mineBlock, 148 | mineToNextEpoch, 149 | mineToNextState, 150 | takeSnapshot, 151 | restoreSnapshot, 152 | }; 153 | -------------------------------------------------------------------------------- /test/helpers/testSetup.js: -------------------------------------------------------------------------------- 1 | const { BigNumber } = ethers; 2 | const initialSupply = (BigNumber.from(10).pow(BigNumber.from(27))); 3 | const { 4 | BLOCK_CONFIRMER_ROLE, 5 | STAKE_MODIFIER_ROLE, 6 | REWARD_MODIFIER_ROLE, 7 | REGISTRY_MODIFIER_ROLE, 8 | GOVERNANCE_ROLE, 9 | PAUSE_ROLE, 10 | SALT_MODIFIER_ROLE, 11 | DEPTH_MODIFIER_ROLE, 12 | ESCAPE_HATCH_ROLE, 13 | RESET_DATABOND_ROLE, 14 | OCCURRENCE_MODIFIER_ROLE, 15 | COLLECTION_CONFIRMER_ROLE, 16 | COLLECTION_MODIFIER_ROLE, 17 | } = require('./constants'); 18 | 19 | const setupContracts = async () => { 20 | const Governance = await ethers.getContractFactory('Governance'); 21 | const BlockManager = await ethers.getContractFactory('BlockManager'); 22 | const BondManager = await ethers.getContractFactory('BondManager'); 23 | const RandomNoManager = await ethers.getContractFactory('RandomNoManager'); 24 | const Delegator = await ethers.getContractFactory('Delegator'); 25 | const CollectionManager = await ethers.getContractFactory('CollectionManager'); 26 | const RAZOR = await ethers.getContractFactory('RAZOR'); 27 | const StakeManager = await ethers.getContractFactory('StakeManager'); 28 | const RewardManager = await ethers.getContractFactory('RewardManager'); 29 | const VoteManager = await ethers.getContractFactory('VoteManager'); 30 | const StakedTokenFactory = await ethers.getContractFactory('StakedTokenFactory'); 31 | const signers = await ethers.getSigners(); 32 | 33 | const governance = await Governance.deploy(); 34 | const blockManager = await BlockManager.deploy(); 35 | const bondManager = await BondManager.deploy(); 36 | const stakedToken = await ethers.getContractFactory('StakedToken'); 37 | const delegator = await Delegator.deploy(); 38 | const collectionManager = await CollectionManager.deploy(); 39 | const stakeManager = await StakeManager.deploy(); 40 | const rewardManager = await RewardManager.deploy(); 41 | const voteManager = await VoteManager.deploy(); 42 | const razor = await RAZOR.deploy(initialSupply); 43 | const stakedTokenFactory = await StakedTokenFactory.deploy(); 44 | const randomNoManager = await RandomNoManager.deploy(); 45 | 46 | await governance.deployed(); 47 | await blockManager.deployed(); 48 | await bondManager.deployed(); 49 | await delegator.deployed(); 50 | await collectionManager.deployed(); 51 | await razor.deployed(); 52 | await stakedTokenFactory.deployed(); 53 | await stakeManager.deployed(); 54 | await rewardManager.deployed(); 55 | await voteManager.deployed(); 56 | await randomNoManager.deployed(); 57 | 58 | const initializeContracts = async () => [ 59 | blockManager.initialize(stakeManager.address, rewardManager.address, voteManager.address, collectionManager.address, 60 | randomNoManager.address), 61 | voteManager.initialize(stakeManager.address, rewardManager.address, blockManager.address, collectionManager.address), 62 | stakeManager.initialize(razor.address, rewardManager.address, voteManager.address, stakedTokenFactory.address), 63 | rewardManager.initialize(stakeManager.address, voteManager.address, blockManager.address, collectionManager.address), 64 | delegator.updateAddress(collectionManager.address, randomNoManager.address), 65 | collectionManager.initialize(voteManager.address, bondManager.address), 66 | randomNoManager.initialize(blockManager.address), 67 | governance.initialize(blockManager.address, bondManager.address, rewardManager.address, stakeManager.address, 68 | voteManager.address, collectionManager.address, randomNoManager.address), 69 | bondManager.initialize(razor.address, collectionManager.address), 70 | 71 | blockManager.grantRole(BLOCK_CONFIRMER_ROLE, voteManager.address), 72 | bondManager.grantRole(RESET_DATABOND_ROLE, governance.address), 73 | stakeManager.grantRole(PAUSE_ROLE, signers[0].address), 74 | rewardManager.grantRole(REWARD_MODIFIER_ROLE, blockManager.address), 75 | rewardManager.grantRole(REWARD_MODIFIER_ROLE, voteManager.address), 76 | rewardManager.grantRole(REWARD_MODIFIER_ROLE, stakeManager.address), 77 | stakeManager.grantRole(STAKE_MODIFIER_ROLE, rewardManager.address), 78 | stakeManager.grantRole(STAKE_MODIFIER_ROLE, blockManager.address), 79 | stakeManager.grantRole(STAKE_MODIFIER_ROLE, voteManager.address), 80 | stakeManager.grantRole(ESCAPE_HATCH_ROLE, signers[0].address), 81 | 82 | collectionManager.grantRole(REGISTRY_MODIFIER_ROLE, blockManager.address), 83 | collectionManager.grantRole(COLLECTION_CONFIRMER_ROLE, blockManager.address), 84 | collectionManager.grantRole(OCCURRENCE_MODIFIER_ROLE, bondManager.address), 85 | collectionManager.grantRole(COLLECTION_MODIFIER_ROLE, bondManager.address), 86 | 87 | collectionManager.grantRole(GOVERNANCE_ROLE, governance.address), 88 | blockManager.grantRole(GOVERNANCE_ROLE, governance.address), 89 | bondManager.grantRole(GOVERNANCE_ROLE, governance.address), 90 | rewardManager.grantRole(GOVERNANCE_ROLE, governance.address), 91 | stakeManager.grantRole(GOVERNANCE_ROLE, governance.address), 92 | voteManager.grantRole(GOVERNANCE_ROLE, governance.address), 93 | voteManager.grantRole(SALT_MODIFIER_ROLE, blockManager.address), 94 | voteManager.grantRole(DEPTH_MODIFIER_ROLE, collectionManager.address), 95 | delegator.grantRole(GOVERNANCE_ROLE, governance.address), 96 | randomNoManager.grantRole(GOVERNANCE_ROLE, governance.address), 97 | ]; 98 | 99 | return { 100 | blockManager, 101 | bondManager, 102 | governance, 103 | delegator, 104 | collectionManager, 105 | razor, 106 | stakeManager, 107 | rewardManager, 108 | voteManager, 109 | initializeContracts, 110 | stakedToken, 111 | stakedTokenFactory, 112 | randomNoManager, 113 | }; 114 | }; 115 | 116 | module.exports = { 117 | setupContracts, 118 | }; 119 | --------------------------------------------------------------------------------