Compare commits

...

28 Commits

Author SHA1 Message Date
0f872c8f1e
7.5.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2025-01-20 15:39:11 -05:00
484a9ffcaf Merge pull request 'Add amountSats to expense items' (#249) from chore/update_schemas into master
Reviewed-on: #249
2025-01-20 20:35:11 +00:00
6e9f565587
Add more logs for IPFS failures
All checks were successful
Release Drafter / Update release notes draft (pull_request) Successful in 4s
2025-01-20 15:32:50 -05:00
f4634fe692
Add amountSats to expense items
closes #248
2025-01-20 15:31:19 -05:00
68968e1fbd
Update Kosmos schemas 2025-01-20 14:41:41 -05:00
Râu Cao
a2ebc609ea
7.4.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-29 15:03:03 +02:00
beca6afc4f Merge pull request 'Add npm version/release script' (#247) from dev/versioning into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #247
2023-08-29 12:59:56 +00:00
Râu Cao
90223dd22e
Add npm version script
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Release Drafter / Update release notes draft (pull_request) Successful in 2s
closes #46
2023-08-29 14:57:07 +02:00
ea3a591a0c Merge pull request 'Improve data in development seeds/bootstrap' (#246) from dev/improve_seeds into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #246
2023-08-29 10:19:26 +00:00
Râu Cao
e0f20d363c
Pre-confirm some contributions and reimbursements on bootstrap
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Release Drafter / Update release notes draft (pull_request) Successful in 3s
2023-08-24 16:43:52 +02:00
Râu Cao
5e33381f2a
Allow overriding confirmedAtBlock and vetoed in JS API 2023-08-24 16:43:18 +02:00
1f91a13f06 Merge pull request 'Update reimbursement to support migration' (#244) from feature/reimbursement_migrations into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #244
2023-08-24 14:04:22 +00:00
7d2a492fc9
Update reimbursement to support migration
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Release Drafter / Update release notes draft (pull_request) Successful in 4s
2023-08-24 15:45:28 +02:00
Râu Cao
30490ce393
"Fix" default network name in hardhat config
All checks were successful
continuous-integration/drone/push Build is passing
Some scripts require "hardhat" while others require "localhost". But we
can fix whatever doesn't work directly in the package config.
2023-08-24 14:52:38 +02:00
Râu Cao
f0a71ca8f1
7.3.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-13 21:01:34 +02:00
Râu Cao
117918e66f
Remove obsolete npm scripts 2023-08-13 20:59:09 +02:00
d0d456b357 Merge pull request 'Migrate to proper RSK testnet deployment' (#242) from new-final-deploy into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #242
2023-08-13 18:54:35 +00:00
cda84fa2ce Add support to start the contribution import from a specific id
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Release Drafter / Update release notes draft (pull_request) Successful in 3s
2023-08-13 14:46:48 +02:00
97e2db93be Add reimbursement import 2023-08-13 14:46:48 +02:00
17c582f6df Add export script for reimbursements 2023-08-13 14:46:48 +02:00
Râu Cao
914d4d9585
Update hardhat config
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2023-08-07 23:06:40 +02:00
Râu Cao
0deeba14fc
Upgrade testnet contribution contract, reinit contributor contract 2023-08-07 23:05:38 +02:00
Râu Cao
c61632d949
Resolve some solhint errors and warnings 2023-08-07 23:05:15 +02:00
Râu Cao
0b593ec795
Merge branch 'master' into new-final-deploy 2023-08-07 22:07:45 +02:00
Râu Cao
401c528e95
Ignore .env 2023-08-07 22:06:42 +02:00
ed2033980c deploy to RSK testnet
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-07 21:55:08 +02:00
17c7a36cb4 Add openzeppelin to repo
but ignore local development chain
2023-08-07 21:10:03 +02:00
Râu Cao
1cb777aa44
Add missing import
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-27 12:00:17 +02:00
23 changed files with 1169 additions and 64 deletions

3
.gitignore vendored
View File

@ -9,4 +9,5 @@ data
cache
artifacts
.openzeppelin
.openzeppelin/unknown-1337.json
.env

0
.openzeppelin/.keep Normal file
View File

View File

@ -0,0 +1,937 @@
{
"manifestVersion": "3.2",
"admin": {
"address": "0xcf844786B3E8b23f6d6D8CA845c0DE07047D54a7",
"txHash": "0xafcf40769c999bae279f48e7d81d0f698c82286dd4178029021f82ecb549e645"
},
"proxies": [
{
"address": "0x0E4b2A1b7655266Ba9A029B50eEB42DBCd83090B",
"txHash": "0xfd629e11999d0448404c81e33ea79cbd18f8a978cf93afcf5c45e97eb63991f8",
"kind": "transparent"
},
{
"address": "0x242fab10d4F395B9DCC59b8Adc6629722c2E65d2",
"txHash": "0xcd6633873db24736e9f40a4c401b658b469b290176e0d03e640ccfb7945a5426",
"kind": "transparent"
},
{
"address": "0x4fe4311a91F90ff98f0978002D84AE4771fe7cF1",
"txHash": "0x8b6e5088ad7f39918bf9e3e67cdc45bd9bf2a62b13e4f7a1441ad3bca27b4c04",
"kind": "transparent"
},
{
"address": "0x252b3Ab7913d6Ed8f303a7e5452F0BFf8bE6b64d",
"txHash": "0x138a863f21ab0ef2400434280bc8c9e389e6dead125b5622deb9533eb2506a53",
"kind": "transparent"
},
{
"address": "0x2C5cf87C0dE8e4E3642de900Fa7B4b630163E2aA",
"txHash": "0x0e4310cd5faba8ce7cae60b3de1412050b4315957e58bc8415680eb5e9de0314",
"kind": "transparent"
},
{
"address": "0x95DC31665D193E377f54b70C535fcDb205525291",
"txHash": "0xb03a4d57e80f73d65f29f75fc419fd6197148e979ed9c330353c8574d952c544",
"kind": "transparent"
},
{
"address": "0x049bA8E70FEbFfd6d03C71211bDA37B4ff064115",
"txHash": "0x5f561059950c1e06fc62cfc7cac4c4618a0e066704fb680b659ae9a08b6e1d27",
"kind": "transparent"
},
{
"address": "0x7ab26A0f00eF0D6e05e5BDE047505a4eD53aF809",
"txHash": "0xfa73dbe843ea1151f925f531365fb919b6138c8963e62332c8e00cf5141e457c",
"kind": "transparent"
},
{
"address": "0x99EC72b34295b62f4bC1527Da461262c615a0b2c",
"txHash": "0x1ca664ffdf50a6519b900c84e715d43a59ae39b35d5914ecb964f5440d486098",
"kind": "transparent"
}
],
"impls": {
"4ef0a0d41e92c95e53ad65fb957441f9b9443f4fe2d1c2221dfde7d1341db071": {
"address": "0x73069A23A5252E9c0D0b5F0493918277074ED987",
"txHash": "0x4c139a7a70dea23d9fdbcb7d8d381be7593fc3d80d59f29aec0fd6f16698136b",
"layout": {
"storage": [
{
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "t_uint8",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
"retypedFrom": "bool"
},
{
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "t_bool",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
},
{
"label": "deployer",
"offset": 2,
"slot": "0",
"type": "t_address",
"contract": "Contributor",
"src": "contracts/Contributor.sol:15"
},
{
"label": "contributionContract",
"offset": 0,
"slot": "1",
"type": "t_contract(IContributionBalance)2238",
"contract": "Contributor",
"src": "contracts/Contributor.sol:16"
},
{
"label": "tokenContract",
"offset": 0,
"slot": "2",
"type": "t_contract(IToken)2221",
"contract": "Contributor",
"src": "contracts/Contributor.sol:17"
},
{
"label": "contributorIds",
"offset": 0,
"slot": "3",
"type": "t_mapping(t_address,t_uint32)",
"contract": "Contributor",
"src": "contracts/Contributor.sol:28"
},
{
"label": "contributors",
"offset": 0,
"slot": "4",
"type": "t_mapping(t_uint32,t_struct(Contributor)2261_storage)",
"contract": "Contributor",
"src": "contracts/Contributor.sol:29"
},
{
"label": "contributorsCount",
"offset": 0,
"slot": "5",
"type": "t_uint32",
"contract": "Contributor",
"src": "contracts/Contributor.sol:30"
},
{
"label": "profileManager",
"offset": 4,
"slot": "5",
"type": "t_address",
"contract": "Contributor",
"src": "contracts/Contributor.sol:32"
}
],
"types": {
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_bytes32": {
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(IContributionBalance)2238": {
"label": "contract IContributionBalance",
"numberOfBytes": "20"
},
"t_contract(IToken)2221": {
"label": "contract IToken",
"numberOfBytes": "20"
},
"t_mapping(t_address,t_uint32)": {
"label": "mapping(address => uint32)",
"numberOfBytes": "32"
},
"t_mapping(t_uint32,t_struct(Contributor)2261_storage)": {
"label": "mapping(uint32 => struct Contributor.Contributor)",
"numberOfBytes": "32"
},
"t_struct(Contributor)2261_storage": {
"label": "struct Contributor.Contributor",
"members": [
{
"label": "account",
"type": "t_address",
"offset": 0,
"slot": "0"
},
{
"label": "hashDigest",
"type": "t_bytes32",
"offset": 0,
"slot": "1"
},
{
"label": "hashFunction",
"type": "t_uint8",
"offset": 0,
"slot": "2"
},
{
"label": "hashSize",
"type": "t_uint8",
"offset": 1,
"slot": "2"
},
{
"label": "exists",
"type": "t_bool",
"offset": 2,
"slot": "2"
},
{
"label": "kreditsWithdrawn",
"type": "t_uint32",
"offset": 3,
"slot": "2"
}
],
"numberOfBytes": "96"
},
"t_uint32": {
"label": "uint32",
"numberOfBytes": "4"
},
"t_uint8": {
"label": "uint8",
"numberOfBytes": "1"
}
}
}
},
"960de0fa0d50c2ede5b2a868a9475e44622a753d4ff7829422c7eb342572b189": {
"address": "0x872fa1C9d207b5ce3CE786f2099c3EeA621dFD70",
"txHash": "0xb338b0878d66e466425c9032ef0f9019f91cda395fae4f83c999534249cd228d",
"layout": {
"storage": [
{
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "t_uint8",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
"retypedFrom": "bool"
},
{
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "t_bool",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
},
{
"label": "contributorContract",
"offset": 2,
"slot": "0",
"type": "t_contract(ContributorInterface)1546",
"contract": "Contribution",
"src": "contracts/Contribution.sol:14"
},
{
"label": "name_",
"offset": 0,
"slot": "1",
"type": "t_string_storage",
"contract": "Contribution",
"src": "contracts/Contribution.sol:28"
},
{
"label": "symbol_",
"offset": 0,
"slot": "2",
"type": "t_string_storage",
"contract": "Contribution",
"src": "contracts/Contribution.sol:29"
},
{
"label": "contributionOwner",
"offset": 0,
"slot": "3",
"type": "t_mapping(t_uint32,t_uint32)",
"contract": "Contribution",
"src": "contracts/Contribution.sol:32"
},
{
"label": "ownedContributions",
"offset": 0,
"slot": "4",
"type": "t_mapping(t_uint32,t_array(t_uint32)dyn_storage)",
"contract": "Contribution",
"src": "contracts/Contribution.sol:34"
},
{
"label": "contributions",
"offset": 0,
"slot": "5",
"type": "t_mapping(t_uint32,t_struct(ContributionData)1570_storage)",
"contract": "Contribution",
"src": "contracts/Contribution.sol:36"
},
{
"label": "contributionsCount",
"offset": 0,
"slot": "6",
"type": "t_uint32",
"contract": "Contribution",
"src": "contracts/Contribution.sol:37"
},
{
"label": "blocksToWait",
"offset": 4,
"slot": "6",
"type": "t_uint32",
"contract": "Contribution",
"src": "contracts/Contribution.sol:40"
},
{
"label": "deployer",
"offset": 8,
"slot": "6",
"type": "t_address",
"contract": "Contribution",
"src": "contracts/Contribution.sol:43"
},
{
"label": "migrationDone",
"offset": 28,
"slot": "6",
"type": "t_bool",
"contract": "Contribution",
"src": "contracts/Contribution.sol:46"
}
],
"types": {
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_array(t_uint32)dyn_storage": {
"label": "uint32[]",
"numberOfBytes": "32"
},
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_bytes32": {
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(ContributorInterface)1546": {
"label": "contract ContributorInterface",
"numberOfBytes": "20"
},
"t_mapping(t_uint32,t_array(t_uint32)dyn_storage)": {
"label": "mapping(uint32 => uint32[])",
"numberOfBytes": "32"
},
"t_mapping(t_uint32,t_struct(ContributionData)1570_storage)": {
"label": "mapping(uint32 => struct Contribution.ContributionData)",
"numberOfBytes": "32"
},
"t_mapping(t_uint32,t_uint32)": {
"label": "mapping(uint32 => uint32)",
"numberOfBytes": "32"
},
"t_string_storage": {
"label": "string",
"numberOfBytes": "32"
},
"t_struct(ContributionData)1570_storage": {
"label": "struct Contribution.ContributionData",
"members": [
{
"label": "contributorId",
"type": "t_uint32",
"offset": 0,
"slot": "0"
},
{
"label": "amount",
"type": "t_uint32",
"offset": 4,
"slot": "0"
},
{
"label": "hashDigest",
"type": "t_bytes32",
"offset": 0,
"slot": "1"
},
{
"label": "hashFunction",
"type": "t_uint8",
"offset": 0,
"slot": "2"
},
{
"label": "hashSize",
"type": "t_uint8",
"offset": 1,
"slot": "2"
},
{
"label": "tokenMetadataURL",
"type": "t_string_storage",
"offset": 0,
"slot": "3"
},
{
"label": "confirmedAtBlock",
"type": "t_uint256",
"offset": 0,
"slot": "4"
},
{
"label": "vetoed",
"type": "t_bool",
"offset": 0,
"slot": "5"
},
{
"label": "exists",
"type": "t_bool",
"offset": 1,
"slot": "5"
}
],
"numberOfBytes": "192"
},
"t_uint256": {
"label": "uint256",
"numberOfBytes": "32"
},
"t_uint32": {
"label": "uint32",
"numberOfBytes": "4"
},
"t_uint8": {
"label": "uint8",
"numberOfBytes": "1"
}
}
}
},
"75d216a88a04f139c0c69c1369ddd6ded974ebf995ccce44546b6ace2dabb597": {
"address": "0x2D7848AF9Af0d2d8D67bbaAbf84D58Bd19F17eFa",
"txHash": "0x8a6621bfc3db4c2bc2d294d69e6d25d499c7667b8da1910b3b0f2bc43968adba",
"layout": {
"storage": [
{
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "t_uint8",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
"retypedFrom": "bool"
},
{
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "t_bool",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
},
{
"label": "__gap",
"offset": 0,
"slot": "1",
"type": "t_array(t_uint256)50_storage",
"contract": "ContextUpgradeable",
"src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36"
},
{
"label": "_balances",
"offset": 0,
"slot": "51",
"type": "t_mapping(t_address,t_uint256)",
"contract": "ERC20Upgradeable",
"src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:37"
},
{
"label": "_allowances",
"offset": 0,
"slot": "52",
"type": "t_mapping(t_address,t_mapping(t_address,t_uint256))",
"contract": "ERC20Upgradeable",
"src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:39"
},
{
"label": "_totalSupply",
"offset": 0,
"slot": "53",
"type": "t_uint256",
"contract": "ERC20Upgradeable",
"src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:41"
},
{
"label": "_name",
"offset": 0,
"slot": "54",
"type": "t_string_storage",
"contract": "ERC20Upgradeable",
"src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:43"
},
{
"label": "_symbol",
"offset": 0,
"slot": "55",
"type": "t_string_storage",
"contract": "ERC20Upgradeable",
"src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:44"
},
{
"label": "__gap",
"offset": 0,
"slot": "56",
"type": "t_array(t_uint256)45_storage",
"contract": "ERC20Upgradeable",
"src": "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol:400"
},
{
"label": "contributorContract",
"offset": 0,
"slot": "101",
"type": "t_contract(ContributorInterface)3364",
"contract": "Token",
"src": "contracts/Token.sol:13"
},
{
"label": "contributorContractAddress",
"offset": 0,
"slot": "102",
"type": "t_address",
"contract": "Token",
"src": "contracts/Token.sol:16"
}
],
"types": {
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_array(t_uint256)45_storage": {
"label": "uint256[45]",
"numberOfBytes": "1440"
},
"t_array(t_uint256)50_storage": {
"label": "uint256[50]",
"numberOfBytes": "1600"
},
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_contract(ContributorInterface)3364": {
"label": "contract ContributorInterface",
"numberOfBytes": "20"
},
"t_mapping(t_address,t_mapping(t_address,t_uint256))": {
"label": "mapping(address => mapping(address => uint256))",
"numberOfBytes": "32"
},
"t_mapping(t_address,t_uint256)": {
"label": "mapping(address => uint256)",
"numberOfBytes": "32"
},
"t_string_storage": {
"label": "string",
"numberOfBytes": "32"
},
"t_uint256": {
"label": "uint256",
"numberOfBytes": "32"
},
"t_uint8": {
"label": "uint8",
"numberOfBytes": "1"
}
}
}
},
"d06fbc00ef593e162a054b1f961d39eaf32e0734f8ba230d3519837b8548e33b": {
"address": "0x5b8AF16247593465cC82b68A7Af49338E141A207",
"txHash": "0x2e052dd42231aa43a484c5a4c376e73b70fd14026611be0b585c826d37fe829c",
"layout": {
"storage": [
{
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "t_uint8",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
"retypedFrom": "bool"
},
{
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "t_bool",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
},
{
"label": "contributorContract",
"offset": 2,
"slot": "0",
"type": "t_contract(ContributorInterface)2958",
"contract": "Reimbursement",
"src": "contracts/Reimbursement.sol:14"
},
{
"label": "reimbursements",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_uint32,t_struct(ReimbursementData)2982_storage)",
"contract": "Reimbursement",
"src": "contracts/Reimbursement.sol:29"
},
{
"label": "reimbursementsCount",
"offset": 0,
"slot": "2",
"type": "t_uint32",
"contract": "Reimbursement",
"src": "contracts/Reimbursement.sol:30"
},
{
"label": "blocksToWait",
"offset": 4,
"slot": "2",
"type": "t_uint32",
"contract": "Reimbursement",
"src": "contracts/Reimbursement.sol:32"
}
],
"types": {
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_bytes32": {
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(ContributorInterface)2958": {
"label": "contract ContributorInterface",
"numberOfBytes": "20"
},
"t_mapping(t_uint32,t_struct(ReimbursementData)2982_storage)": {
"label": "mapping(uint32 => struct Reimbursement.ReimbursementData)",
"numberOfBytes": "32"
},
"t_struct(ReimbursementData)2982_storage": {
"label": "struct Reimbursement.ReimbursementData",
"members": [
{
"label": "recipientId",
"type": "t_uint32",
"offset": 0,
"slot": "0"
},
{
"label": "amount",
"type": "t_uint256",
"offset": 0,
"slot": "1"
},
{
"label": "token",
"type": "t_address",
"offset": 0,
"slot": "2"
},
{
"label": "hashDigest",
"type": "t_bytes32",
"offset": 0,
"slot": "3"
},
{
"label": "hashFunction",
"type": "t_uint8",
"offset": 0,
"slot": "4"
},
{
"label": "hashSize",
"type": "t_uint8",
"offset": 1,
"slot": "4"
},
{
"label": "confirmedAtBlock",
"type": "t_uint256",
"offset": 0,
"slot": "5"
},
{
"label": "vetoed",
"type": "t_bool",
"offset": 0,
"slot": "6"
},
{
"label": "exists",
"type": "t_bool",
"offset": 1,
"slot": "6"
}
],
"numberOfBytes": "224"
},
"t_uint256": {
"label": "uint256",
"numberOfBytes": "32"
},
"t_uint32": {
"label": "uint32",
"numberOfBytes": "4"
},
"t_uint8": {
"label": "uint8",
"numberOfBytes": "1"
}
}
}
},
"27e6fdeedf4e7e81a2c2ecc839d0c13414aa8f5527d4d3573f469358c8aad652": {
"address": "0xfaeA425E6eDd4e9B31dAa3614c7c7862751D6782",
"txHash": "0xe7768586dbfb5d528db3c9d0c2a608a4fcb5d7f04eb9f89913ac21b8d20a72df",
"layout": {
"storage": [
{
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "t_uint8",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:62",
"retypedFrom": "bool"
},
{
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "t_bool",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:67"
},
{
"label": "contributorContract",
"offset": 2,
"slot": "0",
"type": "t_contract(ContributorInterface)1546",
"contract": "Contribution",
"src": "contracts/Contribution.sol:14"
},
{
"label": "name_",
"offset": 0,
"slot": "1",
"type": "t_string_storage",
"contract": "Contribution",
"src": "contracts/Contribution.sol:28"
},
{
"label": "symbol_",
"offset": 0,
"slot": "2",
"type": "t_string_storage",
"contract": "Contribution",
"src": "contracts/Contribution.sol:29"
},
{
"label": "contributionOwner",
"offset": 0,
"slot": "3",
"type": "t_mapping(t_uint32,t_uint32)",
"contract": "Contribution",
"src": "contracts/Contribution.sol:32"
},
{
"label": "ownedContributions",
"offset": 0,
"slot": "4",
"type": "t_mapping(t_uint32,t_array(t_uint32)dyn_storage)",
"contract": "Contribution",
"src": "contracts/Contribution.sol:34"
},
{
"label": "contributions",
"offset": 0,
"slot": "5",
"type": "t_mapping(t_uint32,t_struct(ContributionData)1570_storage)",
"contract": "Contribution",
"src": "contracts/Contribution.sol:36"
},
{
"label": "contributionsCount",
"offset": 0,
"slot": "6",
"type": "t_uint32",
"contract": "Contribution",
"src": "contracts/Contribution.sol:37"
},
{
"label": "blocksToWait",
"offset": 4,
"slot": "6",
"type": "t_uint32",
"contract": "Contribution",
"src": "contracts/Contribution.sol:40"
},
{
"label": "deployer",
"offset": 8,
"slot": "6",
"type": "t_address",
"contract": "Contribution",
"src": "contracts/Contribution.sol:43"
},
{
"label": "migrationDone",
"offset": 28,
"slot": "6",
"type": "t_bool",
"contract": "Contribution",
"src": "contracts/Contribution.sol:46"
}
],
"types": {
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_array(t_uint32)dyn_storage": {
"label": "uint32[]",
"numberOfBytes": "32"
},
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_bytes32": {
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(ContributorInterface)1546": {
"label": "contract ContributorInterface",
"numberOfBytes": "20"
},
"t_mapping(t_uint32,t_array(t_uint32)dyn_storage)": {
"label": "mapping(uint32 => uint32[])",
"numberOfBytes": "32"
},
"t_mapping(t_uint32,t_struct(ContributionData)1570_storage)": {
"label": "mapping(uint32 => struct Contribution.ContributionData)",
"numberOfBytes": "32"
},
"t_mapping(t_uint32,t_uint32)": {
"label": "mapping(uint32 => uint32)",
"numberOfBytes": "32"
},
"t_string_storage": {
"label": "string",
"numberOfBytes": "32"
},
"t_struct(ContributionData)1570_storage": {
"label": "struct Contribution.ContributionData",
"members": [
{
"label": "contributorId",
"type": "t_uint32",
"offset": 0,
"slot": "0"
},
{
"label": "amount",
"type": "t_uint32",
"offset": 4,
"slot": "0"
},
{
"label": "hashDigest",
"type": "t_bytes32",
"offset": 0,
"slot": "1"
},
{
"label": "hashFunction",
"type": "t_uint8",
"offset": 0,
"slot": "2"
},
{
"label": "hashSize",
"type": "t_uint8",
"offset": 1,
"slot": "2"
},
{
"label": "tokenMetadataURL",
"type": "t_string_storage",
"offset": 0,
"slot": "3"
},
{
"label": "confirmedAtBlock",
"type": "t_uint256",
"offset": 0,
"slot": "4"
},
{
"label": "vetoed",
"type": "t_bool",
"offset": 0,
"slot": "5"
},
{
"label": "exists",
"type": "t_bool",
"offset": 1,
"slot": "5"
}
],
"numberOfBytes": "192"
},
"t_uint256": {
"label": "uint256",
"numberOfBytes": "32"
},
"t_uint32": {
"label": "uint32",
"numberOfBytes": "4"
},
"t_uint8": {
"label": "uint8",
"numberOfBytes": "1"
}
}
}
}
}
}

View File

@ -4,6 +4,6 @@
"solhint:recommended"
],
"rules": {
"indent": "2"
"max-line-length": "warn"
}
}

View File

@ -31,18 +31,55 @@ const contractCalls = [
wiki_username: 'Manuel',
}, { gasLimit: 200000 }]],
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Test this thing', url: '' }, { gasLimit: 350000 }]],
['Contribution', 'add', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 1500, kind: 'dev', description: '[67P/kredits-web] Reviewed stuff', url: '' }, { gasLimit: 350000 }]],
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 5000, kind: 'dev', description: '[67P/kredits-contracts] Add tests', url: '' }, { gasLimit: 350000 }]],
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 1500, kind: 'dev', description: '[67P/kredits-contracts] Introduce contribution token', url: '' }, { gasLimit: 350000 }]],
['Contribution', 'add', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 5000, kind: 'dev', description: '[67P/kredits-web] Expense UI, first draft', url: '' }, { gasLimit: 350000 }]],
['Contribution', 'add', [{
contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF',
date: '2019-04-11', amount: 500, kind: 'dev',
description: '[67P/kredits-contracts] Test this thing',
url: '',
confirmedAtBlock: 1,
}, { gasLimit: 350000 }]],
['Contribution', 'add', [{
contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB',
date: '2019-04-11', amount: 1500, kind: 'dev',
description: '[67P/kredits-web] Reviewed stuff',
url: '',
confirmedAtBlock: 1,
}, { gasLimit: 350000 }]],
['Contribution', 'add', [{
contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF',
date: '2019-04-11', amount: 5000, kind: 'dev',
description: '[67P/kredits-contracts] Add tests',
url: '',
confirmedAtBlock: 1,
}, { gasLimit: 350000 }]],
['Contribution', 'add', [{
contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF',
date: '2019-04-11', amount: 1500, kind: 'dev',
description: '[67P/kredits-contracts] Introduce contribution token',
url: '',
}, { gasLimit: 350000 }]],
['Contribution', 'add', [{
contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB',
date: '2019-04-11', amount: 1500, kind: 'design',
description: '[67P/kredits-web] Expense UI, first draft',
url: '',
}, { gasLimit: 350000 }]],
['Reimbursement', 'add', [{ amount: 346800, recipientId: 2, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [
{ title: 'Domain kosmos.social', description: 'Yearly registration fee for domain kosmos.social', amount: 69.00, currency: 'EUR', amountSats: 69216, date: '2020-04-30' },
], confirmedAtBlock: 1 }, { gasLimit: 300000 }]],
['Reimbursement', 'add', [{ amount: 1116000, recipientId: 1, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [
{ title: 'Server rent', description: 'Dedicated server: andromeda.kosmos.org, April 2020', amount: 61, currency: 'EUR', date: '2020-05-28' },
{ title: 'Server rent', description: 'Dedicated server: centaurus.kosmos.org, April 2020', amount: 32, currency: 'EUR', date: '2020-05-28' }
]}, { gasLimit: 300000 }]],
{ title: 'Server rent', description: 'Dedicated server: andromeda.kosmos.org, April 2020', amount: 61, currency: 'EUR', amountSats: 61191, date: '2020-05-28' },
{ title: 'Server rent', description: 'Dedicated server: centaurus.kosmos.org, April 2020', amount: 32, currency: 'EUR', amountSats: 32201, date: '2020-05-28' },
], confirmedAtBlock: 1 }, { gasLimit: 300000 }]],
['Reimbursement', 'add', [{ amount: 166800, recipientId: 2, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [
{ title: 'Domain kosmos.chat', description: 'Yearly registration fee for domain kosmos.chat', amount: 13.90, currency: 'EUR', date: '2020-05-30' }
{ title: 'Domain kosmos.chat', description: 'Yearly registration fee for domain kosmos.chat', amount: 13.90, currency: 'EUR', amountSats: 13944, date: '2020-05-30' },
]}, { gasLimit: 300000 }]],
];

View File

@ -95,13 +95,13 @@ contract Contribution is Initializable {
// Balance is amount of ERC271 tokens, not amount of kredits
function balanceOf(address owner) public view returns (uint256) {
require(owner != address(0));
require(owner != address(0), "Address invalid");
uint32 contributorId = getContributorIdByAddress(owner);
return ownedContributions[contributorId].length;
}
function ownerOf(uint32 contributionId) public view returns (address) {
require(exists(contributionId));
require(exists(contributionId), "Contribution does not exist");
uint32 contributorId = contributions[contributionId].contributorId;
return getContributorAddressById(contributorId);
}
@ -156,10 +156,8 @@ contract Contribution is Initializable {
}
function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint256 confirmedAtBlock, bool vetoed) public {
// require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint32[](0)), 'nope');
// TODO hubot neither has kredits nor a core account
require((confirmedAtBlock == 0 && vetoed == false) || migrationDone == false, 'extra arguments during migration only');
require(balanceOf(msg.sender) > 0 || contributorContract.addressIsCore(msg.sender), 'requires kredits or core status');
require((confirmedAtBlock == 0 && vetoed == false) || migrationDone == false, "Extra arguments not allowed");
require(balanceOf(msg.sender) > 0 || contributorContract.addressIsCore(msg.sender), "Requires kredits or core status");
uint32 contributionId = contributionsCount + 1;
ContributionData storage c = contributions[contributionId];
@ -188,8 +186,8 @@ contract Contribution is Initializable {
function veto(uint32 contributionId) public onlyCore {
ContributionData storage c = contributions[contributionId];
require(c.exists, 'NOT_FOUND');
require(block.number < c.confirmedAtBlock, 'VETO_PERIOD_ENDED');
require(c.exists, "NOT_FOUND");
require(block.number < c.confirmedAtBlock, "VETO_PERIOD_ENDED");
c.vetoed = true;
emit ContributionVetoed(contributionId, msg.sender);

View File

@ -112,17 +112,17 @@ contract Contributor is Initializable {
emit ContributorAdded(_id, account);
}
function isCoreTeam(uint32 id) view public returns (bool) {
function isCoreTeam(uint32 id) public view returns (bool) {
// TODO: for simplicity we simply define the first contributors as core
// later this needs to be changed to something more dynamic
return id > 0 && id < 7;
}
function exists(uint32 id) view public returns (bool) {
function exists(uint32 id) public view returns (bool) {
return contributors[id].exists;
}
function addressIsCore(address account) view public returns (bool) {
function addressIsCore(address account) public view returns (bool) {
// the deployer is always core
if(account == deployer) {
return true;
@ -131,15 +131,15 @@ contract Contributor is Initializable {
return isCoreTeam(id);
}
function addressExists(address account) view public returns (bool) {
function addressExists(address account) public view returns (bool) {
return getContributorByAddress(account).exists;
}
function getContributorIdByAddress(address account) view public returns (uint32) {
function getContributorIdByAddress(address account) public view returns (uint32) {
return contributorIds[account];
}
function getContributorAddressById(uint32 id) view public returns (address) {
function getContributorAddressById(uint32 id) public view returns (address) {
return contributors[id].account;
}
@ -148,7 +148,7 @@ contract Contributor is Initializable {
return contributors[id];
}
function getContributorById(uint32 _id) view public returns (uint32 id, address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, bool isCore, uint256 balance, uint32 totalKreditsEarned, uint256 contributionsCount, bool exists, uint256 kreditsWithdrawn) {
function getContributorById(uint32 _id) public view returns (uint32 id, address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, bool isCore, uint256 balance, uint32 totalKreditsEarned, uint256 contributionsCount, bool exists, uint256 kreditsWithdrawn) {
id = _id;
Contributor storage c = contributors[_id];
account = c.account;

View File

@ -31,18 +31,35 @@ contract Reimbursement is Initializable {
uint32 public blocksToWait;
// The address that deployed the contract
address public deployer;
// Data migration flag
bool public migrationDone;
event ReimbursementAdded(uint32 id, address indexed addedByAccount, uint256 amount);
event ReimbursementVetoed(uint32 id, address vetoedByAccount);
function initialize() public initializer {
blocksToWait = 40320; // 7 days; 15 seconds block time
}
modifier onlyCore {
require(contributorContract.addressIsCore(tx.origin), "Core only");
_;
}
modifier onlyDeployer {
require(msg.sender == deployer, "Deployer only");
_;
}
function initialize() public initializer {
deployer = msg.sender;
migrationDone = false;
blocksToWait = 40320; // 7 days; 15 seconds block time
}
function finishMigration() public onlyDeployer {
migrationDone = true;
}
function setContributorContract(address contributor) public {
require(address(contributorContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
contributorContract = ContributorInterface(contributor);
@ -82,7 +99,8 @@ contract Reimbursement is Initializable {
);
}
function add(uint256 amount, address token, uint32 recipientId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public onlyCore {
function add(uint256 amount, address token, uint32 recipientId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint256 confirmedAtBlock, bool vetoed) public onlyCore {
require((confirmedAtBlock == 0 && vetoed == false) || migrationDone == false, "Extra arguments not allowed");
uint32 reimbursementId = reimbursementsCount + 1;
ReimbursementData storage r = reimbursements[reimbursementId];
r.exists = true;
@ -92,7 +110,14 @@ contract Reimbursement is Initializable {
r.hashDigest = hashDigest;
r.hashFunction = hashFunction;
r.hashSize = hashSize;
r.confirmedAtBlock = block.number + blocksToWait;
if (confirmedAtBlock > 0) {
r.confirmedAtBlock = confirmedAtBlock;
} else {
r.confirmedAtBlock = block.number + 1 + blocksToWait;
}
if (vetoed) { r.vetoed = true; }
reimbursementsCount++;
@ -101,8 +126,8 @@ contract Reimbursement is Initializable {
function veto(uint32 reimbursementId) public onlyCore {
ReimbursementData storage r = reimbursements[reimbursementId];
require(r.exists, 'NOT_FOUND');
require(block.number < r.confirmedAtBlock, 'VETO_PERIOD_ENDED');
require(r.exists, "NOT_FOUND");
require(block.number < r.confirmedAtBlock, "VETO_PERIOD_ENDED");
r.vetoed = true;
emit ReimbursementVetoed(reimbursementId, msg.sender);

View File

@ -1 +1 @@
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"address","name":"addedByAccount","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReimbursementAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ReimbursementVetoed","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"get","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"reimbursements","outputs":[{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reimbursementsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalAmount","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"}]
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"address","name":"addedByAccount","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReimbursementAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ReimbursementVetoed","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finishMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"get","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationDone","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"reimbursements","outputs":[{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reimbursementsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalAmount","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"}]

View File

@ -1,9 +1,9 @@
{
"31": {
"Contributor": "0xf1073Dab6e305583F95e451Cba449bB867a6e3Fd",
"Contribution": "0x1C531F824e339cD37D75B7F391cB8E42e0E0d4bd",
"Token": "0x56F64C3BB45e6a248F4C783f5a1633E53D6A2371",
"Reimbursement": "0x9C5fFBFba2570A9b31D60338453C5480Ce74B342"
"Contributor": "0x95DC31665D193E377f54b70C535fcDb205525291",
"Contribution": "0x049bA8E70FEbFfd6d03C71211bDA37B4ff064115",
"Token": "0x7ab26A0f00eF0D6e05e5BDE047505a4eD53aF809",
"Reimbursement": "0x99EC72b34295b62f4bC1527Da461262c615a0b2c"
},
"1337": {
"Contributor": "0xCc66f9A3cA2670972938FAD91d0865c4a62DFB25",

View File

@ -41,6 +41,8 @@ class Contribution extends Record {
async add (contributionAttr, callOptions = {}) {
const contribution = new ContributionSerializer(contributionAttr);
const confirmedAtBlock = contributionAttr.confirmedAtBlock || 0;
const vetoed = contributionAttr.vetoed || false;
try { await contribution.validate(); }
catch (error) { return Promise.reject(error); }
@ -56,9 +58,11 @@ class Contribution extends Record {
ipfsHashAttr.hashDigest,
ipfsHashAttr.hashFunction,
ipfsHashAttr.hashSize,
confirmedAtBlock,
vetoed,
];
return this.contract.add(...contribution, 0, false, callOptions);
return this.contract.add(...contribution, callOptions);
});
}

View File

@ -52,6 +52,7 @@ class Contributor extends Record {
const jsonStr = contributor.serialize();
// console.log('Adding IPFS doc for', contributorAttr.account);
return this.ipfs
.add(jsonStr)
.then((ipfsHashAttr) => {
@ -62,7 +63,11 @@ class Contributor extends Record {
ipfsHashAttr.hashSize,
];
// console.log('Adding onchain record for', contributorAttr.account);
return this.contract.addContributor(...contributor, callOptions);
}).catch(err => {
console.log('Failed to add IPFS document:', err.message);
throw(err);
});
}

View File

@ -23,6 +23,8 @@ class Reimbursement extends Record {
const amount = parseInt(attrs.amount);
const token = attrs.token;
const recipientId = attrs.recipientId;
const confirmedAtBlock = attrs.confirmedAtBlock || 0;
const vetoed = attrs.vetoed || false;
const expenses = attrs.expenses.map((e) => new ExpenseSerializer(e));
let errorMessage;
@ -56,6 +58,8 @@ class Reimbursement extends Record {
ipfsHashAttr.hashDigest,
ipfsHashAttr.hashFunction,
ipfsHashAttr.hashSize,
confirmedAtBlock,
vetoed,
];
return this.contract.add(...reimbursement, callOptions);

View File

@ -29,6 +29,7 @@ class ExpenseSerializer {
description,
currency,
amount,
amountSats,
date,
url,
tags,
@ -42,6 +43,7 @@ class ExpenseSerializer {
description,
currency,
amount,
amountSats,
date,
'tags': tags || [],
'details': details || {},
@ -76,6 +78,7 @@ class ExpenseSerializer {
description,
currency,
amount,
amountSats,
date,
url,
tags,
@ -87,6 +90,7 @@ class ExpenseSerializer {
description,
currency,
amount,
amountSats,
date,
url,
tags,

View File

@ -9,6 +9,13 @@ class IPFS {
}
this._config = config;
this._ipfsAPI = ipfsClient.create(config);
this._ipfsAPI.id().then(res => {
console.debug('IPFS ID:', res.id);
}).catch(e => {
console.debug('IPFS config:', config);
console.warn('Failed to initialize IPFS:', e.message);
});
}
async catAndMerge (contractData, deserialize) {

18
package-lock.json generated
View File

@ -1,15 +1,15 @@
{
"name": "@kredits/contracts",
"version": "7.2.0",
"version": "7.5.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kredits/contracts",
"version": "7.2.0",
"version": "7.5.0",
"license": "MIT",
"dependencies": {
"@kosmos/schemas": "^3.1.0",
"@kosmos/schemas": "^3.2.0",
"ethers": "^5.4.7",
"ipfs-http-client": "^56.0.3",
"multihashes": "^4.0.3",
@ -1022,9 +1022,9 @@
}
},
"node_modules/@kosmos/schemas": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.1.0.tgz",
"integrity": "sha512-yOTK5WiXFDNAitPByMabE365aEEzFHgSUSgAssbJWt7BZ80HQSVu8XWrQiTbFbCkoIBmXwPP/RoxgXJQVgZTFQ=="
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.2.0.tgz",
"integrity": "sha512-GyWXmWcATcakmEdPOpafdckBgWFqcpSh+tB8nm11VGgtgA94pfoFhKZ3t88WELItKfuP/GFHgMiZmdMB3bSkdQ=="
},
"node_modules/@metamask/eth-sig-util": {
"version": "4.0.1",
@ -20786,9 +20786,9 @@
}
},
"@kosmos/schemas": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.1.0.tgz",
"integrity": "sha512-yOTK5WiXFDNAitPByMabE365aEEzFHgSUSgAssbJWt7BZ80HQSVu8XWrQiTbFbCkoIBmXwPP/RoxgXJQVgZTFQ=="
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.2.0.tgz",
"integrity": "sha512-GyWXmWcATcakmEdPOpafdckBgWFqcpSh+tB8nm11VGgtgA94pfoFhKZ3t88WELItKfuP/GFHgMiZmdMB3bSkdQ=="
},
"@metamask/eth-sig-util": {
"version": "4.0.1",

View File

@ -1,6 +1,6 @@
{
"name": "@kredits/contracts",
"version": "7.2.0",
"version": "7.5.0",
"description": "Smart contracts and JavaScript API for Kredits",
"main": "./lib/kredits.js",
"directories": {
@ -22,11 +22,9 @@
"lint:contract-tests": "eslint apps/*/test",
"lint:wrapper": "eslint lib/",
"test": "hardhat test",
"test:token": "cd apps/token && npm run test",
"test:contributor": "cd apps/contributor && npm run test",
"test:contribution": "cd apps/contribution && npm run test",
"test:proposal": "cd apps/proposal && npm run test",
"setup-git-hooks": "sh scripts/git-hooks/install"
"setup-git-hooks": "sh scripts/git-hooks/install",
"preversion": "npm test && npm run build",
"version": "git add lib/abis"
},
"repository": {
"type": "git",
@ -68,7 +66,7 @@
"yargs": "^15.0.0"
},
"dependencies": {
"@kosmos/schemas": "^3.1.0",
"@kosmos/schemas": "^3.2.0",
"ethers": "^5.4.7",
"ipfs-http-client": "^56.0.3",
"multihashes": "^4.0.3",

View File

@ -1,3 +1,4 @@
const fs = require('fs');
const Kredits = require('../../lib/kredits');
async function main() {

View File

@ -0,0 +1,44 @@
const fs = require('fs');
const Kredits = require('../../lib/kredits');
async function main() {
kredits = new Kredits(hre.ethers.provider, hre.ethers.provider.getSigner())
await kredits.init();
console.log(`Using Reimbursement at: ${kredits.Reimbursement.contract.address}`);
const count = await kredits.Reimbursement.count;
const currentBlockHeight = await hre.ethers.provider.getBlockNumber();
const backup = {};
const promises = [];
for (let i = 1; i <= count; i++) {
promises.push(new Promise((resolve, reject) => {
setTimeout(async () => {
console.log(`Loading reimbursement #${i}`);
await kredits.Reimbursement.contract.get(i).then(contractData => {
backup[i] = {
recipientId: contractData.recipientId,
amount: contractData.amount,
token: contractData.token,
hashDigest: contractData.hashDigest,
hashFunction: contractData.hashFunction,
hashSize: contractData.hashSize,
confirmedAtBlock: contractData.confirmedAtBlock,
confirmed: contractData.confirmedAtBlock <= currentBlockHeight,
vetoed: contractData.vetoed,
id: contractData.id,
}
resolve();
});
}, 100 * i);
}));
}
await Promise.all(promises).then(() => {
fs.writeFileSync("./data/reimbursements.json", JSON.stringify(backup, null, 2));
console.log("Exported");
});
}
main();

View File

@ -20,7 +20,11 @@ async function main() {
const confirmationPeriod = 40320 // blocks
const unconfirmedHeight = currentBlockHeight + confirmationPeriod;
const startId = parseInt(process.env.START_AT || "0");
for (const contributionId of ids) {
if (contributionId < startId) {
continue;
}
const c = contributions[contributionId.toString()];
const confirmedAtBlock = c.confirmed ? currentBlockHeight : unconfirmedHeight;

View File

@ -0,0 +1,36 @@
const fs = require('fs');
const Kredits = require('../../lib/kredits');
async function main() {
kredits = new Kredits(hre.ethers.provider, hre.ethers.provider.getSigner())
await kredits.init();
console.log(`Using Reimbursement at: ${kredits.Reimbursement.contract.address}`);
const count = await kredits.Reimbursement.count;
console.log(`Currently ${count} entries`);
try {
const data = fs.readFileSync("./data/reimbursements.json");
const reimbursements = JSON.parse(data);
const ids = Object.keys(reimbursements)
.map(k => parseInt(k))
.sort(function(a, b) { return a - b });
for (const reimbursementId of ids) {
const reimbursement = reimbursements[reimbursementId.toString()];
const result = await kredits.Reimbursement.contract.add(
reimbursement.amount,
reimbursement.token,
reimbursement.recipientId,
reimbursement.hashDigest,
reimbursement.hashFunction,
reimbursement.hashSize,
);
console.log(`Adding reimbursement #${reimbursementId}: ${result.hash}`);
await result.wait();
};
} catch (e) {
console.error(e);
}
}
main();

View File

@ -39,7 +39,7 @@ async function main() {
contractWrapper.contract[method];
try {
// console.log('trying', func);
// console.log('trying', contractName, method, args);
const result = await func.apply(contractWrapper, args);
// console.log('result:', result);
await result.wait();

View File

@ -67,7 +67,7 @@ describe("Contribution contract", async function () {
500, 1,
"0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f",
18, 32, 0, false
)).to.be.revertedWith("requires kredits or core status");
)).to.be.revertedWith("Requires kredits or core status");
expect(await Contribution.contributionsCount()).to.equal(0);
});
@ -76,7 +76,7 @@ describe("Contribution contract", async function () {
500, 1,
"0xe794f010e617449719c64076546254129f63a6d16cf200031afa646aeb35777f",
18, 32, 23000, true
)).to.be.revertedWith("extra arguments during migration only");
)).to.be.revertedWith("Extra arguments not allowed");
expect(await Contribution.contributionsCount()).to.equal(0);
});