Import/Migrate existing kredits contracts
This brings in the current state of the kredits contracts incl. the Contributors, Operator and Token contract.
This commit is contained in:
parent
f0caa1208d
commit
85ae154860
108
contracts/Contributors.sol
Normal file
108
contracts/Contributors.sol
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
pragma solidity ^0.4.18;
|
||||||
|
|
||||||
|
import './upgradeable/Upgradeable.sol';
|
||||||
|
|
||||||
|
contract Contributors is Upgradeable {
|
||||||
|
|
||||||
|
struct Contributor {
|
||||||
|
address account;
|
||||||
|
bytes32 profileHash;
|
||||||
|
uint8 hashFunction;
|
||||||
|
uint8 hashSize;
|
||||||
|
bool isCore;
|
||||||
|
bool exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping (address => uint) public contributorIds;
|
||||||
|
mapping (uint => Contributor) public contributors;
|
||||||
|
uint256 public contributorsCount;
|
||||||
|
|
||||||
|
event ContributorProfileUpdated(uint id, bytes32 oldProfileHash, bytes32 newProfileHash);
|
||||||
|
event ContributorAddressUpdated(uint id, address oldAddress, address newAddress);
|
||||||
|
event ContributorAdded(uint id, address _address);
|
||||||
|
|
||||||
|
function initialize(address sender) public payable {
|
||||||
|
require(msg.sender == address(registry));
|
||||||
|
uint _id = 1;
|
||||||
|
Contributor c = contributors[_id];
|
||||||
|
c.exists = true;
|
||||||
|
c.isCore = true;
|
||||||
|
c.account = sender;
|
||||||
|
contributorIds[sender] = _id;
|
||||||
|
contributorsCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function coreContributorsCount() constant public returns (uint) {
|
||||||
|
uint count = 0;
|
||||||
|
for (uint256 i = 1; i <= contributorsCount; i++) {
|
||||||
|
if (contributors[i].isCore) {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateContributorAddress(uint _id, address _oldAddress, address _newAddress) public onlyRegistryContractFor('Operator') {
|
||||||
|
contributorIds[_oldAddress] = 0;
|
||||||
|
contributorIds[_newAddress] = _id;
|
||||||
|
contributors[_id].account = _newAddress;
|
||||||
|
ContributorAddressUpdated(_id, _oldAddress, _newAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateContributorProfileHash(uint _id, uint8 _hashFunction, uint8 _hashSize, bytes32 _profileHash) public onlyRegistryContractFor('Operator') {
|
||||||
|
Contributor c = contributors[_id];
|
||||||
|
bytes32 _oldProfileHash = c.profileHash;
|
||||||
|
c.profileHash = _profileHash;
|
||||||
|
c.hashFunction = _hashFunction;
|
||||||
|
c.hashSize = _hashSize;
|
||||||
|
|
||||||
|
ContributorProfileUpdated(_id, _oldProfileHash, c.profileHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addContributor(address _address, uint8 _hashFunction, uint8 _hashSize, bytes32 _profileHash, bool isCore) public onlyRegistryContractFor('Operator') {
|
||||||
|
uint _id = contributorsCount + 1;
|
||||||
|
if (contributors[_id].exists != true) {
|
||||||
|
Contributor c = contributors[_id];
|
||||||
|
c.exists = true;
|
||||||
|
c.isCore = isCore;
|
||||||
|
c.hashFunction = _hashFunction;
|
||||||
|
c.hashSize = _hashSize;
|
||||||
|
c.profileHash = _profileHash;
|
||||||
|
c.account = _address;
|
||||||
|
contributorIds[_address] = _id;
|
||||||
|
|
||||||
|
contributorsCount += 1;
|
||||||
|
|
||||||
|
ContributorAdded(_id, _address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isCore(uint _id) constant public returns (bool) {
|
||||||
|
return contributors[_id].isCore;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exists(uint _id) constant public returns (bool) {
|
||||||
|
return contributors[_id].exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addressIsCore(address _address) constant public returns (bool) {
|
||||||
|
return getContributorByAddress(_address).isCore;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addressExists(address _address) constant public returns (bool) {
|
||||||
|
return getContributorByAddress(_address).exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContributorIdByAddress(address _address) constant public returns (uint) {
|
||||||
|
return contributorIds[_address];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContributorAddressById(uint _id) constant public returns (address) {
|
||||||
|
return contributors[_id].account;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContributorByAddress(address _address) internal returns (Contributor) {
|
||||||
|
uint id = contributorIds[_address];
|
||||||
|
return contributors[id];
|
||||||
|
}
|
||||||
|
}
|
126
contracts/Operator.sol
Normal file
126
contracts/Operator.sol
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
pragma solidity ^0.4.18;
|
||||||
|
|
||||||
|
// ToDo: only load interfaces
|
||||||
|
import './Token.sol';
|
||||||
|
import './Contributors.sol';
|
||||||
|
|
||||||
|
contract Operator is Upgradeable {
|
||||||
|
|
||||||
|
struct Proposal {
|
||||||
|
address creator;
|
||||||
|
uint recipientId;
|
||||||
|
uint votesCount;
|
||||||
|
uint votesNeeded;
|
||||||
|
uint256 amount;
|
||||||
|
bool executed;
|
||||||
|
string ipfsHash;
|
||||||
|
mapping (address => bool) votes;
|
||||||
|
bool exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
Proposal[] public proposals;
|
||||||
|
|
||||||
|
event ProposalCreated(uint256 id, address creator, uint recipient, uint256 amount, string ipfsHash);
|
||||||
|
event ProposalVoted(uint256 id, address voter);
|
||||||
|
event ProposalVoted(uint256 id, address voter, uint256 totalVotes);
|
||||||
|
event ProposalExecuted(uint256 id, uint recipient, uint256 amount, string ipfsHash);
|
||||||
|
|
||||||
|
modifier coreOnly() {
|
||||||
|
require(contributorsContract().addressIsCore(msg.sender));
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
modifier contributorOnly() {
|
||||||
|
require(contributorsContract().addressExists(msg.sender));
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
modifier noEther() {
|
||||||
|
require(msg.value == 0);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
function contributorsContract() constant public returns (Contributors) {
|
||||||
|
return Contributors(registry.getProxyFor('Contributors'));
|
||||||
|
}
|
||||||
|
function tokenContract() constant public returns (Token) {
|
||||||
|
return Token(registry.getProxyFor('Token'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function contributorsCount() constant public returns (uint) {
|
||||||
|
return contributorsContract().contributorsCount();
|
||||||
|
}
|
||||||
|
function coreContributorsCount() constant public returns (uint) {
|
||||||
|
return contributorsContract().coreContributorsCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addContributor(address _address, bytes32 _profileHash, uint8 _hashFunction, uint8 _hashSize, bool _isCore) public coreOnly {
|
||||||
|
contributorsContract().addContributor(_address, _hashFunction, _hashSize, _profileHash, _isCore);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateContributorProfileHash(uint _id, bytes32 _profileHash, uint8 _hashFunction, uint8 _hashSize) public coreOnly {
|
||||||
|
contributorsContract().updateContributorProfileHash(_id, _hashFunction, _hashSize, _profileHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContributor(uint _id) constant public returns (address account, uint8 hashFunction, uint8 hashSize, bytes32 profileHash, bool isCore) {
|
||||||
|
bool exists;
|
||||||
|
|
||||||
|
(account, profileHash, hashFunction, hashSize, isCore, exists) = contributorsContract().contributors(_id);
|
||||||
|
|
||||||
|
if (!exists) { throw; }
|
||||||
|
}
|
||||||
|
|
||||||
|
function proposalsCount() constant public returns (uint) {
|
||||||
|
return proposals.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addProposal(uint _recipient, uint256 _amount, string _ipfsHash) public returns (uint256 proposalId) {
|
||||||
|
require(contributorsContract().exists(_recipient));
|
||||||
|
|
||||||
|
proposalId = proposals.length;
|
||||||
|
uint _votesNeeded = contributorsContract().coreContributorsCount() / 100 * 75;
|
||||||
|
|
||||||
|
var p = Proposal({
|
||||||
|
creator: msg.sender,
|
||||||
|
recipientId: _recipient,
|
||||||
|
amount: _amount,
|
||||||
|
ipfsHash: _ipfsHash,
|
||||||
|
votesCount: 0,
|
||||||
|
votesNeeded: _votesNeeded,
|
||||||
|
executed: false,
|
||||||
|
exists: true
|
||||||
|
});
|
||||||
|
proposals.push(p);
|
||||||
|
ProposalCreated(proposalId, msg.sender, p.recipientId, p.amount, p.ipfsHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
function vote(uint256 _proposalId) public coreOnly returns (uint _pId, bool _executed) {
|
||||||
|
var p = proposals[_proposalId];
|
||||||
|
if (p.executed) { throw; }
|
||||||
|
if (p.votes[msg.sender] == true) { throw; }
|
||||||
|
p.votes[msg.sender] = true;
|
||||||
|
p.votesCount++;
|
||||||
|
_executed = false;
|
||||||
|
_pId = _proposalId;
|
||||||
|
if (p.votesCount >= p.votesNeeded) {
|
||||||
|
executeProposal(_proposalId);
|
||||||
|
_executed = true;
|
||||||
|
}
|
||||||
|
ProposalVoted(_pId, msg.sender, p.votesCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasVotedFor(address _sender, uint256 _proposalId) public constant returns (bool) {
|
||||||
|
Proposal p = proposals[_proposalId];
|
||||||
|
return p.exists && p.votes[_sender];
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeProposal(uint proposalId) private returns (bool) {
|
||||||
|
var p = proposals[proposalId];
|
||||||
|
if (p.executed) { throw; }
|
||||||
|
if (p.votesCount < p.votesNeeded) { throw; }
|
||||||
|
address recipientAddress = contributorsContract().getContributorAddressById(p.recipientId);
|
||||||
|
tokenContract().mintFor(recipientAddress, p.amount, p.ipfsHash);
|
||||||
|
p.executed = true;
|
||||||
|
ProposalExecuted(proposalId, p.recipientId, p.amount, p.ipfsHash);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,11 +10,6 @@ contract Token is Upgradeable, BasicToken {
|
|||||||
|
|
||||||
event LogMint(address indexed recipient, uint256 amount, string reference);
|
event LogMint(address indexed recipient, uint256 amount, string reference);
|
||||||
|
|
||||||
modifier requireRegistry() {
|
|
||||||
require(address(registry) != 0x0);
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
function initialize(address sender) public payable {
|
function initialize(address sender) public payable {
|
||||||
require(msg.sender == address(registry));
|
require(msg.sender == address(registry));
|
||||||
name = 'Kredits';
|
name = 'Kredits';
|
||||||
@ -22,7 +17,7 @@ contract Token is Upgradeable, BasicToken {
|
|||||||
decimals = 18;
|
decimals = 18;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mintFor(address _recipient, uint256 _amount, string _reference) requireRegistry returns (bool success) {
|
function mintFor(address _recipient, uint256 _amount, string _reference) onlyRegistryContractFor('Operator') public returns (bool success) {
|
||||||
totalSupply_ = totalSupply_.add(_amount);
|
totalSupply_ = totalSupply_.add(_amount);
|
||||||
balances[_recipient] = balances[_recipient].add(_amount);
|
balances[_recipient] = balances[_recipient].add(_amount);
|
||||||
|
|
||||||
|
@ -49,4 +49,5 @@ interface IRegistry {
|
|||||||
*/
|
*/
|
||||||
function getLatestVersion(bytes32 name) public view returns (address);
|
function getLatestVersion(bytes32 name) public view returns (address);
|
||||||
|
|
||||||
|
function getProxyFor(bytes32 name) public view returns (address);
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,10 @@ contract Registry is IRegistry {
|
|||||||
return getVersion(name, current);
|
return getVersion(name, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getProxyFor(bytes32 name) public view returns (address) {
|
||||||
|
return proxies[name];
|
||||||
|
}
|
||||||
|
|
||||||
function upgrade(bytes32 name, uint version) public {
|
function upgrade(bytes32 name, uint version) public {
|
||||||
UpgradeabilityProxy(proxies[name]).upgradeTo(version);
|
UpgradeabilityProxy(proxies[name]).upgradeTo(version);
|
||||||
ProxyImplementationUpgraded(name, version);
|
ProxyImplementationUpgraded(name, version);
|
||||||
|
@ -16,6 +16,17 @@ contract UpgradeabilityStorage {
|
|||||||
// contract name
|
// contract name
|
||||||
bytes32 public _proxiedContractName;
|
bytes32 public _proxiedContractName;
|
||||||
|
|
||||||
|
|
||||||
|
modifier requireRegistry() {
|
||||||
|
require(address(registry) != 0x0);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
modifier onlyRegistryContractFor(bytes32 name) {
|
||||||
|
require(address(registry) != 0x0);
|
||||||
|
require(msg.sender == registry.getProxyFor(name));
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Tells the address of the current implementation
|
* @dev Tells the address of the current implementation
|
||||||
* @return address of the current implementation
|
* @return address of the current implementation
|
||||||
|
@ -7,6 +7,7 @@ module.exports = function(deployer) {
|
|||||||
console.log('Token address: ', Token.address);
|
console.log('Token address: ', Token.address);
|
||||||
Registry.deployed().then(function(registry) {
|
Registry.deployed().then(function(registry) {
|
||||||
registry.addVersion('Token', Token.address);
|
registry.addVersion('Token', Token.address);
|
||||||
|
registry.createProxy('Token', 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
13
migrations/1522427321_contributors.js
Normal file
13
migrations/1522427321_contributors.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
var Registry = artifacts.require('./Registry.sol');
|
||||||
|
var Contributors = artifacts.require('./Contributors.sol');
|
||||||
|
|
||||||
|
module.exports = function(deployer) {
|
||||||
|
deployer.deploy(Contributors).then(function(contributors) {
|
||||||
|
console.log('Registry address: ', Registry.address);
|
||||||
|
console.log('Contributors address: ', Contributors.address);
|
||||||
|
Registry.deployed().then(function(registry) {
|
||||||
|
registry.addVersion('Contributors', Contributors.address);
|
||||||
|
registry.createProxy('Contributors', 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
13
migrations/1522430935_operator.js
Normal file
13
migrations/1522430935_operator.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
var Registry = artifacts.require('./Registry.sol');
|
||||||
|
var Operator = artifacts.require('./Operator.sol');
|
||||||
|
|
||||||
|
module.exports = function(deployer) {
|
||||||
|
deployer.deploy(Operator).then(function(operator) {
|
||||||
|
console.log('Registry address: ', Registry.address);
|
||||||
|
console.log('Operator address: ', Operator.address);
|
||||||
|
Registry.deployed().then(function(registry) {
|
||||||
|
registry.addVersion('Operator', Operator.address);
|
||||||
|
registry.createProxy('Operator', 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user