Compare commits

...

28 Commits

Author SHA1 Message Date
Râu Cao
796ccebd84 Add first Contributor contract test
Some checks failed
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is failing
2022-08-24 12:55:50 +01:00
Râu Cao
d72413eb66 Move contract test to its own subdirectory
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2022-08-23 16:34:56 +01:00
Râu Cao
9dd9d298cc Allow setting confirmedAtBlock and vetoed during migration
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2022-08-23 16:20:50 +01:00
Râu Cao
67add71a22 Add tests for Contribution#add()
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2022-08-23 14:41:30 +01:00
Râu Cao
cd07313679 Revert core flag change
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2022-08-23 13:14:19 +01:00
Râu Cao
90172071fa Add test for setting deployer address
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2022-08-23 12:20:42 +01:00
Râu Cao
de1574155c Allow deployer to set a migration-done flag
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
* 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
2022-08-23 12:15:16 +01:00
Râu Cao
0fc4eed09a CI
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2022-08-23 10:55:35 +01:00
Râu Cao
55877897be Formatting
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2022-08-23 10:42:33 +01:00
Râu Cao
59bda71f97 Add mocha, chai, and test for Contribution 2022-08-23 10:42:07 +01:00
Râu Cao
1521e272f9 Finish contributor import script
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2022-08-23 10:01:37 +01:00
Râu Cao
990e2a9649 Also export vetoed contributions
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2022-08-23 09:50:46 +01:00
Râu Cao
883f9adb96 Fix ignored contributions not resolving their promise
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2022-08-23 09:39:05 +01:00
Râu Cao
550bc2b9f4 Improve console output 2022-08-23 09:38:35 +01:00
2fca436fa8 Added export/import function for contributors
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2022-08-22 18:12:18 +02:00
2b05be1897 Merge pull request 'Add linting and contract builds to CI' (#222) from feature/183-ci_linting into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #222
2022-08-10 16:31:31 +00:00
Râu Cao
46b1bbfbf2 Disable contract linting for now
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
So we can continue with actual tests, and fix the linter warnings
separately from other ongoing work.
2022-08-10 11:18:28 +01:00
Râu Cao
98348dc544 Build contracts in CI
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2022-08-09 16:18:28 +01:00
Râu Cao
fd93993a1b Nicer step names
Some checks failed
continuous-integration/drone/push Build is failing
2022-08-09 16:00:29 +01:00
Râu Cao
0d6702fd2b Add JS and Solidity linting to CI 2022-08-09 15:56:08 +01:00
Râu Cao
51e50e7c46 CI: Split setup and test steps
All checks were successful
continuous-integration/drone/push Build is passing
2022-08-09 15:52:16 +01:00
793642c238 Merge pull request 'Set up Drone CI' (#221) from feature/ci_setup into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #221
2022-08-09 14:39:27 +00:00
Râu Cao
c55593d46f Add Docker image configs
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2022-08-08 18:20:38 +02:00
Râu Cao
2b314556ad Set up Drone CI 2022-08-08 18:20:32 +02:00
53955126ff 7.0.0-beta.0 2022-07-16 16:27:56 +02:00
1d1f2bb4ed Merge pull request #218 from 67P/feature/217-rsk_deployment
Refactor deployment script, add error handling
2022-07-16 11:04:55 +02:00
42a2945692 Merge pull request #219 from 67P/feature/217-rsk_deployment-1
Fix typo and add more logs
2022-07-16 11:04:08 +02:00
12326ce73f Fix typo and add more logs 2022-07-15 18:19:06 +02:00
19 changed files with 1167 additions and 235 deletions

6
.dockerignore Normal file
View File

@@ -0,0 +1,6 @@
.openzeppelin
artifacts
cache
deployments
gitno
node_modules

40
.drone.yml Normal file
View File

@@ -0,0 +1,40 @@
kind: pipeline
type: docker
name: default
steps:
- name: setup
image: gitea.kosmos.org/kredits/docker-ci:latest
commands:
- cp -r /app/node_modules /drone/src/node_modules
- chown -R drone:drone /drone/src
- su drone -c 'npm install'
- name: lint js
image: gitea.kosmos.org/kredits/docker-ci:latest
commands:
- su drone -c 'npm run lint:wrapper'
depends_on:
- setup
# - name: lint contracts
# image: gitea.kosmos.org/kredits/docker-ci:latest
# commands:
# - su drone -c 'npm run lint:contracts'
# depends_on:
# - setup
- name: build contracts
image: gitea.kosmos.org/kredits/docker-ci:latest
commands:
- su drone -c 'npm run devchain -- --silent' &
- sleep 5
- su drone -c 'npm run build'
depends_on:
- setup
- name: test
image: gitea.kosmos.org/kredits/docker-ci:latest
commands:
- su drone -c 'npm run devchain -- --silent' &
- sleep 5
- su drone -c 'npm test'
depends_on:
- setup
- build contracts

View File

@@ -1 +1,2 @@
/scripts/
/test/

2
.gitignore vendored
View File

@@ -5,6 +5,8 @@ node_modules
yarn-error.log
.DS_Store
data
cache
artifacts
.openzeppelin

View File

@@ -1,38 +0,0 @@
---
language: node_js
node_js:
- "12"
sudo: false
dist: xenial
cache:
directories:
- node_modules
- apps/contribution/node_modules
- apps/contributor/node_modules
- apps/proposal/node_modules
- apps/token/node_modules
- apps/vault/node_modules
install:
- npm install -g @aragon/cli
- npm install -g truffle
- npm install
before_script:
- npm run devchain &
- sleep 10
script:
- npm run lint:wrapper
- npm run lint:contract-tests
# FIXME Fix tests
# - npm run test:token
# - npm run test:contributor
# - npm run test:contribution
# - npm run test:proposal
branches:
only:
- master

13
Dockerfile Normal file
View File

@@ -0,0 +1,13 @@
# syntax=docker/dockerfile:1
FROM node:16.16
#ENV NODE_ENV=production
RUN useradd -ms /bin/bash drone
WORKDIR /app
COPY ["package.json", "package-lock.json*", "./"]
RUN chown -R drone:drone /app
USER drone
RUN npm install
USER root

View File

@@ -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);
@@ -150,9 +168,12 @@ 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');
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;
@@ -162,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;
@@ -177,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');

View File

@@ -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");

File diff suppressed because one or more lines are too long

View File

@@ -1,8 +1,8 @@
{
"1337": {
"Contributor": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
"Contribution": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
"Token": "0x0165878A594ca255338adfa4d48449f69242Eb8F",
"Reimbursement": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6"
"Contributor": "0xCc66f9A3cA2670972938FAD91d0865c4a62DFB25",
"Contribution": "0x8999CaBc43E28202c5A2257f2a95A45b1F8A62BD",
"Token": "0xe082678eCF749982e33Ea6839852a8cd989aEDE2",
"Reimbursement": "0x984f797d26d3da2E9b9f8Ae4eeFEACC60fCAA90C"
}
}

View File

@@ -58,7 +58,7 @@ class Contribution extends Record {
ipfsHashAttr.hashSize,
];
return this.contract.add(...contribution, callOptions);
return this.contract.add(...contribution, 0, false, callOptions);
});
}

