diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..643a5be --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +TESTNET_RPC_URL=http://localhost:8545/ +TESTNET_PRIVATE_KEY_DEPLOY=0x0000000000000000000000000000000000000000 diff --git a/hardhat.config.ts b/hardhat.config.ts index e5ab4f5..b61632c 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -2,6 +2,7 @@ import { HardhatUserConfig } from 'hardhat/config'; import * as dotenv from 'dotenv'; import '@nomicfoundation/hardhat-chai-matchers'; import '@nomicfoundation/hardhat-ethers'; +import "@nomicfoundation/hardhat-ignition"; import '@openzeppelin/hardhat-upgrades'; import '@typechain/hardhat'; import 'hardhat-contract-sizer'; @@ -22,9 +23,13 @@ const config: HardhatUserConfig = { }, }, networks: { - hardhat: { - allowUnlimitedContractSize: true, - }, + hardhat: {}, + testnet: { + url: process.env.TESTNET_RPC_URL!, + accounts: [ + process.env.TESTNET_PRIVATE_KEY_DEPLOY!, + ], + } }, gasReporter: { currency: 'USD', diff --git a/ignition/modules/ConstantsManager.ts b/ignition/modules/ConstantsManager.ts new file mode 100644 index 0000000..a2de083 --- /dev/null +++ b/ignition/modules/ConstantsManager.ts @@ -0,0 +1,41 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +// npx hardhat ignition deploy ./ignition/modules/ConstantsManager.ts --network testnet --parameters ignition/params.json + +export default buildModule("ConstantsManager", (m) => { + const deployAccount = m.getAccount(0); + + const minSelfStake = m.getParameter('minSelfStake'); + const maxDelegatedRatio = m.getParameter('maxDelegatedRatio'); + const validatorCommissions = m.getParameter('validatorCommissions'); + const burntFeeShare = m.getParameter('burntFeeShare'); + const treasuryFeeShare = m.getParameter('treasuryFeeShare'); + const withdrawalPeriodEpochs = m.getParameter('withdrawalPeriodEpochs'); + const withdrawalPeriodTime = m.getParameter('withdrawalPeriodTime'); + const baseRewardPerSecond = m.getParameter('baseRewardPerSecond'); + const offlinePenaltyThresholdTime = m.getParameter('offlinePenaltyThresholdTime'); + const offlinePenaltyThresholdBlocksNumber = m.getParameter('offlinePenaltyThresholdBlocksNumber'); + const targetGasPowerPerSecond = m.getParameter('targetGasPowerPerSecond'); + const gasPriceBalancingCounterweights = m.getParameter('gasPriceBalancingCounterweights'); + const averageUptimeEpochWindow = m.getParameter('averageUptimeEpochWindow'); + const updateMinAverageUptime = m.getParameter('updateMinAverageUptime'); + + const constantsManager = m.contract("ConstantsManager", [deployAccount]); + + m.call(constantsManager, "updateMinSelfStake", [minSelfStake], {from: deployAccount}); + m.call(constantsManager, "updateMaxDelegatedRatio", [maxDelegatedRatio], {from: deployAccount}); + m.call(constantsManager, "updateValidatorCommission", [validatorCommissions], {from: deployAccount}); + m.call(constantsManager, "updateBurntFeeShare", [burntFeeShare], {from: deployAccount}); + m.call(constantsManager, "updateTreasuryFeeShare", [treasuryFeeShare], {from: deployAccount}); + m.call(constantsManager, "updateWithdrawalPeriodEpochs", [withdrawalPeriodEpochs], {from: deployAccount}); + m.call(constantsManager, "updateWithdrawalPeriodTime", [withdrawalPeriodTime], {from: deployAccount}); + m.call(constantsManager, "updateBaseRewardPerSecond", [baseRewardPerSecond], {from: deployAccount}); + m.call(constantsManager, "updateOfflinePenaltyThresholdTime", [offlinePenaltyThresholdTime], {from: deployAccount}); + m.call(constantsManager, "updateOfflinePenaltyThresholdBlocksNum", [offlinePenaltyThresholdBlocksNumber], {from: deployAccount}); + m.call(constantsManager, "updateTargetGasPowerPerSecond", [targetGasPowerPerSecond], {from: deployAccount}); + m.call(constantsManager, "updateGasPriceBalancingCounterweight", [gasPriceBalancingCounterweights], {from: deployAccount}); + m.call(constantsManager, "updateAverageUptimeEpochWindow", [averageUptimeEpochWindow], {from: deployAccount}); + m.call(constantsManager, "updateMinAverageUptime", [updateMinAverageUptime], {from: deployAccount}); + + return { constantsManager }; +}); \ No newline at end of file diff --git a/ignition/modules/NodeDriver.ts b/ignition/modules/NodeDriver.ts new file mode 100644 index 0000000..61731fa --- /dev/null +++ b/ignition/modules/NodeDriver.ts @@ -0,0 +1,8 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +// npx hardhat ignition deploy ./ignition/modules/NodeDriver.ts --network testnet --parameters ignition/params.json + +export default buildModule("NodeDriver", (m) => { + const nodeDriver = m.contract("NodeDriver"); + return { nodeDriver }; +}); \ No newline at end of file diff --git a/ignition/modules/NodeDriverAuth.ts b/ignition/modules/NodeDriverAuth.ts new file mode 100644 index 0000000..009447d --- /dev/null +++ b/ignition/modules/NodeDriverAuth.ts @@ -0,0 +1,8 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +// npx hardhat ignition deploy ./ignition/modules/NodeDriverAuth.ts --network testnet --parameters ignition/params.json + +export default buildModule("NodeDriverAuth", (m) => { + const NodeDriverAuth = m.contract("NodeDriverAuth"); + return { NodeDriverAuth }; +}); \ No newline at end of file diff --git a/ignition/modules/SFC.ts b/ignition/modules/SFC.ts new file mode 100644 index 0000000..43da629 --- /dev/null +++ b/ignition/modules/SFC.ts @@ -0,0 +1,8 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; + +// npx hardhat ignition deploy ./ignition/modules/SFC.ts --network testnet --parameters ignition/params.json + +export default buildModule("SFC", (m) => { + const sfc = m.contract("SFC"); + return { sfc }; +}); \ No newline at end of file diff --git a/ignition/params.json b/ignition/params.json new file mode 100644 index 0000000..85aee8c --- /dev/null +++ b/ignition/params.json @@ -0,0 +1,18 @@ +{ + "ConstantsManager": { + "minSelfStake": "500000000000000000000000n", + "maxDelegatedRatio": "16000000000000000000n", + "validatorCommissions" : "150000000000000000n", + "burntFeeShare": "200000000000000000n", + "treasuryFeeShare": "100000000000000000n", + "withdrawalPeriodEpochs": 3, + "withdrawalPeriodTime": 604800, + "baseRewardPerSecond": "2668658453701531600n", + "offlinePenaltyThresholdTime": 432000, + "offlinePenaltyThresholdBlocksNumber": 1000, + "targetGasPowerPerSecond": 2000000, + "gasPriceBalancingCounterweights": 3600, + "averageUptimeEpochWindow": 100, + "updateMinAverageUptime": 0 + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3811c6a..a8b443c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@eslint/js": "^9.11.1", "@nomicfoundation/hardhat-chai-matchers": "^2.0.7", "@nomicfoundation/hardhat-ethers": "^3.0.8", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.8", "@nomicfoundation/hardhat-network-helpers": "^1.0.11", "@openzeppelin/hardhat-upgrades": "^3.5.0", "@typechain/ethers-v6": "^0.5.1", @@ -1395,6 +1396,57 @@ "hardhat": "^2.0.0" } }, + "node_modules/@nomicfoundation/hardhat-ignition": { + "version": "0.15.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.8.tgz", + "integrity": "sha512-TN8TFQokcd7VyqGfbXO+KS8Q4K/gmsOFlv8dPnt/N596AncgV2Igxh5C3O+KVez11PDHNqoj1JzcDzzNVHrIRw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@nomicfoundation/ignition-core": "^0.15.8", + "@nomicfoundation/ignition-ui": "^0.15.8", + "chalk": "^4.0.0", + "debug": "^4.3.2", + "fs-extra": "^10.0.0", + "json5": "^2.2.3", + "prompts": "^2.4.2" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-verify": "^2.0.1", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition-ethers": { + "version": "0.15.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.8.tgz", + "integrity": "sha512-5Ev8cXBKgqqOsFXxWe8iijsRabWGd/Vclx3SC903KeKVePdssVsZcYTtRNRcIwRcPJ0RIKJPIZz7MNDo64l3+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.4", + "@nomicfoundation/hardhat-ignition": "^0.15.8", + "@nomicfoundation/ignition-core": "^0.15.8", + "ethers": "^6.7.0", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@nomicfoundation/hardhat-network-helpers": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.12.tgz", @@ -1408,6 +1460,109 @@ "hardhat": "^2.9.5" } }, + "node_modules/@nomicfoundation/hardhat-verify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.12.tgz", + "integrity": "sha512-Lg3Nu7DCXASQRVI/YysjuAX2z8jwOCbS0w5tz2HalWGSTZThqA0v9N0v0psHbKNqzPJa8bNOeapIVSziyJTnAg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^8.1.0", + "debug": "^4.1.1", + "lodash.clonedeep": "^4.5.0", + "picocolors": "^1.1.0", + "semver": "^6.3.0", + "table": "^6.8.0", + "undici": "^5.14.0" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/@nomicfoundation/ignition-core": { + "version": "0.15.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.8.tgz", + "integrity": "sha512-U+CmTjKU9uwvh7qIabqboy/K/sDoClDgpsFRHoFvAj87DPDkXYb/mZBSkXPTU1wxTxrW6GTFE4lG3e7LAyF+kw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/address": "5.6.1", + "@nomicfoundation/solidity-analyzer": "^0.1.1", + "cbor": "^9.0.0", + "debug": "^4.3.2", + "ethers": "^6.7.0", + "fs-extra": "^10.0.0", + "immer": "10.0.2", + "lodash": "4.17.21", + "ndjson": "2.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@ethersproject/address": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.1" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nomicfoundation/ignition-ui": { + "version": "0.15.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.8.tgz", + "integrity": "sha512-VUD5MsWrrv7E2P0AJO01pV8w8m66Du0uwBKXM0oUV5DRIzqm6eYHt9eCDb1KBINDpiFxOQiuyWQMdeKxgPp3qw==", + "dev": true, + "peer": true + }, "node_modules/@nomicfoundation/slang": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-0.17.0.tgz", @@ -5544,6 +5699,18 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", + "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/immutable": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", @@ -5870,6 +6037,28 @@ "node": ">=7.10.1" } }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -5929,6 +6118,17 @@ "node": ">=0.10.0" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/latest-version": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", @@ -5996,6 +6196,14 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -6412,6 +6620,27 @@ "dev": true, "license": "MIT" }, + "node_modules/ndjson": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", + "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "json-stringify-safe": "^5.0.1", + "minimist": "^1.2.5", + "readable-stream": "^3.6.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "ndjson": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -6916,6 +7145,21 @@ "node": ">=10" } }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/proper-lockfile": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", @@ -7585,6 +7829,14 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -7963,6 +8215,17 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -8202,6 +8465,17 @@ "dev": true, "license": "MIT" }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "readable-stream": "3" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index 16df1ff..cc0c676 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@eslint/js": "^9.11.1", "@nomicfoundation/hardhat-chai-matchers": "^2.0.7", "@nomicfoundation/hardhat-ethers": "^3.0.8", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.8", "@nomicfoundation/hardhat-network-helpers": "^1.0.11", "@openzeppelin/hardhat-upgrades": "^3.5.0", "@typechain/ethers-v6": "^0.5.1",