From 093273f15b7d7d9f03adee10581510114843bfc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Wed, 22 Mar 2023 19:11:37 +0700 Subject: [PATCH] Allow a profile manager key to add contributor profiles The profile manager is usually a bot that can also auth users against external sources to prevent spam and integrate with existing Web services. --- contracts/Contributor.sol | 7 +++++-- test/contracts/Contribution.js | 2 +- test/contracts/Contributor.js | 24 ++++++++++++++++++++---- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/contracts/Contributor.sol b/contracts/Contributor.sol index f2ad60d..9c39b5a 100644 --- a/contracts/Contributor.sol +++ b/contracts/Contributor.sol @@ -13,6 +13,7 @@ interface IContributionBalance { contract Contributor is Initializable { address public deployer; + address public profileManager; IContributionBalance public contributionContract; IToken public tokenContract; @@ -43,8 +44,9 @@ contract Contributor is Initializable { _; } - function initialize() public initializer { + function initialize(address profileManagerAddress) public initializer { deployer = msg.sender; + profileManager = profileManagerAddress; } function setContributionContract(address contribution) public onlyCore { @@ -87,8 +89,9 @@ contract Contributor is Initializable { 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((msg.sender == profileManager) || addressIsCore(msg.sender), "Only core and profile manager"); uint32 _id = contributorsCount + 1; assert(!contributors[_id].exists); // this can not be acually Contributor storage c = contributors[_id]; diff --git a/test/contracts/Contribution.js b/test/contracts/Contribution.js index ef189d6..2837f08 100644 --- a/test/contracts/Contribution.js +++ b/test/contracts/Contribution.js @@ -9,7 +9,7 @@ describe("Contribution contract", async function () { [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7] = await ethers.getSigners(); let accounts = [owner, addr1, addr2, addr3, addr4, addr5, addr6, addr7]; const contributorFactory = await ethers.getContractFactory("Contributor"); - Contributor = await upgrades.deployProxy(contributorFactory); + Contributor = await upgrades.deployProxy(contributorFactory, ["0x2946fFfd31096435cb0fc927D306E1C006C5D1aF"]); for (const account of accounts) { await Contributor.addContributor(account.address, "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", 18, 32); } diff --git a/test/contracts/Contributor.js b/test/contracts/Contributor.js index 0e005c6..532fa3a 100644 --- a/test/contracts/Contributor.js +++ b/test/contracts/Contributor.js @@ -1,14 +1,14 @@ const { expect } = require("chai"); 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; describe("Contributor contract", 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"); - Contributor = await upgrades.deployProxy(contributorFactory); + Contributor = await upgrades.deployProxy(contributorFactory, [addr8.address]); const contributionFactory = await ethers.getContractFactory("Contribution"); Contribution = await upgrades.deployProxy(contributionFactory, [40321]); 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.not.equal(addr1.address); }); + + it("sets a profile manager address", async function () { + expect(await Contributor.profileManager()).to.equal(addr8.address); + }); }); describe("add()", function () { @@ -38,7 +42,7 @@ describe("Contributor contract", async function () { "0x608FD4b95116Ea616990Aaeb1d4f1ce07612f261", "0x1d9de6de5c72eedca6d7a5e8a9159e2f5fe676506aece3000acefcc821723429", 18, 32 - )).to.be.revertedWith("Core only"); + )).to.be.revertedWith("Only core and profile manager"); expect(await Contributor.contributorsCount()).to.equal(8); }); @@ -70,6 +74,18 @@ describe("Contributor contract", async function () { 18, 32 )).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 () { -- 2.25.1