diff --git a/apps/contribution/artifact.json b/apps/contribution/artifact.json deleted file mode 100644 index 5f8f197..0000000 --- a/apps/contribution/artifact.json +++ /dev/null @@ -1,912 +0,0 @@ -{ - "roles": [ - { - "name": "Add contributions", - "id": "ADD_CONTRIBUTION_ROLE", - "params": [], - "bytes": "0x493d28cd0d82bcb20db66e4f6390a00122ef772717e282b436ba3240af18bfb1" - }, - { - "name": "Manage token contract", - "id": "MANAGE_TOKEN_CONTRACT_ROLE", - "params": [], - "bytes": "0xdd275187bc43df45ce7b34f6716e572716c69ad44e5e496175008950f032854b" - }, - { - "name": "Veto contributions", - "id": "VETO_CONTRIBUTION_ROLE", - "params": [], - "bytes": "0x495a36de1ed34d5c1b9f8704e7d8bc8badb027221b09c79691d430bc54c4c88f" - } - ], - "environments": { - "default": { - "network": "development", - "appName": "kredits-contribution.open.aragonpm.eth" - } - }, - "path": "contracts/Contribution.sol", - "appName": "kredits-contribution.open.aragonpm.eth", - "appId": "0x09f5274cba299b46c5be722ef672d10eef7a2ef980b612aef529d74fb9da7643", - "abi": [ - { - "constant": true, - "inputs": [], - "name": "hasInitialized", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ADD_CONTRIBUTION_ROLE", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_script", - "type": "bytes" - } - ], - "name": "getEVMScriptExecutor", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getRecoveryVault", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "contributionsCount", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "token", - "type": "address" - } - ], - "name": "allowRecoverability", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "appId", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getInitializationBlock", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "KERNEL_APP_ADDR_NAMESPACE", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - } - ], - "name": "transferToVault", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_sender", - "type": "address" - }, - { - "name": "_role", - "type": "bytes32" - }, - { - "name": "_params", - "type": "uint256[]" - } - ], - "name": "canPerform", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getEVMScriptRegistry", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint32" - } - ], - "name": "contributionOwner", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint32" - } - ], - "name": "contributions", - "outputs": [ - { - "name": "contributorId", - "type": "uint32" - }, - { - "name": "amount", - "type": "uint32" - }, - { - "name": "claimed", - "type": "bool" - }, - { - "name": "hashDigest", - "type": "bytes32" - }, - { - "name": "hashFunction", - "type": "uint8" - }, - { - "name": "hashSize", - "type": "uint8" - }, - { - "name": "tokenMetadataURL", - "type": "string" - }, - { - "name": "confirmedAtBlock", - "type": "uint256" - }, - { - "name": "vetoed", - "type": "bool" - }, - { - "name": "exists", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint32" - }, - { - "name": "", - "type": "uint256" - } - ], - "name": "ownedContributions", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "kernel", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "blocksToWait", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "isPetrified", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "appIds", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "VETO_CONTRIBUTION_ROLE", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "id", - "type": "uint32" - }, - { - "indexed": true, - "name": "contributorId", - "type": "uint32" - }, - { - "indexed": false, - "name": "amount", - "type": "uint32" - } - ], - "name": "ContributionAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "id", - "type": "uint32" - }, - { - "indexed": true, - "name": "contributorId", - "type": "uint32" - }, - { - "indexed": false, - "name": "amount", - "type": "uint32" - } - ], - "name": "ContributionClaimed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "id", - "type": "uint32" - }, - { - "indexed": false, - "name": "vetoedByAccount", - "type": "address" - } - ], - "name": "ContributionVetoed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "executor", - "type": "address" - }, - { - "indexed": false, - "name": "script", - "type": "bytes" - }, - { - "indexed": false, - "name": "input", - "type": "bytes" - }, - { - "indexed": false, - "name": "returnData", - "type": "bytes" - } - ], - "name": "ScriptResult", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "vault", - "type": "address" - }, - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "RecoverToVault", - "type": "event" - }, - { - "constant": false, - "inputs": [ - { - "name": "_appIds", - "type": "bytes32[4]" - } - ], - "name": "initialize", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getTokenContract", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getContributorContract", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "contributorAccount", - "type": "address" - } - ], - "name": "getContributorIdByAddress", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "contributorId", - "type": "uint32" - } - ], - "name": "getContributorAddressById", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "contributionId", - "type": "uint32" - } - ], - "name": "ownerOf", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "index", - "type": "uint32" - } - ], - "name": "tokenOfOwnerByIndex", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "contributionId", - "type": "uint32" - } - ], - "name": "tokenMetadata", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "confirmedOnly", - "type": "bool" - } - ], - "name": "totalKreditsEarned", - "outputs": [ - { - "name": "amount", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "contributorId", - "type": "uint32" - }, - { - "name": "confirmedOnly", - "type": "bool" - } - ], - "name": "totalKreditsEarnedByContributor", - "outputs": [ - { - "name": "amount", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "contributionId", - "type": "uint32" - } - ], - "name": "getContribution", - "outputs": [ - { - "name": "id", - "type": "uint32" - }, - { - "name": "contributorId", - "type": "uint32" - }, - { - "name": "amount", - "type": "uint32" - }, - { - "name": "claimed", - "type": "bool" - }, - { - "name": "hashDigest", - "type": "bytes32" - }, - { - "name": "hashFunction", - "type": "uint8" - }, - { - "name": "hashSize", - "type": "uint8" - }, - { - "name": "confirmedAtBlock", - "type": "uint256" - }, - { - "name": "exists", - "type": "bool" - }, - { - "name": "vetoed", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "amount", - "type": "uint32" - }, - { - "name": "contributorId", - "type": "uint32" - }, - { - "name": "hashDigest", - "type": "bytes32" - }, - { - "name": "hashFunction", - "type": "uint8" - }, - { - "name": "hashSize", - "type": "uint8" - } - ], - "name": "add", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "contributionId", - "type": "uint32" - } - ], - "name": "veto", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "contributionId", - "type": "uint32" - } - ], - "name": "claim", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "contributionId", - "type": "uint32" - } - ], - "name": "exists", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - } - ], - "deployment": { - "contractName": "Contribution", - "compiledAt": "2019-06-13T12:39:07.659Z", - "compiler": { - "name": "solc", - "version": "0.4.24+commit.e67f0147.Emscripten.clang", - "optimizer": { - "enabled": false - } - }, - "flattenedCode": "./code.sol", - "transactionHash": "0x073057bb616243e415823fa9a8c8cc096b573fbd0bbf11c2f59bb75a84291689" - }, - "functions": [ - { - "sig": "mintFor(address,uint256,uint32)", - "roles": [], - "notice": null - }, - { - "sig": "initialize(bytes32[4])", - "roles": [], - "notice": null - }, - { - "sig": "add(uint32,uint32,bytes32,uint8,uint8)", - "roles": [ - "ADD_CONTRIBUTION_ROLE" - ], - "notice": null - }, - { - "sig": "veto(uint32)", - "roles": [ - "VETO_CONTRIBUTION_ROLE" - ], - "notice": null - }, - { - "sig": "claim(uint32)", - "roles": [], - "notice": null - } - ] -} diff --git a/apps/contribution/code.sol b/apps/contribution/code.sol deleted file mode 100644 index 0f5b216..0000000 --- a/apps/contribution/code.sol +++ /dev/null @@ -1,1252 +0,0 @@ - -// File: @aragon/os/contracts/common/UnstructuredStorage.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - -library UnstructuredStorage { - function getStorageBool(bytes32 position) internal view returns (bool data) { - assembly { data := sload(position) } - } - - function getStorageAddress(bytes32 position) internal view returns (address data) { - assembly { data := sload(position) } - } - - function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) { - assembly { data := sload(position) } - } - - function getStorageUint256(bytes32 position) internal view returns (uint256 data) { - assembly { data := sload(position) } - } - - function setStorageBool(bytes32 position, bool data) internal { - assembly { sstore(position, data) } - } - - function setStorageAddress(bytes32 position, address data) internal { - assembly { sstore(position, data) } - } - - function setStorageBytes32(bytes32 position, bytes32 data) internal { - assembly { sstore(position, data) } - } - - function setStorageUint256(bytes32 position, uint256 data) internal { - assembly { sstore(position, data) } - } -} - -// File: @aragon/os/contracts/acl/IACL.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - -interface IACL { - function initialize(address permissionsCreator) external; - - // TODO: this should be external - // See https://github.com/ethereum/solidity/issues/4832 - function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool); -} - -// File: @aragon/os/contracts/common/IVaultRecoverable.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - -interface IVaultRecoverable { - event RecoverToVault(address indexed vault, address indexed token, uint256 amount); - - function transferToVault(address token) external; - - function allowRecoverability(address token) external view returns (bool); - function getRecoveryVault() external view returns (address); -} - -// File: @aragon/os/contracts/kernel/IKernel.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - - -interface IKernelEvents { - event SetApp(bytes32 indexed namespace, bytes32 indexed appId, address app); -} - - -// This should be an interface, but interfaces can't inherit yet :( -contract IKernel is IKernelEvents, IVaultRecoverable { - function acl() public view returns (IACL); - function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool); - - function setApp(bytes32 namespace, bytes32 appId, address app) public; - function getApp(bytes32 namespace, bytes32 appId) public view returns (address); -} - -// File: @aragon/os/contracts/apps/AppStorage.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - - -contract AppStorage { - using UnstructuredStorage for bytes32; - - /* Hardcoded constants to save gas - bytes32 internal constant KERNEL_POSITION = keccak256("aragonOS.appStorage.kernel"); - bytes32 internal constant APP_ID_POSITION = keccak256("aragonOS.appStorage.appId"); - */ - bytes32 internal constant KERNEL_POSITION = 0x4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b; - bytes32 internal constant APP_ID_POSITION = 0xd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b; - - function kernel() public view returns (IKernel) { - return IKernel(KERNEL_POSITION.getStorageAddress()); - } - - function appId() public view returns (bytes32) { - return APP_ID_POSITION.getStorageBytes32(); - } - - function setKernel(IKernel _kernel) internal { - KERNEL_POSITION.setStorageAddress(address(_kernel)); - } - - function setAppId(bytes32 _appId) internal { - APP_ID_POSITION.setStorageBytes32(_appId); - } -} - -// File: @aragon/os/contracts/acl/ACLSyntaxSugar.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - -contract ACLSyntaxSugar { - function arr() internal pure returns (uint256[]) { - return new uint256[](0); - } - - function arr(bytes32 _a) internal pure returns (uint256[] r) { - return arr(uint256(_a)); - } - - function arr(bytes32 _a, bytes32 _b) internal pure returns (uint256[] r) { - return arr(uint256(_a), uint256(_b)); - } - - function arr(address _a) internal pure returns (uint256[] r) { - return arr(uint256(_a)); - } - - function arr(address _a, address _b) internal pure returns (uint256[] r) { - return arr(uint256(_a), uint256(_b)); - } - - function arr(address _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) { - return arr(uint256(_a), _b, _c); - } - - function arr(address _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) { - return arr(uint256(_a), _b, _c, _d); - } - - function arr(address _a, uint256 _b) internal pure returns (uint256[] r) { - return arr(uint256(_a), uint256(_b)); - } - - function arr(address _a, address _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) { - return arr(uint256(_a), uint256(_b), _c, _d, _e); - } - - function arr(address _a, address _b, address _c) internal pure returns (uint256[] r) { - return arr(uint256(_a), uint256(_b), uint256(_c)); - } - - function arr(address _a, address _b, uint256 _c) internal pure returns (uint256[] r) { - return arr(uint256(_a), uint256(_b), uint256(_c)); - } - - function arr(uint256 _a) internal pure returns (uint256[] r) { - r = new uint256[](1); - r[0] = _a; - } - - function arr(uint256 _a, uint256 _b) internal pure returns (uint256[] r) { - r = new uint256[](2); - r[0] = _a; - r[1] = _b; - } - - function arr(uint256 _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) { - r = new uint256[](3); - r[0] = _a; - r[1] = _b; - r[2] = _c; - } - - function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) { - r = new uint256[](4); - r[0] = _a; - r[1] = _b; - r[2] = _c; - r[3] = _d; - } - - function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) { - r = new uint256[](5); - r[0] = _a; - r[1] = _b; - r[2] = _c; - r[3] = _d; - r[4] = _e; - } -} - - -contract ACLHelpers { - function decodeParamOp(uint256 _x) internal pure returns (uint8 b) { - return uint8(_x >> (8 * 30)); - } - - function decodeParamId(uint256 _x) internal pure returns (uint8 b) { - return uint8(_x >> (8 * 31)); - } - - function decodeParamsList(uint256 _x) internal pure returns (uint32 a, uint32 b, uint32 c) { - a = uint32(_x); - b = uint32(_x >> (8 * 4)); - c = uint32(_x >> (8 * 8)); - } -} - -// File: @aragon/os/contracts/common/Uint256Helpers.sol - -pragma solidity ^0.4.24; - - -library Uint256Helpers { - uint256 private constant MAX_UINT64 = uint64(-1); - - string private constant ERROR_NUMBER_TOO_BIG = "UINT64_NUMBER_TOO_BIG"; - - function toUint64(uint256 a) internal pure returns (uint64) { - require(a <= MAX_UINT64, ERROR_NUMBER_TOO_BIG); - return uint64(a); - } -} - -// File: @aragon/os/contracts/common/TimeHelpers.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - -contract TimeHelpers { - using Uint256Helpers for uint256; - - /** - * @dev Returns the current block number. - * Using a function rather than `block.number` allows us to easily mock the block number in - * tests. - */ - function getBlockNumber() internal view returns (uint256) { - return block.number; - } - - /** - * @dev Returns the current block number, converted to uint64. - * Using a function rather than `block.number` allows us to easily mock the block number in - * tests. - */ - function getBlockNumber64() internal view returns (uint64) { - return getBlockNumber().toUint64(); - } - - /** - * @dev Returns the current timestamp. - * Using a function rather than `block.timestamp` allows us to easily mock it in - * tests. - */ - function getTimestamp() internal view returns (uint256) { - return block.timestamp; // solium-disable-line security/no-block-members - } - - /** - * @dev Returns the current timestamp, converted to uint64. - * Using a function rather than `block.timestamp` allows us to easily mock it in - * tests. - */ - function getTimestamp64() internal view returns (uint64) { - return getTimestamp().toUint64(); - } -} - -// File: @aragon/os/contracts/common/Initializable.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - - -contract Initializable is TimeHelpers { - using UnstructuredStorage for bytes32; - - // keccak256("aragonOS.initializable.initializationBlock") - bytes32 internal constant INITIALIZATION_BLOCK_POSITION = 0xebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e; - - string private constant ERROR_ALREADY_INITIALIZED = "INIT_ALREADY_INITIALIZED"; - string private constant ERROR_NOT_INITIALIZED = "INIT_NOT_INITIALIZED"; - - modifier onlyInit { - require(getInitializationBlock() == 0, ERROR_ALREADY_INITIALIZED); - _; - } - - modifier isInitialized { - require(hasInitialized(), ERROR_NOT_INITIALIZED); - _; - } - - /** - * @return Block number in which the contract was initialized - */ - function getInitializationBlock() public view returns (uint256) { - return INITIALIZATION_BLOCK_POSITION.getStorageUint256(); - } - - /** - * @return Whether the contract has been initialized by the time of the current block - */ - function hasInitialized() public view returns (bool) { - uint256 initializationBlock = getInitializationBlock(); - return initializationBlock != 0 && getBlockNumber() >= initializationBlock; - } - - /** - * @dev Function to be called by top level contract after initialization has finished. - */ - function initialized() internal onlyInit { - INITIALIZATION_BLOCK_POSITION.setStorageUint256(getBlockNumber()); - } - - /** - * @dev Function to be called by top level contract after initialization to enable the contract - * at a future block number rather than immediately. - */ - function initializedAt(uint256 _blockNumber) internal onlyInit { - INITIALIZATION_BLOCK_POSITION.setStorageUint256(_blockNumber); - } -} - -// File: @aragon/os/contracts/common/Petrifiable.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - -contract Petrifiable is Initializable { - // Use block UINT256_MAX (which should be never) as the initializable date - uint256 internal constant PETRIFIED_BLOCK = uint256(-1); - - function isPetrified() public view returns (bool) { - return getInitializationBlock() == PETRIFIED_BLOCK; - } - - /** - * @dev Function to be called by top level contract to prevent being initialized. - * Useful for freezing base contracts when they're used behind proxies. - */ - function petrify() internal onlyInit { - initializedAt(PETRIFIED_BLOCK); - } -} - -// File: @aragon/os/contracts/common/Autopetrified.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - -contract Autopetrified is Petrifiable { - constructor() public { - // Immediately petrify base (non-proxy) instances of inherited contracts on deploy. - // This renders them uninitializable (and unusable without a proxy). - petrify(); - } -} - -// File: @aragon/os/contracts/common/ConversionHelpers.sol - -pragma solidity ^0.4.24; - - -library ConversionHelpers { - string private constant ERROR_IMPROPER_LENGTH = "CONVERSION_IMPROPER_LENGTH"; - - function dangerouslyCastUintArrayToBytes(uint256[] memory _input) internal pure returns (bytes memory output) { - // Force cast the uint256[] into a bytes array, by overwriting its length - // Note that the bytes array doesn't need to be initialized as we immediately overwrite it - // with the input and a new length. The input becomes invalid from this point forward. - uint256 byteLength = _input.length * 32; - assembly { - output := _input - mstore(output, byteLength) - } - } - - function dangerouslyCastBytesToUintArray(bytes memory _input) internal pure returns (uint256[] memory output) { - // Force cast the bytes array into a uint256[], by overwriting its length - // Note that the uint256[] doesn't need to be initialized as we immediately overwrite it - // with the input and a new length. The input becomes invalid from this point forward. - uint256 intsLength = _input.length / 32; - require(_input.length == intsLength * 32, ERROR_IMPROPER_LENGTH); - - assembly { - output := _input - mstore(output, intsLength) - } - } -} - -// File: @aragon/os/contracts/common/ReentrancyGuard.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - -contract ReentrancyGuard { - using UnstructuredStorage for bytes32; - - /* Hardcoded constants to save gas - bytes32 internal constant REENTRANCY_MUTEX_POSITION = keccak256("aragonOS.reentrancyGuard.mutex"); - */ - bytes32 private constant REENTRANCY_MUTEX_POSITION = 0xe855346402235fdd185c890e68d2c4ecad599b88587635ee285bce2fda58dacb; - - string private constant ERROR_REENTRANT = "REENTRANCY_REENTRANT_CALL"; - - modifier nonReentrant() { - // Ensure mutex is unlocked - require(!REENTRANCY_MUTEX_POSITION.getStorageBool(), ERROR_REENTRANT); - - // Lock mutex before function call - REENTRANCY_MUTEX_POSITION.setStorageBool(true); - - // Perform function call - _; - - // Unlock mutex after function call - REENTRANCY_MUTEX_POSITION.setStorageBool(false); - } -} - -// File: @aragon/os/contracts/lib/token/ERC20.sol - -// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/a9f910d34f0ab33a1ae5e714f69f9596a02b4d91/contracts/token/ERC20/ERC20.sol - -pragma solidity ^0.4.24; - - -/** - * @title ERC20 interface - * @dev see https://github.com/ethereum/EIPs/issues/20 - */ -contract ERC20 { - function totalSupply() public view returns (uint256); - - function balanceOf(address _who) public view returns (uint256); - - function allowance(address _owner, address _spender) - public view returns (uint256); - - function transfer(address _to, uint256 _value) public returns (bool); - - function approve(address _spender, uint256 _value) - public returns (bool); - - function transferFrom(address _from, address _to, uint256 _value) - public returns (bool); - - event Transfer( - address indexed from, - address indexed to, - uint256 value - ); - - event Approval( - address indexed owner, - address indexed spender, - uint256 value - ); -} - -// File: @aragon/os/contracts/common/EtherTokenConstant.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - -// aragonOS and aragon-apps rely on address(0) to denote native ETH, in -// contracts where both tokens and ETH are accepted -contract EtherTokenConstant { - address internal constant ETH = address(0); -} - -// File: @aragon/os/contracts/common/IsContract.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - -contract IsContract { - /* - * NOTE: this should NEVER be used for authentication - * (see pitfalls: https://github.com/fergarrui/ethereum-security/tree/master/contracts/extcodesize). - * - * This is only intended to be used as a sanity check that an address is actually a contract, - * RATHER THAN an address not being a contract. - */ - function isContract(address _target) internal view returns (bool) { - if (_target == address(0)) { - return false; - } - - uint256 size; - assembly { size := extcodesize(_target) } - return size > 0; - } -} - -// File: @aragon/os/contracts/common/SafeERC20.sol - -// Inspired by AdEx (https://github.com/AdExNetwork/adex-protocol-eth/blob/b9df617829661a7518ee10f4cb6c4108659dd6d5/contracts/libs/SafeERC20.sol) -// and 0x (https://github.com/0xProject/0x-monorepo/blob/737d1dc54d72872e24abce5a1dbe1b66d35fa21a/contracts/protocol/contracts/protocol/AssetProxy/ERC20Proxy.sol#L143) - -pragma solidity ^0.4.24; - - - -library SafeERC20 { - // Before 0.5, solidity has a mismatch between `address.transfer()` and `token.transfer()`: - // https://github.com/ethereum/solidity/issues/3544 - bytes4 private constant TRANSFER_SELECTOR = 0xa9059cbb; - - string private constant ERROR_TOKEN_BALANCE_REVERTED = "SAFE_ERC_20_BALANCE_REVERTED"; - string private constant ERROR_TOKEN_ALLOWANCE_REVERTED = "SAFE_ERC_20_ALLOWANCE_REVERTED"; - - function invokeAndCheckSuccess(address _addr, bytes memory _calldata) - private - returns (bool) - { - bool ret; - assembly { - let ptr := mload(0x40) // free memory pointer - - let success := call( - gas, // forward all gas - _addr, // address - 0, // no value - add(_calldata, 0x20), // calldata start - mload(_calldata), // calldata length - ptr, // write output over free memory - 0x20 // uint256 return - ) - - if gt(success, 0) { - // Check number of bytes returned from last function call - switch returndatasize - - // No bytes returned: assume success - case 0 { - ret := 1 - } - - // 32 bytes returned: check if non-zero - case 0x20 { - // Only return success if returned data was true - // Already have output in ptr - ret := eq(mload(ptr), 1) - } - - // Not sure what was returned: don't mark as success - default { } - } - } - return ret; - } - - function staticInvoke(address _addr, bytes memory _calldata) - private - view - returns (bool, uint256) - { - bool success; - uint256 ret; - assembly { - let ptr := mload(0x40) // free memory pointer - - success := staticcall( - gas, // forward all gas - _addr, // address - add(_calldata, 0x20), // calldata start - mload(_calldata), // calldata length - ptr, // write output over free memory - 0x20 // uint256 return - ) - - if gt(success, 0) { - ret := mload(ptr) - } - } - return (success, ret); - } - - /** - * @dev Same as a standards-compliant ERC20.transfer() that never reverts (returns false). - * Note that this makes an external call to the token. - */ - function safeTransfer(ERC20 _token, address _to, uint256 _amount) internal returns (bool) { - bytes memory transferCallData = abi.encodeWithSelector( - TRANSFER_SELECTOR, - _to, - _amount - ); - return invokeAndCheckSuccess(_token, transferCallData); - } - - /** - * @dev Same as a standards-compliant ERC20.transferFrom() that never reverts (returns false). - * Note that this makes an external call to the token. - */ - function safeTransferFrom(ERC20 _token, address _from, address _to, uint256 _amount) internal returns (bool) { - bytes memory transferFromCallData = abi.encodeWithSelector( - _token.transferFrom.selector, - _from, - _to, - _amount - ); - return invokeAndCheckSuccess(_token, transferFromCallData); - } - - /** - * @dev Same as a standards-compliant ERC20.approve() that never reverts (returns false). - * Note that this makes an external call to the token. - */ - function safeApprove(ERC20 _token, address _spender, uint256 _amount) internal returns (bool) { - bytes memory approveCallData = abi.encodeWithSelector( - _token.approve.selector, - _spender, - _amount - ); - return invokeAndCheckSuccess(_token, approveCallData); - } - - /** - * @dev Static call into ERC20.balanceOf(). - * Reverts if the call fails for some reason (should never fail). - */ - function staticBalanceOf(ERC20 _token, address _owner) internal view returns (uint256) { - bytes memory balanceOfCallData = abi.encodeWithSelector( - _token.balanceOf.selector, - _owner - ); - - (bool success, uint256 tokenBalance) = staticInvoke(_token, balanceOfCallData); - require(success, ERROR_TOKEN_BALANCE_REVERTED); - - return tokenBalance; - } - - /** - * @dev Static call into ERC20.allowance(). - * Reverts if the call fails for some reason (should never fail). - */ - function staticAllowance(ERC20 _token, address _owner, address _spender) internal view returns (uint256) { - bytes memory allowanceCallData = abi.encodeWithSelector( - _token.allowance.selector, - _owner, - _spender - ); - - (bool success, uint256 allowance) = staticInvoke(_token, allowanceCallData); - require(success, ERROR_TOKEN_ALLOWANCE_REVERTED); - - return allowance; - } -} - -// File: @aragon/os/contracts/common/VaultRecoverable.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - - - - - -contract VaultRecoverable is IVaultRecoverable, EtherTokenConstant, IsContract { - using SafeERC20 for ERC20; - - string private constant ERROR_DISALLOWED = "RECOVER_DISALLOWED"; - string private constant ERROR_VAULT_NOT_CONTRACT = "RECOVER_VAULT_NOT_CONTRACT"; - string private constant ERROR_TOKEN_TRANSFER_FAILED = "RECOVER_TOKEN_TRANSFER_FAILED"; - - /** - * @notice Send funds to recovery Vault. This contract should never receive funds, - * but in case it does, this function allows one to recover them. - * @param _token Token balance to be sent to recovery vault. - */ - function transferToVault(address _token) external { - require(allowRecoverability(_token), ERROR_DISALLOWED); - address vault = getRecoveryVault(); - require(isContract(vault), ERROR_VAULT_NOT_CONTRACT); - - uint256 balance; - if (_token == ETH) { - balance = address(this).balance; - vault.transfer(balance); - } else { - ERC20 token = ERC20(_token); - balance = token.staticBalanceOf(this); - require(token.safeTransfer(vault, balance), ERROR_TOKEN_TRANSFER_FAILED); - } - - emit RecoverToVault(vault, _token, balance); - } - - /** - * @dev By default deriving from AragonApp makes it recoverable - * @param token Token address that would be recovered - * @return bool whether the app allows the recovery - */ - function allowRecoverability(address token) public view returns (bool) { - return true; - } - - // Cast non-implemented interface to be public so we can use it internally - function getRecoveryVault() public view returns (address); -} - -// File: @aragon/os/contracts/evmscript/IEVMScriptExecutor.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - -interface IEVMScriptExecutor { - function execScript(bytes script, bytes input, address[] blacklist) external returns (bytes); - function executorType() external pure returns (bytes32); -} - -// File: @aragon/os/contracts/evmscript/IEVMScriptRegistry.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - -contract EVMScriptRegistryConstants { - /* Hardcoded constants to save gas - bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = apmNamehash("evmreg"); - */ - bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = 0xddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd61; -} - - -interface IEVMScriptRegistry { - function addScriptExecutor(IEVMScriptExecutor executor) external returns (uint id); - function disableScriptExecutor(uint256 executorId) external; - - // TODO: this should be external - // See https://github.com/ethereum/solidity/issues/4832 - function getScriptExecutor(bytes script) public view returns (IEVMScriptExecutor); -} - -// File: @aragon/os/contracts/kernel/KernelConstants.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - -contract KernelAppIds { - /* Hardcoded constants to save gas - bytes32 internal constant KERNEL_CORE_APP_ID = apmNamehash("kernel"); - bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = apmNamehash("acl"); - bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = apmNamehash("vault"); - */ - bytes32 internal constant KERNEL_CORE_APP_ID = 0x3b4bf6bf3ad5000ecf0f989d5befde585c6860fea3e574a4fab4c49d1c177d9c; - bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = 0xe3262375f45a6e2026b7e7b18c2b807434f2508fe1a2a3dfb493c7df8f4aad6a; - bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = 0x7e852e0fcfce6551c13800f1e7476f982525c2b5277ba14b24339c68416336d1; -} - - -contract KernelNamespaceConstants { - /* Hardcoded constants to save gas - bytes32 internal constant KERNEL_CORE_NAMESPACE = keccak256("core"); - bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = keccak256("base"); - bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = keccak256("app"); - */ - bytes32 internal constant KERNEL_CORE_NAMESPACE = 0xc681a85306374a5ab27f0bbc385296a54bcd314a1948b6cf61c4ea1bc44bb9f8; - bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = 0xf1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f; - bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb; -} - -// File: @aragon/os/contracts/evmscript/EVMScriptRunner.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - - - - - -contract EVMScriptRunner is AppStorage, Initializable, EVMScriptRegistryConstants, KernelNamespaceConstants { - string private constant ERROR_EXECUTOR_UNAVAILABLE = "EVMRUN_EXECUTOR_UNAVAILABLE"; - string private constant ERROR_PROTECTED_STATE_MODIFIED = "EVMRUN_PROTECTED_STATE_MODIFIED"; - - /* This is manually crafted in assembly - string private constant ERROR_EXECUTOR_INVALID_RETURN = "EVMRUN_EXECUTOR_INVALID_RETURN"; - */ - - event ScriptResult(address indexed executor, bytes script, bytes input, bytes returnData); - - function getEVMScriptExecutor(bytes _script) public view returns (IEVMScriptExecutor) { - return IEVMScriptExecutor(getEVMScriptRegistry().getScriptExecutor(_script)); - } - - function getEVMScriptRegistry() public view returns (IEVMScriptRegistry) { - address registryAddr = kernel().getApp(KERNEL_APP_ADDR_NAMESPACE, EVMSCRIPT_REGISTRY_APP_ID); - return IEVMScriptRegistry(registryAddr); - } - - function runScript(bytes _script, bytes _input, address[] _blacklist) - internal - isInitialized - protectState - returns (bytes) - { - IEVMScriptExecutor executor = getEVMScriptExecutor(_script); - require(address(executor) != address(0), ERROR_EXECUTOR_UNAVAILABLE); - - bytes4 sig = executor.execScript.selector; - bytes memory data = abi.encodeWithSelector(sig, _script, _input, _blacklist); - - bytes memory output; - assembly { - let success := delegatecall( - gas, // forward all gas - executor, // address - add(data, 0x20), // calldata start - mload(data), // calldata length - 0, // don't write output (we'll handle this ourselves) - 0 // don't write output - ) - - output := mload(0x40) // free mem ptr get - - switch success - case 0 { - // If the call errored, forward its full error data - returndatacopy(output, 0, returndatasize) - revert(output, returndatasize) - } - default { - switch gt(returndatasize, 0x3f) - case 0 { - // Need at least 0x40 bytes returned for properly ABI-encoded bytes values, - // revert with "EVMRUN_EXECUTOR_INVALID_RETURN" - // See remix: doing a `revert("EVMRUN_EXECUTOR_INVALID_RETURN")` always results in - // this memory layout - mstore(output, 0x08c379a000000000000000000000000000000000000000000000000000000000) // error identifier - mstore(add(output, 0x04), 0x0000000000000000000000000000000000000000000000000000000000000020) // starting offset - mstore(add(output, 0x24), 0x000000000000000000000000000000000000000000000000000000000000001e) // reason length - mstore(add(output, 0x44), 0x45564d52554e5f4558454355544f525f494e56414c49445f52455455524e0000) // reason - - revert(output, 100) // 100 = 4 + 3 * 32 (error identifier + 3 words for the ABI encoded error) - } - default { - // Copy result - // - // Needs to perform an ABI decode for the expected `bytes` return type of - // `executor.execScript()` as solidity will automatically ABI encode the returned bytes as: - // [ position of the first dynamic length return value = 0x20 (32 bytes) ] - // [ output length (32 bytes) ] - // [ output content (N bytes) ] - // - // Perform the ABI decode by ignoring the first 32 bytes of the return data - let copysize := sub(returndatasize, 0x20) - returndatacopy(output, 0x20, copysize) - - mstore(0x40, add(output, copysize)) // free mem ptr set - } - } - } - - emit ScriptResult(address(executor), _script, _input, output); - - return output; - } - - modifier protectState { - address preKernel = address(kernel()); - bytes32 preAppId = appId(); - _; // exec - require(address(kernel()) == preKernel, ERROR_PROTECTED_STATE_MODIFIED); - require(appId() == preAppId, ERROR_PROTECTED_STATE_MODIFIED); - } -} - -// File: @aragon/os/contracts/apps/AragonApp.sol - -/* - * SPDX-License-Identitifer: MIT - */ - -pragma solidity ^0.4.24; - - - - - - - - - -// Contracts inheriting from AragonApp are, by default, immediately petrified upon deployment so -// that they can never be initialized. -// Unless overriden, this behaviour enforces those contracts to be usable only behind an AppProxy. -// ReentrancyGuard, EVMScriptRunner, and ACLSyntaxSugar are not directly used by this contract, but -// are included so that they are automatically usable by subclassing contracts -contract AragonApp is AppStorage, Autopetrified, VaultRecoverable, ReentrancyGuard, EVMScriptRunner, ACLSyntaxSugar { - string private constant ERROR_AUTH_FAILED = "APP_AUTH_FAILED"; - - modifier auth(bytes32 _role) { - require(canPerform(msg.sender, _role, new uint256[](0)), ERROR_AUTH_FAILED); - _; - } - - modifier authP(bytes32 _role, uint256[] _params) { - require(canPerform(msg.sender, _role, _params), ERROR_AUTH_FAILED); - _; - } - - /** - * @dev Check whether an action can be performed by a sender for a particular role on this app - * @param _sender Sender of the call - * @param _role Role on this app - * @param _params Permission params for the role - * @return Boolean indicating whether the sender has the permissions to perform the action. - * Always returns false if the app hasn't been initialized yet. - */ - function canPerform(address _sender, bytes32 _role, uint256[] _params) public view returns (bool) { - if (!hasInitialized()) { - return false; - } - - IKernel linkedKernel = kernel(); - if (address(linkedKernel) == address(0)) { - return false; - } - - return linkedKernel.hasPermission( - _sender, - address(this), - _role, - ConversionHelpers.dangerouslyCastUintArrayToBytes(_params) - ); - } - - /** - * @dev Get the recovery vault for the app - * @return Recovery vault address for the app - */ - function getRecoveryVault() public view returns (address) { - // Funds recovery via a vault is only available when used with a kernel - return kernel().getRecoveryVault(); // if kernel is not set, it will revert - } -} - -// File: contracts/Contribution.sol - -pragma solidity ^0.4.24; - - - -interface IToken { - 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 { - 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 { - uint32 contributorId; - uint32 amount; - bool claimed; - bytes32 hashDigest; - uint8 hashFunction; - uint8 hashSize; - string tokenMetadataURL; - uint256 confirmedAtBlock; - bool vetoed; - bool exists; - } - - string internal name_; - string internal symbol_; - - // map contribution ID to contributor - mapping(uint32 => uint32) public contributionOwner; - // map contributor to contribution IDs - mapping(uint32 => uint32[]) public ownedContributions; - - mapping(uint32 => ContributionData) public contributions; - uint32 public contributionsCount; - - uint32 public blocksToWait; - - 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; - blocksToWait = 40320; // 7 days; 15 seconds block time - 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_; - } - - function symbol() external view returns (string) { - return symbol_; - } - - // Balance is amount of ERC271 tokens, not amount of kredits - function balanceOf(address owner) public view returns (uint256) { - require(owner != address(0)); - uint32 contributorId = getContributorIdByAddress(owner); - return ownedContributions[contributorId].length; - } - - function ownerOf(uint32 contributionId) public view returns (address) { - require(exists(contributionId)); - uint32 contributorId = contributions[contributionId].contributorId; - return getContributorAddressById(contributorId); - } - - function tokenOfOwnerByIndex(address owner, uint32 index) public view returns (uint32) { - uint32 contributorId = getContributorIdByAddress(owner); - return ownedContributions[contributorId][index]; - } - - function tokenMetadata(uint32 contributionId) public view returns (string) { - return contributions[contributionId].tokenMetadataURL; - } - - // - // Custom functions - // - - function totalKreditsEarned(bool confirmedOnly) public view returns (uint32 amount) { - for (uint32 i = 1; i <= contributionsCount; i++) { - ContributionData memory c = contributions[i]; - if (!c.vetoed && (block.number >= c.confirmedAtBlock || !confirmedOnly)) { - amount += c.amount; // should use safemath - } - } - } - - function totalKreditsEarnedByContributor(uint32 contributorId, bool confirmedOnly) public view returns (uint32 amount) { - uint256 tokenCount = ownedContributions[contributorId].length; - for (uint256 i = 0; i < tokenCount; i++) { - uint32 cId = ownedContributions[contributorId][i]; - ContributionData memory c = contributions[cId]; - if (!c.vetoed && (block.number >= c.confirmedAtBlock || !confirmedOnly)) { - amount += c.amount; // should use safemath - } - } - } - - 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) { - id = contributionId; - ContributionData storage c = contributions[id]; - return ( - id, - c.contributorId, - c.amount, - c.claimed, - c.hashDigest, - c.hashFunction, - c.hashSize, - c.confirmedAtBlock, - c.exists, - c.vetoed - ); - } - - 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.contributorId = contributorId; - c.hashDigest = hashDigest; - c.hashFunction = hashFunction; - c.hashSize = hashSize; - if (contributionId < 10) { - c.confirmedAtBlock = block.number; - } else { - c.confirmedAtBlock = block.number + blocksToWait; - } - - contributionsCount++; - - contributionOwner[contributionId] = contributorId; - ownedContributions[contributorId].push(contributionId); - - emit ContributionAdded(contributionId, contributorId, amount); - } - - 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'); - require(block.number < c.confirmedAtBlock, 'VETO_PERIOD_ENDED'); - c.vetoed = true; - - emit ContributionVetoed(contributionId, msg.sender); - } - - function claim(uint32 contributionId) public isInitialized { - 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 token = getTokenContract(); - 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(uint32 contributionId) view public returns (bool) { - return contributions[contributionId].exists; - } -}