874
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "kredits-contracts",
"version": "6.0.0",
"version": "7.0.0-beta.0",
"description": "Ethereum contracts and npm wrapper for Kredits",
"main": "./lib/kredits.js",
"directories": {
@@ -21,7 +21,7 @@
"lint:contracts": "solhint \"contracts/**/*.sol\" \"apps/*/contracts/**/*.sol\"",
"lint:contract-tests": "eslint apps/*/test",
"lint:wrapper": "eslint lib/",
"test": "npm run test:token && npm run test:contributor && npm run test:contribution && npm run test:proposal",
"test": "hardhat test",
"test:token": "cd apps/token && npm run test",
"test:contributor": "cd apps/contributor && npm run test",
"test:contribution": "cd apps/contribution && npm run test",
@@ -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",

View File

@@ -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);
@@ -22,7 +24,7 @@ async function main() {
let contract = await upgrades.deployProxy(contractFactories[contractName], params)
.catch(handleError);
contracts[contractName.toLowerCase()] = contract;
contracts[contractName] = contract;
await contract.deployed().then(() => {
console.log(`${contractName} deployed to:`, contract.address);
@@ -39,30 +41,63 @@ async function main() {
await deployContractProxy('Token');
await deployContractProxy('Reimbursement');
await contracts.Contributor
console.log('Calling Contributor#setTokenContract')
await contracts.Contributor.functions
.setTokenContract(contracts.Token.address)
.then(res => res.wait()).catch(handleError);
await contracts.Contributor
.setContributionContract(contracts.Contribution.address)
.then(res => res.wait()).catch(handleError);
.then(res => {
console.log(`...transaction published: ${res.hash}`);
return res.wait();
}).catch(handleError);
await contracts.Contribution
console.log('Calling Contributor#setContributionContract')
await contracts.Contributor.functions
.setContributionContract(contracts.Contribution.address)
.then(res => {
console.log(`...transaction published: ${res.hash}`);
return res.wait();
}).catch(handleError);
console.log('Calling Contribution#setTokenContract')
await contracts.Contribution.functions
.setTokenContract(contracts.Token.address)
.then(res => res.wait()).catch(handleError);
await contracts.Contribution
.setContributorContract(contracts.Contributor.address)
.then(res => res.wait()).catch(handleError);
.then(res => {
console.log(`...transaction published: ${res.hash}`);
return res.wait();
}).catch(handleError);
await contracts.Token
console.log('Calling Contribution#setContributorContract')
await contracts.Contribution.functions
.setContributorContract(contracts.Contributor.address)
.then(res => {
console.log(`...transaction published: ${res.hash}`);
return res.wait();
}).catch(handleError);
console.log('Calling Token#setContributionContract')
await contracts.Token.functions
.setContributionContract(contracts.Contribution.address)
.then(res => res.wait()).catch(handleError);
await contracts.Token
.setContributorContract(contracts.Contributor.address)
.then(res => res.wait()).catch(handleError);
.then(res => {
console.log(`...transaction published: ${res.hash}`);
return res.wait();
}).catch(handleError);
await contracts.Reimbursement
console.log('Calling Token#setContributorContract')
await contracts.Token.functions
.setContributorContract(contracts.Contributor.address)
.then(res => res.wait()).catch(handleError);
.then(res => {
console.log(`...transaction published: ${res.hash}`);
return res.wait();
}).catch(handleError);
console.log('Calling Reimbursement#setContributorContract')
await contracts.Reimbursement.functions
.setContributorContract(contracts.Contributor.address)
.then(res => {
console.log(`...transaction published: ${res.hash}`);
return res.wait();
}).catch(handleError);
const addresses = {
Contributor: contracts.Contributor.address,

View File

@@ -0,0 +1,42 @@
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 => {
backup[i] = {
amount: contractData.amount,
contributorId: contractData.contributorId,
hashDigest: contractData.hashDigest,
hashFunction: contractData.hashFunction,
hashSize: contractData.hashSize,
confirmedAtBlock: contractData.confirmedAtBlock,
confirmed: contractData.confirmedAtBlock <= currentBlockHeight,
vetoed: contractData.vetoed,
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();

View File

@@ -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();

View File

@@ -0,0 +1,33 @@
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}`);
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});
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();

View File

@@ -0,0 +1,157 @@
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("Contribution 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 contributionFactory = await ethers.getContractFactory("Contribution");
Contribution = await upgrades.deployProxy(contributionFactory, [40321]);
});
it("sets the veto confirmation period", async function () {
expect(await Contribution.blocksToWait()).to.equal(40321);
});
it("sets the data migration flag", async function () {
expect(await Contribution.migrationDone()).to.be.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("finishMigration()", 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.be.false;
});
it("allows the deployer to mark the migration as finished", async function () {
await Contribution.finishMigration();
expect(await Contribution.migrationDone()).to.equal(true);
});
});
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())
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, 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, 0, false
);
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, 0, false
);
await Contribution.connect(addr7).add(
1500, 1,
"0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f",
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, 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;
});
});
});
});

View File

@@ -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);
});
});
});