Permissions
This commit is contained in:
parent
623cf6d6da
commit
ffd4a5aeaf
@ -9,6 +9,7 @@ interface IToken {
|
||||
interface ContributorInterface {
|
||||
function getContributorAddressById(uint32 contributorId) external view returns (address);
|
||||
function getContributorIdByAddress(address contributorAccount) external view returns (uint32);
|
||||
function addressIsCore(address sender) external view returns (bool);
|
||||
// TODO Maybe use for validation
|
||||
// function exists(uint32 contributorId) public view returns (bool);
|
||||
}
|
||||
@ -17,11 +18,6 @@ contract Contribution is Initializable {
|
||||
ContributorInterface public contributorContract;
|
||||
IToken public tokenContract;
|
||||
|
||||
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;
|
||||
|
||||
struct ContributionData {
|
||||
uint32 contributorId;
|
||||
uint32 amount;
|
||||
@ -52,17 +48,22 @@ contract Contribution is Initializable {
|
||||
event ContributionClaimed(uint32 id, uint32 indexed contributorId, uint32 amount);
|
||||
event ContributionVetoed(uint32 id, address vetoedByAccount);
|
||||
|
||||
modifier onlyCore {
|
||||
require(contributorContract.addressIsCore(msg.sender), "Core only");
|
||||
_;
|
||||
}
|
||||
|
||||
function initialize(uint32 blocksToWait_) public initializer {
|
||||
blocksToWait = blocksToWait_;
|
||||
}
|
||||
|
||||
// TODO who can call this when?
|
||||
function setTokenContract(address token) public {
|
||||
require(address(tokenContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
|
||||
tokenContract = IToken(token);
|
||||
}
|
||||
|
||||
// TODO who can call this when?
|
||||
function setContributorContract(address contributor) public {
|
||||
require(address(contributorContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
|
||||
contributorContract = ContributorInterface(contributor);
|
||||
}
|
||||
|
||||
@ -151,6 +152,7 @@ contract Contribution is Initializable {
|
||||
|
||||
function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public{
|
||||
//require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint32[](0)), 'nope');
|
||||
require(balanceOf(msg.sender) > 0, "Must have Kredits");
|
||||
uint32 contributionId = contributionsCount + 1;
|
||||
ContributionData storage c = contributions[contributionId];
|
||||
c.exists = true;
|
||||
@ -174,7 +176,8 @@ contract Contribution is Initializable {
|
||||
emit ContributionAdded(contributionId, contributorId, amount);
|
||||
}
|
||||
|
||||
function veto(uint32 contributionId) public {
|
||||
function veto(uint32 contributionId) public onlyCore {
|
||||
|
||||
ContributionData storage c = contributions[contributionId];
|
||||
require(c.exists, 'NOT_FOUND');
|
||||
require(!c.claimed, 'ALREADY_CLAIMED');
|
||||
@ -201,4 +204,5 @@ contract Contribution is Initializable {
|
||||
function exists(uint32 contributionId) public view returns (bool) {
|
||||
return contributions[contributionId].exists;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ interface IContributionBalance {
|
||||
}
|
||||
|
||||
contract Contributor is Initializable {
|
||||
address deployer;
|
||||
IContributionBalance public contributionContract;
|
||||
ITokenBalance public tokenContract;
|
||||
|
||||
@ -30,18 +31,22 @@ contract Contributor is Initializable {
|
||||
event ContributorAccountUpdated(uint32 id, address oldAccount, address newAccount);
|
||||
event ContributorAdded(uint32 id, address account);
|
||||
|
||||
|
||||
function initialize() public initializer {
|
||||
|
||||
modifier onlyCore {
|
||||
require(addressIsCore(msg.sender), "Core only");
|
||||
_;
|
||||
}
|
||||
|
||||
// TODO who can call this when?
|
||||
function setContributionContract(address contribution) public {
|
||||
function initialize() public initializer {
|
||||
deployer = msg.sender;
|
||||
}
|
||||
|
||||
function setContributionContract(address contribution) public onlyCore {
|
||||
require(address(contributionContract) == address(0) || addressIsCore(msg.sender), "Core only");
|
||||
contributionContract = IContributionBalance(contribution);
|
||||
}
|
||||
|
||||
// TODO who can call this when?
|
||||
function setTokenContract(address token) public {
|
||||
function setTokenContract(address token) public onlyCore {
|
||||
require(address(tokenContract) == address(0) || addressIsCore(msg.sender), "Core only");
|
||||
tokenContract = ITokenBalance(token);
|
||||
}
|
||||
|
||||
@ -55,7 +60,7 @@ contract Contributor is Initializable {
|
||||
return count;
|
||||
}
|
||||
|
||||
function updateContributorAccount(uint32 id, address oldAccount, address newAccount) public {
|
||||
function updateContributorAccount(uint32 id, address oldAccount, address newAccount) public onlyCore {
|
||||
require(newAccount != address(0), "invalid new account address");
|
||||
require(getContributorAddressById(id) == oldAccount, "contributor does not exist");
|
||||
|
||||
@ -65,7 +70,7 @@ contract Contributor is Initializable {
|
||||
emit ContributorAccountUpdated(id, oldAccount, newAccount);
|
||||
}
|
||||
|
||||
function updateContributorProfileHash(uint32 id, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public {
|
||||
function updateContributorProfileHash(uint32 id, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public onlyCore {
|
||||
Contributor storage c = contributors[id];
|
||||
bytes32 oldHashDigest = c.hashDigest;
|
||||
c.hashDigest = hashDigest;
|
||||
@ -75,7 +80,7 @@ contract Contributor is Initializable {
|
||||
ContributorProfileUpdated(id, oldHashDigest, c.hashDigest);
|
||||
}
|
||||
|
||||
function addContributor(address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public {
|
||||
function addContributor(address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public onlyCore {
|
||||
require(!addressExists(account));
|
||||
uint32 _id = contributorsCount + 1;
|
||||
assert(!contributors[_id].exists); // this can not be acually
|
||||
@ -94,7 +99,7 @@ contract Contributor is Initializable {
|
||||
function isCoreTeam(uint32 id) view public 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 < 7;
|
||||
return id > 1 && id < 7 || msg.sender == deployer;
|
||||
}
|
||||
|
||||
function exists(uint32 id) view public returns (bool) {
|
||||
@ -137,16 +142,4 @@ contract Contributor is Initializable {
|
||||
exists = c.exists;
|
||||
}
|
||||
|
||||
function canPerform(address _who, address _where, bytes32 _what, uint256[] memory _how) public returns (bool) {
|
||||
address sender = _who;
|
||||
if (sender == address(0)) {
|
||||
sender = tx.origin;
|
||||
}
|
||||
// _what == keccak256('VOTE_PROPOSAL_ROLE')
|
||||
if (_what == 0xd61216798314d2fc33e42ff2021d66707b1e38517d3f7166798a9d3a196a9c96) {
|
||||
return contributorIds[sender] != uint256(0);
|
||||
}
|
||||
|
||||
return addressIsCore(sender);
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,16 @@ pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
|
||||
interface ContributorInterface {
|
||||
function getContributorAddressById(uint32 contributorId) external view returns (address);
|
||||
function getContributorIdByAddress(address contributorAccount) external view returns (uint32);
|
||||
function addressIsCore(address sender) external view returns (bool);
|
||||
// TODO Maybe use for validation
|
||||
// function exists(uint32 contributorId) public view returns (bool);
|
||||
}
|
||||
|
||||
contract Reimbursement is Initializable {
|
||||
bytes32 public constant ADD_REIMBURSEMENT_ROLE = keccak256("ADD_REIMBURSEMENT_ROLE");
|
||||
bytes32 public constant VETO_REIMBURSEMENT_ROLE = keccak256("VETO_REIMBURSEMENT_ROLE");
|
||||
// bytes32 public constant MANAGE_APPS_ROLE = keccak256("MANAGE_APPS_ROLE");
|
||||
ContributorInterface public contributorContract;
|
||||
|
||||
struct ReimbursementData {
|
||||
uint32 recipientId;
|
||||
@ -31,6 +37,24 @@ contract Reimbursement is Initializable {
|
||||
blocksToWait = 40320; // 7 days; 15 seconds block time
|
||||
}
|
||||
|
||||
modifier onlyCore {
|
||||
require(contributorContract.addressIsCore(msg.sender), "Core only");
|
||||
_;
|
||||
}
|
||||
|
||||
function setContributorContract(address contributor) public {
|
||||
require(address(contributorContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
|
||||
contributorContract = ContributorInterface(contributor);
|
||||
}
|
||||
|
||||
function getContributorIdByAddress(address contributorAccount) public view returns (uint32) {
|
||||
return contributorContract.getContributorIdByAddress(contributorAccount);
|
||||
}
|
||||
|
||||
function getContributorAddressById(uint32 contributorId) public view returns (address) {
|
||||
return contributorContract.getContributorAddressById(contributorId);
|
||||
}
|
||||
|
||||
function totalAmount(bool confirmedOnly) public view returns (uint256 amount) {
|
||||
for (uint32 i = 1; i <= reimbursementsCount; i++) {
|
||||
ReimbursementData memory r = reimbursements[i];
|
||||
@ -57,7 +81,7 @@ contract Reimbursement is Initializable {
|
||||
);
|
||||
}
|
||||
|
||||
function add(uint256 amount, address token, uint32 recipientId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public {
|
||||
function add(uint256 amount, address token, uint32 recipientId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public onlyCore {
|
||||
uint32 reimbursementId = reimbursementsCount + 1;
|
||||
ReimbursementData storage r = reimbursements[reimbursementId];
|
||||
r.exists = true;
|
||||
@ -74,7 +98,7 @@ contract Reimbursement is Initializable {
|
||||
emit ReimbursementAdded(reimbursementId, msg.sender, amount);
|
||||
}
|
||||
|
||||
function veto(uint32 reimbursementId) public {
|
||||
function veto(uint32 reimbursementId) public onlyCore {
|
||||
ReimbursementData storage r = reimbursements[reimbursementId];
|
||||
require(r.exists, 'NOT_FOUND');
|
||||
require(block.number < r.confirmedAtBlock, 'VETO_PERIOD_ENDED');
|
||||
|
@ -3,10 +3,19 @@ pragma solidity ^0.8.0;
|
||||
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol";
|
||||
|
||||
interface ContributorInterface {
|
||||
function getContributorAddressById(uint32 contributorId) external view returns (address);
|
||||
function getContributorIdByAddress(address contributorAccount) external view returns (uint32);
|
||||
function addressIsCore(address sender) external view returns (bool);
|
||||
// TODO Maybe use for validation
|
||||
// function exists(uint32 contributorId) public view returns (bool);
|
||||
}
|
||||
|
||||
contract Token is Initializable, ERC20Upgradeable {
|
||||
ContributorInterface public contributorContract;
|
||||
using SafeMathUpgradeable for uint256;
|
||||
|
||||
bytes32 public constant MINT_TOKEN_ROLE = keccak256("MINT_TOKEN_ROLE");
|
||||
address public contributionContract;
|
||||
|
||||
event LogMint(address indexed recipient, uint256 amount, uint32 contributionId);
|
||||
|
||||
@ -14,7 +23,17 @@ contract Token is Initializable, ERC20Upgradeable {
|
||||
__ERC20_init('Kredits', 'KS');
|
||||
}
|
||||
|
||||
function setContributionContract(address contribution) public {
|
||||
require(address(contributionContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
|
||||
contributionContract = contribution;
|
||||
}
|
||||
function setContributorContract(address contributor) public {
|
||||
require(address(contributorContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
|
||||
contributorContract = ContributorInterface(contributor);
|
||||
}
|
||||
|
||||
function mintFor(address contributorAccount, uint256 amount, uint32 contributionId) public {
|
||||
require(contributionContract == msg.sender, "Only Contribution");
|
||||
require(amount > 0, "INVALID_AMOUNT");
|
||||
|
||||
uint256 amountInWei = amount.mul(1 ether);
|
||||
|
@ -1,7 +1,7 @@
|
||||
const { ethers, upgrades } = require("hardhat");
|
||||
|
||||
const path = require('path');
|
||||
const fileInject = require('./helpers/file_inject.js');
|
||||
const path = require("path");
|
||||
const fileInject = require("./helpers/file_inject.js");
|
||||
|
||||
async function main() {
|
||||
const network = await hre.ethers.provider.getNetwork();
|
||||
@ -16,19 +16,27 @@ async function main() {
|
||||
const contributor = await upgrades.deployProxy(Contributor, []);
|
||||
await contributor.deployed();
|
||||
console.log("Contributor deployed to:", contributor.address);
|
||||
console.log("...waiting for 1 confirmation");
|
||||
await contributor.deployTransaction.wait();
|
||||
|
||||
const blocksToWait = 40320; // 7 days; 15 seconds block time
|
||||
const contribution = await upgrades.deployProxy(Contribution, [blocksToWait]);
|
||||
await contribution.deployed();
|
||||
console.log("Contribution deployed to:", contribution.address);
|
||||
console.log("...waiting for 1 confirmation");
|
||||
await contribution.deployTransaction.wait();
|
||||
|
||||
const token = await upgrades.deployProxy(Token, []);
|
||||
await token.deployed();
|
||||
console.log("Token deployed to:", token.address);
|
||||
console.log("...waiting for 1 confirmation");
|
||||
await token.deployTransaction.wait();
|
||||
|
||||
const reimbursement = await upgrades.deployProxy(Reimbursement, []);
|
||||
await reimbursement.deployed();
|
||||
console.log("Reimbursement deployed to:", reimbursement.address);
|
||||
console.log("...waiting for 1 confirmation");
|
||||
await reimbursement.deployTransaction.wait();
|
||||
|
||||
await contributor.setTokenContract(token.address);
|
||||
await contributor.setContributionContract(contribution.address);
|
||||
@ -36,6 +44,11 @@ async function main() {
|
||||
await contribution.setTokenContract(token.address);
|
||||
await contribution.setContributorContract(contributor.address);
|
||||
|
||||
await token.setContributionContract(contribution.address);
|
||||
await token.setContributorContract(contributor.address);
|
||||
|
||||
await reimbursement.setContributorContract(contributor.address);
|
||||
|
||||
const c = await contributor.contributionContract();
|
||||
console.log(c);
|
||||
|
||||
@ -43,11 +56,11 @@ async function main() {
|
||||
Contributor: contributor.address,
|
||||
Contribution: contribution.address,
|
||||
Token: token.address,
|
||||
Reimbursement: reimbursement.address
|
||||
Reimbursement: reimbursement.address,
|
||||
};
|
||||
|
||||
const libPath = path.join(__dirname, '..', 'lib');
|
||||
fileInject(path.join(libPath, 'addresses.json'), networkId, addresses);
|
||||
const libPath = path.join(__dirname, "..", "lib");
|
||||
fileInject(path.join(libPath, "addresses.json"), networkId, addresses);
|
||||
}
|
||||
|
||||
main();
|
||||
|
Loading…
x
Reference in New Issue
Block a user