Repo sync
parent
53b5fa02e6
commit
1fff694a1b
|
@ -1,5 +1,6 @@
|
||||||
# Vornoi · [![GitHub license](https://img.shields.io/badge/license-GPL3%2FApache2-blue)](https://github.com/Qrucial/voronoi/blob/main/LICENSE)
|
# Vornoi · [![GitHub license](https://img.shields.io/badge/license-GPL3%2FApache2-blue)](https://github.com/Qrucial/voronoi/blob/main/LICENSE)
|
||||||
Making "decentralized" blockchain projects actually decentralized. Currently implementing the solutions: for Polkadot and Ethereum.
|
Making "decentralized" blockchain projects actually decentralized. Currently implementing the solutions: for Polkadot and Ethereum.
|
||||||
|
The currently deployable Voronoi code can be smart contract folder. Voronoi ERC20 implementation is already in beta version.
|
||||||
|
|
||||||
### Assumption
|
### Assumption
|
||||||
Cryptocurrency project with decentralization as one of the core principle.
|
Cryptocurrency project with decentralization as one of the core principle.
|
||||||
|
@ -37,6 +38,11 @@ Always publish the address on multiple public sources so users can verify it bef
|
||||||
### Example Topology of a real decentralized smart contract
|
### Example Topology of a real decentralized smart contract
|
||||||
![Decentralized Organization](/images/DecentraLibExample.jpg)
|
![Decentralized Organization](/images/DecentraLibExample.jpg)
|
||||||
|
|
||||||
|
|
||||||
|
### Voronoi on Moonbase Alpha testnet
|
||||||
|
Explorer URL: https://moonbase-blockscout.testnet.moonbeam.network/tx/0xb43184f219f3e32607ecf0527787d64c25c42ec46b407bcce6d4606ef861e7f9
|
||||||
|
|
||||||
|
|
||||||
### Contributing
|
### Contributing
|
||||||
Voronoi is an open project which welcomes contribution. Please send us a pull request in case you have a contribution.
|
Voronoi is an open project which welcomes contribution. Please send us a pull request in case you have a contribution.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,280 @@
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// Example of Voronoi Solidity solution, by QRUCIAL OÜ
|
||||||
|
// Code state: Beta
|
||||||
|
// Coder: Six
|
||||||
|
|
||||||
|
pragma solidity ^0.8.11;
|
||||||
|
|
||||||
|
contract VoronoiToken {
|
||||||
|
string public constant name = "VoronoiERC20";
|
||||||
|
string public constant symbol = "VE2";
|
||||||
|
uint8 public constant decimals = 0;
|
||||||
|
|
||||||
|
event Transfer(address indexed _from, address indexed _to, uint256 _value);
|
||||||
|
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
|
||||||
|
event major_impact_call(bool value); // Event when a Major Impact Function is called
|
||||||
|
event minor_impact_call(bool value); // Event when a Minor Impact Function is called
|
||||||
|
event function_unlock(uint256 value); // Unlock event, when a function gets unlocked, unit256 -> func ID
|
||||||
|
|
||||||
|
mapping(address => uint256) balances;
|
||||||
|
mapping(address => mapping (address => uint256)) allowed;
|
||||||
|
|
||||||
|
mapping (uint256 => address) internal unlocker_ids; // Needs to be in sync with the unlocker_ids, max 10
|
||||||
|
mapping (uint256 => uint256) internal unlocker_stakes; // Address to threshold amount (single account can have multiple)
|
||||||
|
|
||||||
|
uint256 private totalSupply_ = 100000000;
|
||||||
|
address private admin;
|
||||||
|
uint256 private _voronoi_count;
|
||||||
|
uint256 private threshold;
|
||||||
|
uint256 private _voronoi_last_time;
|
||||||
|
|
||||||
|
bool private _paused;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
admin = msg.sender;
|
||||||
|
balances[msg.sender] = totalSupply_;
|
||||||
|
_paused = false;
|
||||||
|
_voronoi_count = 0;
|
||||||
|
threshold = 3;
|
||||||
|
_voronoi_last_time = block.timestamp;
|
||||||
|
unlocker_ids[0] = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
|
||||||
|
unlocker_ids[1] = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
|
||||||
|
unlocker_ids[2] = 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c;
|
||||||
|
unlocker_ids[3] = 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db;
|
||||||
|
unlocker_ids[4] = 0x617F2E2fD72FD9D5503197092aC168c91465E7f2;
|
||||||
|
unlocker_ids[5] = 0x1aE0EA34a72D944a8C7603FfB3eC30a6669E454C;
|
||||||
|
unlocker_ids[6] = 0x583031D1113aD414F02576BD6afaBfb302140225;
|
||||||
|
unlocker_ids[7] = 0x583031D1113aD414F02576BD6afaBfb302140225;
|
||||||
|
unlocker_ids[8] = 0x0A098Eda01Ce92ff4A4CCb7A4fFFb5A43EBC70DC;
|
||||||
|
unlocker_ids[9] = 0x0A098Eda01Ce92ff4A4CCb7A4fFFb5A43EBC70DC;
|
||||||
|
unlocker_stakes[0] = 1;
|
||||||
|
unlocker_stakes[1] = 1;
|
||||||
|
unlocker_stakes[2] = 1;
|
||||||
|
unlocker_stakes[3] = 1;
|
||||||
|
unlocker_stakes[4] = 1;
|
||||||
|
unlocker_stakes[5] = 1;
|
||||||
|
unlocker_stakes[6] = 1;
|
||||||
|
unlocker_stakes[7] = 1;
|
||||||
|
unlocker_stakes[8] = 1;
|
||||||
|
unlocker_stakes[9] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function voronoi_stake_up() external returns (bool success){
|
||||||
|
emit minor_impact_call(true);
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
|
||||||
|
if (msg.sender == unlocker_ids[0]){
|
||||||
|
require(unlocker_stakes[0] == 1);
|
||||||
|
unlocker_stakes[0] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[1]) {
|
||||||
|
require(unlocker_stakes[1] == 1);
|
||||||
|
unlocker_stakes[1] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[2]) {
|
||||||
|
require(unlocker_stakes[2] == 1);
|
||||||
|
unlocker_stakes[2] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[3]) {
|
||||||
|
require(unlocker_stakes[3] == 1);
|
||||||
|
unlocker_stakes[3] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[4]) {
|
||||||
|
require(unlocker_stakes[4] == 1);
|
||||||
|
unlocker_stakes[4] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[5]) {
|
||||||
|
require(unlocker_stakes[5] == 1);
|
||||||
|
unlocker_stakes[5] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[6]) {
|
||||||
|
require(unlocker_stakes[6] == 1);
|
||||||
|
unlocker_stakes[6] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[7]) {
|
||||||
|
require(unlocker_stakes[7] == 1);
|
||||||
|
unlocker_stakes[7] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[8]) {
|
||||||
|
require(unlocker_stakes[8] == 1);
|
||||||
|
unlocker_stakes[8] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[9]) {
|
||||||
|
require(unlocker_stakes[9] == 1);
|
||||||
|
unlocker_stakes[9] = 0;
|
||||||
|
}
|
||||||
|
_voronoi_count = _voronoi_count + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function vcheck_stake(uint256 _idToCheck) external view returns(uint256 success){
|
||||||
|
return unlocker_stakes[_idToCheck];
|
||||||
|
}
|
||||||
|
|
||||||
|
function vcheck_count() external view returns(uint256 success){
|
||||||
|
return _voronoi_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function v_reset() external returns (bool success){
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
require(block.timestamp >= _voronoi_last_time + 1 minutes); // You can only do it once every hour to secure voting logic
|
||||||
|
_voronoi_last_time = block.timestamp;
|
||||||
|
_voronoi_count = 0;
|
||||||
|
unlocker_stakes[0] = 1;
|
||||||
|
unlocker_stakes[1] = 1;
|
||||||
|
unlocker_stakes[2] = 1;
|
||||||
|
unlocker_stakes[3] = 1;
|
||||||
|
unlocker_stakes[4] = 1;
|
||||||
|
unlocker_stakes[5] = 1;
|
||||||
|
unlocker_stakes[6] = 1;
|
||||||
|
unlocker_stakes[7] = 1;
|
||||||
|
unlocker_stakes[8] = 1;
|
||||||
|
unlocker_stakes[9] = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unlocker_role_change(uint256 _id, address _new_unlocker) external returns (bool){
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
require(_voronoi_count >= threshold);
|
||||||
|
unlocker_ids[_id] = _new_unlocker;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function pause() external returns (bool success) {
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(_voronoi_count >= threshold);
|
||||||
|
_paused = true;
|
||||||
|
return _paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unpause() external returns (bool success) {
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(_voronoi_count >= threshold);
|
||||||
|
_paused = false;
|
||||||
|
return _paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminChange(address newAdmin) external returns (address to) {
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(_voronoi_count >= threshold);
|
||||||
|
require(address(newAdmin) != address(0));
|
||||||
|
admin = newAdmin;
|
||||||
|
return newAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function totalSupply() external view returns (uint256) {
|
||||||
|
return totalSupply_;
|
||||||
|
}
|
||||||
|
|
||||||
|
function balanceOf(address _owner) external view returns (uint256 balance) {
|
||||||
|
return balances[_owner];
|
||||||
|
}
|
||||||
|
|
||||||
|
function transfer(address _to, uint256 _value) external returns (bool success) {
|
||||||
|
emit minor_impact_call(true);
|
||||||
|
require(_paused == false);
|
||||||
|
require(_value <= balances[msg.sender]);
|
||||||
|
balances[msg.sender] -= _value;
|
||||||
|
balances[_to] += _value;
|
||||||
|
emit Transfer(msg.sender, _to, _value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function transferFrom(address _from, address _to, uint256 _value) external returns (bool success) {
|
||||||
|
emit minor_impact_call(true);
|
||||||
|
require(_paused == false);
|
||||||
|
require(_value <= balances[_from]);
|
||||||
|
require(_value <= allowed[_from][msg.sender]);
|
||||||
|
balances[_from] -= _value;
|
||||||
|
allowed[_from][msg.sender] -= _value;
|
||||||
|
balances[_to] += _value;
|
||||||
|
emit Transfer(_from, _to, _value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function approve(address _spender, uint256 _value) external returns (bool success) {
|
||||||
|
emit minor_impact_call(true);
|
||||||
|
allowed[msg.sender][_spender] = _value;
|
||||||
|
emit Approval(msg.sender, _spender, _value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowance(address _owner, address _spender) external view returns (uint remaining) {
|
||||||
|
return allowed[_owner][_spender];
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminWithdraw() external returns (bool success) {
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(msg.sender == admin, "Not authorized");
|
||||||
|
require(_voronoi_count >= threshold);
|
||||||
|
payable(msg.sender).transfer(address(this).balance);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fallback() external payable {}
|
||||||
|
receive() external payable {}
|
||||||
|
}
|
|
@ -0,0 +1,310 @@
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// Example of Voronoi DAO in Solidity, by QRUCIAL OÜ
|
||||||
|
// Setup: One leader (could be CEO, Prime Minister, etc irl) and 10 voters (could be members of the board, etc).
|
||||||
|
// Code state: Beta
|
||||||
|
// Coder: Six
|
||||||
|
|
||||||
|
pragma solidity ^0.8.11;
|
||||||
|
|
||||||
|
contract VoronoiDAO {
|
||||||
|
|
||||||
|
event Transfer(address indexed _from, address indexed _to, uint256 _value);
|
||||||
|
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
|
||||||
|
event major_impact_call(bool value); // Event when a Major Impact Function is called
|
||||||
|
event minor_impact_call(bool value); // Event when a Minor Impact Function is called
|
||||||
|
event function_unlock(uint256 value); // Unlock event, when a function gets unlocked, unit256 -> func ID
|
||||||
|
|
||||||
|
mapping (uint256 => address) internal unlocker_ids; // Needs to be in sync with the unlocker_ids, max 10
|
||||||
|
mapping (uint256 => uint256) internal unlocker_stakes; // Address to threshold amount (single account can have multiple)
|
||||||
|
mapping (uint256 => uint256) internal voronoi_function_count; // Some functions need to be controlled separately
|
||||||
|
mapping (uint256 => address) internal nominee; // Possibilty to nominate. To get in, vouches are needed.
|
||||||
|
mapping (uint256 => uint256) internal nominee_vouch;
|
||||||
|
uint256 private nominee_position;
|
||||||
|
|
||||||
|
address private Leader;
|
||||||
|
uint256 private _voronoi_count;
|
||||||
|
uint256 private threshold;
|
||||||
|
uint256 private _voronoi_last_time;
|
||||||
|
|
||||||
|
bool private _paused;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
Leader = msg.sender; // The Leader is the one who starts the DAO! Can be modified by voting.
|
||||||
|
_paused = false;
|
||||||
|
_voronoi_count = 0;
|
||||||
|
threshold = 4;
|
||||||
|
_voronoi_last_time = block.timestamp;
|
||||||
|
unlocker_ids[0] = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
|
||||||
|
unlocker_ids[1] = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
|
||||||
|
unlocker_ids[2] = 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c;
|
||||||
|
unlocker_ids[3] = 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db;
|
||||||
|
unlocker_ids[4] = 0x617F2E2fD72FD9D5503197092aC168c91465E7f2;
|
||||||
|
unlocker_ids[5] = 0x1aE0EA34a72D944a8C7603FfB3eC30a6669E454C;
|
||||||
|
unlocker_ids[6] = 0x583031D1113aD414F02576BD6afaBfb302140225;
|
||||||
|
unlocker_ids[7] = 0x583031D1113aD414F02576BD6afaBfb302140225;
|
||||||
|
unlocker_ids[8] = 0x0A098Eda01Ce92ff4A4CCb7A4fFFb5A43EBC70DC;
|
||||||
|
unlocker_ids[9] = 0x0A098Eda01Ce92ff4A4CCb7A4fFFb5A43EBC70DC;
|
||||||
|
unlocker_stakes[0] = 1;
|
||||||
|
unlocker_stakes[1] = 1;
|
||||||
|
unlocker_stakes[2] = 1;
|
||||||
|
unlocker_stakes[3] = 1;
|
||||||
|
unlocker_stakes[4] = 1;
|
||||||
|
unlocker_stakes[5] = 1;
|
||||||
|
unlocker_stakes[6] = 1;
|
||||||
|
unlocker_stakes[7] = 1;
|
||||||
|
unlocker_stakes[8] = 1;
|
||||||
|
unlocker_stakes[9] = 1;
|
||||||
|
voronoi_function_count[0] = 0;
|
||||||
|
voronoi_function_count[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function voronoi_vote_up_main() external returns (bool success){
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
|
||||||
|
if (msg.sender == unlocker_ids[0]){
|
||||||
|
require(unlocker_stakes[0] == 1);
|
||||||
|
unlocker_stakes[0] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[1]) {
|
||||||
|
require(unlocker_stakes[1] == 1);
|
||||||
|
unlocker_stakes[1] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[2]) {
|
||||||
|
require(unlocker_stakes[2] == 1);
|
||||||
|
unlocker_stakes[2] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[3]) {
|
||||||
|
require(unlocker_stakes[3] == 1);
|
||||||
|
unlocker_stakes[3] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[4]) {
|
||||||
|
require(unlocker_stakes[4] == 1);
|
||||||
|
unlocker_stakes[4] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[5]) {
|
||||||
|
require(unlocker_stakes[5] == 1);
|
||||||
|
unlocker_stakes[5] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[6]) {
|
||||||
|
require(unlocker_stakes[6] == 1);
|
||||||
|
unlocker_stakes[6] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[7]) {
|
||||||
|
require(unlocker_stakes[7] == 1);
|
||||||
|
unlocker_stakes[7] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[8]) {
|
||||||
|
require(unlocker_stakes[8] == 1);
|
||||||
|
unlocker_stakes[8] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[9]) {
|
||||||
|
require(unlocker_stakes[9] == 1);
|
||||||
|
unlocker_stakes[9] = 0;
|
||||||
|
}
|
||||||
|
_voronoi_count = _voronoi_count + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function voronoi_vote_up_specific(uint256 _spec) external returns (bool success){
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
|
||||||
|
if (msg.sender == unlocker_ids[0]){
|
||||||
|
require(unlocker_stakes[0] == 1);
|
||||||
|
unlocker_stakes[0] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[1]) {
|
||||||
|
require(unlocker_stakes[1] == 1);
|
||||||
|
unlocker_stakes[1] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[2]) {
|
||||||
|
require(unlocker_stakes[2] == 1);
|
||||||
|
unlocker_stakes[2] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[3]) {
|
||||||
|
require(unlocker_stakes[3] == 1);
|
||||||
|
unlocker_stakes[3] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[4]) {
|
||||||
|
require(unlocker_stakes[4] == 1);
|
||||||
|
unlocker_stakes[4] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[5]) {
|
||||||
|
require(unlocker_stakes[5] == 1);
|
||||||
|
unlocker_stakes[5] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[6]) {
|
||||||
|
require(unlocker_stakes[6] == 1);
|
||||||
|
unlocker_stakes[6] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[7]) {
|
||||||
|
require(unlocker_stakes[7] == 1);
|
||||||
|
unlocker_stakes[7] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[8]) {
|
||||||
|
require(unlocker_stakes[8] == 1);
|
||||||
|
unlocker_stakes[8] = 0;
|
||||||
|
}
|
||||||
|
else if (msg.sender == unlocker_ids[9]) {
|
||||||
|
require(unlocker_stakes[9] == 1);
|
||||||
|
unlocker_stakes[9] = 0;
|
||||||
|
}
|
||||||
|
voronoi_function_count[_spec] = voronoi_function_count[_spec] + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function vcheck_state(uint256 _idToCheck) external view returns(uint256 success){
|
||||||
|
return unlocker_stakes[_idToCheck];
|
||||||
|
}
|
||||||
|
|
||||||
|
function vcheck_count() external view returns(uint256 success){
|
||||||
|
return _voronoi_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function v_reset() external returns (bool success){
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
require(block.timestamp >= _voronoi_last_time + 15 minutes); // You can only do it once every 15 mins to secure voting logic
|
||||||
|
_voronoi_last_time = block.timestamp;
|
||||||
|
_voronoi_count = 0;
|
||||||
|
voronoi_function_count[0] = 0;
|
||||||
|
voronoi_function_count[1] = 0;
|
||||||
|
unlocker_stakes[0] = 1;
|
||||||
|
unlocker_stakes[1] = 1;
|
||||||
|
unlocker_stakes[2] = 1;
|
||||||
|
unlocker_stakes[3] = 1;
|
||||||
|
unlocker_stakes[4] = 1;
|
||||||
|
unlocker_stakes[5] = 1;
|
||||||
|
unlocker_stakes[6] = 1;
|
||||||
|
unlocker_stakes[7] = 1;
|
||||||
|
unlocker_stakes[8] = 1;
|
||||||
|
unlocker_stakes[9] = 1;
|
||||||
|
nominee[0] = address(0);
|
||||||
|
nominee_vouch[0] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function voter_nominate(uint256 _position, address _new_addr) external returns (bool){
|
||||||
|
require(block.timestamp >= _voronoi_last_time + 15 minutes); // Nomination can happen only once per 15 mins.
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
nominee[0] = _new_addr;
|
||||||
|
nominee_position = _position;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function voter_role_change() external returns (bool){ // Change or remove addresses.
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(voronoi_function_count[0] >= threshold); // Needs to be specifically allowed!
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
unlocker_ids[nominee_position] = nominee[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function pause() external returns (bool success) {
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(_voronoi_count >= threshold);
|
||||||
|
_paused = true;
|
||||||
|
return _paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unpause() external returns (bool success) {
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(_voronoi_count >= threshold);
|
||||||
|
_paused = false;
|
||||||
|
return _paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
function LeaderChange(address newLeader) external returns (address to) {
|
||||||
|
require(msg.sender == unlocker_ids[0] ||
|
||||||
|
msg.sender == unlocker_ids[1] ||
|
||||||
|
msg.sender == unlocker_ids[2] ||
|
||||||
|
msg.sender == unlocker_ids[3] ||
|
||||||
|
msg.sender == unlocker_ids[4] ||
|
||||||
|
msg.sender == unlocker_ids[5] ||
|
||||||
|
msg.sender == unlocker_ids[6] ||
|
||||||
|
msg.sender == unlocker_ids[7] ||
|
||||||
|
msg.sender == unlocker_ids[8] ||
|
||||||
|
msg.sender == unlocker_ids[9]);
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(_voronoi_count >= threshold);
|
||||||
|
Leader = newLeader;
|
||||||
|
return newLeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function LeaderWithdraw() external returns (bool success) { // If the DAO decides, the Leader can withdraw all Coins.
|
||||||
|
require(msg.sender == Leader, "Not authorized");
|
||||||
|
emit major_impact_call(true);
|
||||||
|
require(voronoi_function_count[1] >= threshold); // Needs to be specifically allowed!
|
||||||
|
payable(msg.sender).transfer(address(this).balance);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fallback() external payable {}
|
||||||
|
receive() external payable {}
|
||||||
|
}
|
|
@ -1,77 +0,0 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Example of Voronoi Solidity solution, by QRUCIAL OÜ
|
|
||||||
// Coder: Six
|
|
||||||
pragma solidity ^0.8.10;
|
|
||||||
|
|
||||||
// DRAFT In this example, 4 parties (threshold = 4) out of 6 need to agree to execute the critical_impact() function
|
|
||||||
// Requirement: no single account should be able to call any Major Impact function.
|
|
||||||
|
|
||||||
contract Voronoi_Example {
|
|
||||||
|
|
||||||
mapping (address => uint256) internal unlockers; // Address to threshold amount (single account can have multiple)
|
|
||||||
mapping (uint256 => uint256) internal function_locks; // Function required to be unlocked
|
|
||||||
uint256 private threshold; // Threshold for unlock
|
|
||||||
|
|
||||||
event major_impact_call(bool value); // Event when a Major Impact Function is called
|
|
||||||
event minor_impact_call(bool value); // Event when a Minor Impact Function is called
|
|
||||||
event function_unlock(uint256 value); // Unlock event, when a function gets unlocked, unit256 -> func ID
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
threshold = 4; // An unlock happens when this threshold is reached or passed
|
|
||||||
unlockers[msg.sender] = 1; // Add starter unlocker addresses, in this example 6
|
|
||||||
unlockers[0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2] = 1;
|
|
||||||
unlockers[0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c] = 1;
|
|
||||||
unlockers[0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db] = 1;
|
|
||||||
unlockers[0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB] = 1;
|
|
||||||
unlockers[0x617F2E2fD72FD9D5503197092aC168c91465E7f2] = 1;
|
|
||||||
function_locks[0] = 0; // Locked function [0] - unlocker_role_add()
|
|
||||||
function_locks[1] = 0; // Locked function [1] - unlocker_role_remove()
|
|
||||||
function_locks[2] = 0; // Locked function [2] - critical_impact1()
|
|
||||||
function_locks[3] = 0; // Locked function [3] - critical_impact2()
|
|
||||||
}
|
|
||||||
|
|
||||||
function unlocker_role_add(address new_unlocker) external returns (bool){
|
|
||||||
emit major_impact_call(true);
|
|
||||||
require(unlockers[msg.sender] == 1);
|
|
||||||
require(function_locks[0] >= threshold);
|
|
||||||
unlockers[new_unlocker] = 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function unlocker_role_remove(address rem_unlocker) external returns (bool){
|
|
||||||
emit major_impact_call(true);
|
|
||||||
require(unlockers[msg.sender] == 1);
|
|
||||||
require(function_locks[1] >= threshold);
|
|
||||||
unlockers[rem_unlocker] = 0; // Alternative option to remove fully
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function unlock_voter(uint256 func_id) external returns (bool){
|
|
||||||
require(unlockers[msg.sender] == 1);
|
|
||||||
unlockers[msg.sender] = 0; // This could be improved, as now everyone can only vote once
|
|
||||||
function_locks[func_id] = function_locks[func_id] + 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Voronoi solidity is ready to use after this.
|
|
||||||
// You can add your ERC20/ERC115 or other code and use the Voronoi security functions
|
|
||||||
|
|
||||||
function critical_impact1() external returns (bool) {
|
|
||||||
emit major_impact_call(true);
|
|
||||||
require(function_locks[2] >= threshold);
|
|
||||||
function_locks[1] = 0; // Can be called only once and threshold is reset.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function critical_impact2() external returns (bool) {
|
|
||||||
emit major_impact_call(true);
|
|
||||||
require(function_locks[3] >= threshold);
|
|
||||||
function_locks[2] = 0; // Can be called only once and threshold is reset.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function minor_impact() external returns (bool) { // No unlock check, just execute
|
|
||||||
emit minor_impact_call(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue