Compare commits

...

16 Commits

Author SHA1 Message Date
Râu Cao
b49d1130a9 7.1.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-26 15:49:57 +02:00
Râu Cao
657cdc8afa Update JS ABIs 2023-04-26 15:49:44 +02:00
Râu Cao
ae9aa7aaaf Update seeds 2023-04-26 15:47:01 +02:00
Râu Cao
708515ba4b Add emit statement for event 2023-04-26 15:46:41 +02:00
7eceea5d57 Merge pull request 'Fix wrapper function: Reimbursement.getData()' (#237) from bugfix/reimbursement_get-data into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #237
2023-04-26 13:44:14 +00:00
Râu Cao
089ffd42fe Fix wrapper function: Reimbursement.getData()
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 4s
2023-04-26 15:42:17 +02:00
Râu Cao
43d9bc0a07 Add missing profile manager address to seeds
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-25 16:38:02 +02:00
Râu Cao
6113e456af Add release drafter action configs
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-11 23:13:05 +02:00
8ef6fc06ce Merge pull request 'Allow a profile manager key to add contributor profiles' (#236) from feature/profile_manager into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #236
2023-04-11 21:06:42 +00:00
Râu Cao
093273f15b Allow a profile manager key to add contributor profiles
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
The profile manager is usually a bot that can also auth users against
external sources to prevent spam and integrate with existing Web
services.
2023-03-22 19:11:37 +07:00
Râu Cao
1dc54eccea Update seeds
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-22 18:15:51 +07:00
Râu Cao
bb662e377c Update README
All checks were successful
continuous-integration/drone/push Build is passing
* Add build status badge
* Add section about testing
* Formatting
2023-03-22 18:14:12 +07:00
Râu Cao
d6bbc441f8 Update package name in lockfile
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-19 14:52:32 +08:00
Râu Cao
46090b3740 Update README
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-04 12:27:16 +01:00
Râu Cao
828f831c52 7.0.1
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-02 19:07:56 +01:00
Râu Cao
500180c6da Update npm badge
Some checks are pending
continuous-integration/drone/push Build is running
2022-11-02 19:07:42 +01:00
13 changed files with 80 additions and 33 deletions

View File

@@ -0,0 +1,14 @@
name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
version-resolver:
major:
labels:
- release/major
minor:
labels:
- release/minor
- feature
patch:
labels:
- release/patch
default: patch

View File

@@ -0,0 +1,11 @@
name: Release Drafter
on:
pull_request:
types: [closed]
jobs:
release_drafter_job:
name: Update release notes draft
runs-on: ubuntu-latest
steps:
- name: Release Drafter
uses: https://github.com/raucao/gitea-release-drafter@dev

View File

@@ -1,4 +1,5 @@
[![npm](https://img.shields.io/npm/v/kredits-contracts.svg)](https://www.npmjs.com/package/kredits-contracts) [![npm](https://img.shields.io/npm/v/@kredits/contracts.svg)](https://www.npmjs.com/package/@kredits/contracts)
[![Build Status](https://drone.kosmos.org/api/badges/kredits/contracts/status.svg)](https://drone.kosmos.org/kredits/contracts)
# Kredits Contracts # Kredits Contracts
@@ -26,7 +27,7 @@ To run a local development chain run:
### Bootstrap ### Bootstrap
1. Run an Ethereum node and ipfs 1. Run an EVM node and ipfs
$ npm run devchain $ npm run devchain
$ ipfs daemon $ ipfs daemon
@@ -56,6 +57,16 @@ If you need to fund development accounts with devchain coins:
$ npm run fund # or hardhat fund --network localhost $ npm run fund # or hardhat fund --network localhost
## Specs / Testing
With a local development chain running:
$ hardhat test
If you add or change contract code, please make sure to add and/or adapt tests
accordingly. Don't worry, it's easy! You can use existing tests as a template
for new ones.
## Contract architecture ## Contract architecture
We use the [OpenZeppelin hardhat We use the [OpenZeppelin hardhat
@@ -145,12 +156,3 @@ To run the console on one of the non localhost networks you can also just pass
on the --network argument. on the --network argument.
$ hardhat console --network rsk $ hardhat console --network rsk
## Known Issues
When resetting ganache Metamask might have an invalid transaction nonce and
transactions get rejected. Nonces in Ethereum must be incrementing and have no
gap.
To solve this reset the metamask account (Account -> Settings -> Reset Account)

View File

@@ -15,7 +15,7 @@ const contractCalls = [
name: 'raucao', name: 'raucao',
kind: 'person', kind: 'person',
url: '', url: '',
github_username: 'skddc', github_username: 'raucao',
github_uid: 842, github_uid: 842,
gitea_username: 'raucao', gitea_username: 'raucao',
wiki_username: 'Basti', wiki_username: 'Basti',
@@ -33,7 +33,7 @@ const contractCalls = [
['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: 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: 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: 1500, kind: 'dev', description: '[67P/kredits-contracts] Add tests', 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: 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: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 5000, kind: 'dev', description: '[67P/kredits-web] Expense UI, first draft', url: '' }, { gasLimit: 350000 }]],

View File

@@ -13,6 +13,7 @@ interface IContributionBalance {
contract Contributor is Initializable { contract Contributor is Initializable {
address public deployer; address public deployer;
address public profileManager;
IContributionBalance public contributionContract; IContributionBalance public contributionContract;
IToken public tokenContract; IToken public tokenContract;
@@ -43,8 +44,9 @@ contract Contributor is Initializable {
_; _;
} }
function initialize() public initializer { function initialize(address profileManagerAddress) public initializer {
deployer = msg.sender; deployer = msg.sender;
profileManager = profileManagerAddress;
} }
function setContributionContract(address contribution) public onlyCore { function setContributionContract(address contribution) public onlyCore {
@@ -84,11 +86,12 @@ contract Contributor is Initializable {
c.hashFunction = hashFunction; c.hashFunction = hashFunction;
c.hashSize = hashSize; c.hashSize = hashSize;
ContributorProfileUpdated(id, oldHashDigest, c.hashDigest); emit ContributorProfileUpdated(id, oldHashDigest, c.hashDigest);
} }
function addContributor(address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public onlyCore { function addContributor(address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public {
require(!addressExists(account), "Address already in use"); require(!addressExists(account), "Address already in use");
require((msg.sender == profileManager) || addressIsCore(msg.sender), "Only core and profile manager");
uint32 _id = contributorsCount + 1; uint32 _id = contributorsCount + 1;
assert(!contributors[_id].exists); // this can not be acually assert(!contributors[_id].exists); // this can not be acually
Contributor storage c = contributors[_id]; Contributor storage c = contributors[_id];

View File

@@ -16,6 +16,7 @@ contract Reimbursement is Initializable {
struct ReimbursementData { struct ReimbursementData {
uint32 recipientId; uint32 recipientId;
uint256 amount; uint256 amount;
// TODO remove token entirely
address token; address token;
bytes32 hashDigest; bytes32 hashDigest;
uint8 hashFunction; uint8 hashFunction;

File diff suppressed because one or more lines are too long

View File

@@ -16,7 +16,7 @@ class Reimbursement extends Record {
} }
getData (id) { getData (id) {
return this.contract.getReimbursement(id); return this.contract.get(id);
} }
async add (attrs, callOptions = {}) { async add (attrs, callOptions = {}) {

8
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "kredits-contracts", "name": "@kredits/contracts",
"version": "7.0.0", "version": "7.1.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "kredits-contracts", "name": "@kredits/contracts",
"version": "7.0.0", "version": "7.1.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@kosmos/schemas": "^3.1.0", "@kosmos/schemas": "^3.1.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@kredits/contracts", "name": "@kredits/contracts",
"version": "7.0.0", "version": "7.1.0",
"description": "Smart contracts and JavaScript API for Kredits", "description": "Smart contracts and JavaScript API for Kredits",
"main": "./lib/kredits.js", "main": "./lib/kredits.js",
"directories": { "directories": {

View File

@@ -36,7 +36,7 @@ async function main() {
const blocksVetoPeriod = 40320; // 7 days; 15 seconds block time const blocksVetoPeriod = 40320; // 7 days; 15 seconds block time
await deployContractProxy('Contributor'); await deployContractProxy('Contributor', [ '0x0000000000000000000000000000000000000000' ] );
await deployContractProxy('Contribution', [ blocksVetoPeriod ]); await deployContractProxy('Contribution', [ blocksVetoPeriod ]);
await deployContractProxy('Token'); await deployContractProxy('Token');
await deployContractProxy('Reimbursement'); await deployContractProxy('Reimbursement');

View File

@@ -9,7 +9,7 @@ describe("Contribution contract", async function () {
[owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7] = await ethers.getSigners(); [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7] = await ethers.getSigners();
let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7]; let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7];
const contributorFactory = await ethers.getContractFactory("Contributor"); const contributorFactory = await ethers.getContractFactory("Contributor");
Contributor = await upgrades.deployProxy(contributorFactory); Contributor = await upgrades.deployProxy(contributorFactory, ["0x2946fFfd31096435cb0fc927D306E1C006C5D1aF"]);
for (const account of accounts) { for (const account of accounts) {
await Contributor.addContributor(account.address, "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", 18, 32); await Contributor.addContributor(account.address, "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", 18, 32);
} }

View File

@@ -1,14 +1,14 @@
const { expect } = require("chai"); const { expect } = require("chai");
const { ethers, upgrades } = require("hardhat"); const { ethers, upgrades } = require("hardhat");
let owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7; let owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7, addr8;
let Contribution, Contributor, Token; let Contribution, Contributor, Token;
describe("Contributor contract", async function () { describe("Contributor contract", async function () {
before(async function () { before(async function () {
[owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7] = await ethers.getSigners(); [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7, addr8] = await ethers.getSigners();
const contributorFactory = await ethers.getContractFactory("Contributor"); const contributorFactory = await ethers.getContractFactory("Contributor");
Contributor = await upgrades.deployProxy(contributorFactory); Contributor = await upgrades.deployProxy(contributorFactory, [addr8.address]);
const contributionFactory = await ethers.getContractFactory("Contribution"); const contributionFactory = await ethers.getContractFactory("Contribution");
Contribution = await upgrades.deployProxy(contributionFactory, [40321]); Contribution = await upgrades.deployProxy(contributionFactory, [40321]);
const tokenFactory = await ethers.getContractFactory("Token"); const tokenFactory = await ethers.getContractFactory("Token");
@@ -30,6 +30,10 @@ describe("Contributor contract", async function () {
expect(await Contributor.deployer()).to.equal(owner.address); expect(await Contributor.deployer()).to.equal(owner.address);
expect(await Contributor.deployer()).to.not.equal(addr1.address); expect(await Contributor.deployer()).to.not.equal(addr1.address);
}); });
it("sets a profile manager address", async function () {
expect(await Contributor.profileManager()).to.equal(addr8.address);
});
}); });
describe("add()", function () { describe("add()", function () {
@@ -38,7 +42,7 @@ describe("Contributor contract", async function () {
"0x608FD4b95116Ea616990Aaeb1d4f1ce07612f261", "0x608FD4b95116Ea616990Aaeb1d4f1ce07612f261",
"0x1d9de6de5c72eedca6d7a5e8a9159e2f5fe676506aece3000acefcc821723429", "0x1d9de6de5c72eedca6d7a5e8a9159e2f5fe676506aece3000acefcc821723429",
18, 32 18, 32
)).to.be.revertedWith("Core only"); )).to.be.revertedWith("Only core and profile manager");
expect(await Contributor.contributorsCount()).to.equal(8); expect(await Contributor.contributorsCount()).to.equal(8);
}); });
@@ -70,6 +74,18 @@ describe("Contributor contract", async function () {
18, 32 18, 32
)).to.emit(Contributor, "ContributorAdded").withArgs(10, "0x765E88b4F9a59C3a3b300C6eFF9E6E9fDDf9FbD9"); )).to.emit(Contributor, "ContributorAdded").withArgs(10, "0x765E88b4F9a59C3a3b300C6eFF9E6E9fDDf9FbD9");
}); });
it("allows the profile manager account to create a contributor profile", async function () {
await Contributor.connect(addr8).addContributor(
"0x954712B8703Df5255A219B139ba7BFC256E72a15",
"0x1d9de6de5c72eedca6d7a5e8a9159e2f5fe676506aece3000acefcc821723429",
18, 32
);
expect(await Contributor.contributorsCount()).to.equal(11);
const c = await Contributor.getContributorById(11);
expect(c['account']).to.equal("0x954712B8703Df5255A219B139ba7BFC256E72a15");
});
}); });
describe("withdraw()", function () { describe("withdraw()", function () {