Use ID instead of address for contribution owner
This commit is contained in:
parent
732dfe7b29
commit
20acfc70e3
@ -7,17 +7,25 @@ interface IToken {
|
|||||||
function mintFor(address contributorAccount, uint256 amount, uint256 contributionId) public;
|
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 {
|
contract Contribution is AragonApp {
|
||||||
bytes32 public constant ADD_CONTRIBUTION_ROLE = keccak256("ADD_CONTRIBUTION_ROLE");
|
bytes32 public constant ADD_CONTRIBUTION_ROLE = keccak256("ADD_CONTRIBUTION_ROLE");
|
||||||
bytes32 public constant VETO_CONTRIBUTION_ROLE = keccak256("VETO_CONTRIBUTION_ROLE");
|
bytes32 public constant VETO_CONTRIBUTION_ROLE = keccak256("VETO_CONTRIBUTION_ROLE");
|
||||||
|
|
||||||
bytes32 public constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;
|
bytes32 public constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;
|
||||||
|
|
||||||
// ensure alphabetic order
|
// ensure alphabetic order
|
||||||
enum Apps { Contribution, Contributor, Proposal, Token }
|
enum Apps { Contribution, Contributor, Proposal, Token }
|
||||||
bytes32[4] public appIds;
|
bytes32[4] public appIds;
|
||||||
|
|
||||||
struct ContributionData {
|
struct ContributionData {
|
||||||
address contributor;
|
uint256 contributorId;
|
||||||
uint256 amount;
|
uint256 amount;
|
||||||
bool claimed;
|
bool claimed;
|
||||||
bytes32 hashDigest;
|
bytes32 hashDigest;
|
||||||
@ -28,19 +36,22 @@ contract Contribution is AragonApp {
|
|||||||
bool vetoed;
|
bool vetoed;
|
||||||
bool exists;
|
bool exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
string internal name_;
|
string internal name_;
|
||||||
string internal symbol_;
|
string internal symbol_;
|
||||||
|
|
||||||
mapping(uint256 => address) contributionOwner;
|
// map contribution ID to contributor
|
||||||
mapping(address => uint256[]) ownedContributions;
|
mapping(uint256 => uint256) public contributionOwner;
|
||||||
|
// map contributor to contribution IDs
|
||||||
|
mapping(uint256 => uint256[]) public ownedContributions;
|
||||||
|
|
||||||
mapping(uint256 => ContributionData) public contributions;
|
mapping(uint256 => ContributionData) public contributions;
|
||||||
uint256 public contributionsCount;
|
uint256 public contributionsCount;
|
||||||
|
|
||||||
uint256 public blocksToWait = 0;
|
uint256 public blocksToWait = 0;
|
||||||
|
|
||||||
event ContributionAdded(uint256 id, address indexed contributor, uint256 amount);
|
event ContributionAdded(uint256 id, uint256 indexed contributorId, uint256 amount);
|
||||||
event ContributionClaimed(uint256 id, address indexed contributor, uint256 amount);
|
event ContributionClaimed(uint256 id, uint256 indexed contributorId, uint256 amount);
|
||||||
event ContributionVetoed(uint256 id, address vetoedByAccount);
|
event ContributionVetoed(uint256 id, address vetoedByAccount);
|
||||||
|
|
||||||
function initialize(bytes32[4] _appIds) public onlyInit {
|
function initialize(bytes32[4] _appIds) public onlyInit {
|
||||||
@ -48,11 +59,29 @@ contract Contribution is AragonApp {
|
|||||||
initialized();
|
initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO refactor into a single function
|
||||||
function getTokenContract() public view returns (address) {
|
function getTokenContract() public view returns (address) {
|
||||||
IKernel k = IKernel(kernel());
|
IKernel k = IKernel(kernel());
|
||||||
|
|
||||||
return k.getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Token)]);
|
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) {
|
function name() external view returns (string) {
|
||||||
return name_;
|
return name_;
|
||||||
@ -62,30 +91,38 @@ contract Contribution is AragonApp {
|
|||||||
return symbol_;
|
return symbol_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Balance is amount of ERC271 tokens, not amount of kredits
|
||||||
function balanceOf(address owner) public view returns (uint256) {
|
function balanceOf(address owner) public view returns (uint256) {
|
||||||
require(owner != address(0));
|
require(owner != address(0));
|
||||||
return ownedContributions[owner].length;
|
uint256 contributorId = getContributorIdByAddress(owner);
|
||||||
|
return ownedContributions[contributorId].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ownerOf(uint256 contributionId) public view returns (address) {
|
function ownerOf(uint256 contributionId) public view returns (address) {
|
||||||
require(exists(contributionId));
|
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) {
|
function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
|
||||||
return ownedContributions[contributor][index];
|
uint256 contributorId = getContributorIdByAddress(owner);
|
||||||
|
return ownedContributions[contributorId][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
function tokenMetadata(uint256 contributionId) public view returns (string) {
|
function tokenMetadata(uint256 contributionId) public view returns (string) {
|
||||||
return contributions[contributionId].tokenMetadataURL;
|
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;
|
id = contributionId;
|
||||||
ContributionData storage c = contributions[id];
|
ContributionData storage c = contributions[id];
|
||||||
return (
|
return (
|
||||||
id,
|
id,
|
||||||
c.contributor,
|
c.contributorId,
|
||||||
c.amount,
|
c.amount,
|
||||||
c.claimed,
|
c.claimed,
|
||||||
c.hashDigest,
|
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');
|
//require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint256[](0)), 'nope');
|
||||||
uint256 contributionId = contributionsCount + 1;
|
uint256 contributionId = contributionsCount + 1;
|
||||||
ContributionData storage c = contributions[contributionId];
|
ContributionData storage c = contributions[contributionId];
|
||||||
c.exists = true;
|
c.exists = true;
|
||||||
c.amount = amount;
|
c.amount = amount;
|
||||||
c.claimed = false;
|
c.claimed = false;
|
||||||
c.contributor = contributorAccount;
|
c.contributorId = contributorId;
|
||||||
c.hashDigest = hashDigest;
|
c.hashDigest = hashDigest;
|
||||||
c.hashFunction = hashFunction;
|
c.hashFunction = hashFunction;
|
||||||
c.hashSize = hashSize;
|
c.hashSize = hashSize;
|
||||||
@ -112,10 +149,10 @@ contract Contribution is AragonApp {
|
|||||||
|
|
||||||
contributionsCount++;
|
contributionsCount++;
|
||||||
|
|
||||||
contributionOwner[contributionId] = contributorAccount;
|
contributionOwner[contributionId] = contributorId;
|
||||||
ownedContributions[contributorAccount].push(contributionId);
|
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(uint256 contributionId) public isInitialized auth(VETO_CONTRIBUTION_ROLE) {
|
||||||
@ -136,8 +173,9 @@ contract Contribution is AragonApp {
|
|||||||
|
|
||||||
c.claimed = true;
|
c.claimed = true;
|
||||||
address token = getTokenContract();
|
address token = getTokenContract();
|
||||||
IToken(token).mintFor(c.contributor, c.amount, contributionId);
|
address contributorAccount = getContributorAddressById(c.contributorId);
|
||||||
emit ContributionClaimed(contributionId, c.contributor, c.amount);
|
IToken(token).mintFor(contributorAccount, c.amount, contributionId);
|
||||||
|
emit ContributionClaimed(contributionId, c.contributorId, c.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function exists(uint256 contributionId) view public returns (bool) {
|
function exists(uint256 contributionId) view public returns (bool) {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
const contractCalls = [
|
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: '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 }]],
|
['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: 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] 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', 'addProposal', [{ contributorId: 3, amount: 500, kind: 'code', description: '[67P/kredits-contracts] Hacked on kredits', url: '' }, { gasLimit: 350000 }]],
|
||||||
['Proposal', 'vote', [1, { gasLimit: 550000 }]],
|
// ['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', [{ contributorId: 2, 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: 3, amount: 1500, kind: 'dev', description: '[67P/kredits-web] Reviewed stuff', url: '' }, { gasLimit: 350000 }]],
|
||||||
['Contribution', 'claim', [1, { gasLimit: 300000 }]]
|
['Contribution', 'claim', [1, { gasLimit: 300000 }]]
|
||||||
];
|
];
|
||||||
const funds = [
|
const funds = [
|
||||||
|
File diff suppressed because one or more lines are too long
@ -29,15 +29,33 @@ class Contribution extends Base {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getByContributor(contributor) {
|
getByContributorId(contributorId) {
|
||||||
return this.functions.balanceOf(contributor)
|
return this.functions.balanceOf(address)
|
||||||
then((balance) => {
|
then((balance) => {
|
||||||
count = balance.toNumber();
|
count = balance.toNumber();
|
||||||
|
|
||||||
let contributions = [];
|
let contributions = [];
|
||||||
|
|
||||||
for (let index = 0; index <= count; index++) {
|
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) => {
|
.then((id) => {
|
||||||
contributions.push(this.getById(id));
|
contributions.push(this.getById(id));
|
||||||
});
|
});
|
||||||
@ -56,7 +74,7 @@ class Contribution extends Base {
|
|||||||
.then((ipfsHashAttr) => {
|
.then((ipfsHashAttr) => {
|
||||||
let contribution = [
|
let contribution = [
|
||||||
contributionAttr.amount,
|
contributionAttr.amount,
|
||||||
contributionAttr.contributorAccount,
|
contributionAttr.contributorId,
|
||||||
ipfsHashAttr.hashDigest,
|
ipfsHashAttr.hashDigest,
|
||||||
ipfsHashAttr.hashFunction,
|
ipfsHashAttr.hashFunction,
|
||||||
ipfsHashAttr.hashSize,
|
ipfsHashAttr.hashSize,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user