recommendations
This commit is contained in:
parent
55d2bc14d0
commit
c45cd363b9
48
chains.json
48
chains.json
|
@ -702,5 +702,53 @@
|
||||||
"address": "0x9c888ff4D7d4F512C79073ad5016116327fD8315"
|
"address": "0x9c888ff4D7d4F512C79073ad5016116327fD8315"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"0x49d86540d21be243d6b35ac3d57a70a706f7deb3bb86ef077f4284cd96c49996": {
|
||||||
|
"contracts": {
|
||||||
|
"0xe5413cb03538126884d14df481da47efdeba969bd6c7e3609abaf1dc42973b1a": {
|
||||||
|
"name": "MiniMeTokenFactory",
|
||||||
|
"address": "0x7078E9E73FeFf15eC5C4C58233adc19447719979"
|
||||||
|
},
|
||||||
|
"0x1dc86cbe444c7243c6565fc68d02a9a0623e97a7d9470f1debede7951c2acb37": {
|
||||||
|
"name": "SNT",
|
||||||
|
"address": "0x195fcB5B1D04E58C90813a5d67a5Ab84Bc4D85e5"
|
||||||
|
},
|
||||||
|
"0xdbb86398e138a56d6f9aedadef62d41d99e5a3c6a39d64605ec1e4ad2ed03552": {
|
||||||
|
"name": "Meritocracy",
|
||||||
|
"address": "0x9c888ff4D7d4F512C79073ad5016116327fD8315"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0xafffa90a8bde013ecfaa2f52c9e3a91cec80efb2bf21a11aa6322dd14cdcff9f": {
|
||||||
|
"contracts": {
|
||||||
|
"0xe5413cb03538126884d14df481da47efdeba969bd6c7e3609abaf1dc42973b1a": {
|
||||||
|
"name": "MiniMeTokenFactory",
|
||||||
|
"address": "0x7078E9E73FeFf15eC5C4C58233adc19447719979"
|
||||||
|
},
|
||||||
|
"0x1dc86cbe444c7243c6565fc68d02a9a0623e97a7d9470f1debede7951c2acb37": {
|
||||||
|
"name": "SNT",
|
||||||
|
"address": "0x195fcB5B1D04E58C90813a5d67a5Ab84Bc4D85e5"
|
||||||
|
},
|
||||||
|
"0xdbb86398e138a56d6f9aedadef62d41d99e5a3c6a39d64605ec1e4ad2ed03552": {
|
||||||
|
"name": "Meritocracy",
|
||||||
|
"address": "0x9c888ff4D7d4F512C79073ad5016116327fD8315"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0xb78c5af6ccf56c3a3467561d3ae57a6446fd2239d3b1ad07cc6c9a0bd0a865d2": {
|
||||||
|
"contracts": {
|
||||||
|
"0xe5413cb03538126884d14df481da47efdeba969bd6c7e3609abaf1dc42973b1a": {
|
||||||
|
"name": "MiniMeTokenFactory",
|
||||||
|
"address": "0x7078E9E73FeFf15eC5C4C58233adc19447719979"
|
||||||
|
},
|
||||||
|
"0x1dc86cbe444c7243c6565fc68d02a9a0623e97a7d9470f1debede7951c2acb37": {
|
||||||
|
"name": "SNT",
|
||||||
|
"address": "0x195fcB5B1D04E58C90813a5d67a5Ab84Bc4D85e5"
|
||||||
|
},
|
||||||
|
"0x78671fa87a2081dd20332ebf134a0e2dab79f47bfe878fb8911921d78dbad054": {
|
||||||
|
"name": "Meritocracy",
|
||||||
|
"address": "0x9c888ff4D7d4F512C79073ad5016116327fD8315"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@ DApp:
|
||||||
- allows you to send SNT to meritocracy
|
- allows you to send SNT to meritocracy
|
||||||
- add/remove contributor
|
- add/remove contributor
|
||||||
- add/remove adminstrator
|
- add/remove adminstrator
|
||||||
|
|
||||||
|
Extension:
|
||||||
|
- Command:
|
||||||
|
- above command = display allocation, received, withdraw button, allocate button? (might be better in dapp)
|
||||||
|
- /kudos 500 "<person>" "<praise>"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "token/ERC20Token.sol";
|
import "token/ERC20Token.sol";
|
||||||
|
@ -35,7 +40,7 @@ contract Meritocracy {
|
||||||
Status[] status;
|
Status[] status;
|
||||||
}
|
}
|
||||||
|
|
||||||
address public token; // token contract
|
ERC20Token public token; // token contract
|
||||||
address payable public owner; // contract owner
|
address payable public owner; // contract owner
|
||||||
uint256 public lastForfeit; // timestamp to block admins calling forfeitAllocations too quickly
|
uint256 public lastForfeit; // timestamp to block admins calling forfeitAllocations too quickly
|
||||||
address[] public registry; // array of contributor addresses
|
address[] public registry; // array of contributor addresses
|
||||||
|
@ -43,16 +48,30 @@ contract Meritocracy {
|
||||||
mapping(address => bool) public admins;
|
mapping(address => bool) public admins;
|
||||||
mapping(address => Contributor) public contributors;
|
mapping(address => Contributor) public contributors;
|
||||||
|
|
||||||
|
// Modifiers -------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Functions only Owner can call
|
||||||
|
modifier onlyOwner() {
|
||||||
|
require(msg.sender == owner);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions only Admin can call
|
||||||
|
modifier onlyAdmin() {
|
||||||
|
require(admins[msg.sender]);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
// Open Functions ----------------------------------------------------------------------------------------
|
// Open Functions ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Split amount over each contributor in registry, anyone can contribute.
|
// Split amount over each contributor in registry, any contributor can allocate? TODO maybe relax this restriction, so anyone can allocate tokens
|
||||||
function allocate(uint256 _amount) external {
|
function allocate(uint256 _amount) external {
|
||||||
// Locals
|
// Locals
|
||||||
uint256 individualAmount;
|
uint256 individualAmount;
|
||||||
Contributor memory cAllocator = contributors[msg.sender];
|
// Contributor memory cAllocator = contributors[msg.sender];
|
||||||
// Requirements
|
// Requirements
|
||||||
require(cAllocator.addr == msg.sender); // is sender a Contributor?
|
// require(cAllocator.addr != address(0)); // is sender a Contributor? TODO maybe relax this restriction.
|
||||||
require(ERC20Token(token).transferFrom(msg.sender, address(this), _amount));
|
require(token.transferFrom(msg.sender, address(this), _amount));
|
||||||
// Body
|
// Body
|
||||||
// cAllocator.inPot = true;
|
// cAllocator.inPot = true;
|
||||||
individualAmount = _amount / registry.length;
|
individualAmount = _amount / registry.length;
|
||||||
|
@ -62,7 +81,7 @@ contract Meritocracy {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getter for Dynamic Array Length
|
// Getter for Dynamic Array Length
|
||||||
function registryLength() external returns (uint256) {
|
function registryLength() public view returns (uint256) {
|
||||||
return registry.length;
|
return registry.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +100,7 @@ contract Meritocracy {
|
||||||
uint256 r = cReceiver.received;
|
uint256 r = cReceiver.received;
|
||||||
cReceiver.received = 0;
|
cReceiver.received = 0;
|
||||||
// cReceiver.inPot = false;
|
// cReceiver.inPot = false;
|
||||||
ERC20Token(token).transferFrom(address(this), cReceiver.addr, r);
|
token.transferFrom(address(this), cReceiver.addr, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow Contributors to award allocated tokens to other Contributors
|
// Allow Contributors to award allocated tokens to other Contributors
|
||||||
|
@ -112,11 +131,10 @@ contract Meritocracy {
|
||||||
// Admin Functions -------------------------------------------------------------------------------------
|
// Admin Functions -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Add Contributor to Registry
|
// Add Contributor to Registry
|
||||||
function addContributor(address _contributor) public {
|
function addContributor(address _contributor) public onlyAdmin() {
|
||||||
// Requirements
|
// Requirements
|
||||||
require(admins[msg.sender]);
|
require(registry.length + 1 <= maxContributors); // Don't go out of bounds
|
||||||
require(registry.length + 1 <= maxContributors);
|
require(contributors[_contributor].addr == address(0)); // Contributor doesn't exist
|
||||||
require(contributors[_contributor].addr == address(0));
|
|
||||||
// Body
|
// Body
|
||||||
Contributor storage c = contributors[_contributor];
|
Contributor storage c = contributors[_contributor];
|
||||||
c.addr = _contributor;
|
c.addr = _contributor;
|
||||||
|
@ -124,9 +142,9 @@ contract Meritocracy {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Multiple Contributors to the Registry in one tx
|
// Add Multiple Contributors to the Registry in one tx
|
||||||
function addContributors(address[] calldata _newContributors ) external {
|
function addContributors(address[] calldata _newContributors ) external onlyAdmin() {
|
||||||
// Requirements
|
// Requirements
|
||||||
require(registry.length + _newContributors.length <= maxContributors);
|
require(registry.length + _newContributors.length <= maxContributors); // Don't go out of bounds
|
||||||
// Body
|
// Body
|
||||||
for (uint256 i = 0; i < _newContributors.length; i++) {
|
for (uint256 i = 0; i < _newContributors.length; i++) {
|
||||||
addContributor(_newContributors[i]);
|
addContributor(_newContributors[i]);
|
||||||
|
@ -135,19 +153,19 @@ contract Meritocracy {
|
||||||
|
|
||||||
// Remove Contributor from Registry
|
// Remove Contributor from Registry
|
||||||
// Note: Should not be easy to remove multiple contributors in one tx
|
// Note: Should not be easy to remove multiple contributors in one tx
|
||||||
function removeContributor(address _contributor) external {
|
// WARN: Changed to idx, client can do loop by enumerating registry
|
||||||
|
function removeContributor(uint256 idx) external onlyAdmin() { // address _contributor
|
||||||
// Requirements
|
// Requirements
|
||||||
require(admins[msg.sender]);
|
require(idx < registry.length - 1); // idx needs to be smaller than registry.length - 1 OR maxContributors
|
||||||
// Body
|
// Body
|
||||||
// Find id of contributor address
|
// Find id of contributor address
|
||||||
uint256 idx = 0;
|
// uint256 idx = 0;
|
||||||
for (uint256 i = 0; i < registry.length; i++) { // should never be longer than maxContributors, see addContributor
|
// for (uint256 i = 0; i < registry.length; i++) { // should never be longer than maxContributors, see addContributor
|
||||||
if (registry[i] == _contributor) {
|
// if (registry[i] == _contributor) {
|
||||||
idx = i;
|
// idx = i;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
address c = registry[idx];
|
address c = registry[idx];
|
||||||
// Swap & Pop!
|
// Swap & Pop!
|
||||||
registry[idx] = registry[registry.length - 1];
|
registry[idx] = registry[registry.length - 1];
|
||||||
|
@ -156,18 +174,14 @@ contract Meritocracy {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implictly sets a finite limit to registry length
|
// Implictly sets a finite limit to registry length
|
||||||
function setMaxContributors(uint256 _maxContributors) external {
|
function setMaxContributors(uint256 _maxContributors) external onlyAdmin() {
|
||||||
// Requirements
|
|
||||||
require(admins[msg.sender]);
|
|
||||||
require(_maxContributors > registry.length); // have to removeContributor first
|
require(_maxContributors > registry.length); // have to removeContributor first
|
||||||
// Body
|
// Body
|
||||||
maxContributors = _maxContributors;
|
maxContributors = _maxContributors;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zero-out allocations for contributors, minimum once a week, if allocation still exists, add to burn
|
// Zero-out allocations for contributors, minimum once a week, if allocation still exists, add to burn
|
||||||
function forfeitAllocations() public {
|
function forfeitAllocations() public onlyAdmin() {
|
||||||
// Requirements
|
|
||||||
require(admins[msg.sender]);
|
|
||||||
require(block.timestamp >= lastForfeit + 1 weeks); // prevents multiple admins accidently calling too quickly.
|
require(block.timestamp >= lastForfeit + 1 weeks); // prevents multiple admins accidently calling too quickly.
|
||||||
// Body
|
// Body
|
||||||
lastForfeit = block.timestamp;
|
lastForfeit = block.timestamp;
|
||||||
|
@ -183,25 +197,17 @@ contract Meritocracy {
|
||||||
// Owner Functions -------------------------------------------------------------------------------------
|
// Owner Functions -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Set Admin flag for address to true
|
// Set Admin flag for address to true
|
||||||
function addAdmin(address _admin) public {
|
function addAdmin(address _admin) public onlyOwner() {
|
||||||
// Requirements
|
|
||||||
require(msg.sender == owner);
|
|
||||||
// Body
|
|
||||||
admins[_admin] = true;
|
admins[_admin] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Admin flag for address to false
|
// Set Admin flag for address to false
|
||||||
function removeAdmin(address _admin) public {
|
function removeAdmin(address _admin) public onlyOwner() {
|
||||||
// Requirements
|
|
||||||
require(msg.sender == owner);
|
|
||||||
// Body
|
|
||||||
delete admins[_admin];
|
delete admins[_admin];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change owner address, ideally to a management contract or multisig
|
// Change owner address, ideally to a management contract or multisig
|
||||||
function changeOwner(address payable _owner) external {
|
function changeOwner(address payable _owner) external onlyOwner() {
|
||||||
// Requirements
|
|
||||||
require(msg.sender == owner);
|
|
||||||
// Body
|
// Body
|
||||||
removeAdmin(owner);
|
removeAdmin(owner);
|
||||||
addAdmin(_owner);
|
addAdmin(_owner);
|
||||||
|
@ -210,41 +216,34 @@ contract Meritocracy {
|
||||||
|
|
||||||
// Change Token address
|
// Change Token address
|
||||||
// WARN: call escape first, or escape(token);
|
// WARN: call escape first, or escape(token);
|
||||||
function changeToken(address _token) external {
|
function changeToken(address _token) external onlyOwner() {
|
||||||
// Locals
|
|
||||||
uint256 r;
|
|
||||||
// Requirements
|
|
||||||
require(msg.sender == owner);
|
|
||||||
// Body
|
// Body
|
||||||
// Zero-out allocation and received, send out received tokens before token switch.
|
// Zero-out allocation and received, send out received tokens before token switch.
|
||||||
for (uint256 i = 0; i < registry.length; i++) {
|
for (uint256 i = 0; i < registry.length; i++) {
|
||||||
Contributor storage c = contributors[registry[i]];
|
Contributor storage c = contributors[registry[i]];
|
||||||
r = c.received;
|
uint256 r = c.received;
|
||||||
c.received = 0;
|
c.received = 0;
|
||||||
c.allocation = 0;
|
c.allocation = 0;
|
||||||
// WARN: Should totalReceived and totalForfeited be zeroed-out?
|
// WARN: Should totalReceived and totalForfeited be zeroed-out?
|
||||||
ERC20Token(token).transferFrom(address(this), c.addr, r); // Transfer any owed tokens to contributor
|
token.transferFrom(address(this), c.addr, r); // Transfer any owed tokens to contributor
|
||||||
}
|
}
|
||||||
lastForfeit = block.timestamp;
|
lastForfeit = block.timestamp;
|
||||||
token = _token;
|
token = ERC20Token(_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failsafe, Owner can escape hatch all Tokens and ETH from Contract.
|
// Failsafe, Owner can escape hatch all Tokens and ETH from Contract.
|
||||||
function escape() public {
|
function escape() public onlyOwner() {
|
||||||
// Requirements
|
|
||||||
require(msg.sender == owner);
|
|
||||||
// Body
|
// Body
|
||||||
ERC20Token(token).transferFrom(address(this), owner, ERC20Token(token).balanceOf(address(this)));
|
token.transferFrom(address(this), owner, token.balanceOf(address(this)));
|
||||||
address(owner).transfer(address(this).balance);
|
owner.transfer(address(this).balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overloaded failsafe function, recourse incase changeToken is called before escape and funds are in a different token
|
// Overloaded failsafe function, recourse incase changeToken is called before escape and funds are in a different token
|
||||||
// Don't want to require in changeToken incase bad behaviour of ERC20 token
|
// Don't want to require in changeToken incase bad behaviour of ERC20 token
|
||||||
function escape(address _token) external {
|
function escape(address _token) external onlyOwner() {
|
||||||
// Requirements
|
|
||||||
require(msg.sender == owner);
|
|
||||||
// Body
|
// Body
|
||||||
ERC20Token(_token).transferFrom(address(this), owner, ERC20Token(_token).balanceOf(address(this)));
|
ERC20Token t = ERC20Token(_token);
|
||||||
|
t.transferFrom(address(this), owner, t.balanceOf(address(this)));
|
||||||
escape();
|
escape();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,9 +253,7 @@ contract Meritocracy {
|
||||||
owner = msg.sender;
|
owner = msg.sender;
|
||||||
addAdmin(owner);
|
addAdmin(owner);
|
||||||
lastForfeit = block.timestamp;
|
lastForfeit = block.timestamp;
|
||||||
token = _token;
|
token = ERC20Token(_token);
|
||||||
maxContributors= _maxContributors;
|
maxContributors= _maxContributors;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function() public { throw; } // TODO Probably not needed?
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue