From 2fca436fa8692637eb79f769c44f5e5caa12545c Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Mon, 22 Aug 2022 18:12:18 +0200 Subject: [PATCH 01/21] Added export/import function for contributors --- .gitignore | 2 ++ scripts/export/contributions.js | 45 +++++++++++++++++++++++++++++++++ scripts/export/contributors.js | 38 ++++++++++++++++++++++++++++ scripts/import/contributors.js | 26 +++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 scripts/export/contributions.js create mode 100644 scripts/export/contributors.js create mode 100644 scripts/import/contributors.js diff --git a/.gitignore b/.gitignore index 25396cf..161e741 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ node_modules yarn-error.log .DS_Store +data + cache artifacts .openzeppelin diff --git a/scripts/export/contributions.js b/scripts/export/contributions.js new file mode 100644 index 0000000..17de504 --- /dev/null +++ b/scripts/export/contributions.js @@ -0,0 +1,45 @@ +const Kredits = require('../../lib/kredits'); + +async function main() { + kredits = new Kredits(hre.ethers.provider, hre.ethers.provider.getSigner()) + await kredits.init(); + + console.log(`Using Contribution at: ${kredits.Contribution.contract.address}`); + + const count = await kredits.Contribution.count; + const currentBlockHeight = await XMLHttpRequest.ethers.provider.getBlockNumber(); + + const backup = {}; + const promises = []; + for (let i = 1; i <= count; i++) { + promises.push(new Promise((resolve, reject) => { + setTimeout(async () => { + console.log(`Loading contribution ${i}`); + await kredits.Contribution.contract.getContribution(i).then(contractData => { + if (contractData.vetoed) { + console.log(`Ignoring vetoed contribution #${contractData.id}`); + return; + } + backup[i] = { + amount: contractData.amount, + contributorId: contractData.contributorId, + hashDigest: contractData.hashDigest, + hashFunction: contractData.hashFunction, + hashSize: contractData.hashSize, + confirmedAtBlock: contractData.confirmedAtBlock, + confirmed: contractData.confirmedAtBlock <= currentBlockHeight, + id: contractData.id, + } + resolve(); + }); + }, 100 * i); + })); + } + + await Promise.all(promises).then(() => { + fs.writeFileSync("./data/contributions.json", JSON.stringify(backup, null, 2)); + console.log("Exported"); + }); +} + +main(); diff --git a/scripts/export/contributors.js b/scripts/export/contributors.js new file mode 100644 index 0000000..0b54e90 --- /dev/null +++ b/scripts/export/contributors.js @@ -0,0 +1,38 @@ +const fs = require('fs'); +const Kredits = require('../../lib/kredits'); + +async function main() { + kredits = new Kredits(hre.ethers.provider, hre.ethers.provider.getSigner()) + await kredits.init(); + + console.log(`Using Contributor at: ${kredits.Contributor.contract.address}`); + + const count = await kredits.Contributor.count; + + const backup = {}; + const promises = []; + for (let i = 1; i <= count; i++) { + promises.push(new Promise((resolve, reject) => { + setTimeout(async () => { + console.log(`Loading contributor ${i}`); + await kredits.Contributor.contract.getContributorById(i).then(contractData => { + backup[i] = { + account: contractData.account, + hashDigest: contractData.hashDigest, + hashFunction: contractData.hashFunction, + hashSize: contractData.hashSize, + id: contractData.id, + } + resolve(); + }); + }, 100 * i); + })); + } + + await Promise.all(promises).then(() => { + fs.writeFileSync("./data/contributors.json", JSON.stringify(backup, null, 2)); + console.log("Exported"); + }); +} + +main(); diff --git a/scripts/import/contributors.js b/scripts/import/contributors.js new file mode 100644 index 0000000..4b52daf --- /dev/null +++ b/scripts/import/contributors.js @@ -0,0 +1,26 @@ +const Kredits = require('../../lib/kredits'); + +async function main() { + kredits = new Kredits(hre.ethers.provider, hre.ethers.provider.getSigner()) + await kredits.init(); + + console.log(`Using Contributor at: ${kredits.Contributor.contract.address}`); + + const data = fs.readFileSync("./data/contributors.json"); + const contributors = JSON.parse(data); + + const ids = Object.keys(contributors).map(k => parseInt(k)).sort(); + for (const contributorId of ids) { + const contributor = contributors[contributorId.toString()]; + const result = kredits.Contributor.contract.addContributor({ + account: contributor.account, + hashDigest: contirbutor.hashDigest, + hashFunction: contributor.hashFunction, + hashSize: contributr.hashSize, + }); + // await result.wait(); + console.log(`Added contributor #${id}: ${result.hash}`); + }; +} + +main(); From 550bc2b9f4b5c9eb640f21dd835d19d2c4a6df67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 09:38:35 +0100 Subject: [PATCH 02/21] Improve console output --- scripts/export/contributions.js | 2 +- scripts/export/contributors.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/export/contributions.js b/scripts/export/contributions.js index 17de504..d1af468 100644 --- a/scripts/export/contributions.js +++ b/scripts/export/contributions.js @@ -14,7 +14,7 @@ async function main() { for (let i = 1; i <= count; i++) { promises.push(new Promise((resolve, reject) => { setTimeout(async () => { - console.log(`Loading contribution ${i}`); + console.log(`Loading contribution #${i}`); await kredits.Contribution.contract.getContribution(i).then(contractData => { if (contractData.vetoed) { console.log(`Ignoring vetoed contribution #${contractData.id}`); diff --git a/scripts/export/contributors.js b/scripts/export/contributors.js index 0b54e90..8e6d76c 100644 --- a/scripts/export/contributors.js +++ b/scripts/export/contributors.js @@ -14,7 +14,7 @@ async function main() { for (let i = 1; i <= count; i++) { promises.push(new Promise((resolve, reject) => { setTimeout(async () => { - console.log(`Loading contributor ${i}`); + console.log(`Loading contributor #${i}`); await kredits.Contributor.contract.getContributorById(i).then(contractData => { backup[i] = { account: contractData.account, From 883f9adb9676b2faaeeb5be913a873b2a2e55440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 09:39:05 +0100 Subject: [PATCH 03/21] Fix ignored contributions not resolving their promise --- scripts/export/contributions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/export/contributions.js b/scripts/export/contributions.js index d1af468..8ea36ac 100644 --- a/scripts/export/contributions.js +++ b/scripts/export/contributions.js @@ -18,7 +18,7 @@ async function main() { await kredits.Contribution.contract.getContribution(i).then(contractData => { if (contractData.vetoed) { console.log(`Ignoring vetoed contribution #${contractData.id}`); - return; + resolve(); } backup[i] = { amount: contractData.amount, From 990e2a9649b76ece4b16a5d974449de5ca15aa0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 09:50:46 +0100 Subject: [PATCH 04/21] Also export vetoed contributions --- scripts/export/contributions.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/export/contributions.js b/scripts/export/contributions.js index 8ea36ac..18e9da5 100644 --- a/scripts/export/contributions.js +++ b/scripts/export/contributions.js @@ -16,10 +16,6 @@ async function main() { setTimeout(async () => { console.log(`Loading contribution #${i}`); await kredits.Contribution.contract.getContribution(i).then(contractData => { - if (contractData.vetoed) { - console.log(`Ignoring vetoed contribution #${contractData.id}`); - resolve(); - } backup[i] = { amount: contractData.amount, contributorId: contractData.contributorId, @@ -28,6 +24,7 @@ async function main() { hashSize: contractData.hashSize, confirmedAtBlock: contractData.confirmedAtBlock, confirmed: contractData.confirmedAtBlock <= currentBlockHeight, + vetoed: contractData.vetoed, id: contractData.id, } resolve(); From 1521e272f90e6b13e3795b49dd9fde088fcaef3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 10:01:37 +0100 Subject: [PATCH 05/21] Finish contributor import script --- scripts/import/contributors.js | 35 ++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/scripts/import/contributors.js b/scripts/import/contributors.js index 4b52daf..c2f71b3 100644 --- a/scripts/import/contributors.js +++ b/scripts/import/contributors.js @@ -1,3 +1,4 @@ +const fs = require('fs'); const Kredits = require('../../lib/kredits'); async function main() { @@ -6,21 +7,27 @@ async function main() { console.log(`Using Contributor at: ${kredits.Contributor.contract.address}`); - const data = fs.readFileSync("./data/contributors.json"); - const contributors = JSON.parse(data); + try { + const data = fs.readFileSync("./data/contributors.json"); + const contributors = JSON.parse(data); + const ids = Object.keys(contributors) + .map(k => parseInt(k)) + .sort(function(a, b){return a-b}); - const ids = Object.keys(contributors).map(k => parseInt(k)).sort(); - for (const contributorId of ids) { - const contributor = contributors[contributorId.toString()]; - const result = kredits.Contributor.contract.addContributor({ - account: contributor.account, - hashDigest: contirbutor.hashDigest, - hashFunction: contributor.hashFunction, - hashSize: contributr.hashSize, - }); - // await result.wait(); - console.log(`Added contributor #${id}: ${result.hash}`); - }; + for (const contributorId of ids) { + const contributor = contributors[contributorId.toString()]; + const result = await kredits.Contributor.contract.addContributor( + contributor.account, + contributor.hashDigest, + contributor.hashFunction, + contributor.hashSize, + ); + // await result.wait(); + console.log(`Added contributor #${contributorId}: ${result.hash}`); + }; + } catch(e) { + console.log(e); + } } main(); From 59bda71f974e95873fb87814f718984b6372bbc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 10:41:46 +0100 Subject: [PATCH 06/21] Add mocha, chai, and test for Contribution --- .eslintignore | 1 + package-lock.json | 811 ++++++++++++++++++++++++++++++++++++------- package.json | 3 + test/Contribution.js | 19 + 4 files changed, 701 insertions(+), 133 deletions(-) create mode 100644 test/Contribution.js diff --git a/.eslintignore b/.eslintignore index 6633896..2ba1088 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ /scripts/ +/test/ diff --git a/package-lock.json b/package-lock.json index c07d67b..ca5efda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,11 +17,13 @@ "tv4": "^1.3.0" }, "devDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^1.0.3", "@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-waffle": "^2.0.1", "@openzeppelin/contracts-upgradeable": "^4.3.2", "@openzeppelin/hardhat-upgrades": "^1.10.0", "async-each-series": "^1.1.0", + "chai": "^4.3.6", "cli-table": "^0.3.1", "colors": "^1.0.3", "eslint": "^8.14.0", @@ -35,6 +37,7 @@ "hardhat-deploy": "^0.11.4", "hardhat-deploy-ethers": "^0.3.0-beta.10", "homedir": "^0.6.0", + "mocha": "^10.0.0", "promptly": "^3.0.3", "solhint": "^3.3.7", "truffle-hdwallet-provider": "^1.0.17", @@ -1084,6 +1087,121 @@ "resolved": "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz", "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" }, + "node_modules/@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/secp256k1": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", + "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.3.tgz", + "integrity": "sha512-qEE7Drs2HSY+krH09TXm6P9LFogs0BqbUq6wPD7nQRhmJ+p5zoDaIZjM5WL1pHqU5MpGqya3y+BdwmTYBfU5UA==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "chalk": "^2.4.2", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" + }, + "peerDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.0", + "chai": "^4.2.0", + "ethers": "^5.0.0", + "hardhat": "^2.9.4" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@nomiclabs/hardhat-ethers": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.5.tgz", @@ -1271,6 +1389,51 @@ "ms": "^2.1.1" } }, + "node_modules/@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@scure/bip32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", + "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.1.1", + "@noble/secp256k1": "~1.6.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/@scure/bip39": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", + "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" + } + }, "node_modules/@sentry/core": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", @@ -1383,9 +1546,9 @@ } }, "node_modules/@solidity-parser/parser": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.1.tgz", - "integrity": "sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz", + "integrity": "sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==", "dev": true, "dependencies": { "antlr4ts": "^0.5.0-alpha.4" @@ -1433,6 +1596,15 @@ "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", "dev": true }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", + "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1870,6 +2042,15 @@ "node": ">=0.8" } }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/ast-parents": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", @@ -3143,6 +3324,48 @@ "cborg": "cli.js" } }, + "node_modules/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "dependencies": { + "check-error": "^1.0.2" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 5" + } + }, + "node_modules/chai/node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3162,6 +3385,15 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/checkpoint-store": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", @@ -3878,6 +4110,18 @@ "node": ">=0.10.0" } }, + "node_modules/deep-eql": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.0.tgz", + "integrity": "sha512-4YM7QHOMBoVWqGPnp3OPPK7+WCIhUR2OTpahlNQFiyTH3QEeiu9MtBiTAJBkfny4PNhpFbV/jm3lv0iCfb40MA==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-equal": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", @@ -11439,6 +11683,15 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -11586,15 +11839,6 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -11618,20 +11862,20 @@ } }, "node_modules/hardhat": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.3.tgz", - "integrity": "sha512-7Vw99RbYbMZ15UzegOR/nqIYIqddZXvLwJGaX5sX4G5bydILnbjmDU6g3jMKJSiArEixS3vHAEaOs5CW1JQ3hg==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.10.2.tgz", + "integrity": "sha512-L/KvDDT/MA6332uAtYTqdcHoSABljw4pPjHQe5SHdIJ+xKfaSc6vDKw03CmrQ5Xup0gHs8XnVSBpZo1AbbIW7g==", "dev": true, "dependencies": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/blockchain": "^5.5.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "@ethereumjs/vm": "^5.6.0", + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/blockchain": "^5.5.2", + "@ethereumjs/common": "^2.6.4", + "@ethereumjs/tx": "^3.5.1", + "@ethereumjs/vm": "^5.9.0", "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.14.1", + "@solidity-parser/parser": "^0.14.2", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", "abort-controller": "^3.0.0", @@ -11644,19 +11888,19 @@ "debug": "^4.1.1", "enquirer": "^2.3.0", "env-paths": "^2.2.0", - "ethereum-cryptography": "^0.1.2", + "ethereum-cryptography": "^1.0.3", "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.3", + "ethereumjs-util": "^7.1.4", "find-up": "^2.1.0", "fp-ts": "1.19.3", "fs-extra": "^7.0.1", - "glob": "^7.1.3", + "glob": "7.2.0", "immutable": "^4.0.0-rc.12", "io-ts": "1.10.4", "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.2.2", + "merkle-patricia-tree": "^4.2.4", "mnemonist": "^0.38.0", - "mocha": "^9.2.0", + "mocha": "^10.0.0", "p-map": "^4.0.0", "qs": "^6.7.0", "raw-body": "^2.4.1", @@ -11668,7 +11912,7 @@ "stacktrace-parser": "^0.1.10", "true-case-path": "^2.2.1", "tsort": "0.0.1", - "undici": "^4.14.1", + "undici": "^5.4.0", "uuid": "^8.3.2", "ws": "^7.4.6" }, @@ -11676,7 +11920,19 @@ "hardhat": "internal/cli/cli.js" }, "engines": { - "node": "^12.0.0 || ^14.0.0 || ^16.0.0" + "node": "^14.0.0 || ^16.0.0 || ^18.0.0" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } } }, "node_modules/hardhat-deploy": { @@ -11824,6 +12080,18 @@ "node": ">=0.8.0" } }, + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" + } + }, "node_modules/hardhat/node_modules/ethereumjs-abi": { "version": "0.6.8", "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", @@ -11843,6 +12111,29 @@ "@types/node": "*" } }, + "node_modules/hardhat/node_modules/ethereumjs-abi/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, "node_modules/hardhat/node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", @@ -13611,6 +13902,15 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, "node_modules/lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -13954,42 +14254,44 @@ } }, "node_modules/mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", "dev": true, "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", - "debug": "4.3.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", - "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", - "minimatch": "4.2.1", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.1", + "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha/node_modules/argparse": { @@ -13998,6 +14300,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -14009,24 +14320,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/mocha/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -14074,12 +14367,12 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" @@ -14298,9 +14591,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -14609,6 +14902,12 @@ "node": ">= 0.8.0" } }, + "node_modules/ordinal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", + "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", + "dev": true + }, "node_modules/os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -15040,6 +15339,15 @@ "node": ">=0.10.0" } }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", @@ -17592,6 +17900,15 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -17696,9 +18013,9 @@ "dev": true }, "node_modules/undici": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz", - "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==", + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.9.1.tgz", + "integrity": "sha512-6fB3a+SNnWEm4CJbgo0/CWR8RGcOCQP68SF4X0mxtYTq2VNN8T88NYrWVBAeSX+zb7bny2dx2iYhP3XHi00omg==", "dev": true, "engines": { "node": ">=12.18" @@ -19181,9 +19498,9 @@ } }, "node_modules/workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "node_modules/wrap-ansi": { @@ -20527,6 +20844,90 @@ "resolved": "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz", "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" }, + "@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "dev": true + }, + "@noble/secp256k1": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.6.3.tgz", + "integrity": "sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==", + "dev": true + }, + "@nomicfoundation/hardhat-chai-matchers": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.3.tgz", + "integrity": "sha512-qEE7Drs2HSY+krH09TXm6P9LFogs0BqbUq6wPD7nQRhmJ+p5zoDaIZjM5WL1pHqU5MpGqya3y+BdwmTYBfU5UA==", + "dev": true, + "requires": { + "@ethersproject/abi": "^5.1.2", + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "chalk": "^2.4.2", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "@nomiclabs/hardhat-ethers": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.5.tgz", @@ -20719,6 +21120,33 @@ } } }, + "@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "dev": true + }, + "@scure/bip32": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.0.tgz", + "integrity": "sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==", + "dev": true, + "requires": { + "@noble/hashes": "~1.1.1", + "@noble/secp256k1": "~1.6.0", + "@scure/base": "~1.1.0" + } + }, + "@scure/bip39": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", + "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "dev": true, + "requires": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" + } + }, "@sentry/core": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", @@ -20807,9 +21235,9 @@ "dev": true }, "@solidity-parser/parser": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.1.tgz", - "integrity": "sha512-eLjj2L6AuQjBB6s/ibwCAc0DwrR5Ge+ys+wgWo+bviU7fV2nTMQhU63CGaDKXg9iTmMxwhkyoggdIR7ZGRfMgw==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.3.tgz", + "integrity": "sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==", "dev": true, "requires": { "antlr4ts": "^0.5.0-alpha.4" @@ -20854,6 +21282,15 @@ "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", "dev": true }, + "@types/chai-as-promised": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", + "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -21242,6 +21679,12 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, "ast-parents": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", @@ -22450,6 +22893,41 @@ "resolved": "https://registry.npmjs.org/cborg/-/cborg-1.9.1.tgz", "integrity": "sha512-6xKRdJ89ncwEXJGx9rFMRBNp72UqgYSGt2a88rqsvCLda4OuhRlh3xD2nu+ufrw6h9l94K0cnvyD4WEGpKtRtw==" }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "dependencies": { + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + } + } + }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "^1.0.2" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -22466,6 +22944,12 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, "checkpoint-store": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", @@ -23080,6 +23564,15 @@ } } }, + "deep-eql": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.0.tgz", + "integrity": "sha512-4YM7QHOMBoVWqGPnp3OPPK7+WCIhUR2OTpahlNQFiyTH3QEeiu9MtBiTAJBkfny4PNhpFbV/jm3lv0iCfb40MA==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, "deep-equal": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", @@ -29978,6 +30471,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true + }, "get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -30103,12 +30602,6 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -30126,20 +30619,20 @@ } }, "hardhat": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.9.3.tgz", - "integrity": "sha512-7Vw99RbYbMZ15UzegOR/nqIYIqddZXvLwJGaX5sX4G5bydILnbjmDU6g3jMKJSiArEixS3vHAEaOs5CW1JQ3hg==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.10.2.tgz", + "integrity": "sha512-L/KvDDT/MA6332uAtYTqdcHoSABljw4pPjHQe5SHdIJ+xKfaSc6vDKw03CmrQ5Xup0gHs8XnVSBpZo1AbbIW7g==", "dev": true, "requires": { - "@ethereumjs/block": "^3.6.0", - "@ethereumjs/blockchain": "^5.5.0", - "@ethereumjs/common": "^2.6.0", - "@ethereumjs/tx": "^3.4.0", - "@ethereumjs/vm": "^5.6.0", + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/blockchain": "^5.5.2", + "@ethereumjs/common": "^2.6.4", + "@ethereumjs/tx": "^3.5.1", + "@ethereumjs/vm": "^5.9.0", "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.14.1", + "@solidity-parser/parser": "^0.14.2", "@types/bn.js": "^5.1.0", "@types/lru-cache": "^5.1.0", "abort-controller": "^3.0.0", @@ -30152,19 +30645,19 @@ "debug": "^4.1.1", "enquirer": "^2.3.0", "env-paths": "^2.2.0", - "ethereum-cryptography": "^0.1.2", + "ethereum-cryptography": "^1.0.3", "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.3", + "ethereumjs-util": "^7.1.4", "find-up": "^2.1.0", "fp-ts": "1.19.3", "fs-extra": "^7.0.1", - "glob": "^7.1.3", + "glob": "7.2.0", "immutable": "^4.0.0-rc.12", "io-ts": "1.10.4", "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.2.2", + "merkle-patricia-tree": "^4.2.4", "mnemonist": "^0.38.0", - "mocha": "^9.2.0", + "mocha": "^10.0.0", "p-map": "^4.0.0", "qs": "^6.7.0", "raw-body": "^2.4.1", @@ -30176,7 +30669,7 @@ "stacktrace-parser": "^0.1.10", "true-case-path": "^2.2.1", "tsort": "0.0.1", - "undici": "^4.14.1", + "undici": "^5.4.0", "uuid": "^8.3.2", "ws": "^7.4.6" }, @@ -30234,6 +30727,18 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "ethereum-cryptography": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.1.2.tgz", + "integrity": "sha512-XDSJlg4BD+hq9N2FjvotwUET9Tfxpxc3kWGE2AqUG5vcbeunnbImVk3cj6e/xT3phdW21mE8R5IugU4fspQDcQ==", + "dev": true, + "requires": { + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.6.3", + "@scure/bip32": "1.1.0", + "@scure/bip39": "1.1.0" + } + }, "ethereumjs-abi": { "version": "0.6.8", "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", @@ -30253,6 +30758,29 @@ "@types/node": "*" } }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, "ethereumjs-util": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", @@ -31778,6 +32306,15 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -32067,32 +32604,30 @@ } }, "mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", - "debug": "4.3.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", - "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", - "minimatch": "4.2.1", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.1", + "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" @@ -32104,6 +32639,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -32115,23 +32659,6 @@ "wrap-ansi": "^7.0.0" } }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -32167,12 +32694,12 @@ } }, "minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" } }, "ms": { @@ -32357,9 +32884,9 @@ "dev": true }, "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==" }, "native-fetch": { "version": "3.0.0", @@ -32596,6 +33123,12 @@ "word-wrap": "^1.2.3" } }, + "ordinal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", + "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", + "dev": true + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -32930,6 +33463,12 @@ "pinkie-promise": "^2.0.0" } }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, "pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", @@ -35038,6 +35577,12 @@ "prelude-ls": "^1.2.1" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -35135,9 +35680,9 @@ "dev": true }, "undici": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz", - "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==", + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.9.1.tgz", + "integrity": "sha512-6fB3a+SNnWEm4CJbgo0/CWR8RGcOCQP68SF4X0mxtYTq2VNN8T88NYrWVBAeSX+zb7bny2dx2iYhP3XHi00omg==", "dev": true }, "universalify": { @@ -36472,9 +37017,9 @@ "dev": true }, "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "wrap-ansi": { diff --git a/package.json b/package.json index b06b2ea..a3c4692 100644 --- a/package.json +++ b/package.json @@ -39,11 +39,13 @@ }, "homepage": "https://github.com/67P/kredits-contracts#readme", "devDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^1.0.3", "@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-waffle": "^2.0.1", "@openzeppelin/contracts-upgradeable": "^4.3.2", "@openzeppelin/hardhat-upgrades": "^1.10.0", "async-each-series": "^1.1.0", + "chai": "^4.3.6", "cli-table": "^0.3.1", "colors": "^1.0.3", "eslint": "^8.14.0", @@ -57,6 +59,7 @@ "hardhat-deploy": "^0.11.4", "hardhat-deploy-ethers": "^0.3.0-beta.10", "homedir": "^0.6.0", + "mocha": "^10.0.0", "promptly": "^3.0.3", "solhint": "^3.3.7", "truffle-hdwallet-provider": "^1.0.17", diff --git a/test/Contribution.js b/test/Contribution.js new file mode 100644 index 0000000..ef874ca --- /dev/null +++ b/test/Contribution.js @@ -0,0 +1,19 @@ +const { expect } = require("chai"); +const { ethers, upgrades } = require("hardhat"); +let hardhatContribution; + +describe("Contribution contract", function () { + + describe("Deployment", function () { + before(async function () { + // const [owner] = await ethers.getSigners(); + const Contribution = await ethers.getContractFactory("Contribution"); + hardhatContribution = await upgrades.deployProxy(Contribution, [40321]); + }); + + it("sets the veto confirmation period", async function () { + expect(await hardhatContribution.blocksToWait()).to.equal(40321); + }); + }); + +}); From 55877897bea3bd11399ce4b1c13d2c2f7b06c7cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 10:42:33 +0100 Subject: [PATCH 07/21] Formatting --- scripts/create-proxy.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/create-proxy.js b/scripts/create-proxy.js index 7aa40d7..80c9a0f 100644 --- a/scripts/create-proxy.js +++ b/scripts/create-proxy.js @@ -1,4 +1,6 @@ -const { ethers, upgrades } = require("hardhat"); const path = require("path"); const fileInject = require("./helpers/file_inject.js"); +const { ethers, upgrades } = require("hardhat"); +const path = require("path"); +const fileInject = require("./helpers/file_inject.js"); function handleError(error) { console.error(error.message); From 0fc4eed09afea24e68f9234165d4d3c27c99c659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 10:55:35 +0100 Subject: [PATCH 08/21] CI --- .drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index 003e6f4..82508b5 100644 --- a/.drone.yml +++ b/.drone.yml @@ -24,7 +24,7 @@ steps: - name: build contracts image: gitea.kosmos.org/kredits/docker-ci:latest commands: - - su drone -c 'npm run devchain' & + - su drone -c 'npm run devchain -- --silent' & - sleep 5 - su drone -c 'npm run build' depends_on: @@ -32,7 +32,7 @@ steps: - name: test image: gitea.kosmos.org/kredits/docker-ci:latest commands: - - su drone -c 'npm run devchain' & + - su drone -c 'npm run devchain -- --silent' & - sleep 5 - su drone -c 'npm test' depends_on: From de1574155c91e2fcf32dd1ef15addfd629d27128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 12:15:16 +0100 Subject: [PATCH 09/21] Allow deployer to set a migration-done flag * Save deployer's address on contract initialization * Add modifier for requiring tx sender to be deployer * Add migrationDone flag and function to set it to finished status --- contracts/Contribution.sol | 18 ++++++++++++++++ contracts/Contributor.sol | 2 +- hardhat.config.js | 1 + package-lock.json | 18 ++++++++++------ test/Contribution.js | 42 +++++++++++++++++++++++++++++++++----- 5 files changed, 69 insertions(+), 12 deletions(-) diff --git a/contracts/Contribution.sol b/contracts/Contribution.sol index 8c64106..d275b39 100644 --- a/contracts/Contribution.sol +++ b/contracts/Contribution.sol @@ -42,8 +42,15 @@ contract Contribution is Initializable { mapping(uint32 => ContributionData) public contributions; uint32 public contributionsCount; + // Confirmation veto period uint32 public blocksToWait; + // The address that deployed the contract + address public deployer; + + // Data migration flag + bool public migrationDone; + event ContributionAdded(uint32 id, uint32 indexed contributorId, uint32 amount); event ContributionClaimed(uint32 id, uint32 indexed contributorId, uint32 amount); event ContributionVetoed(uint32 id, address vetoedByAccount); @@ -53,10 +60,21 @@ contract Contribution is Initializable { _; } + modifier onlyDeployer { + require(msg.sender == deployer, "Deployer only"); + _; + } + function initialize(uint32 blocksToWait_) public initializer { + deployer = msg.sender; + migrationDone = false; blocksToWait = blocksToWait_; } + function finishMigration() public onlyDeployer { + migrationDone = true; + } + function setTokenContract(address token) public { require(address(tokenContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only"); tokenContract = IToken(token); diff --git a/contracts/Contributor.sol b/contracts/Contributor.sol index a2255b4..20f9b9c 100644 --- a/contracts/Contributor.sol +++ b/contracts/Contributor.sol @@ -99,7 +99,7 @@ contract Contributor is Initializable { function isCoreTeam(uint32 id) view public returns (bool) { // TODO: for simplicity we simply define the first contributors as core // later this needs to be changed to something more dynamic - return id > 0 && id < 7; + return id > 0 && id < 6; } function exists(uint32 id) view public returns (bool) { diff --git a/hardhat.config.js b/hardhat.config.js index d5d5681..1190ee2 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -1,6 +1,7 @@ require("@nomiclabs/hardhat-waffle"); require("hardhat-deploy"); require("hardhat-deploy-ethers"); +require("@nomicfoundation/hardhat-chai-matchers"); require("@openzeppelin/hardhat-upgrades"); const Kredits = require("./lib/kredits"); diff --git a/package-lock.json b/package-lock.json index ca5efda..3b2b2a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1216,6 +1216,12 @@ "dependencies": { "@types/sinon-chai": "^3.2.3", "@types/web3": "1.0.19" + }, + "peerDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.0", + "ethereum-waffle": "^3.2.0", + "ethers": "^5.0.0", + "hardhat": "^2.0.0" } }, "node_modules/@openzeppelin/contracts-upgradeable": { @@ -1708,9 +1714,9 @@ } }, "node_modules/@types/sinon": { - "version": "10.0.11", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz", - "integrity": "sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g==", + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", + "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", "dev": true, "dependencies": { "@types/sinonjs__fake-timers": "*" @@ -21394,9 +21400,9 @@ } }, "@types/sinon": { - "version": "10.0.11", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz", - "integrity": "sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g==", + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", + "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", "dev": true, "requires": { "@types/sinonjs__fake-timers": "*" diff --git a/test/Contribution.js b/test/Contribution.js index ef874ca..cb3fae2 100644 --- a/test/Contribution.js +++ b/test/Contribution.js @@ -1,18 +1,50 @@ const { expect } = require("chai"); const { ethers, upgrades } = require("hardhat"); -let hardhatContribution; +let owner, addr1, addr2, addr3, addr4, addr5, addr6; +let Contribution, Contributor; -describe("Contribution contract", function () { +describe("Contribution contract", async function () { + before(async function () { + [owner, addr1, addr2, addr3, addr4, addr5, addr6] = await ethers.getSigners(); + let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6]; + const contributorFactory = await ethers.getContractFactory("Contributor"); + Contributor = await upgrades.deployProxy(contributorFactory); + for (const account of accounts) { + await Contributor.addContributor(account.address, "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", 18, 32); + } + }); describe("Deployment", function () { before(async function () { // const [owner] = await ethers.getSigners(); - const Contribution = await ethers.getContractFactory("Contribution"); - hardhatContribution = await upgrades.deployProxy(Contribution, [40321]); + const contributionFactory = await ethers.getContractFactory("Contribution"); + Contribution = await upgrades.deployProxy(contributionFactory, [40321]); }); it("sets the veto confirmation period", async function () { - expect(await hardhatContribution.blocksToWait()).to.equal(40321); + expect(await Contribution.blocksToWait()).to.equal(40321); + }); + + it("sets the data migration flag", async function () { + expect(await Contribution.migrationDone()).to.equal(false); + }); + }); + + describe("Data migration", function () { + before(async function () { + const contributionFactory = await ethers.getContractFactory("Contribution"); + Contribution = await upgrades.deployProxy(contributionFactory, [40321]); + await Contribution.setContributorContract(Contributor.address).then(res => res.wait()) + }); + + it("does not allow random accounts to mark the migration as finished", async function () { + await expect(Contribution.connect(addr1).finishMigration()).to.be.revertedWith("Deployer only"); + expect(await Contribution.migrationDone()).to.equal(false); + }); + + it("allows the deployer to mark the migration as finished", async function () { + await Contribution.finishMigration(); + expect(await Contribution.migrationDone()).to.equal(true); }); }); From 90172071fac514c25474823630201c0969c84ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 12:20:42 +0100 Subject: [PATCH 10/21] Add test for setting deployer address --- test/Contribution.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/Contribution.js b/test/Contribution.js index cb3fae2..241caf8 100644 --- a/test/Contribution.js +++ b/test/Contribution.js @@ -28,6 +28,11 @@ describe("Contribution contract", async function () { it("sets the data migration flag", async function () { expect(await Contribution.migrationDone()).to.equal(false); }); + + it("sets the deployer address", async function () { + expect(await Contribution.deployer()).to.equal(owner.address); + expect(await Contribution.deployer()).to.not.equal(addr1.address); + }); }); describe("Data migration", function () { From cd07313679468fbb2eec3fc8ca790f472d0e3638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 13:14:19 +0100 Subject: [PATCH 11/21] Revert core flag change --- contracts/Contributor.sol | 2 +- test/Contribution.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/Contributor.sol b/contracts/Contributor.sol index 20f9b9c..a2255b4 100644 --- a/contracts/Contributor.sol +++ b/contracts/Contributor.sol @@ -99,7 +99,7 @@ contract Contributor is Initializable { function isCoreTeam(uint32 id) view public returns (bool) { // TODO: for simplicity we simply define the first contributors as core // later this needs to be changed to something more dynamic - return id > 0 && id < 6; + return id > 0 && id < 7; } function exists(uint32 id) view public returns (bool) { diff --git a/test/Contribution.js b/test/Contribution.js index 241caf8..ebcfe85 100644 --- a/test/Contribution.js +++ b/test/Contribution.js @@ -1,12 +1,12 @@ const { expect } = require("chai"); const { ethers, upgrades } = require("hardhat"); -let owner, addr1, addr2, addr3, addr4, addr5, addr6; +let owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7; let Contribution, Contributor; describe("Contribution contract", async function () { before(async function () { - [owner, addr1, addr2, addr3, addr4, addr5, addr6] = await ethers.getSigners(); - let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6]; + [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7] = await ethers.getSigners(); + let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7]; const contributorFactory = await ethers.getContractFactory("Contributor"); Contributor = await upgrades.deployProxy(contributorFactory); for (const account of accounts) { From 67add71a22fd76eea813079a893ed5d4d8f63cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 14:41:30 +0100 Subject: [PATCH 12/21] Add tests for Contribution#add() --- contracts/Contribution.sol | 5 ++-- test/Contribution.js | 54 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/contracts/Contribution.sol b/contracts/Contribution.sol index d275b39..d3745cf 100644 --- a/contracts/Contribution.sol +++ b/contracts/Contribution.sol @@ -169,8 +169,9 @@ contract Contribution is Initializable { } function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public { - //require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint32[](0)), 'nope'); - require(balanceOf(msg.sender) > 0 || contributorContract.addressIsCore(msg.sender), 'must have kredits or core'); + // require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint32[](0)), 'nope'); + // TODO hubot neither has kredits nor a core account + require(balanceOf(msg.sender) > 0 || contributorContract.addressIsCore(msg.sender), 'requires kredits or core status'); uint32 contributionId = contributionsCount + 1; ContributionData storage c = contributions[contributionId]; c.exists = true; diff --git a/test/Contribution.js b/test/Contribution.js index ebcfe85..02de504 100644 --- a/test/Contribution.js +++ b/test/Contribution.js @@ -1,5 +1,6 @@ const { expect } = require("chai"); const { ethers, upgrades } = require("hardhat"); +const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); let owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7; let Contribution, Contributor; @@ -14,7 +15,7 @@ describe("Contribution contract", async function () { } }); - describe("Deployment", function () { + describe("initialize()", function () { before(async function () { // const [owner] = await ethers.getSigners(); const contributionFactory = await ethers.getContractFactory("Contribution"); @@ -35,7 +36,7 @@ describe("Contribution contract", async function () { }); }); - describe("Data migration", function () { + describe("finishMigration()", function () { before(async function () { const contributionFactory = await ethers.getContractFactory("Contribution"); Contribution = await upgrades.deployProxy(contributionFactory, [40321]); @@ -53,4 +54,53 @@ describe("Contribution contract", async function () { }); }); + describe("add()", function () { + before(async function () { + const contributionFactory = await ethers.getContractFactory("Contribution"); + Contribution = await upgrades.deployProxy(contributionFactory, [40321]); + await Contribution.setContributorContract(Contributor.address).then(res => res.wait()) + }); + + it("does not allow non-contributors to add a contribution", async function () { + await expect(Contribution.connect(addr7).add( + 500, 1, + "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32 + )).to.be.revertedWith("requires kredits or core status"); + expect(await Contribution.contributionsCount()).to.equal(0); + }); + + it("allows core contributors to add a contribution", async function () { + await Contribution.connect(addr2).add( + 2001, 1, + "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32 + ); + expect(await Contribution.contributionsCount()).to.equal(1); + }); + + it("allows contributors to add a contribution", async function () { + // Issue some kredits for new contributor #8 (addr7) + await Contribution.connect(addr1).add( + 5000, 8, + "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32 + ); + await Contribution.connect(addr7).add( + 1500, 1, + "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32 + ); + expect(await Contribution.contributionsCount()).to.equal(3); + }); + + it("emits a ContributionAdded event", async function () { + await expect(Contribution.connect(addr1).add( + 2001, 1, + "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32 + )).to.emit(Contribution, "ContributionAdded").withArgs(anyValue, 1, 2001); + }); + }); + }); From 9dd9d298ccb5a1ed35e7a2b45f48af84eb83fd4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 16:20:50 +0100 Subject: [PATCH 13/21] Allow setting confirmedAtBlock and vetoed during migration --- contracts/Contribution.sol | 12 ++++--- lib/abis/Contribution.json | 2 +- lib/addresses.json | 8 ++--- lib/contracts/contribution.js | 2 +- test/Contribution.js | 66 +++++++++++++++++++++++++++++++---- 5 files changed, 73 insertions(+), 17 deletions(-) diff --git a/contracts/Contribution.sol b/contracts/Contribution.sol index d3745cf..b4b65a0 100644 --- a/contracts/Contribution.sol +++ b/contracts/Contribution.sol @@ -168,10 +168,12 @@ contract Contribution is Initializable { ); } - function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public { + function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint256 confirmedAtBlock, bool vetoed) public { // require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint32[](0)), 'nope'); // TODO hubot neither has kredits nor a core account + require((confirmedAtBlock == 0 && vetoed == false) || migrationDone == false, 'extra arguments during migration only'); require(balanceOf(msg.sender) > 0 || contributorContract.addressIsCore(msg.sender), 'requires kredits or core status'); + uint32 contributionId = contributionsCount + 1; ContributionData storage c = contributions[contributionId]; c.exists = true; @@ -181,12 +183,15 @@ contract Contribution is Initializable { c.hashDigest = hashDigest; c.hashFunction = hashFunction; c.hashSize = hashSize; - if (contributionId < 10) { - c.confirmedAtBlock = block.number; + + if (confirmedAtBlock > 0) { + c.confirmedAtBlock = confirmedAtBlock; } else { c.confirmedAtBlock = block.number + 1 + blocksToWait; } + if (vetoed) { c.vetoed = true; } + contributionsCount++; contributionOwner[contributionId] = contributorId; @@ -196,7 +201,6 @@ contract Contribution is Initializable { } function veto(uint32 contributionId) public onlyCore { - ContributionData storage c = contributions[contributionId]; require(c.exists, 'NOT_FOUND'); require(!c.claimed, 'ALREADY_CLAIMED'); diff --git a/lib/abis/Contribution.json b/lib/abis/Contribution.json index bce7ca6..78552d1 100644 --- a/lib/abis/Contribution.json +++ b/lib/abis/Contribution.json @@ -1 +1 @@ -[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"contributorId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"ContributionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"contributorId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"ContributionClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ContributionVetoed","type":"event"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributionOwner","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributions","outputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"string","name":"tokenMetadataURL","type":"string"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"getContribution","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"blocksToWait_","type":"uint32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownedContributions","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setTokenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenContract","outputs":[{"internalType":"contract IToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"tokenMetadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint32","name":"index","type":"uint32"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalKreditsEarned","outputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalKreditsEarnedByContributor","outputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"contributorId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"ContributionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"contributorId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"ContributionClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ContributionVetoed","type":"event"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributionOwner","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributions","outputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"string","name":"tokenMetadataURL","type":"string"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finishMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"getContribution","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"blocksToWait_","type":"uint32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationDone","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownedContributions","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setTokenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenContract","outputs":[{"internalType":"contract IToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"tokenMetadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint32","name":"index","type":"uint32"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalKreditsEarned","outputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalKreditsEarnedByContributor","outputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/addresses.json b/lib/addresses.json index 5bba5b6..cba931a 100644 --- a/lib/addresses.json +++ b/lib/addresses.json @@ -1,8 +1,8 @@ { "1337": { - "Contributor": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", - "Contribution": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - "Token": "0x0165878A594ca255338adfa4d48449f69242Eb8F", - "Reimbursement": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" + "Contributor": "0xCc66f9A3cA2670972938FAD91d0865c4a62DFB25", + "Contribution": "0x8999CaBc43E28202c5A2257f2a95A45b1F8A62BD", + "Token": "0xe082678eCF749982e33Ea6839852a8cd989aEDE2", + "Reimbursement": "0x984f797d26d3da2E9b9f8Ae4eeFEACC60fCAA90C" } } \ No newline at end of file diff --git a/lib/contracts/contribution.js b/lib/contracts/contribution.js index 0f2bbb7..f6648d9 100644 --- a/lib/contracts/contribution.js +++ b/lib/contracts/contribution.js @@ -58,7 +58,7 @@ class Contribution extends Record { ipfsHashAttr.hashSize, ]; - return this.contract.add(...contribution, callOptions); + return this.contract.add(...contribution, 0, false, callOptions); }); } diff --git a/test/Contribution.js b/test/Contribution.js index 02de504..b6d6a25 100644 --- a/test/Contribution.js +++ b/test/Contribution.js @@ -27,7 +27,7 @@ describe("Contribution contract", async function () { }); it("sets the data migration flag", async function () { - expect(await Contribution.migrationDone()).to.equal(false); + expect(await Contribution.migrationDone()).to.be.false; }); it("sets the deployer address", async function () { @@ -45,7 +45,7 @@ describe("Contribution contract", async function () { it("does not allow random accounts to mark the migration as finished", async function () { await expect(Contribution.connect(addr1).finishMigration()).to.be.revertedWith("Deployer only"); - expect(await Contribution.migrationDone()).to.equal(false); + expect(await Contribution.migrationDone()).to.be.false; }); it("allows the deployer to mark the migration as finished", async function () { @@ -59,22 +59,32 @@ describe("Contribution contract", async function () { const contributionFactory = await ethers.getContractFactory("Contribution"); Contribution = await upgrades.deployProxy(contributionFactory, [40321]); await Contribution.setContributorContract(Contributor.address).then(res => res.wait()) + await Contribution.finishMigration(); }); it("does not allow non-contributors to add a contribution", async function () { await expect(Contribution.connect(addr7).add( 500, 1, "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", - 18, 32 + 18, 32, 0, false )).to.be.revertedWith("requires kredits or core status"); expect(await Contribution.contributionsCount()).to.equal(0); }); + it("does not allow special arguments outside of a migration", async function () { + await expect(Contribution.connect(addr7).add( + 500, 1, + "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32, 23000, true + )).to.be.revertedWith("extra arguments during migration only"); + expect(await Contribution.contributionsCount()).to.equal(0); + }); + it("allows core contributors to add a contribution", async function () { await Contribution.connect(addr2).add( 2001, 1, "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", - 18, 32 + 18, 32, 0, false ); expect(await Contribution.contributionsCount()).to.equal(1); }); @@ -84,23 +94,65 @@ describe("Contribution contract", async function () { await Contribution.connect(addr1).add( 5000, 8, "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", - 18, 32 + 18, 32, 0, false ); await Contribution.connect(addr7).add( 1500, 1, "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", - 18, 32 + 18, 32, 0, false ); expect(await Contribution.contributionsCount()).to.equal(3); }); + it("sets confirmedAtBlock to current block plus blocksToWait", async function () { + await Contribution.connect(addr1).add( + 500, 3, + "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32, 0, false + ); + expect(await Contribution.contributionsCount()).to.equal(4); + const c = await Contribution.getContribution(4); + const currentBlockNumber = await kredits.provider.getBlockNumber(); + expect(c['confirmedAtBlock']).to.equal(currentBlockNumber + 1 + 40321); + }); + it("emits a ContributionAdded event", async function () { await expect(Contribution.connect(addr1).add( 2001, 1, "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", - 18, 32 + 18, 32, 0, false )).to.emit(Contribution, "ContributionAdded").withArgs(anyValue, 1, 2001); }); + + describe("with extra arguments during migration", async function () { + before(async function () { + const contributionFactory = await ethers.getContractFactory("Contribution"); + Contribution = await upgrades.deployProxy(contributionFactory, [40321]); + await Contribution.setContributorContract(Contributor.address).then(res => res.wait()) + }); + + it("allows to add a contribution with custom confirmedAtBlock", async function () { + await Contribution.connect(addr2).add( + 2001, 1, + "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32, 23000, false + ); + expect(await Contribution.contributionsCount()).to.equal(1); + const c = await Contribution.getContribution(1); + expect(c['confirmedAtBlock'].toNumber()).to.equal(23000); + }); + + it("allows to add a vetoed contribution", async function () { + await Contribution.connect(addr2).add( + 2001, 1, + "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32, 23000, true + ); + expect(await Contribution.contributionsCount()).to.equal(2); + const c = await Contribution.getContribution(2); + expect(c['vetoed']).to.be.true; + }); + }); }); }); From d72413eb66fac226be2b8cf013c32947284810c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 23 Aug 2022 16:34:56 +0100 Subject: [PATCH 14/21] Move contract test to its own subdirectory --- test/{ => contracts}/Contribution.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{ => contracts}/Contribution.js (100%) diff --git a/test/Contribution.js b/test/contracts/Contribution.js similarity index 100% rename from test/Contribution.js rename to test/contracts/Contribution.js From 796ccebd84cf34de4a8302e73ee1cf999f20b990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Wed, 24 Aug 2022 12:55:50 +0100 Subject: [PATCH 15/21] Add first Contributor contract test --- test/contracts/Contribution.js | 1 - test/contracts/Contributor.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 test/contracts/Contributor.js diff --git a/test/contracts/Contribution.js b/test/contracts/Contribution.js index b6d6a25..d46eed0 100644 --- a/test/contracts/Contribution.js +++ b/test/contracts/Contribution.js @@ -154,5 +154,4 @@ describe("Contribution contract", async function () { }); }); }); - }); diff --git a/test/contracts/Contributor.js b/test/contracts/Contributor.js new file mode 100644 index 0000000..d4f2716 --- /dev/null +++ b/test/contracts/Contributor.js @@ -0,0 +1,30 @@ +const { expect } = require("chai"); +const { ethers, upgrades } = require("hardhat"); +// const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); +let owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7; +let Contribution, Contributor; + +describe("Contributor contract", async function () { + before(async function () { + [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7] = await ethers.getSigners(); + // let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7]; + // const contributorFactory = await ethers.getContractFactory("Contributor"); + // Contributor = await upgrades.deployProxy(contributorFactory); + // for (const account of accounts) { + // await Contributor.addContributor(account.address, "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", 18, 32); + // } + }); + + describe("initialize()", function () { + before(async function () { + // const [owner] = await ethers.getSigners(); + const contributorFactory = await ethers.getContractFactory("Contributor"); + Contributor = await upgrades.deployProxy(contributorFactory); + }); + + it("sets the deployer address", async function () { + expect(await Contributor.deployer()).to.equal(owner.address); + expect(await Contributor.deployer()).to.not.equal(addr1.address); + }); + }); +}); From dc2c8130f33047210cd0c2f076f82e15aa6f42e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Wed, 24 Aug 2022 13:33:04 +0100 Subject: [PATCH 16/21] Add tests for Contributor#add() --- test/contracts/Contributor.js | 55 ++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/test/contracts/Contributor.js b/test/contracts/Contributor.js index d4f2716..e340aa2 100644 --- a/test/contracts/Contributor.js +++ b/test/contracts/Contributor.js @@ -1,23 +1,15 @@ const { expect } = require("chai"); const { ethers, upgrades } = require("hardhat"); -// const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); let owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7; let Contribution, Contributor; describe("Contributor contract", async function () { before(async function () { [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7] = await ethers.getSigners(); - // let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7]; - // const contributorFactory = await ethers.getContractFactory("Contributor"); - // Contributor = await upgrades.deployProxy(contributorFactory); - // for (const account of accounts) { - // await Contributor.addContributor(account.address, "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", 18, 32); - // } }); describe("initialize()", function () { before(async function () { - // const [owner] = await ethers.getSigners(); const contributorFactory = await ethers.getContractFactory("Contributor"); Contributor = await upgrades.deployProxy(contributorFactory); }); @@ -27,4 +19,51 @@ describe("Contributor contract", async function () { expect(await Contributor.deployer()).to.not.equal(addr1.address); }); }); + + describe("add()", function () { + before(async function () { + const contributorFactory = await ethers.getContractFactory("Contributor"); + Contributor = await upgrades.deployProxy(contributorFactory); + + let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7]; + for (const account of accounts) { + await Contributor.addContributor(account.address, "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", 18, 32); + } + }); + + it("does not allow random accounts to create a contributor profile", async function () { + await expect(Contributor.connect(addr7).addContributor( + "0x608FD4b95116Ea616990Aaeb1d4f1ce07612f261", + "0x1d9de6de5c72eedca6d7a5e8a9159e2f5fe676506aece3000acefcc821723429", + 18, 32 + )).to.be.revertedWith("Core only"); + expect(await Contributor.contributorsCount()).to.equal(8); + }); + + it("allows core contributors to create a contributor profile", async function () { + await Contributor.connect(addr1).addContributor( + "0x608FD4b95116Ea616990Aaeb1d4f1ce07612f261", + "0x1d9de6de5c72eedca6d7a5e8a9159e2f5fe676506aece3000acefcc821723429", + 18, 32 + ) + expect(await Contributor.contributorsCount()).to.equal(9); + }); + + it("does not allow to create accounts with an existing address", async function () { + await expect(Contributor.connect(addr1).addContributor( + "0x608FD4b95116Ea616990Aaeb1d4f1ce07612f261", + "0x1d9de6de5c72eedca6d7a5e8a9159e2f5fe676506aece3000acefcc821723429", + 18, 32 + )).to.be.revertedWith("Address already in use"); + expect(await Contributor.contributorsCount()).to.equal(9); + }); + + it("emits a ContributorAdded event", async function () { + await expect(Contributor.connect(addr1).addContributor( + "0x765E88b4F9a59C3a3b300C6eFF9E6E9fDDf9FbD9", + "0xcfbeeadc244dfdc55bbad50d431871439df067970db84c73023956c96a6f5df2", + 18, 32 + )).to.emit(Contributor, "ContributorAdded").withArgs(10, "0x765E88b4F9a59C3a3b300C6eFF9E6E9fDDf9FbD9"); + }); + }); }); From 2b3fd1241d6b88d291c458d15f4a800ad3aecb4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Thu, 25 Aug 2022 10:39:28 +0200 Subject: [PATCH 17/21] WIP Remove claims, add withdrawals --- contracts/Contribution.sol | 32 +-------------- contracts/Contributor.sol | 33 +++++++++++++--- contracts/Token.sol | 18 +++------ lib/abis/Contribution.json | 2 +- lib/abis/Contributor.json | 2 +- lib/abis/Token.json | 2 +- scripts/create-proxy.js | 18 --------- scripts/list-contributions.js | 3 +- test/contracts/Contribution.js | 2 +- test/contracts/Contributor.js | 71 ++++++++++++++++++++++++++-------- 10 files changed, 93 insertions(+), 90 deletions(-) diff --git a/contracts/Contribution.sol b/contracts/Contribution.sol index b4b65a0..6589f8d 100644 --- a/contracts/Contribution.sol +++ b/contracts/Contribution.sol @@ -2,10 +2,6 @@ pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -interface IToken { - function mintFor(address contributorAccount, uint256 amount, uint32 contributionId) external; -} - interface ContributorInterface { function getContributorAddressById(uint32 contributorId) external view returns (address); function getContributorIdByAddress(address contributorAccount) external view returns (uint32); @@ -16,12 +12,10 @@ interface ContributorInterface { contract Contribution is Initializable { ContributorInterface public contributorContract; - IToken public tokenContract; struct ContributionData { uint32 contributorId; uint32 amount; - bool claimed; bytes32 hashDigest; uint8 hashFunction; uint8 hashSize; @@ -52,7 +46,6 @@ contract Contribution is Initializable { bool public migrationDone; event ContributionAdded(uint32 id, uint32 indexed contributorId, uint32 amount); - event ContributionClaimed(uint32 id, uint32 indexed contributorId, uint32 amount); event ContributionVetoed(uint32 id, address vetoedByAccount); modifier onlyCore { @@ -75,11 +68,6 @@ contract Contribution is Initializable { migrationDone = true; } - function setTokenContract(address token) public { - require(address(tokenContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only"); - tokenContract = IToken(token); - } - function setContributorContract(address contributor) public { require(address(contributorContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only"); contributorContract = ContributorInterface(contributor); @@ -151,14 +139,13 @@ contract Contribution is Initializable { } } - function getContribution(uint32 contributionId) public view returns (uint32 id, uint32 contributorId, uint32 amount, bool claimed, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint256 confirmedAtBlock, bool exists, bool vetoed) { + function getContribution(uint32 contributionId) public view returns (uint32 id, uint32 contributorId, uint32 amount, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint256 confirmedAtBlock, bool exists, bool vetoed) { id = contributionId; ContributionData storage c = contributions[id]; return ( id, c.contributorId, c.amount, - c.claimed, c.hashDigest, c.hashFunction, c.hashSize, @@ -178,7 +165,6 @@ contract Contribution is Initializable { ContributionData storage c = contributions[contributionId]; c.exists = true; c.amount = amount; - c.claimed = false; c.contributorId = contributorId; c.hashDigest = hashDigest; c.hashFunction = hashFunction; @@ -203,29 +189,13 @@ contract Contribution is Initializable { function veto(uint32 contributionId) public onlyCore { ContributionData storage c = contributions[contributionId]; require(c.exists, 'NOT_FOUND'); - require(!c.claimed, 'ALREADY_CLAIMED'); require(block.number < c.confirmedAtBlock, 'VETO_PERIOD_ENDED'); c.vetoed = true; emit ContributionVetoed(contributionId, msg.sender); } - function claim(uint32 contributionId) public { - ContributionData storage c = contributions[contributionId]; - require(c.exists, 'NOT_FOUND'); - require(!c.claimed, 'ALREADY_CLAIMED'); - require(!c.vetoed, 'VETOED'); - require(block.number >= c.confirmedAtBlock, 'NOT_CLAIMABLE'); - - c.claimed = true; - address contributorAccount = getContributorAddressById(c.contributorId); - uint256 amount = uint256(c.amount); - tokenContract.mintFor(contributorAccount, amount, contributionId); - emit ContributionClaimed(contributionId, c.contributorId, c.amount); - } - function exists(uint32 contributionId) public view returns (bool) { return contributions[contributionId].exists; } - } diff --git a/contracts/Contributor.sol b/contracts/Contributor.sol index a2255b4..f33e337 100644 --- a/contracts/Contributor.sol +++ b/contracts/Contributor.sol @@ -2,7 +2,8 @@ pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -interface ITokenBalance { +interface IToken { + function mintFor(address contributorAccount, uint256 amount) external; function balanceOf(address contributorAccount) external view returns (uint256); } interface IContributionBalance { @@ -11,9 +12,9 @@ interface IContributionBalance { } contract Contributor is Initializable { - address deployer; + address public deployer; IContributionBalance public contributionContract; - ITokenBalance public tokenContract; + IToken public tokenContract; struct Contributor { address account; @@ -21,6 +22,7 @@ contract Contributor is Initializable { uint8 hashFunction; uint8 hashSize; bool exists; + uint256 kreditsWithdrawn; } mapping (address => uint32) public contributorIds; @@ -36,6 +38,11 @@ contract Contributor is Initializable { _; } + modifier onlyContributors { + require(addressExists(msg.sender) && contributionContract.balanceOf(msg.sender) > 0, "Contributors only"); + _; + } + function initialize() public initializer { deployer = msg.sender; } @@ -47,7 +54,7 @@ contract Contributor is Initializable { function setTokenContract(address token) public onlyCore { require(address(tokenContract) == address(0) || addressIsCore(msg.sender), "Core only"); - tokenContract = ITokenBalance(token); + tokenContract = IToken(token); } function coreContributorsCount() public view returns (uint32) { @@ -81,7 +88,7 @@ contract Contributor is Initializable { } function addContributor(address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public onlyCore { - require(!addressExists(account)); + require(!addressExists(account), "Address already in use"); uint32 _id = contributorsCount + 1; assert(!contributors[_id].exists); // this can not be acually Contributor storage c = contributors[_id]; @@ -90,6 +97,7 @@ contract Contributor is Initializable { c.hashFunction = hashFunction; c.hashSize = hashSize; c.account = account; + c.kreditsWithdrawn = 0; contributorIds[account] = _id; contributorsCount += 1; @@ -132,7 +140,7 @@ contract Contributor is Initializable { return contributors[id]; } - function getContributorById(uint32 _id) public view returns (uint32 id, address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, bool isCore, uint256 balance, uint32 totalKreditsEarned, uint256 contributionsCount, bool exists ) { + function getContributorById(uint32 _id) view public returns (uint32 id, address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, bool isCore, uint256 balance, uint32 totalKreditsEarned, uint256 contributionsCount, bool exists, uint256 kreditsWithdrawn) { id = _id; Contributor storage c = contributors[_id]; account = c.account; @@ -144,6 +152,19 @@ contract Contributor is Initializable { totalKreditsEarned = contributionContract.totalKreditsEarnedByContributor(_id, true); contributionsCount = contributionContract.balanceOf(c.account); exists = c.exists; + kreditsWithdrawn = c.kreditsWithdrawn; } + function withdraw() public onlyContributors { + uint32 id = getContributorIdByAddress(msg.sender); + Contributor storage c = contributors[id]; + + // TODO check if we need a failsafe for unconfirmed or malicious txs + uint256 confirmedKredits = contributionContract.totalKreditsEarnedByContributor(id, true); + uint256 amountWithdrawable = confirmedKredits - c.kreditsWithdrawn; + require (amountWithdrawable > 0, "No kredits available"); + + c.kreditsWithdrawn += amountWithdrawable; + tokenContract.mintFor(msg.sender, amountWithdrawable); + } } diff --git a/contracts/Token.sol b/contracts/Token.sol index d5aa872..ba9cae7 100644 --- a/contracts/Token.sol +++ b/contracts/Token.sol @@ -7,38 +7,32 @@ interface ContributorInterface { function getContributorAddressById(uint32 contributorId) external view returns (address); function getContributorIdByAddress(address contributorAccount) external view returns (uint32); function addressIsCore(address sender) external view returns (bool); - // TODO Maybe use for validation - // function exists(uint32 contributorId) public view returns (bool); } contract Token is Initializable, ERC20Upgradeable { ContributorInterface public contributorContract; using SafeMathUpgradeable for uint256; - address public contributionContract; + address public contributorContractAddress; - event LogMint(address indexed recipient, uint256 amount, uint32 contributionId); + event KreditsMinted(address indexed recipient, uint256 amount); function initialize() public virtual initializer { __ERC20_init('Kredits', 'KS'); } - function setContributionContract(address contribution) public { - require(address(contributionContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only"); - contributionContract = contribution; - } function setContributorContract(address contributor) public { require(address(contributorContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only"); contributorContract = ContributorInterface(contributor); + contributorContractAddress = contributor; } - function mintFor(address contributorAccount, uint256 amount, uint32 contributionId) public { - require(contributionContract == msg.sender, "Only Contribution"); + function mintFor(address contributorAccount, uint256 amount) public { + require(contributorContractAddress == msg.sender, "Only Contributor"); require(amount > 0, "INVALID_AMOUNT"); uint256 amountInWei = amount.mul(1 ether); _mint(contributorAccount, amountInWei); - emit LogMint(contributorAccount, amount, contributionId); + emit KreditsMinted(contributorAccount, amount); } - } diff --git a/lib/abis/Contribution.json b/lib/abis/Contribution.json index 78552d1..2c69623 100644 --- a/lib/abis/Contribution.json +++ b/lib/abis/Contribution.json @@ -1 +1 @@ -[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"contributorId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"ContributionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"contributorId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"ContributionClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ContributionVetoed","type":"event"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributionOwner","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributions","outputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"string","name":"tokenMetadataURL","type":"string"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finishMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"getContribution","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"blocksToWait_","type":"uint32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationDone","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownedContributions","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setTokenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenContract","outputs":[{"internalType":"contract IToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"tokenMetadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint32","name":"index","type":"uint32"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalKreditsEarned","outputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalKreditsEarnedByContributor","outputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"contributorId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"ContributionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ContributionVetoed","type":"event"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributionOwner","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributions","outputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"string","name":"tokenMetadataURL","type":"string"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finishMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"getContribution","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"blocksToWait_","type":"uint32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationDone","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownedContributions","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"tokenMetadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint32","name":"index","type":"uint32"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalKreditsEarned","outputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalKreditsEarnedByContributor","outputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abis/Contributor.json b/lib/abis/Contributor.json index 4e96e9f..662f701 100644 --- a/lib/abis/Contributor.json +++ b/lib/abis/Contributor.json @@ -1 +1 @@ -[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"oldAccount","type":"address"},{"indexed":false,"internalType":"address","name":"newAccount","type":"address"}],"name":"ContributorAccountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ContributorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"oldHashDigest","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"newHashDigest","type":"bytes32"}],"name":"ContributorProfileUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"addContributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addressExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addressIsCore","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionContract","outputs":[{"internalType":"contract IContributionBalance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"contributorIds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributors","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coreContributorsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_id","type":"uint32"}],"name":"getContributorById","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"bool","name":"isCore","type":"bool"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint32","name":"totalKreditsEarned","type":"uint32"},{"internalType":"uint256","name":"contributionsCount","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"isCoreTeam","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contribution","type":"address"}],"name":"setContributionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setTokenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenContract","outputs":[{"internalType":"contract ITokenBalance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"oldAccount","type":"address"},{"internalType":"address","name":"newAccount","type":"address"}],"name":"updateContributorAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"updateContributorProfileHash","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"oldAccount","type":"address"},{"indexed":false,"internalType":"address","name":"newAccount","type":"address"}],"name":"ContributorAccountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ContributorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"oldHashDigest","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"newHashDigest","type":"bytes32"}],"name":"ContributorProfileUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"addContributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addressExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addressIsCore","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionContract","outputs":[{"internalType":"contract IContributionBalance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"contributorIds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributors","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint256","name":"kreditsWithdrawn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coreContributorsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_id","type":"uint32"}],"name":"getContributorById","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"bool","name":"isCore","type":"bool"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint32","name":"totalKreditsEarned","type":"uint32"},{"internalType":"uint256","name":"contributionsCount","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint256","name":"kreditsWithdrawn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"isCoreTeam","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contribution","type":"address"}],"name":"setContributionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setTokenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenContract","outputs":[{"internalType":"contract IToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"oldAccount","type":"address"},{"internalType":"address","name":"newAccount","type":"address"}],"name":"updateContributorAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"updateContributorProfileHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abis/Token.json b/lib/abis/Token.json index 7221b85..0f1a165 100644 --- a/lib/abis/Token.json +++ b/lib/abis/Token.json @@ -1 +1 @@ -[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"mintFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contribution","type":"address"}],"name":"setContributionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"KreditsMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/scripts/create-proxy.js b/scripts/create-proxy.js index 80c9a0f..44bfa03 100644 --- a/scripts/create-proxy.js +++ b/scripts/create-proxy.js @@ -57,16 +57,6 @@ async function main() { return res.wait(); }).catch(handleError); - - console.log('Calling Contribution#setTokenContract') - await contracts.Contribution.functions - .setTokenContract(contracts.Token.address) - .then(res => { - console.log(`...transaction published: ${res.hash}`); - return res.wait(); - }).catch(handleError); - - console.log('Calling Contribution#setContributorContract') await contracts.Contribution.functions .setContributorContract(contracts.Contributor.address) @@ -75,14 +65,6 @@ async function main() { return res.wait(); }).catch(handleError); - console.log('Calling Token#setContributionContract') - await contracts.Token.functions - .setContributionContract(contracts.Contribution.address) - .then(res => { - console.log(`...transaction published: ${res.hash}`); - return res.wait(); - }).catch(handleError); - console.log('Calling Token#setContributorContract') await contracts.Token.functions .setContributorContract(contracts.Contributor.address) diff --git a/scripts/list-contributions.js b/scripts/list-contributions.js index b884f29..7d4304a 100644 --- a/scripts/list-contributions.js +++ b/scripts/list-contributions.js @@ -12,7 +12,7 @@ async function main() { console.log(`Using Contribution at: ${kredits.Contribution.contract.address}`); const table = new Table({ - head: ['ID', 'Contributor ID', 'Description', 'Amount', 'Confirmed?', 'Vetoed?', 'Claimed?', 'IPFS'] + head: ['ID', 'Contributor ID', 'Description', 'Amount', 'Confirmed?', 'Vetoed?', 'IPFS'] }) try { @@ -31,7 +31,6 @@ async function main() { c.amount.toString(), `${confirmed} (${c.confirmedAtBlock})`, c.vetoed, - c.claimed, c.ipfsHash ]) }); diff --git a/test/contracts/Contribution.js b/test/contracts/Contribution.js index d46eed0..ef189d6 100644 --- a/test/contracts/Contribution.js +++ b/test/contracts/Contribution.js @@ -128,7 +128,7 @@ describe("Contribution contract", async function () { before(async function () { const contributionFactory = await ethers.getContractFactory("Contribution"); Contribution = await upgrades.deployProxy(contributionFactory, [40321]); - await Contribution.setContributorContract(Contributor.address).then(res => res.wait()) + await Contribution.setContributorContract(Contributor.address); }); it("allows to add a contribution with custom confirmedAtBlock", async function () { diff --git a/test/contracts/Contributor.js b/test/contracts/Contributor.js index e340aa2..02ece20 100644 --- a/test/contracts/Contributor.js +++ b/test/contracts/Contributor.js @@ -1,19 +1,31 @@ const { expect } = require("chai"); const { ethers, upgrades } = require("hardhat"); let owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7; -let Contribution, Contributor; +let Contribution, Contributor, Token; describe("Contributor contract", async function () { before(async function () { [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7] = await ethers.getSigners(); + + const contributorFactory = await ethers.getContractFactory("Contributor"); + Contributor = await upgrades.deployProxy(contributorFactory); + const contributionFactory = await ethers.getContractFactory("Contribution"); + Contribution = await upgrades.deployProxy(contributionFactory, [40321]); + const tokenFactory = await ethers.getContractFactory("Token"); + Token = await upgrades.deployProxy(tokenFactory); + + await Contributor.setTokenContract(Token.address); + await Contributor.setContributionContract(Contribution.address); + await Contribution.setContributorContract(Contributor.address); + await Token.setContributorContract(Contributor.address); + + let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7]; + for (const account of accounts) { + await Contributor.addContributor(account.address, "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", 18, 32); + } }); describe("initialize()", function () { - before(async function () { - const contributorFactory = await ethers.getContractFactory("Contributor"); - Contributor = await upgrades.deployProxy(contributorFactory); - }); - it("sets the deployer address", async function () { expect(await Contributor.deployer()).to.equal(owner.address); expect(await Contributor.deployer()).to.not.equal(addr1.address); @@ -21,16 +33,6 @@ describe("Contributor contract", async function () { }); describe("add()", function () { - before(async function () { - const contributorFactory = await ethers.getContractFactory("Contributor"); - Contributor = await upgrades.deployProxy(contributorFactory); - - let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7]; - for (const account of accounts) { - await Contributor.addContributor(account.address, "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", 18, 32); - } - }); - it("does not allow random accounts to create a contributor profile", async function () { await expect(Contributor.connect(addr7).addContributor( "0x608FD4b95116Ea616990Aaeb1d4f1ce07612f261", @@ -45,8 +47,11 @@ describe("Contributor contract", async function () { "0x608FD4b95116Ea616990Aaeb1d4f1ce07612f261", "0x1d9de6de5c72eedca6d7a5e8a9159e2f5fe676506aece3000acefcc821723429", 18, 32 - ) + ); expect(await Contributor.contributorsCount()).to.equal(9); + const c = await Contributor.getContributorById(9); + expect(c['account']).to.equal("0x608FD4b95116Ea616990Aaeb1d4f1ce07612f261"); + expect(c['kreditsWithdrawn']).to.equal(0); }); it("does not allow to create accounts with an existing address", async function () { @@ -66,4 +71,36 @@ describe("Contributor contract", async function () { )).to.emit(Contributor, "ContributorAdded").withArgs(10, "0x765E88b4F9a59C3a3b300C6eFF9E6E9fDDf9FbD9"); }); }); + + describe("withdraw()", function () { + before(async function () { + // Add some pre-confirmed contributions (confirmedAtBlock 1) + await Contribution.add( + 1500, 2, "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32, 1, false + ); + await Contribution.add( + 5000, 2, "0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f", + 18, 32, 1, false + ); + await Contribution.finishMigration(); + }); + + it("requires the transaction sender to be a contributor", async function () { + await expect(Contributor.withdraw()).to.be.revertedWith("Contributors only"); + }); + + it("executes a withdrawal of all available ERC20 kredits", async function () { + let c = await Contributor.getContributorById(2); + expect(c['balance']).to.equal(0); + await Contributor.connect(addr1).withdraw(); + c = await Contributor.getContributorById(2); + // TODO Are we required to use Wei for ERC20 tokens? + expect(c['balance'].toString()).to.equal("6500000000000000000000"); + }); + + it("requires the withdrawable amount to be larger than 0", async function () { + await expect(Contributor.connect(addr1).withdraw()).to.be.revertedWith("No kredits available"); + }); + }); }); From e99184b83f32bb24276a80754d67fd10006a6bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Thu, 25 Aug 2022 11:51:31 +0200 Subject: [PATCH 18/21] Make test complete, add FIXME note --- test/contracts/Contributor.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/contracts/Contributor.js b/test/contracts/Contributor.js index 02ece20..3639c77 100644 --- a/test/contracts/Contributor.js +++ b/test/contracts/Contributor.js @@ -97,6 +97,8 @@ describe("Contributor contract", async function () { c = await Contributor.getContributorById(2); // TODO Are we required to use Wei for ERC20 tokens? expect(c['balance'].toString()).to.equal("6500000000000000000000"); + // FIXME This is also a BigNumber (uint256), but stored at Wei reolution + expect(c['kreditsWithdrawn'].toString()).to.equal('6500'); }); it("requires the withdrawable amount to be larger than 0", async function () { From 5da710cc14203d64dff4786a51b2051945c90147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Sat, 27 Aug 2022 10:29:56 +0200 Subject: [PATCH 19/21] Use uint32 for kreditsWithdrawn Same as the properties and functions in the Contribution contract --- contracts/Contributor.sol | 6 +++--- test/contracts/Contributor.js | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/contracts/Contributor.sol b/contracts/Contributor.sol index f33e337..f2ad60d 100644 --- a/contracts/Contributor.sol +++ b/contracts/Contributor.sol @@ -22,7 +22,7 @@ contract Contributor is Initializable { uint8 hashFunction; uint8 hashSize; bool exists; - uint256 kreditsWithdrawn; + uint32 kreditsWithdrawn; } mapping (address => uint32) public contributorIds; @@ -160,8 +160,8 @@ contract Contributor is Initializable { Contributor storage c = contributors[id]; // TODO check if we need a failsafe for unconfirmed or malicious txs - uint256 confirmedKredits = contributionContract.totalKreditsEarnedByContributor(id, true); - uint256 amountWithdrawable = confirmedKredits - c.kreditsWithdrawn; + uint32 confirmedKredits = contributionContract.totalKreditsEarnedByContributor(id, true); + uint32 amountWithdrawable = confirmedKredits - c.kreditsWithdrawn; require (amountWithdrawable > 0, "No kredits available"); c.kreditsWithdrawn += amountWithdrawable; diff --git a/test/contracts/Contributor.js b/test/contracts/Contributor.js index 3639c77..e20c02c 100644 --- a/test/contracts/Contributor.js +++ b/test/contracts/Contributor.js @@ -95,10 +95,8 @@ describe("Contributor contract", async function () { expect(c['balance']).to.equal(0); await Contributor.connect(addr1).withdraw(); c = await Contributor.getContributorById(2); - // TODO Are we required to use Wei for ERC20 tokens? expect(c['balance'].toString()).to.equal("6500000000000000000000"); - // FIXME This is also a BigNumber (uint256), but stored at Wei reolution - expect(c['kreditsWithdrawn'].toString()).to.equal('6500'); + expect(c['kreditsWithdrawn']).to.equal(6500); }); it("requires the withdrawable amount to be larger than 0", async function () { From f29054bc0bb4afeff03fdbebd22c33cfbc939122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Tue, 30 Aug 2022 12:18:45 +0200 Subject: [PATCH 20/21] Add script for importing contributions --- scripts/import/contributions.js | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 scripts/import/contributions.js diff --git a/scripts/import/contributions.js b/scripts/import/contributions.js new file mode 100644 index 0000000..e0a8466 --- /dev/null +++ b/scripts/import/contributions.js @@ -0,0 +1,39 @@ +const fs = require('fs'); +const Kredits = require('../../lib/kredits'); + +async function main() { + kredits = new Kredits(hre.ethers.provider, hre.ethers.provider.getSigner()) + await kredits.init(); + + console.log(`Using Contribution at: ${kredits.Contribution.contract.address}`); + + try { + const data = fs.readFileSync("./data/contributions.json"); + const contributions = JSON.parse(data); + const ids = Object.keys(contributions) + .map(k => parseInt(k)) + .sort(function(a, b){return a-b}); + + const currentBlockHeight = await kredits.provider.getBlockNumber(); + const confirmationPeriod = 40320 // blocks + const unconfirmedHeight = currentBlockHeight + confirmationPeriod; + + for (const contributionId of ids) { + const c = contributions[contributionId.toString()]; + + const confirmedAtBlock = c.confirmed ? currentBlockHeight : unconfirmedHeight; + + const result = await kredits.Contribution.contract.add( + c.amount, c.contributorId, + c.hashDigest, c.hashFunction, c.hashSize, + confirmedAtBlock, c.vetoed + ); + // await result.wait(); + console.log(`Added contribution #${contributionId}: ${result.hash}`); + }; + } catch(e) { + console.log(e); + } +} + +main(); From 258c1cc755d47855b3fe6fbda484605d5c6a8208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Wed, 31 Aug 2022 09:55:26 +0200 Subject: [PATCH 21/21] Use ethers from correct parent object --- scripts/export/contributions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/export/contributions.js b/scripts/export/contributions.js index 18e9da5..2d8b9a8 100644 --- a/scripts/export/contributions.js +++ b/scripts/export/contributions.js @@ -7,7 +7,7 @@ async function main() { console.log(`Using Contribution at: ${kredits.Contribution.contract.address}`); const count = await kredits.Contribution.count; - const currentBlockHeight = await XMLHttpRequest.ethers.provider.getBlockNumber(); + const currentBlockHeight = await hre.ethers.provider.getBlockNumber(); const backup = {}; const promises = [];