update to latest solc, update to new instance model, democracy acl

This commit is contained in:
Ricardo Guilherme Schmidt 2019-02-14 10:41:11 -02:00
parent bd491164f6
commit 729f9d0e59
No known key found for this signature in database
GPG Key ID: BFB3F5C8ED618A94
17 changed files with 363 additions and 390 deletions

View File

@ -31,6 +31,17 @@ module.exports = {
"await MiniMeToken.methods.changeController(StatusRoot.address).send()",
"await StatusRoot.methods.setOpen(true).send()",
]
},
"DelegationView": {
"args": [ "0x0" ]
},
"DelegationInit": {
},
"DelegationFactory": {
"args": ["$DelegationView", "$DelegationInit", "0x0"]
},
"Democracy": {
"args": ["$MiniMeToken", "$DelegationFactory"]
}
}
},

View File

@ -1,28 +1,8 @@
pragma solidity >=0.5.0 <0.6.0;
/**
* @title Delegation
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH).
*/
contract Delegation {
event Delegate(address who, address to);
//default delegation proxy, being used when user didn't set any delegation at this level.
address public parentDelegation;
//snapshots of changes, allow delegation changes be done at any time without compromising vote results.
mapping (address => DelegateSet[]) public delegations;
struct DelegateSet {
uint128 fromBlock; //when this was updated
address to; //who recieved this delegaton
}
interface Delegation {
/**
* @notice Calls Constructor
*/
constructor(address _parentDelegation) public {
parentDelegation = _parentDelegation;
}
event Delegate(address who, address to);
/**
* @notice Changes the delegation of `msg.sender` to `_to`. if _to 0x00: delegate to self.
@ -30,36 +10,28 @@ contract Delegation {
* If once defined and want to delegate to parent proxy, set `_to` as parent address.
* @param _to To what address the caller address will delegate to.
*/
function delegate(address _to) external {
_updateDelegate(msg.sender, _to);
}
function delegate(address _to) external;
/**
* @notice Reads `_who` configured delegation in this level,
* or from parent level if `_who` never defined/defined to parent address.
* @param _who What address to lookup.
* @return The address `_who` choosen delegate to.
*/
*/
function delegatedTo(address _who)
public
external
view
returns (address)
{
return delegatedToAt(_who, block.number);
}
returns (address directDelegate);
/**
* @notice Reads the final delegate of `_who` at block number `_block`.
* @param _who Address to lookup.
* @return Final delegate address.
*/
function delegationOf(address _who)
public
external
view
returns(address)
{
return delegationOfAt(_who, block.number);
}
returns(address finalDelegate);
/**
* @notice Reads `_who` configured delegation at block number `_block` in this level,
@ -72,28 +44,10 @@ contract Delegation {
address _who,
uint _block
)
public
external
view
returns (address directDelegate)
{
DelegateSet[] storage checkpoints = delegations[_who];
//In case there is no registry
if (checkpoints.length == 0) {
if (parentDelegation != 0x0) {
return Delegation(parentDelegation).delegatedToAt(_who, _block);
} else {
return 0x0;
}
}
DelegateSet memory d = _getMemoryAt(checkpoints, _block);
// Case user set delegate to parentDelegation address
if (d.to == parentDelegation && d.to != 0x0) {
return Delegation(parentDelegation).delegatedToAt(_who, _block);
}
return d.to;
}
returns (address directDelegate);
/**
* @notice Reads the final delegate of `_who` at block number `_block`.
* @param _who Address to lookup.
@ -104,62 +58,8 @@ contract Delegation {
address _who,
uint _block
)
public
external
view
returns(address finalDelegate)
{
finalDelegate = delegatedToAt(_who, _block);
if (finalDelegate != 0x0) { //_who is delegating?
return delegationOfAt(finalDelegate, _block); //load the delegation of _who delegation
} else {
return _who; //reached the endpoint of delegation
}
}
returns(address finalDelegate);
/**
* @dev Changes the delegation of `_from` to `_to`. if _to 0x00: delegate to self.
* In case of having a parent proxy, if never defined, fall back to parent proxy.
* If once defined and want to delegate to parent proxy, set `_to` as parent address.
* @param _from Address delegating.
* @param _to Address delegated.
*/
function _updateDelegate(address _from, address _to) internal {
emit Delegate(_from, _to);
DelegateSet memory _newFrom; //allocate memory
DelegateSet[] storage fromHistory = delegations[_from];
//Add the new delegation
_newFrom.fromBlock = uint128(block.number);
_newFrom.to = _to; //delegate address
fromHistory.push(_newFrom); //register `from` delegation update;
}
/**
* @dev `_getDelegationAt` retrieves the delegation at a given block number.
* @param checkpoints The memory being queried.
* @param _block The block number to retrieve the value at.
* @return The delegation being queried.
*/
function _getMemoryAt(DelegateSet[] storage checkpoints, uint _block) internal view returns (DelegateSet d) {
// Case last checkpoint is the one;
if (_block >= checkpoints[checkpoints.length-1].fromBlock) {
d = checkpoints[checkpoints.length-1];
} else {
// Lookup in array;
uint min = 0;
uint max = checkpoints.length-1;
while (max > min) {
uint mid = (max + min + 1) / 2;
if (checkpoints[mid].fromBlock <= _block) {
min = mid;
} else {
max = mid-1;
}
}
d = checkpoints[min];
}
}
}

View File

@ -0,0 +1,126 @@
pragma solidity >=0.5.0 <0.6.0;
import "../deploy/InstanceAbstract.sol";
import "./Delegation.sol";
/**
* @title DelegationAbstract
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH).
*/
contract DelegationAbstract is InstanceAbstract, Delegation {
struct DelegateSet {
uint128 fromBlock; //when this was updated
address to; //who recieved this delegaton
}
//default delegation proxy, being used when user didn't set any delegation at this level.
address public parentDelegation;
//snapshots of changes, allow delegation changes be done at any time without compromising vote results.
mapping (address => DelegateSet[]) public delegations;
constructor() internal {
}
/**
* @dev Changes the delegation of `_from` to `_to`. if _to 0x00: delegate to self.
* In case of having a parent proxy, if never defined, fall back to parent proxy.
* If once defined and want to delegate to parent proxy, set `_to` as parent address.
* @param _from Address delegating.
* @param _to Address delegated.
*/
function updateDelegate(address _from, address _to) internal {
emit Delegate(_from, _to);
DelegateSet memory _newFrom; //allocate memory
DelegateSet[] storage fromHistory = delegations[_from];
//Add the new delegation
_newFrom.fromBlock = uint128(block.number);
_newFrom.to = _to; //delegate address
fromHistory.push(_newFrom); //register `from` delegation update;
}
/**
* @dev `_getDelegationAt` retrieves the delegation at a given block number.
* @param checkpoints The memory being queried.
* @param _block The block number to retrieve the value at.
* @return The delegation being queried.
*/
function getMemoryAt(DelegateSet[] storage checkpoints, uint _block) internal view returns (DelegateSet memory d) {
// Case last checkpoint is the one;
if (_block >= checkpoints[checkpoints.length-1].fromBlock) {
d = checkpoints[checkpoints.length-1];
} else {
// Lookup in array;
uint min = 0;
uint max = checkpoints.length-1;
while (max > min) {
uint mid = (max + min + 1) / 2;
if (checkpoints[mid].fromBlock <= _block) {
min = mid;
} else {
max = mid-1;
}
}
d = checkpoints[min];
}
}
/**
* @notice Reads `_who` configured delegation at block number `_block` in this level,
* or from parent level if `_who` never defined/defined to parent address.
* @param _who What address to lookup.
* @param _block Block number of what height in history.
* @return The address `_who` choosen delegate to.
*/
function findDelegatedToAt(
address _who,
uint _block
)
internal
view
returns (address directDelegate)
{
DelegateSet[] storage checkpoints = delegations[_who];
//In case there is no registry
if (checkpoints.length == 0) {
if (parentDelegation != address(0)) {
return Delegation(parentDelegation).delegatedToAt(_who, _block);
} else {
return address(0);
}
}
DelegateSet memory d = getMemoryAt(checkpoints, _block);
// Case user set delegate to parentDelegation address
if (d.to == parentDelegation && d.to != address(0x0)) {
return Delegation(parentDelegation).delegatedToAt(_who, _block);
}
return d.to;
}
/**
* @notice Reads the final delegate of `_who` at block number `_block`.
* @param _who Address to lookup.
* @param _block From what block.
* @return Final delegate address.
*/
function findDelegationOfAt(
address _who,
uint _block
)
internal
view
returns(address finalDelegate)
{
finalDelegate = findDelegatedToAt(_who, _block);
if (finalDelegate != address(0)) { //_who is delegating?
return findDelegationOfAt(finalDelegate, _block); //load the delegation of _who delegation
} else {
return _who; //reached the endpoint of delegation
}
}
}

View File

@ -1,11 +1,20 @@
pragma solidity >=0.5.0 <0.6.0;
import "../token/MiniMeTokenInterface.sol";
import "./DelegationAbstract.sol";
contract DelegationInterface {
/**
* @title DelegationBase
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Creates a delegation proxy killable model for cheap redeploy and upgradability.
*/
contract DelegationBase is DelegationAbstract {
event Delegate(address who, address to);
/**
* @notice Calls Constructor
*/
constructor(address _parentDelegation) public {
parentDelegation = _parentDelegation;
}
/**
* @notice Changes the delegation of `msg.sender` to `_to`. if _to 0x00: delegate to self.
@ -13,28 +22,36 @@ contract DelegationInterface {
* If once defined and want to delegate to parent proxy, set `_to` as parent address.
* @param _to To what address the caller address will delegate to.
*/
function delegate(address _to) external;
function delegate(address _to) external {
updateDelegate(msg.sender, _to);
}
/**
* @notice Reads `_who` configured delegation in this level,
* or from parent level if `_who` never defined/defined to parent address.
* @param _who What address to lookup.
* @return The address `_who` choosen delegate to.
*/
*/
function delegatedTo(address _who)
public
external
view
returns (address directDelegate);
returns (address)
{
return findDelegatedToAt(_who, block.number);
}
/**
* @notice Reads the final delegate of `_who` at block number `_block`.
* @param _who Address to lookup.
* @return Final delegate address.
*/
function delegationOf(address _who)
public
external
view
returns(address finalDelegate);
returns(address)
{
return findDelegationOfAt(_who, block.number);
}
/**
* @notice Reads `_who` configured delegation at block number `_block` in this level,
@ -47,10 +64,13 @@ contract DelegationInterface {
address _who,
uint _block
)
public
external
view
returns (address directDelegate);
returns (address directDelegate)
{
return findDelegatedToAt(_who, _block);
}
/**
* @notice Reads the final delegate of `_who` at block number `_block`.
* @param _who Address to lookup.
@ -61,8 +81,11 @@ contract DelegationInterface {
address _who,
uint _block
)
public
external
view
returns(address finalDelegate);
returns(address finalDelegate)
{
return findDelegationOfAt(_who, _block);
}
}

View File

@ -1,8 +1,6 @@
pragma solidity >=0.5.0 <0.6.0;
import "./DelegationInterface.sol";
import "./DelegationKernel.sol";
import "../deploy/Factory.sol";
import "../deploy/InstanceFactory.sol";
import "../deploy/Instance.sol";
/**
@ -10,20 +8,21 @@ import "../deploy/Instance.sol";
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Upgradable delegation proxy factory
*/
contract DelegationFactory is Factory {
contract DelegationFactory is InstanceFactory {
constructor()
Factory(new DelegationKernel())
public
constructor(InstanceAbstract _base, InstanceAbstract _init, InstanceAbstract _emergency)
InstanceFactory(_base, _init, _emergency)
public
{ }
function createDelegation(address _parent)
function createDelegation(
address
)
external
returns (DelegationInterface)
{
DelegationKernel instance = DelegationKernel(address(new Instance(latestKernel)));
instance.initializeDelegation(_parent);
return DelegationInterface(address(instance));
returns (InstanceAbstract instance)
{
instance = new Instance(base, prototypes[address(base)].init, msg.data);
emit InstanceCreated(instance);
}
}

View File

@ -0,0 +1,32 @@
pragma solidity >=0.5.0 <0.6.0;
import "./DelegationAbstract.sol";
/**
* @title DelegationInit
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract DelegationInit is DelegationAbstract {
/**
* @notice Constructor of the model - only knows about watchdog that can trigger upgrade
*/
constructor() public {
parentDelegation = address(-1); //avoids calling create delegation within the Init contract.
}
/**
* @notice Creates a new Delegation with `_parentDelegation` as default delegation.
*/
function createDelegation(address _parentDelegation) external {
require(parentDelegation == address(0), "Bad call"); //avoids control of Init contract
parentDelegation = _parentDelegation;
}
function delegate(address) external {}
function delegatedTo(address) external view returns (address) {}
function delegationOf(address) external view returns (address) {}
function delegatedToAt(address,uint) external view returns (address) {}
function delegationOfAt(address,uint) external view returns (address) {}
}

View File

@ -1,30 +0,0 @@
pragma solidity >=0.5.0 <0.6.0;
import "../deploy/InstanceStorage.sol";
import "./DelegationView.sol";
/**
* @title DelegationKernel
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Creates a delegation proxy killable model for cheap redeploy and upgradability.
*/
contract DelegationKernel is InstanceStorage, DelegationView {
bool private ready = false; //TODO: abstract initialized flag
/**
* @notice Constructor of the model - only knows about watchdog that can trigger upgrade
*/
constructor() DelegationView(0x0) public {
ready = true;
}
/**
* @notice Creates a new Delegation with `_parentDelegation` as default delegation.
*/
function initializeDelegation(address _parentDelegation) public {
require(!ready);
ready = true;
parentDelegation = _parentDelegation;
}
}

View File

@ -1,14 +1,14 @@
pragma solidity >=0.5.0 <0.6.0;
import "./Delegation.sol";
import "./DelegationBase.sol";
/**
* @title Delegation
* @title DelegationView
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Creates a delegation proxy layer for MiniMeTokenInterface.
* @dev Creates a delegation proxy layer for MiniMeToken.
*/
contract DelegationView is Delegation {
contract DelegationView is DelegationBase {
//storage of preprocessed view of FinalDelegate
mapping(bytes32 => FinalDelegate) public delegationView;
@ -18,7 +18,7 @@ contract DelegationView is Delegation {
bool found;
}
constructor(address _parentDelegation) Delegation(_parentDelegation) public {
constructor(address _parentDelegation) DelegationBase(_parentDelegation) public {
}
@ -28,20 +28,20 @@ contract DelegationView is Delegation {
* @param _block From what block.
* @return Final delegate address.
*/
function delegationOfAt(
function findDelegationOfAt(
address _who,
uint _block
)
public
internal
view
returns(address finalDelegate)
{
bytes32 searchIndex = keccak256(_who, _block);
bytes32 searchIndex = keccak256(abi.encodePacked(_who, _block));
FinalDelegate memory search = delegationView[searchIndex];
if (search.found) {
return search.delegate;
} else {
return super.delegationOfAt(_who, _block);
return super.findDelegationOfAt(_who, _block);
}
}
@ -61,14 +61,14 @@ contract DelegationView is Delegation {
external
returns (bool)
{
bytes32 searchIndex = keccak256(_delegator,_block);
bytes32 searchIndex = keccak256(abi.encodePacked(_delegator,_block));
FinalDelegate memory search = delegationView[searchIndex];
require(!search.found);
for (uint i = 0; i < loopLimit; i++) {
if (search.delegate == address(0)) {
search.delegate = _delegator;
}
address delegateFrom = delegatedToAt(search.delegate, _block);
address delegateFrom = findDelegatedToAt(search.delegate, _block);
if (delegateFrom == address(0)) {
// search.delegate demonsted this address didnt delegated,
search.found = true; // so its the final delegate
@ -100,11 +100,11 @@ contract DelegationView is Delegation {
returns (address lastDelegate, bool found)
{
require(_block > block.number); //cannot renderize current state view ?
bytes32 searchIndex = keccak256(_delegator, _block);
bytes32 searchIndex = keccak256(abi.encodePacked(_delegator, _block));
FinalDelegate memory search = delegationView[searchIndex];
if (!search.found) {
if (search.delegate == address(0)) {
lastDelegate = delegatedToAt(_delegator, _block);
lastDelegate = findDelegatedToAt(_delegator, _block);
if (lastDelegate == address(0)) {
//`_delegator` FinalDelegate is itself
lastDelegate = _delegator;

View File

@ -1,6 +1,6 @@
pragma solidity >=0.5.0 <0.6.0;
import "../token/MiniMeTokenInterface.sol";
import "../token/MiniMeToken.sol";
import "./DelegationFactory.sol";
import "./TrustNetwork.sol";
import "./ProposalCuration.sol";
@ -9,46 +9,31 @@ import "./ProposalManager.sol";
contract Democracy {
MiniMeTokenInterface public token;
MiniMeToken public token;
TrustNetwork public trustNet;
ProposalManager public proposalManager;
mapping (bytes32 => Allowance) topicAllowance;
mapping (bytes32 => mapping (address => mapping (bytes32 => bool))) allowance;
mapping (uint256 => bool) executedProposals;
struct Allowance {
mapping(address => bool) anyCall;
mapping(bytes32 => bool) calls;
modifier selfOnly {
require(msg.sender == address(this), "Unauthorized");
_;
}
constructor(MiniMeTokenInterface _token, DelegationFactory _DelegationFactory) public {
constructor(MiniMeToken _token, DelegationFactory _DelegationFactory) public {
token = _token;
trustNet = new TrustNetwork(_DelegationFactory);
proposalManager = new ProposalCuration(_token, trustNet).proposalManager();
}
function allowTopicSpecific(bytes32 _topic, address _destination, bytes4 _allowedCall, bool allowance)
external
{
require(msg.sender == address(this));
topicAllowance[_topic].calls[keccak256(_destination, _allowedCall)] = allowance;
}
function allowTopicAnyCall(bytes32 _topic, address _destination, bool allowance)
external
{
require(msg.sender == address(this));
topicAllowance[_topic].anyCall[_destination] = allowance;
}
function executeProposal(
uint256 _proposalId,
address _destination,
uint _value,
bytes _data
bytes calldata _data
)
external
returns (bool success)
returns (bool success, bytes memory r)
{
require(!executedProposals[_proposalId]);
executedProposals[_proposalId] = true;
@ -60,27 +45,64 @@ contract Democracy {
require(approved);
require(
txHash == keccak256(
_destination,
_value,
_data
abi.encodePacked(
_destination,
_data
)
)
);
if(topic != 0x0) { //if not root topic
Allowance storage allowed = topicAllowance[topic];
if(!allowed.anyCall[_destination]){ //if topic not allowed any call to destination
bytes memory data = _data;
bytes4 calling;
assembly {
calling := mload(add(data, 4))
}
delete data;
require(allowed.calls[keccak256(_destination, calling)]); //require call allowance
if(topic != bytes32(0)) { //if not root topic
bytes memory data = _data;
bytes4 sig;
assembly {
sig := mload(add(data, 4))
}
delete sig;
require(isTopicAllowed(topic, _destination, sig)); //require call allowance
}
//execute the call
return _destination.call.value(_value)(_data);
(success, r) = _destination.call(_data);
}
function setTopicAllowance(bytes32 _topic, address _destination, bytes4 _callSig, bool _allowed) external selfOnly {
require(_topic != bytes32(0), "Cannot change root topic");
allowance[_topic][_destination][_callSig] = _allowed;
}
function setProposalManager(ProposalManager _proposalManager) external selfOnly {
require(address(_proposalManager) != address(0), "Bad call");
proposalManager = _proposalManager;
}
function setTrustNetwork(TrustNetwork _trustNet) external selfOnly {
require(address(_trustNet) != address(0), "Bad call");
trustNet = _trustNet;
}
function setToken(MiniMeToken _token) external selfOnly {
require(address(_token) != address(0), "Bad call");
token = _token;
}
function isTopicAllowed(
bytes32 topic,
address destinAddr,
bytes4 calledSig
)
public
view
returns (bool)
{
return allowance[topic][destinAddr][calledSig]
|| allowance[topic][destinAddr][bytes4(0)]
|| allowance[topic][address(0)][calledSig]
|| allowance[topic][address(0)][bytes4(0)]
|| allowance[topic][destinAddr][calledSig]
|| allowance[topic][destinAddr][bytes4(0)]
|| allowance[topic][address(0)][calledSig]
|| allowance[topic][address(0)][bytes4(0)];
}
}

View File

@ -1,7 +1,7 @@
pragma solidity >=0.5.0 <0.6.0;
import "../common/Controlled.sol";
import "../token/MiniMeTokenInterface.sol";
import "../token/MiniMeToken.sol";
import "./ProposalManager.sol";
contract ProposalCuration is Controlled {
@ -15,7 +15,7 @@ contract ProposalCuration is Controlled {
ProposalManager public proposalManager;
uint256 public approvalTimeLimit;
MiniMeTokenInterface token;
MiniMeToken token;
mapping (address => SubmitPrice) submitAllowances;
@ -34,7 +34,7 @@ contract ProposalCuration is Controlled {
}
constructor(
MiniMeTokenInterface _token,
MiniMeToken _token,
TrustNetworkInterface _trustNet
)
public
@ -47,8 +47,8 @@ contract ProposalCuration is Controlled {
bytes32 _topic,
address _to,
uint256 _value,
bytes _data,
bytes _description
bytes calldata _data,
bytes calldata _description
)
external
returns (uint256 proposalId)
@ -56,7 +56,7 @@ contract ProposalCuration is Controlled {
uint256 submitPrice = getSubmitPrice(msg.sender);
require(token.allowance(msg.sender, address(this)) >= submitPrice);
require(token.transferFrom(msg.sender, address(this), submitPrice));
proposalId = proposalManager.addProposal(_topic,keccak256(_to,_value,_data));
proposalId = proposalManager.addProposal(_topic,keccak256(abi.encodePacked(_to,_value,_data)));
proposals[proposalId] = ProposalData(
msg.sender,
_to,

View File

@ -2,8 +2,8 @@ pragma solidity >=0.5.0 <0.6.0;
import "../common/Controlled.sol";
import "../common/MessageSigned.sol";
import "../token/MiniMeTokenInterface.sol";
import "./DelegationInterface.sol";
import "../token/MiniMeToken.sol";
import "./Delegation.sol";
import "./TrustNetworkInterface.sol";
/**
@ -15,7 +15,7 @@ contract ProposalManager is Controlled, MessageSigned {
event ProposalSet(bytes32 indexed topic, uint256 proposalId, bytes32 txHash);
event ProposalResult(uint256 proposalId, uint8 finalResult);
MiniMeTokenInterface public token;
MiniMeToken public token;
TrustNetworkInterface public trustNet;
uint256 public tabulationBlockDelay;
Proposal[] public proposals;
@ -43,7 +43,7 @@ contract ProposalManager is Controlled, MessageSigned {
}
constructor(
MiniMeTokenInterface _token,
MiniMeToken _token,
TrustNetworkInterface _trustNet
)
public
@ -91,8 +91,8 @@ contract ProposalManager is Controlled, MessageSigned {
}
function tabulateVote(uint _proposalId, Vote _vote, uint256 _position, bytes32[] _proof, bytes _signature)
public
function tabulateVote(uint _proposalId, Vote _vote, uint256 _position, bytes32[] calldata _proof, bytes calldata _signature)
external
{
Proposal storage proposal = proposals[_proposalId];
require(block.number > proposal.voteBlockEnd, "Voting running");

View File

@ -2,7 +2,7 @@ pragma solidity >=0.5.0 <0.6.0;
import "../common/Controlled.sol";
import "./TrustNetworkInterface.sol";
import "./DelegationInterface.sol";
import "./Delegation.sol";
import "./DelegationFactory.sol";
@ -17,30 +17,30 @@ contract TrustNetwork is TrustNetworkInterface, Controlled {
DelegationFactory delegationFactory;
struct Topic {
DelegationInterface voteDelegation;
DelegationInterface vetoDelegation;
Delegation voteDelegation;
Delegation vetoDelegation;
}
constructor(address _delegationFactory) public {
delegationFactory = DelegationFactory(_delegationFactory);
topics[0x0] = newTopic(0x0, 0x0);
constructor(DelegationFactory _delegationFactory) public {
delegationFactory = _delegationFactory;
topics[bytes32(0)] = newTopic(address(0), address(0));
}
function addTopic(bytes32 topicId, bytes32 parentTopic) public onlyController {
Topic memory parent = topics[parentTopic];
address vote = address(parent.voteDelegation);
address veto = address(parent.vetoDelegation);
require(vote != 0x0);
require(veto != 0x0);
require(vote != address(0));
require(veto != address(0));
Topic storage topic = topics[topicId];
require(address(topic.voteDelegation) == 0x0);
require(address(topic.vetoDelegation) == 0x0);
require(address(topic.voteDelegation) == address(0));
require(address(topic.vetoDelegation) == address(0));
topics[topicId] = newTopic(vote, veto);
}
function getTopic(bytes32 _topicId) public view returns (DelegationInterface vote, DelegationInterface veto) {
function getTopic(bytes32 _topicId) public view returns (Delegation vote, Delegation veto) {
Topic memory topic = topics[_topicId];
vote = topic.voteDelegation;
veto = topic.vetoDelegation;
@ -51,7 +51,7 @@ contract TrustNetwork is TrustNetworkInterface, Controlled {
)
public
view
returns (DelegationInterface voteDelegation)
returns (Delegation voteDelegation)
{
return topics[_topicId].voteDelegation;
}
@ -61,16 +61,16 @@ contract TrustNetwork is TrustNetworkInterface, Controlled {
)
public
view
returns (DelegationInterface vetoDelegation)
returns (Delegation vetoDelegation)
{
return topics[_topicId].vetoDelegation;
}
function newTopic(address _vote, address _veto) internal returns (Topic topic) {
function newTopic(address _vote, address _veto) internal returns (Topic memory topic) {
topic = Topic ({
voteDelegation: delegationFactory.createDelegation(_vote),
vetoDelegation: delegationFactory.createDelegation(_veto)
voteDelegation: Delegation(address(delegationFactory.createDelegation(_vote))),
vetoDelegation: Delegation(address(delegationFactory.createDelegation(_veto)))
});
}

View File

@ -1,11 +1,11 @@
pragma solidity >=0.5.0 <0.6.0;
import "./DelegationInterface.sol";
import "./Delegation.sol";
contract TrustNetworkInterface {
function addTopic(bytes32 topicId, bytes32 parentTopic) public;
function getTopic(bytes32 _topicId) public view returns (DelegationInterface vote, DelegationInterface veto);
function getVoteDelegation(bytes32 _topicId) public view returns (DelegationInterface voteDelegation);
function getVetoDelegation(bytes32 _topicId) public view returns (DelegationInterface vetoDelegation);
function getTopic(bytes32 _topicId) public view returns (Delegation vote, Delegation veto);
function getVoteDelegation(bytes32 _topicId) public view returns (Delegation voteDelegation);
function getVetoDelegation(bytes32 _topicId) public view returns (Delegation vetoDelegation);
}

View File

@ -43,6 +43,7 @@ contract TestStatusNetwork is StatusNetwork {
function _generateTokens(address _who, uint _amount) private {
require(msg.sender == owner || open, "Test Mint Disabled");
address statusNetwork = snt.controller();
if(statusNetwork == address(this)){
snt.generateTokens(_who, _amount);
} else {

View File

@ -1,108 +0,0 @@
pragma solidity ^0.4.23;
import "./ERC20Token.sol";
contract MiniMeTokenInterface is ERC20Token {
/**
* @notice `msg.sender` approves `_spender` to send `_amount` tokens on
* its behalf, and then a function is triggered in the contract that is
* being approved, `_spender`. This allows users to use their tokens to
* interact with contracts in one function call instead of two
* @param _spender The address of the contract able to transfer the tokens
* @param _amount The amount of tokens to be approved for transfer
* @return True if the function call was successful
*/
function approveAndCall(
address _spender,
uint256 _amount,
bytes _extraData
)
external
returns (bool success);
/**
* @notice Creates a new clone token with the initial distribution being
* this token at `_snapshotBlock`
* @param _cloneTokenName Name of the clone token
* @param _cloneDecimalUnits Number of decimals of the smallest unit
* @param _cloneTokenSymbol Symbol of the clone token
* @param _snapshotBlock Block when the distribution of the parent token is
* copied to set the initial distribution of the new clone token;
* if the block is zero than the actual block, the current block is used
* @param _transfersEnabled True if transfers are allowed in the clone
* @return The address of the new MiniMeToken Contract
*/
function createCloneToken(
string _cloneTokenName,
uint8 _cloneDecimalUnits,
string _cloneTokenSymbol,
uint _snapshotBlock,
bool _transfersEnabled
)
public
returns(address);
/**
* @notice Generates `_amount` tokens that are assigned to `_owner`
* @param _owner The address that will be assigned the new tokens
* @param _amount The quantity of tokens generated
* @return True if the tokens are generated correctly
*/
function generateTokens(
address _owner,
uint _amount
)
public
returns (bool);
/**
* @notice Burns `_amount` tokens from `_owner`
* @param _owner The address that will lose the tokens
* @param _amount The quantity of tokens to burn
* @return True if the tokens are burned correctly
*/
function destroyTokens(
address _owner,
uint _amount
)
public
returns (bool);
/**
* @notice Enables token holders to transfer their tokens freely if true
* @param _transfersEnabled True if transfers are allowed in the clone
*/
function enableTransfers(bool _transfersEnabled) public;
/**
* @notice This method can be used by the controller to extract mistakenly
* sent tokens to this contract.
* @param _token The address of the token contract that you want to recover
* set to 0 in case you want to extract ether.
*/
function claimTokens(address _token) public;
/**
* @dev Queries the balance of `_owner` at a specific `_blockNumber`
* @param _owner The address from which the balance will be retrieved
* @param _blockNumber The block number when the balance is queried
* @return The balance at `_blockNumber`
*/
function balanceOfAt(
address _owner,
uint _blockNumber
)
public
constant
returns (uint);
/**
* @notice Total amount of tokens at a specific `_blockNumber`.
* @param _blockNumber The block number when the totalSupply is queried
* @return The total amount of tokens at `_blockNumber`
*/
function totalSupplyAt(uint _blockNumber) public view returns(uint);
}

View File

@ -84,11 +84,7 @@ contract StandardToken is ERC20Token {
{
if (balances[_from] >= _value && _value > 0) {
balances[_from] -= _value;
if(_to == address(0)) {
supply -= _value;
} else {
balances[_to] += _value;
}
balances[_to] += _value;
emit Transfer(_from, _to, _value);
return true;
} else {

View File

@ -1,23 +1,24 @@
const utils = require("../utils/testUtils")
const Delegation = require('Embark/contracts/Delegation');
const DelegationView = require('Embark/contracts/DelegationView');
const ChildDelegation = require('Embark/contracts/ChildDelegation');
config({
contracts: {
"Delegation": {
"args": [ 0 ]
"DelegationView": {
"args": [ "0x0" ]
},
"ChildDelegation": {
"instanceOf": "Delegation",
"instanceOf": "DelegationView",
"args": [
"$Delegation"
"$DelegationView"
]
}
}
});
contract("Delegation", function() {
contract("DelegationView", function() {
this.timeout(0);
var accounts;
@ -30,41 +31,41 @@ contract("Delegation", function() {
it("starts with no delegate", async function () {
let result = await Delegation.methods.delegatedTo(accounts[0]).call()
let result = await DelegationView.methods.delegatedTo(accounts[0]).call()
assert.equal(result, utils.zeroAddress)
})
it("starts with delegation to self", async function () {
result = await Delegation.methods.delegationOf(accounts[0]).call()
result = await DelegationView.methods.delegationOf(accounts[0]).call()
assert.equal(result, accounts[0])
})
it("a0 delegate to a1", async function () {
result = await Delegation.methods.delegate(accounts[1]).send({from: accounts[0]})
result = await DelegationView.methods.delegate(accounts[1]).send({from: accounts[0]})
const delegateArgs = result.events.Delegate.returnValues;
assert.equal(delegateArgs.who, accounts[0])
assert.equal(delegateArgs.to, accounts[1])
result = await Delegation.methods.delegatedTo(accounts[0]).call()
result = await DelegationView.methods.delegatedTo(accounts[0]).call()
assert.equal(result, accounts[1])
result = await Delegation.methods.delegationOf(accounts[0]).call()
result = await DelegationView.methods.delegationOf(accounts[0]).call()
assert.equal(result, accounts[1])
})
it("a1 delegate to a2", async function () {
result = await Delegation.methods.delegate(accounts[2]).send({from: accounts[1]})
result = await DelegationView.methods.delegate(accounts[2]).send({from: accounts[1]})
const delegateArgs = result.events.Delegate.returnValues;
assert.equal(delegateArgs.who, accounts[1])
assert.equal(delegateArgs.to, accounts[2])
result = await Delegation.methods.delegatedTo(accounts[1]).call()
result = await DelegationView.methods.delegatedTo(accounts[1]).call()
assert.equal(result, accounts[2])
result = await Delegation.methods.delegationOf(accounts[0]).call()
result = await DelegationView.methods.delegationOf(accounts[0]).call()
assert.equal(result, accounts[2])
result = await Delegation.methods.delegationOf(accounts[1]).call()
result = await DelegationView.methods.delegationOf(accounts[1]).call()
assert.equal(result, accounts[2])
@ -72,20 +73,20 @@ contract("Delegation", function() {
it("a2 delegate to a3", async function () {
result = await Delegation.methods.delegate(accounts[3]).send({from: accounts[2]})
result = await DelegationView.methods.delegate(accounts[3]).send({from: accounts[2]})
const delegateArgs = result.events.Delegate.returnValues;
assert.equal(delegateArgs.who, accounts[2])
assert.equal(delegateArgs.to, accounts[3])
result = await Delegation.methods.delegatedTo(accounts[2]).call()
result = await DelegationView.methods.delegatedTo(accounts[2]).call()
assert.equal(result, accounts[3])
result = await Delegation.methods.delegationOf(accounts[0]).call()
result = await DelegationView.methods.delegationOf(accounts[0]).call()
assert.equal(result, accounts[3])
result = await Delegation.methods.delegationOf(accounts[1]).call()
result = await DelegationView.methods.delegationOf(accounts[1]).call()
assert.equal(result, accounts[3])
result = await Delegation.methods.delegationOf(accounts[2]).call()
result = await DelegationView.methods.delegationOf(accounts[2]).call()
assert.equal(result, accounts[3])