Merge pull request #73 from 67P/feature/contribution_owner
Convert contribution owner to ID, use smaller number formats
This commit is contained in:
commit
99394e7f14
@ -4,7 +4,14 @@ import "@aragon/os/contracts/apps/AragonApp.sol";
|
||||
import "@aragon/os/contracts/kernel/IKernel.sol";
|
||||
|
||||
interface IToken {
|
||||
function mintFor(address contributorAccount, uint256 amount, uint256 contributionId) public;
|
||||
function mintFor(address contributorAccount, uint256 amount, uint32 contributionId) public;
|
||||
}
|
||||
|
||||
interface ContributorInterface {
|
||||
function getContributorAddressById(uint32 contributorId) public view returns (address);
|
||||
function getContributorIdByAddress(address contributorAccount) public view returns (uint32);
|
||||
// TODO Maybe use for validation
|
||||
// function exists(uint32 contributorId) public view returns (bool);
|
||||
}
|
||||
|
||||
contract Contribution is AragonApp {
|
||||
@ -12,13 +19,14 @@ contract Contribution is AragonApp {
|
||||
bytes32 public constant VETO_CONTRIBUTION_ROLE = keccak256("VETO_CONTRIBUTION_ROLE");
|
||||
|
||||
bytes32 public constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;
|
||||
|
||||
// ensure alphabetic order
|
||||
enum Apps { Contribution, Contributor, Proposal, Token }
|
||||
bytes32[4] public appIds;
|
||||
|
||||
struct ContributionData {
|
||||
address contributor;
|
||||
uint256 amount;
|
||||
uint32 contributorId;
|
||||
uint32 amount;
|
||||
bool claimed;
|
||||
bytes32 hashDigest;
|
||||
uint8 hashFunction;
|
||||
@ -28,31 +36,52 @@ contract Contribution is AragonApp {
|
||||
bool vetoed;
|
||||
bool exists;
|
||||
}
|
||||
|
||||
string internal name_;
|
||||
string internal symbol_;
|
||||
|
||||
mapping(uint256 => address) contributionOwner;
|
||||
mapping(address => uint256[]) ownedContributions;
|
||||
// map contribution ID to contributor
|
||||
mapping(uint32 => uint32) public contributionOwner;
|
||||
// map contributor to contribution IDs
|
||||
mapping(uint32 => uint32[]) public ownedContributions;
|
||||
|
||||
mapping(uint256 => ContributionData) public contributions;
|
||||
uint256 public contributionsCount;
|
||||
mapping(uint32 => ContributionData) public contributions;
|
||||
uint32 public contributionsCount;
|
||||
|
||||
uint256 public blocksToWait = 0;
|
||||
uint32 public blocksToWait = 0;
|
||||
|
||||
event ContributionAdded(uint256 id, address indexed contributor, uint256 amount);
|
||||
event ContributionClaimed(uint256 id, address indexed contributor, uint256 amount);
|
||||
event ContributionVetoed(uint256 id, address vetoedByAccount);
|
||||
event ContributionAdded(uint32 id, uint32 indexed contributorId, uint32 amount);
|
||||
event ContributionClaimed(uint32 id, uint32 indexed contributorId, uint32 amount);
|
||||
event ContributionVetoed(uint32 id, address vetoedByAccount);
|
||||
|
||||
function initialize(bytes32[4] _appIds) public onlyInit {
|
||||
appIds = _appIds;
|
||||
initialized();
|
||||
}
|
||||
|
||||
// TODO refactor into a single function
|
||||
function getTokenContract() public view returns (address) {
|
||||
IKernel k = IKernel(kernel());
|
||||
|
||||
return k.getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Token)]);
|
||||
}
|
||||
function getContributorContract() public view returns (address) {
|
||||
IKernel k = IKernel(kernel());
|
||||
return k.getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Contributor)]);
|
||||
}
|
||||
|
||||
function getContributorIdByAddress(address contributorAccount) public view returns (uint32) {
|
||||
address contributor = getContributorContract();
|
||||
return ContributorInterface(contributor).getContributorIdByAddress(contributorAccount);
|
||||
}
|
||||
|
||||
function getContributorAddressById(uint32 contributorId) public view returns (address) {
|
||||
address contributor = getContributorContract();
|
||||
return ContributorInterface(contributor).getContributorAddressById(contributorId);
|
||||
}
|
||||
|
||||
//
|
||||
// Token standard functions (ERC 721)
|
||||
//
|
||||
|
||||
function name() external view returns (string) {
|
||||
return name_;
|
||||
@ -62,30 +91,38 @@ contract Contribution is AragonApp {
|
||||
return symbol_;
|
||||
}
|
||||
|
||||
// Balance is amount of ERC271 tokens, not amount of kredits
|
||||
function balanceOf(address owner) public view returns (uint256) {
|
||||
require(owner != address(0));
|
||||
return ownedContributions[owner].length;
|
||||
uint32 contributorId = getContributorIdByAddress(owner);
|
||||
return ownedContributions[contributorId].length;
|
||||
}
|
||||
|
||||
function ownerOf(uint256 contributionId) public view returns (address) {
|
||||
function ownerOf(uint32 contributionId) public view returns (address) {
|
||||
require(exists(contributionId));
|
||||
return contributions[contributionId].contributor;
|
||||
uint32 contributorId = contributions[contributionId].contributorId;
|
||||
return getContributorAddressById(contributorId);
|
||||
}
|
||||
|
||||
function tokenOfOwnerByIndex(address contributor, uint256 index) public view returns (uint256) {
|
||||
return ownedContributions[contributor][index];
|
||||
function tokenOfOwnerByIndex(address owner, uint32 index) public view returns (uint32) {
|
||||
uint32 contributorId = getContributorIdByAddress(owner);
|
||||
return ownedContributions[contributorId][index];
|
||||
}
|
||||
|
||||
function tokenMetadata(uint256 contributionId) public view returns (string) {
|
||||
function tokenMetadata(uint32 contributionId) public view returns (string) {
|
||||
return contributions[contributionId].tokenMetadataURL;
|
||||
}
|
||||
|
||||
function getContribution(uint256 contributionId) public view returns (uint256 id, address contributor, uint256 amount, bool claimed, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint claimAfterBlock, bool exists, bool vetoed) {
|
||||
//
|
||||
// Custom functions
|
||||
//
|
||||
|
||||
function getContribution(uint32 contributionId) public view returns (uint32 id, uint32 contributorId, uint32 amount, bool claimed, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint claimAfterBlock, bool exists, bool vetoed) {
|
||||
id = contributionId;
|
||||
ContributionData storage c = contributions[id];
|
||||
return (
|
||||
id,
|
||||
c.contributor,
|
||||
c.contributorId,
|
||||
c.amount,
|
||||
c.claimed,
|
||||
c.hashDigest,
|
||||
@ -97,14 +134,14 @@ contract Contribution is AragonApp {
|
||||
);
|
||||
}
|
||||
|
||||
function add(uint256 amount, address contributorAccount, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(ADD_CONTRIBUTION_ROLE) {
|
||||
//require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint256[](0)), 'nope');
|
||||
uint256 contributionId = contributionsCount + 1;
|
||||
function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(ADD_CONTRIBUTION_ROLE) {
|
||||
//require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint32[](0)), 'nope');
|
||||
uint32 contributionId = contributionsCount + 1;
|
||||
ContributionData storage c = contributions[contributionId];
|
||||
c.exists = true;
|
||||
c.amount = amount;
|
||||
c.claimed = false;
|
||||
c.contributor = contributorAccount;
|
||||
c.contributorId = contributorId;
|
||||
c.hashDigest = hashDigest;
|
||||
c.hashFunction = hashFunction;
|
||||
c.hashSize = hashSize;
|
||||
@ -112,13 +149,13 @@ contract Contribution is AragonApp {
|
||||
|
||||
contributionsCount++;
|
||||
|
||||
contributionOwner[contributionId] = contributorAccount;
|
||||
ownedContributions[contributorAccount].push(contributionId);
|
||||
contributionOwner[contributionId] = contributorId;
|
||||
ownedContributions[contributorId].push(contributionId);
|
||||
|
||||
emit ContributionAdded(contributionId, contributorAccount, amount);
|
||||
emit ContributionAdded(contributionId, contributorId, amount);
|
||||
}
|
||||
|
||||
function veto(uint256 contributionId) public isInitialized auth(VETO_CONTRIBUTION_ROLE) {
|
||||
function veto(uint32 contributionId) public isInitialized auth(VETO_CONTRIBUTION_ROLE) {
|
||||
ContributionData storage c = contributions[contributionId];
|
||||
require(c.exists, 'NOT_FOUND');
|
||||
require(!c.claimed, 'ALREADY_CLAIMED');
|
||||
@ -127,7 +164,7 @@ contract Contribution is AragonApp {
|
||||
emit ContributionVetoed(contributionId, msg.sender);
|
||||
}
|
||||
|
||||
function claim(uint256 contributionId) public isInitialized {
|
||||
function claim(uint32 contributionId) public isInitialized {
|
||||
ContributionData storage c = contributions[contributionId];
|
||||
require(c.exists, 'NOT_FOUND');
|
||||
require(!c.claimed, 'ALREADY_CLAIMED');
|
||||
@ -136,11 +173,13 @@ contract Contribution is AragonApp {
|
||||
|
||||
c.claimed = true;
|
||||
address token = getTokenContract();
|
||||
IToken(token).mintFor(c.contributor, c.amount, contributionId);
|
||||
emit ContributionClaimed(contributionId, c.contributor, c.amount);
|
||||
address contributorAccount = getContributorAddressById(c.contributorId);
|
||||
uint256 amount = uint256(c.amount);
|
||||
IToken(token).mintFor(contributorAccount, amount, contributionId);
|
||||
emit ContributionClaimed(contributionId, c.contributorId, c.amount);
|
||||
}
|
||||
|
||||
function exists(uint256 contributionId) view public returns (bool) {
|
||||
function exists(uint32 contributionId) view public returns (bool) {
|
||||
return contributions[contributionId].exists;
|
||||
}
|
||||
}
|
||||
|
@ -20,20 +20,20 @@ contract Contributor is AragonApp {
|
||||
bool exists;
|
||||
}
|
||||
|
||||
mapping (address => uint256) public contributorIds;
|
||||
mapping (uint256 => Contributor) public contributors;
|
||||
uint256 public contributorsCount;
|
||||
mapping (address => uint32) public contributorIds;
|
||||
mapping (uint32 => Contributor) public contributors;
|
||||
uint32 public contributorsCount;
|
||||
|
||||
// ensure alphabetic order
|
||||
enum Apps { Contribution, Contributor, Proposal, Token }
|
||||
bytes32[4] public appIds;
|
||||
|
||||
event ContributorProfileUpdated(uint256 id, bytes32 oldIpfsHash, bytes32 newIpfsHash);
|
||||
event ContributorAccountUpdated(uint256 id, address oldAccount, address newAccount);
|
||||
event ContributorAdded(uint256 id, address account);
|
||||
event ContributorProfileUpdated(uint32 id, bytes32 oldIpfsHash, bytes32 newIpfsHash);
|
||||
event ContributorAccountUpdated(uint32 id, address oldAccount, address newAccount);
|
||||
event ContributorAdded(uint32 id, address account);
|
||||
|
||||
function initialize(address root,bytes32[4] _appIds) public onlyInit {
|
||||
uint256 _id = contributorsCount + 1;
|
||||
uint32 _id = contributorsCount + 1;
|
||||
Contributor storage c = contributors[_id];
|
||||
c.exists = true;
|
||||
c.isCore = true;
|
||||
@ -52,9 +52,9 @@ contract Contributor is AragonApp {
|
||||
return k.getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Token)]);
|
||||
}
|
||||
|
||||
function coreContributorsCount() view public returns (uint256) {
|
||||
uint256 count = 0;
|
||||
for (uint256 i = 1; i <= contributorsCount; i++) {
|
||||
function coreContributorsCount() view public returns (uint32) {
|
||||
uint32 count = 0;
|
||||
for (uint32 i = 1; i <= contributorsCount; i++) {
|
||||
if (contributors[i].isCore) {
|
||||
count += 1;
|
||||
}
|
||||
@ -62,14 +62,14 @@ contract Contributor is AragonApp {
|
||||
return count;
|
||||
}
|
||||
|
||||
function updateContributorAccount(uint256 id, address oldAccount, address newAccount) public auth(MANAGE_CONTRIBUTORS_ROLE) {
|
||||
function updateContributorAccount(uint32 id, address oldAccount, address newAccount) public auth(MANAGE_CONTRIBUTORS_ROLE) {
|
||||
contributorIds[oldAccount] = 0;
|
||||
contributorIds[newAccount] = id;
|
||||
contributors[id].account = newAccount;
|
||||
ContributorAccountUpdated(id, oldAccount, newAccount);
|
||||
}
|
||||
|
||||
function updateContributorIpfsHash(uint256 id, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public isInitialized auth(MANAGE_CONTRIBUTORS_ROLE) {
|
||||
function updateContributorIpfsHash(uint32 id, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public isInitialized auth(MANAGE_CONTRIBUTORS_ROLE) {
|
||||
Contributor storage c = contributors[id];
|
||||
bytes32 oldIpfsHash = c.ipfsHash;
|
||||
c.ipfsHash = ipfsHash;
|
||||
@ -81,7 +81,7 @@ contract Contributor is AragonApp {
|
||||
|
||||
function addContributor(address account, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, bool isCore) public isInitialized auth(MANAGE_CONTRIBUTORS_ROLE) {
|
||||
require(!addressExists(account));
|
||||
uint256 _id = contributorsCount + 1;
|
||||
uint32 _id = contributorsCount + 1;
|
||||
assert(!contributors[_id].exists); // this can not be acually
|
||||
Contributor storage c = contributors[_id];
|
||||
c.exists = true;
|
||||
@ -96,11 +96,11 @@ contract Contributor is AragonApp {
|
||||
emit ContributorAdded(_id, account);
|
||||
}
|
||||
|
||||
function isCore(uint256 id) view public returns (bool) {
|
||||
function isCore(uint32 id) view public returns (bool) {
|
||||
return contributors[id].isCore;
|
||||
}
|
||||
|
||||
function exists(uint256 id) view public returns (bool) {
|
||||
function exists(uint32 id) view public returns (bool) {
|
||||
return contributors[id].exists;
|
||||
}
|
||||
|
||||
@ -112,20 +112,20 @@ contract Contributor is AragonApp {
|
||||
return getContributorByAddress(account).exists;
|
||||
}
|
||||
|
||||
function getContributorIdByAddress(address account) view public returns (uint256) {
|
||||
function getContributorIdByAddress(address account) view public returns (uint32) {
|
||||
return contributorIds[account];
|
||||
}
|
||||
|
||||
function getContributorAddressById(uint256 id) view public returns (address) {
|
||||
function getContributorAddressById(uint32 id) view public returns (address) {
|
||||
return contributors[id].account;
|
||||
}
|
||||
|
||||
function getContributorByAddress(address account) internal view returns (Contributor) {
|
||||
uint256 id = contributorIds[account];
|
||||
uint32 id = contributorIds[account];
|
||||
return contributors[id];
|
||||
}
|
||||
|
||||
function getContributorById(uint256 _id) public view returns (uint256 id, address account, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, bool isCore, uint256 balance, bool exists ) {
|
||||
function getContributorById(uint32 _id) public view returns (uint32 id, address account, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, bool isCore, uint256 balance, bool exists ) {
|
||||
id = _id;
|
||||
Contributor storage c = contributors[_id];
|
||||
account = c.account;
|
||||
@ -138,14 +138,14 @@ contract Contributor is AragonApp {
|
||||
exists = c.exists;
|
||||
}
|
||||
|
||||
function canPerform(address _who, address _where, bytes32 _what, uint256[] memory _how) public returns (bool) {
|
||||
function canPerform(address _who, address _where, bytes32 _what/*, uint256[] memory _how*/) public returns (bool) {
|
||||
address sender = _who;
|
||||
if (sender == address(-1)) {
|
||||
sender = tx.origin;
|
||||
}
|
||||
// _what == keccak256('VOTE_PROPOSAL_ROLE')
|
||||
if (_what == 0xd61216798314d2fc33e42ff2021d66707b1e38517d3f7166798a9d3a196a9c96) {
|
||||
return contributorIds[sender] != uint256(0);
|
||||
return contributorIds[sender] != uint256(0);
|
||||
}
|
||||
|
||||
return addressIsCore(sender);
|
||||
|
@ -4,13 +4,13 @@ import "@aragon/os/contracts/apps/AragonApp.sol";
|
||||
import "@aragon/os/contracts/kernel/IKernel.sol";
|
||||
|
||||
interface IContributor {
|
||||
function getContributorAddressById(uint256 contributorId) public view returns (address);
|
||||
function getContributorIdByAddress(address contributorAccount) public view returns (uint256);
|
||||
function exists(uint256 contributorId) public view returns (bool);
|
||||
function getContributorAddressById(uint32 contributorId) public view returns (address);
|
||||
function getContributorIdByAddress(address contributorAccount) public view returns (uint32);
|
||||
function exists(uint32 contributorId) public view returns (bool);
|
||||
}
|
||||
|
||||
interface IContribution {
|
||||
function add(uint256 amount, address contributor, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public;
|
||||
function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public;
|
||||
}
|
||||
|
||||
contract Proposal is AragonApp {
|
||||
@ -25,26 +25,26 @@ contract Proposal is AragonApp {
|
||||
|
||||
struct Proposal {
|
||||
address creatorAccount;
|
||||
uint contributorId;
|
||||
uint votesCount;
|
||||
uint votesNeeded;
|
||||
uint256 amount;
|
||||
uint32 contributorId;
|
||||
uint16 votesCount;
|
||||
uint16 votesNeeded;
|
||||
uint32 amount;
|
||||
bool executed;
|
||||
bytes32 hashDigest;
|
||||
uint8 hashFunction;
|
||||
uint8 hashSize;
|
||||
uint256[] voterIds;
|
||||
mapping (uint256 => bool) votes;
|
||||
uint32[] voterIds;
|
||||
mapping (uint32 => bool) votes;
|
||||
bool exists;
|
||||
}
|
||||
|
||||
mapping(uint256 => Proposal) public proposals;
|
||||
uint256 public proposalsCount;
|
||||
mapping(uint32 => Proposal) public proposals;
|
||||
uint32 public proposalsCount;
|
||||
|
||||
event ProposalCreated(uint256 id, address creatorAccount, uint256 contributorId, uint256 amount);
|
||||
event ProposalCreated(uint32 id, address creatorAccount, uint32 contributorId, uint32 amount);
|
||||
|
||||
event ProposalVoted(uint256 id, uint256 voterId, uint256 totalVotes);
|
||||
event ProposalExecuted(uint256 id, uint256 contributorId, uint256 amount);
|
||||
event ProposalVoted(uint32 id, uint32 voterId, uint16 totalVotes);
|
||||
event ProposalExecuted(uint32 id, uint32 contributorId, uint32 amount);
|
||||
|
||||
function initialize(bytes32[4] _appIds) public onlyInit {
|
||||
appIds = _appIds;
|
||||
@ -59,11 +59,11 @@ contract Proposal is AragonApp {
|
||||
return IKernel(kernel()).getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Contribution)]);
|
||||
}
|
||||
|
||||
function addProposal(uint contributorId, uint256 amount, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(ADD_PROPOSAL_ROLE) {
|
||||
function addProposal(uint32 contributorId, uint32 amount, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(ADD_PROPOSAL_ROLE) {
|
||||
require(IContributor(getContributorContract()).exists(contributorId), 'CONTRIBUTOR_NOT_FOUND');
|
||||
|
||||
uint256 proposalId = proposalsCount + 1;
|
||||
uint256 _votesNeeded = 1; //contributorsContract().coreContributorsCount() / 100 * 75;
|
||||
uint32 proposalId = proposalsCount + 1;
|
||||
uint16 _votesNeeded = 1; //contributorsContract().coreContributorsCount() / 100 * 75;
|
||||
|
||||
Proposal storage p = proposals[proposalId];
|
||||
p.creatorAccount = msg.sender;
|
||||
@ -75,23 +75,23 @@ contract Proposal is AragonApp {
|
||||
p.votesCount = 0;
|
||||
p.votesNeeded = _votesNeeded;
|
||||
p.exists = true;
|
||||
|
||||
|
||||
proposalsCount++;
|
||||
emit ProposalCreated(proposalId, msg.sender, p.contributorId, p.amount);
|
||||
}
|
||||
|
||||
function getProposal(uint proposalId) public view returns (uint256 id, address creatorAccount, uint256 contributorId, uint256 votesCount, uint256 votesNeeded, uint256 amount, bool executed, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint256[] voterIds, bool exists) {
|
||||
function getProposal(uint32 proposalId) public view returns (uint32 id, address creatorAccount, uint32 contributorId, uint16 votesCount, uint16 votesNeeded, uint32 amount, bool executed, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint32[] voterIds, bool exists) {
|
||||
id = proposalId;
|
||||
Proposal storage p = proposals[id];
|
||||
return (
|
||||
id,
|
||||
p.creatorAccount,
|
||||
p.contributorId,
|
||||
p.votesCount,
|
||||
p.contributorId,
|
||||
p.votesCount,
|
||||
p.votesNeeded,
|
||||
p.amount,
|
||||
p.executed,
|
||||
p.hashDigest,
|
||||
p.executed,
|
||||
p.hashDigest,
|
||||
p.hashFunction,
|
||||
p.hashSize,
|
||||
p.voterIds,
|
||||
@ -99,10 +99,10 @@ contract Proposal is AragonApp {
|
||||
);
|
||||
}
|
||||
|
||||
function vote(uint256 proposalId) public isInitialized auth(VOTE_PROPOSAL_ROLE) {
|
||||
function vote(uint32 proposalId) public isInitialized auth(VOTE_PROPOSAL_ROLE) {
|
||||
Proposal storage p = proposals[proposalId];
|
||||
require(!p.executed, 'ALREADY_EXECUTED');
|
||||
uint256 voterId = IContributor(getContributorContract()).getContributorIdByAddress(msg.sender);
|
||||
uint32 voterId = IContributor(getContributorContract()).getContributorIdByAddress(msg.sender);
|
||||
require(p.votes[voterId] != true, 'ALREADY_VOTED');
|
||||
p.voterIds.push(voterId);
|
||||
p.votes[voterId] = true;
|
||||
@ -114,20 +114,19 @@ contract Proposal is AragonApp {
|
||||
emit ProposalVoted(proposalId, voterId, p.votesCount);
|
||||
}
|
||||
|
||||
function batchVote(uint256[] _proposalIds) public isInitialized auth(VOTE_PROPOSAL_ROLE) {
|
||||
for (uint256 i = 0; i < _proposalIds.length; i++) {
|
||||
function batchVote(uint32[] _proposalIds) public isInitialized auth(VOTE_PROPOSAL_ROLE) {
|
||||
for (uint32 i = 0; i < _proposalIds.length; i++) {
|
||||
vote(_proposalIds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function executeProposal(uint proposalId) private {
|
||||
function executeProposal(uint32 proposalId) private {
|
||||
Proposal storage p = proposals[proposalId];
|
||||
require(!p.executed, 'ALREADY_EXECUTED');
|
||||
require(p.votesCount >= p.votesNeeded, 'MISSING_VOTES');
|
||||
|
||||
|
||||
p.executed = true;
|
||||
address contributorAccount = IContributor(getContributorContract()).getContributorAddressById(p.contributorId);
|
||||
IContribution(getContributionContract()).add(p.amount, contributorAccount, p.hashDigest, p.hashFunction, p.hashSize);
|
||||
IContribution(getContributionContract()).add(p.amount, p.contributorId, p.hashDigest, p.hashFunction, p.hashSize);
|
||||
emit ProposalExecuted(proposalId, p.contributorId, p.amount);
|
||||
}
|
||||
|
||||
|
@ -9,15 +9,15 @@ contract Token is ERC20Token, AragonApp {
|
||||
// ensure alphabetic order
|
||||
enum Apps { Contribution, Contributor, Proposal, Token }
|
||||
bytes32[4] public appIds;
|
||||
|
||||
event LogMint(address indexed recipient, uint256 amount, uint256 contributionId);
|
||||
|
||||
|
||||
event LogMint(address indexed recipient, uint256 amount, uint32 contributionId);
|
||||
|
||||
function initialize(bytes32[4] _appIds) public onlyInit {
|
||||
appIds = _appIds;
|
||||
initialized();
|
||||
}
|
||||
|
||||
function mintFor(address contributorAccount, uint256 amount, uint256 contributionId) public isInitialized auth(MINT_TOKEN_ROLE) {
|
||||
function mintFor(address contributorAccount, uint256 amount, uint32 contributionId) public isInitialized auth(MINT_TOKEN_ROLE) {
|
||||
_mint(contributorAccount, amount);
|
||||
emit LogMint(contributorAccount, amount, contributionId);
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ const contractCalls = [
|
||||
['Proposal', 'addProposal', [{ contributorId: 3, amount: 500, kind: 'code', description: '[67P/kredits-contracts] Ran the seeds', url: '' }, { gasLimit: 350000 }]],
|
||||
['Proposal', 'addProposal', [{ contributorId: 3, amount: 500, kind: 'code', description: '[67P/kredits-contracts] Hacked on kredits', url: '' }, { gasLimit: 350000 }]],
|
||||
['Proposal', 'vote', [1, { gasLimit: 550000 }]],
|
||||
['Contribution', 'addContribution', [{ contributorAccount: '0x49575f3DD9a0d60aE661BC992f72D837A77f05Bc', amount: 5000, kind: 'dev', description: '[67P/kredits-contracts] Introduce contribution token', url: '' }, { gasLimit: 350000 }]],
|
||||
['Contribution', 'addContribution', [{ contributorAccount: '0x7e8f313c56f809188313aa274fa67ee58c31515d', amount: 1500, kind: 'dev', description: '[67P/kredits-web] Reviewed stuff', url: '' }, { gasLimit: 350000 }]],
|
||||
['Contribution', 'addContribution', [{ contributorId: 2, amount: 5000, kind: 'dev', description: '[67P/kredits-contracts] Introduce contribution token', url: '' }, { gasLimit: 350000 }]],
|
||||
['Contribution', 'addContribution', [{ contributorId: 3, amount: 1500, kind: 'dev', description: '[67P/kredits-web] Reviewed stuff', url: '' }, { gasLimit: 350000 }]],
|
||||
['Contribution', 'claim', [1, { gasLimit: 300000 }]]
|
||||
];
|
||||
const funds = [
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +1,4 @@
|
||||
const ethers = require('ethers');
|
||||
const RSVP = require('rsvp');
|
||||
|
||||
const ContributionSerializer = require('../serializers/contribution');
|
||||
const Base = require('./base');
|
||||
@ -7,43 +6,44 @@ const Base = require('./base');
|
||||
class Contribution extends Base {
|
||||
all() {
|
||||
return this.functions.contributionsCount()
|
||||
.then((count) => {
|
||||
count = count.toNumber();
|
||||
.then(async (count) => {
|
||||
let contributions = [];
|
||||
|
||||
for (let id = 1; id <= count; id++) {
|
||||
contributions.push(this.getById(id));
|
||||
const contribution = await this.getById(id)
|
||||
contributions.push(contribution);
|
||||
}
|
||||
|
||||
return RSVP.all(contributions);
|
||||
return contributions;
|
||||
});
|
||||
}
|
||||
|
||||
getById(id) {
|
||||
id = ethers.utils.bigNumberify(id);
|
||||
|
||||
return this.functions.getContribution(id)
|
||||
.then((data) => {
|
||||
.then(data => {
|
||||
return this.ipfs.catAndMerge(data, ContributionSerializer.deserialize);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
getByContributor(contributor) {
|
||||
return this.functions.balanceOf(contributor)
|
||||
then((balance) => {
|
||||
count = balance.toNumber();
|
||||
getByContributorId(contributorId) {
|
||||
return this.functions.getContributorAddressById(contributorId)
|
||||
.then(address => this.getByContributorAddress(address));
|
||||
}
|
||||
|
||||
let contributions = [];
|
||||
getByContributorAddress(address) {
|
||||
return this.functions.balanceOf(address)
|
||||
.then(async (balance) => {
|
||||
const count = balance.toNumber();
|
||||
const contributions = [];
|
||||
|
||||
for (let index = 0; index <= count; index++) {
|
||||
this.functions.tokenOfOwnerByIndex(contributor, index)
|
||||
.then((id) => {
|
||||
contributions.push(this.getById(id));
|
||||
});
|
||||
for (let index = 0; index < count; index++) {
|
||||
const id = await this.functions.tokenOfOwnerByIndex(address, index);
|
||||
const contribution = await this.getById(id);
|
||||
contributions.push(contribution);
|
||||
}
|
||||
|
||||
return RSVP.all(contributions);
|
||||
return contributions;
|
||||
});
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ class Contribution extends Base {
|
||||
.then((ipfsHashAttr) => {
|
||||
let contribution = [
|
||||
contributionAttr.amount,
|
||||
contributionAttr.contributorAccount,
|
||||
contributionAttr.contributorId,
|
||||
ipfsHashAttr.hashDigest,
|
||||
ipfsHashAttr.hashFunction,
|
||||
ipfsHashAttr.hashSize,
|
||||
|
@ -7,8 +7,7 @@ const Base = require('./base');
|
||||
class Contributor extends Base {
|
||||
all() {
|
||||
return this.functions.contributorsCount()
|
||||
.then((count) => {
|
||||
count = count.toNumber();
|
||||
.then(count => {
|
||||
let contributors = [];
|
||||
|
||||
for (let id = 1; id <= count; id++) {
|
||||
@ -20,8 +19,6 @@ class Contributor extends Base {
|
||||
}
|
||||
|
||||
getById(id) {
|
||||
id = ethers.utils.bigNumberify(id);
|
||||
|
||||
return this.functions.getContributorById(id)
|
||||
.then((data) => {
|
||||
// TODO: remove when naming updated on the contract
|
||||
|
@ -7,8 +7,7 @@ const Base = require('./base');
|
||||
class Proposal extends Base {
|
||||
all() {
|
||||
return this.functions.proposalsCount()
|
||||
.then((count) => {
|
||||
count = count.toNumber();
|
||||
.then(count => {
|
||||
let proposals = [];
|
||||
|
||||
for (let id = 1; id <= count; id++) {
|
||||
@ -20,10 +19,8 @@ class Proposal extends Base {
|
||||
}
|
||||
|
||||
getById(id) {
|
||||
id = ethers.utils.bigNumberify(id);
|
||||
|
||||
return this.functions.getProposal(id)
|
||||
.then((data) => {
|
||||
.then(data => {
|
||||
return this.ipfs.catAndMerge(data, ContributionSerializer.deserialize);
|
||||
});
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ module.exports = async function(callback) {
|
||||
console.log(`Creating a contribution for contributor account ${contributorAccount} ID: ${contributorId}`);
|
||||
|
||||
let contributionAttributes = {
|
||||
contributorAccount,
|
||||
contributorId,
|
||||
amount: await promptly.prompt('Amount: '),
|
||||
description: await promptly.prompt('Description: '),
|
||||
kind: await promptly.prompt('Kind: ', { default: 'dev' }),
|
||||
|
@ -14,7 +14,6 @@ module.exports = async function(callback) {
|
||||
|
||||
console.log(`Using Contribution at: ${kredits.Contribution.contract.address}`);
|
||||
|
||||
|
||||
const table = new Table({
|
||||
head: ['ID', 'Contributor account', 'Amount', 'Claimed?', 'Vetoed?', 'Description']
|
||||
})
|
||||
@ -24,7 +23,7 @@ module.exports = async function(callback) {
|
||||
contributions.forEach((c) => {
|
||||
table.push([
|
||||
c.id.toString(),
|
||||
c.contributor,
|
||||
c.contributorId,
|
||||
c.amount.toString(),
|
||||
c.claimed,
|
||||
c.vetoed,
|
||||
|
@ -14,7 +14,6 @@ module.exports = async function(callback) {
|
||||
|
||||
console.log(`Using Proposal at: ${kredits.Proposal.contract.address}`);
|
||||
|
||||
|
||||
const table = new Table({
|
||||
head: ['ID', 'Contributor ID', 'Amount', 'Votes', 'Executed?', 'Description']
|
||||
})
|
||||
|
@ -40,6 +40,7 @@ module.exports = async function(callback) {
|
||||
next();
|
||||
}).catch((error) => {
|
||||
console.log(`[FAILED] kredits.${contractName}.${method}(${JSON.stringify(args)})`);
|
||||
console.log(`Error: ${error.message}`);
|
||||
next();
|
||||
});
|
||||
}, () => { console.log("\nDone!") });
|
||||
|
Loading…
x
Reference in New Issue
Block a user