Use ID instead of address for contribution owner

This commit is contained in:
Basti 2019-04-04 14:43:38 +02:00
parent 732dfe7b29
commit 20acfc70e3
No known key found for this signature in database
GPG Key ID: BE4634D632D39B67
4 changed files with 86 additions and 30 deletions

View File

@ -7,17 +7,25 @@ interface IToken {
function mintFor(address contributorAccount, uint256 amount, uint256 contributionId) public;
}
interface ContributorInterface {
function getContributorAddressById(uint256 contributorId) public view returns (address);
function getContributorIdByAddress(address contributorAccount) public view returns (uint256);
// TODO Maybe use for validation
// function exists(uint256 contributorId) public view returns (bool);
}
contract Contribution is AragonApp {
bytes32 public constant ADD_CONTRIBUTION_ROLE = keccak256("ADD_CONTRIBUTION_ROLE");
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 contributorId;
uint256 amount;
bool claimed;
bytes32 hashDigest;
@ -28,19 +36,22 @@ 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(uint256 => uint256) public contributionOwner;
// map contributor to contribution IDs
mapping(uint256 => uint256[]) public ownedContributions;
mapping(uint256 => ContributionData) public contributions;
uint256 public contributionsCount;
uint256 public blocksToWait = 0;
event ContributionAdded(uint256 id, address indexed contributor, uint256 amount);
event ContributionClaimed(uint256 id, address indexed contributor, uint256 amount);
event ContributionAdded(uint256 id, uint256 indexed contributorId, uint256 amount);
event ContributionClaimed(uint256 id, uint256 indexed contributorId, uint256 amount);
event ContributionVetoed(uint256 id, address vetoedByAccount);
function initialize(bytes32[4] _appIds) public onlyInit {
@ -48,11 +59,29 @@ contract Contribution is AragonApp {
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 (uint256) {
address contributor = getContributorContract();
return ContributorInterface(contributor).getContributorIdByAddress(contributorAccount);
}
function getContributorAddressById(uint256 contributorId) public view returns (uint256) {
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;
uint256 contributorId = getContributorIdByAddress(owner);
return ownedContributions[contributorId].length;
}
function ownerOf(uint256 contributionId) public view returns (address) {
require(exists(contributionId));
return contributions[contributionId].contributor;
uint256 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, uint256 index) public view returns (uint256) {
uint256 contributorId = getContributorIdByAddress(owner);
return ownedContributions[contributorId][index];
}
function tokenMetadata(uint256 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(uint256 contributionId) public view returns (uint256 id, uint256 contributorId, uint256 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) {
function add(uint256 amount, uint256 contributorId, 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;
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,10 +149,10 @@ 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) {
@ -136,8 +173,9 @@ 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);
IToken(token).mintFor(contributorAccount, c.amount, contributionId);
emit ContributionClaimed(contributionId, c.contributorId, c.amount);
}
function exists(uint256 contributionId) view public returns (bool) {

View File

@ -1,12 +1,12 @@
const contractCalls = [
['Contributor', 'add', [{ account: '0x7e8f313c56f809188313aa274fa67ee58c31515d', name: 'bumi', isCore: true, kind: 'person', url: '', github_username: 'bumi', github_uid: 318, wiki_username: 'bumi' }, { gasLimit: 200000 }]],
['Contributor', 'add', [{ account: '0x49575f3DD9a0d60aE661BC992f72D837A77f05Bc', name: 'raucao', isCore: true, kind: 'person', url: '', github_username: 'skddc', github_uid: 842, wiki_username: 'raucau' }, { gasLimit: 200000 }]],
['Proposal', 'addProposal', [{ contributorId: 2, 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] 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 }]],
// ['Proposal', 'addProposal', [{ contributorId: 2, 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] 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', [{ 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

View File

@ -29,15 +29,33 @@ class Contribution extends Base {
}
getByContributor(contributor) {
return this.functions.balanceOf(contributor)
getByContributorId(contributorId) {
return this.functions.balanceOf(address)
then((balance) => {
count = balance.toNumber();
let contributions = [];
for (let index = 0; index <= count; index++) {
this.functions.tokenOfOwnerByIndex(contributor, index)
this.functions.tokenOfOwnerByIndex(address, index)
.then((id) => {
contributions.push(this.getById(id));
});
}
return RSVP.all(contributions);
});
}
getByContributorAddress(address) {
return this.functions.balanceOf(address)
then((balance) => {
count = balance.toNumber();
let contributions = [];
for (let index = 0; index <= count; index++) {
this.functions.tokenOfOwnerByIndex(address, index)
.then((id) => {
contributions.push(this.getById(id));
});
@ -56,7 +74,7 @@ class Contribution extends Base {
.then((ipfsHashAttr) => {
let contribution = [
contributionAttr.amount,
contributionAttr.contributorAccount,
contributionAttr.contributorId,
ipfsHashAttr.hashDigest,
ipfsHashAttr.hashFunction,
ipfsHashAttr.hashSize,