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..f2ad60d 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; + uint32 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 + uint32 confirmedKredits = contributionContract.totalKreditsEarnedByContributor(id, true); + uint32 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 d4f2716..e20c02c 100644 --- a/test/contracts/Contributor.js +++ b/test/contracts/Contributor.js @@ -1,30 +1,106 @@ 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; +let Contribution, Contributor, Token; 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); - // } + + 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 [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); }); }); + + describe("add()", function () { + 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); + 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 () { + 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"); + }); + }); + + 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); + expect(c['balance'].toString()).to.equal("6500000000000000000000"); + expect(c['kreditsWithdrawn']).to.equal(6500); + }); + + it("requires the withdrawable amount to be larger than 0", async function () { + await expect(Contributor.connect(addr1).withdraw()).to.be.revertedWith("No kredits available"); + }); + }); });