Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 5 from a total of 5 transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
GlobalConstraintRegistrar
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2018-08-28
*/
pragma solidity ^0.4.24;
// File: openzeppelin-solidity/contracts/ownership/Ownable.sol
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipRenounced(address indexed previousOwner);
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
* @notice Renouncing to ownership will leave the contract without an owner.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipRenounced(owner);
owner = address(0);
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function transferOwnership(address _newOwner) public onlyOwner {
_transferOwnership(_newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function _transferOwnership(address _newOwner) internal {
require(_newOwner != address(0));
emit OwnershipTransferred(owner, _newOwner);
owner = _newOwner;
}
}
// File: openzeppelin-solidity/contracts/math/SafeMath.sol
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
// Gas optimization: this is cheaper than asserting 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
// uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return a / b;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
}
// File: contracts/controller/Reputation.sol
/**
* @title Reputation system
* @dev A DAO has Reputation System which allows peers to rate other peers in order to build trust .
* A reputation is use to assign influence measure to a DAO'S peers.
* Reputation is similar to regular tokens but with one crucial difference: It is non-transferable.
* The Reputation contract maintain a map of address to reputation value.
* It provides an onlyOwner functions to mint and burn reputation _to (or _from) a specific address.
*/
contract Reputation is Ownable {
using SafeMath for uint;
mapping (address => uint256) public balances;
uint256 public totalSupply;
uint public decimals = 18;
// Event indicating minting of reputation to an address.
event Mint(address indexed _to, uint256 _amount);
// Event indicating burning of reputation for an address.
event Burn(address indexed _from, uint256 _amount);
/**
* @dev return the reputation amount of a given owner
* @param _owner an address of the owner which we want to get his reputation
*/
function reputationOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
/**
* @dev Generates `_amount` of reputation that are assigned to `_to`
* @param _to The address that will be assigned the new reputation
* @param _amount The quantity of reputation to be generated
* @return True if the reputation are generated correctly
*/
function mint(address _to, uint _amount)
public
onlyOwner
returns (bool)
{
totalSupply = totalSupply.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Mint(_to, _amount);
return true;
}
/**
* @dev Burns `_amount` of reputation from `_from`
* if _amount tokens to burn > balances[_from] the balance of _from will turn to zero.
* @param _from The address that will lose the reputation
* @param _amount The quantity of reputation to burn
* @return True if the reputation are burned correctly
*/
function burn(address _from, uint _amount)
public
onlyOwner
returns (bool)
{
uint amountMinted = _amount;
if (balances[_from] < _amount) {
amountMinted = balances[_from];
}
totalSupply = totalSupply.sub(amountMinted);
balances[_from] = balances[_from].sub(amountMinted);
emit Burn(_from, amountMinted);
return true;
}
}
// File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol
/**
* @title ERC20Basic
* @dev Simpler version of ERC20 interface
* See https://github.com/ethereum/EIPs/issues/179
*/
contract ERC20Basic {
function totalSupply() public view returns (uint256);
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
// File: openzeppelin-solidity/contracts/token/ERC20/BasicToken.sol
/**
* @title Basic token
* @dev Basic version of StandardToken, with no allowances.
*/
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
mapping(address => uint256) balances;
uint256 totalSupply_;
/**
* @dev Total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
/**
* @dev Transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner];
}
}
// File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender)
public view returns (uint256);
function transferFrom(address from, address to, uint256 value)
public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
// File: openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol
/**
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* https://github.com/ethereum/EIPs/issues/20
* Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) internal allowed;
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(
address _from,
address _to,
uint256 _value
)
public
returns (bool)
{
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(
address _owner,
address _spender
)
public
view
returns (uint256)
{
return allowed[_owner][_spender];
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _addedValue The amount of tokens to increase the allowance by.
*/
function increaseApproval(
address _spender,
uint256 _addedValue
)
public
returns (bool)
{
allowed[msg.sender][_spender] = (
allowed[msg.sender][_spender].add(_addedValue));
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseApproval(
address _spender,
uint256 _subtractedValue
)
public
returns (bool)
{
uint256 oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}
// File: openzeppelin-solidity/contracts/token/ERC20/MintableToken.sol
/**
* @title Mintable token
* @dev Simple ERC20 Token example, with mintable token creation
* Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
*/
contract MintableToken is StandardToken, Ownable {
event Mint(address indexed to, uint256 amount);
event MintFinished();
bool public mintingFinished = false;
modifier canMint() {
require(!mintingFinished);
_;
}
modifier hasMintPermission() {
require(msg.sender == owner);
_;
}
/**
* @dev Function to mint tokens
* @param _to The address that will receive the minted tokens.
* @param _amount The amount of tokens to mint.
* @return A boolean that indicates if the operation was successful.
*/
function mint(
address _to,
uint256 _amount
)
hasMintPermission
canMint
public
returns (bool)
{
totalSupply_ = totalSupply_.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Mint(_to, _amount);
emit Transfer(address(0), _to, _amount);
return true;
}
/**
* @dev Function to stop minting new tokens.
* @return True if the operation was successful.
*/
function finishMinting() onlyOwner canMint public returns (bool) {
mintingFinished = true;
emit MintFinished();
return true;
}
}
// File: openzeppelin-solidity/contracts/token/ERC20/BurnableToken.sol
/**
* @title Burnable Token
* @dev Token that can be irreversibly burned (destroyed).
*/
contract BurnableToken is BasicToken {
event Burn(address indexed burner, uint256 value);
/**
* @dev Burns a specific amount of tokens.
* @param _value The amount of token to be burned.
*/
function burn(uint256 _value) public {
_burn(msg.sender, _value);
}
function _burn(address _who, uint256 _value) internal {
require(_value <= balances[_who]);
// no need to require value <= totalSupply, since that would imply the
// sender's balance is greater than the totalSupply, which *should* be an assertion failure
balances[_who] = balances[_who].sub(_value);
totalSupply_ = totalSupply_.sub(_value);
emit Burn(_who, _value);
emit Transfer(_who, address(0), _value);
}
}
// File: contracts/token/ERC827/ERC827.sol
/**
* @title ERC827 interface, an extension of ERC20 token standard
*
* @dev Interface of a ERC827 token, following the ERC20 standard with extra
* methods to transfer value and data and execute calls in transfers and
* approvals.
*/
contract ERC827 is ERC20 {
function approveAndCall(address _spender,uint256 _value,bytes _data) public payable returns(bool);
function transferAndCall(address _to,uint256 _value,bytes _data) public payable returns(bool);
function transferFromAndCall(address _from,address _to,uint256 _value,bytes _data) public payable returns(bool);
}
// File: contracts/token/ERC827/ERC827Token.sol
/* solium-disable security/no-low-level-calls */
pragma solidity ^0.4.24;
/**
* @title ERC827, an extension of ERC20 token standard
*
* @dev Implementation the ERC827, following the ERC20 standard with extra
* methods to transfer value and data and execute calls in transfers and
* approvals. Uses OpenZeppelin StandardToken.
*/
contract ERC827Token is ERC827, StandardToken {
/**
* @dev Addition to ERC20 token methods. It allows to
* approve the transfer of value and execute a call with the sent data.
* Beware that changing an allowance with this method brings the risk that
* someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race condition
* is to first reduce the spender's allowance to 0 and set the desired value
* afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address that will spend the funds.
* @param _value The amount of tokens to be spent.
* @param _data ABI-encoded contract call to call `_spender` address.
* @return true if the call function was executed successfully
*/
function approveAndCall(
address _spender,
uint256 _value,
bytes _data
)
public
payable
returns (bool)
{
require(_spender != address(this));
super.approve(_spender, _value);
// solium-disable-next-line security/no-call-value
require(_spender.call.value(msg.value)(_data));
return true;
}
/**
* @dev Addition to ERC20 token methods. Transfer tokens to a specified
* address and execute a call with the sent data on the same transaction
* @param _to address The address which you want to transfer to
* @param _value uint256 the amout of tokens to be transfered
* @param _data ABI-encoded contract call to call `_to` address.
* @return true if the call function was executed successfully
*/
function transferAndCall(
address _to,
uint256 _value,
bytes _data
)
public
payable
returns (bool)
{
require(_to != address(this));
super.transfer(_to, _value);
// solium-disable-next-line security/no-call-value
require(_to.call.value(msg.value)(_data));
return true;
}
/**
* @dev Addition to ERC20 token methods. Transfer tokens from one address to
* another and make a contract call on the same transaction
* @param _from The address which you want to send tokens from
* @param _to The address which you want to transfer to
* @param _value The amout of tokens to be transferred
* @param _data ABI-encoded contract call to call `_to` address.
* @return true if the call function was executed successfully
*/
function transferFromAndCall(
address _from,
address _to,
uint256 _value,
bytes _data
)
public payable returns (bool)
{
require(_to != address(this));
super.transferFrom(_from, _to, _value);
// solium-disable-next-line security/no-call-value
require(_to.call.value(msg.value)(_data));
return true;
}
/**
* @dev Addition to StandardToken methods. Increase the amount of tokens that
* an owner allowed to a spender and execute a call with the sent data.
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _addedValue The amount of tokens to increase the allowance by.
* @param _data ABI-encoded contract call to call `_spender` address.
*/
function increaseApprovalAndCall(
address _spender,
uint _addedValue,
bytes _data
)
public
payable
returns (bool)
{
require(_spender != address(this));
super.increaseApproval(_spender, _addedValue);
// solium-disable-next-line security/no-call-value
require(_spender.call.value(msg.value)(_data));
return true;
}
/**
* @dev Addition to StandardToken methods. Decrease the amount of tokens that
* an owner allowed to a spender and execute a call with the sent data.
* approve should be called when allowed[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _subtractedValue The amount of tokens to decrease the allowance by.
* @param _data ABI-encoded contract call to call `_spender` address.
*/
function decreaseApprovalAndCall(
address _spender,
uint _subtractedValue,
bytes _data
)
public
payable
returns (bool)
{
require(_spender != address(this));
super.decreaseApproval(_spender, _subtractedValue);
// solium-disable-next-line security/no-call-value
require(_spender.call.value(msg.value)(_data));
return true;
}
}
// File: contracts/controller/DAOToken.sol
/**
* @title DAOToken, base on zeppelin contract.
* @dev ERC20 compatible token. It is a mintable, destructible, burnable token.
*/
contract DAOToken is ERC827Token,MintableToken,BurnableToken {
string public name;
string public symbol;
// solium-disable-next-line uppercase
uint8 public constant decimals = 18;
uint public cap;
/**
* @dev Constructor
* @param _name - token name
* @param _symbol - token symbol
* @param _cap - token cap - 0 value means no cap
*/
constructor(string _name, string _symbol,uint _cap) public {
name = _name;
symbol = _symbol;
cap = _cap;
}
/**
* @dev Function to mint tokens
* @param _to The address that will receive the minted tokens.
* @param _amount The amount of tokens to mint.
* @return A boolean that indicates if the operation was successful.
*/
function mint(address _to, uint256 _amount) public onlyOwner canMint returns (bool) {
if (cap > 0)
require(totalSupply_.add(_amount) <= cap);
return super.mint(_to, _amount);
}
}
// File: contracts/controller/Avatar.sol
/**
* @title An Avatar holds tokens, reputation and ether for a controller
*/
contract Avatar is Ownable {
bytes32 public orgName;
DAOToken public nativeToken;
Reputation public nativeReputation;
event GenericAction(address indexed _action, bytes32[] _params);
event SendEther(uint _amountInWei, address indexed _to);
event ExternalTokenTransfer(address indexed _externalToken, address indexed _to, uint _value);
event ExternalTokenTransferFrom(address indexed _externalToken, address _from, address _to, uint _value);
event ExternalTokenIncreaseApproval(StandardToken indexed _externalToken, address _spender, uint _addedValue);
event ExternalTokenDecreaseApproval(StandardToken indexed _externalToken, address _spender, uint _subtractedValue);
event ReceiveEther(address indexed _sender, uint _value);
/**
* @dev the constructor takes organization name, native token and reputation system
and creates an avatar for a controller
*/
constructor(bytes32 _orgName, DAOToken _nativeToken, Reputation _nativeReputation) public {
orgName = _orgName;
nativeToken = _nativeToken;
nativeReputation = _nativeReputation;
}
/**
* @dev enables an avatar to receive ethers
*/
function() public payable {
emit ReceiveEther(msg.sender, msg.value);
}
/**
* @dev perform a generic call to an arbitrary contract
* @param _contract the contract's address to call
* @param _data ABI-encoded contract call to call `_contract` address.
* @return the return bytes of the called contract's function.
*/
function genericCall(address _contract,bytes _data) public onlyOwner {
// solium-disable-next-line security/no-low-level-calls
bool result = _contract.call(_data);
// solium-disable-next-line security/no-inline-assembly
assembly {
// Copy the returned data.
returndatacopy(0, 0, returndatasize)
switch result
// call returns 0 on error.
case 0 { revert(0, returndatasize) }
default { return(0, returndatasize) }
}
}
/**
* @dev send ethers from the avatar's wallet
* @param _amountInWei amount to send in Wei units
* @param _to send the ethers to this address
* @return bool which represents success
*/
function sendEther(uint _amountInWei, address _to) public onlyOwner returns(bool) {
_to.transfer(_amountInWei);
emit SendEther(_amountInWei, _to);
return true;
}
/**
* @dev external token transfer
* @param _externalToken the token contract
* @param _to the destination address
* @param _value the amount of tokens to transfer
* @return bool which represents success
*/
function externalTokenTransfer(StandardToken _externalToken, address _to, uint _value)
public onlyOwner returns(bool)
{
_externalToken.transfer(_to, _value);
emit ExternalTokenTransfer(_externalToken, _to, _value);
return true;
}
/**
* @dev external token transfer from a specific account
* @param _externalToken the token contract
* @param _from the account to spend token from
* @param _to the destination address
* @param _value the amount of tokens to transfer
* @return bool which represents success
*/
function externalTokenTransferFrom(
StandardToken _externalToken,
address _from,
address _to,
uint _value
)
public onlyOwner returns(bool)
{
_externalToken.transferFrom(_from, _to, _value);
emit ExternalTokenTransferFrom(_externalToken, _from, _to, _value);
return true;
}
/**
* @dev increase approval for the spender address to spend a specified amount of tokens
* on behalf of msg.sender.
* @param _externalToken the address of the Token Contract
* @param _spender address
* @param _addedValue the amount of ether (in Wei) which the approval is referring to.
* @return bool which represents a success
*/
function externalTokenIncreaseApproval(StandardToken _externalToken, address _spender, uint _addedValue)
public onlyOwner returns(bool)
{
_externalToken.increaseApproval(_spender, _addedValue);
emit ExternalTokenIncreaseApproval(_externalToken, _spender, _addedValue);
return true;
}
/**
* @dev decrease approval for the spender address to spend a specified amount of tokens
* on behalf of msg.sender.
* @param _externalToken the address of the Token Contract
* @param _spender address
* @param _subtractedValue the amount of ether (in Wei) which the approval is referring to.
* @return bool which represents a success
*/
function externalTokenDecreaseApproval(StandardToken _externalToken, address _spender, uint _subtractedValue )
public onlyOwner returns(bool)
{
_externalToken.decreaseApproval(_spender, _subtractedValue);
emit ExternalTokenDecreaseApproval(_externalToken,_spender, _subtractedValue);
return true;
}
}
// File: contracts/globalConstraints/GlobalConstraintInterface.sol
contract GlobalConstraintInterface {
enum CallPhase { Pre, Post,PreAndPost }
function pre( address _scheme, bytes32 _params, bytes32 _method ) public returns(bool);
function post( address _scheme, bytes32 _params, bytes32 _method ) public returns(bool);
/**
* @dev when return if this globalConstraints is pre, post or both.
* @return CallPhase enum indication Pre, Post or PreAndPost.
*/
function when() public returns(CallPhase);
}
// File: contracts/controller/ControllerInterface.sol
/**
* @title Controller contract
* @dev A controller controls the organizations tokens ,reputation and avatar.
* It is subject to a set of schemes and constraints that determine its behavior.
* Each scheme has it own parameters and operation permissions.
*/
interface ControllerInterface {
/**
* @dev Mint `_amount` of reputation that are assigned to `_to` .
* @param _amount amount of reputation to mint
* @param _to beneficiary address
* @return bool which represents a success
*/
function mintReputation(uint256 _amount, address _to,address _avatar)
external
returns(bool);
/**
* @dev Burns `_amount` of reputation from `_from`
* @param _amount amount of reputation to burn
* @param _from The address that will lose the reputation
* @return bool which represents a success
*/
function burnReputation(uint256 _amount, address _from,address _avatar)
external
returns(bool);
/**
* @dev mint tokens .
* @param _amount amount of token to mint
* @param _beneficiary beneficiary address
* @param _avatar address
* @return bool which represents a success
*/
function mintTokens(uint256 _amount, address _beneficiary,address _avatar)
external
returns(bool);
/**
* @dev register or update a scheme
* @param _scheme the address of the scheme
* @param _paramsHash a hashed configuration of the usage of the scheme
* @param _permissions the permissions the new scheme will have
* @param _avatar address
* @return bool which represents a success
*/
function registerScheme(address _scheme, bytes32 _paramsHash, bytes4 _permissions,address _avatar)
external
returns(bool);
/**
* @dev unregister a scheme
* @param _avatar address
* @param _scheme the address of the scheme
* @return bool which represents a success
*/
function unregisterScheme(address _scheme,address _avatar)
external
returns(bool);
/**
* @dev unregister the caller's scheme
* @param _avatar address
* @return bool which represents a success
*/
function unregisterSelf(address _avatar) external returns(bool);
function isSchemeRegistered( address _scheme,address _avatar) external view returns(bool);
function getSchemeParameters(address _scheme,address _avatar) external view returns(bytes32);
function getGlobalConstraintParameters(address _globalConstraint,address _avatar) external view returns(bytes32);
function getSchemePermissions(address _scheme,address _avatar) external view returns(bytes4);
/**
* @dev globalConstraintsCount return the global constraint pre and post count
* @return uint globalConstraintsPre count.
* @return uint globalConstraintsPost count.
*/
function globalConstraintsCount(address _avatar) external view returns(uint,uint);
function isGlobalConstraintRegistered(address _globalConstraint,address _avatar) external view returns(bool);
/**
* @dev add or update Global Constraint
* @param _globalConstraint the address of the global constraint to be added.
* @param _params the constraint parameters hash.
* @param _avatar the avatar of the organization
* @return bool which represents a success
*/
function addGlobalConstraint(address _globalConstraint, bytes32 _params,address _avatar)
external returns(bool);
/**
* @dev remove Global Constraint
* @param _globalConstraint the address of the global constraint to be remove.
* @param _avatar the organization avatar.
* @return bool which represents a success
*/
function removeGlobalConstraint (address _globalConstraint,address _avatar)
external returns(bool);
/**
* @dev upgrade the Controller
* The function will trigger an event 'UpgradeController'.
* @param _newController the address of the new controller.
* @param _avatar address
* @return bool which represents a success
*/
function upgradeController(address _newController,address _avatar)
external returns(bool);
/**
* @dev perform a generic call to an arbitrary contract
* @param _contract the contract's address to call
* @param _data ABI-encoded contract call to call `_contract` address.
* @param _avatar the controller's avatar address
* @return bytes32 - the return value of the called _contract's function.
*/
function genericCall(address _contract,bytes _data,address _avatar)
external
returns(bytes32);
/**
* @dev send some ether
* @param _amountInWei the amount of ether (in Wei) to send
* @param _to address of the beneficiary
* @param _avatar address
* @return bool which represents a success
*/
function sendEther(uint _amountInWei, address _to,address _avatar)
external returns(bool);
/**
* @dev send some amount of arbitrary ERC20 Tokens
* @param _externalToken the address of the Token Contract
* @param _to address of the beneficiary
* @param _value the amount of ether (in Wei) to send
* @param _avatar address
* @return bool which represents a success
*/
function externalTokenTransfer(StandardToken _externalToken, address _to, uint _value,address _avatar)
external
returns(bool);
/**
* @dev transfer token "from" address "to" address
* One must to approve the amount of tokens which can be spend from the
* "from" account.This can be done using externalTokenApprove.
* @param _externalToken the address of the Token Contract
* @param _from address of the account to send from
* @param _to address of the beneficiary
* @param _value the amount of ether (in Wei) to send
* @param _avatar address
* @return bool which represents a success
*/
function externalTokenTransferFrom(StandardToken _externalToken, address _from, address _to, uint _value,address _avatar)
external
returns(bool);
/**
* @dev increase approval for the spender address to spend a specified amount of tokens
* on behalf of msg.sender.
* @param _externalToken the address of the Token Contract
* @param _spender address
* @param _addedValue the amount of ether (in Wei) which the approval is referring to.
* @param _avatar address
* @return bool which represents a success
*/
function externalTokenIncreaseApproval(StandardToken _externalToken, address _spender, uint _addedValue,address _avatar)
external
returns(bool);
/**
* @dev decrease approval for the spender address to spend a specified amount of tokens
* on behalf of msg.sender.
* @param _externalToken the address of the Token Contract
* @param _spender address
* @param _subtractedValue the amount of ether (in Wei) which the approval is referring to.
* @param _avatar address
* @return bool which represents a success
*/
function externalTokenDecreaseApproval(StandardToken _externalToken, address _spender, uint _subtractedValue,address _avatar)
external
returns(bool);
/**
* @dev getNativeReputation
* @param _avatar the organization avatar.
* @return organization native reputation
*/
function getNativeReputation(address _avatar)
external
view
returns(address);
}
// File: contracts/controller/Controller.sol
/**
* @title Controller contract
* @dev A controller controls the organizations tokens,reputation and avatar.
* It is subject to a set of schemes and constraints that determine its behavior.
* Each scheme has it own parameters and operation permissions.
*/
contract Controller is ControllerInterface {
struct Scheme {
bytes32 paramsHash; // a hash "configuration" of the scheme
bytes4 permissions; // A bitwise flags of permissions,
// All 0: Not registered,
// 1st bit: Flag if the scheme is registered,
// 2nd bit: Scheme can register other schemes
// 3rd bit: Scheme can add/remove global constraints
// 4th bit: Scheme can upgrade the controller
// 5th bit: Scheme can call genericCall on behalf of
// the organization avatar
}
struct GlobalConstraint {
address gcAddress;
bytes32 params;
}
struct GlobalConstraintRegister {
bool isRegistered; //is registered
uint index; //index at globalConstraints
}
mapping(address=>Scheme) public schemes;
Avatar public avatar;
DAOToken public nativeToken;
Reputation public nativeReputation;
// newController will point to the new controller after the present controller is upgraded
address public newController;
// globalConstraintsPre that determine pre conditions for all actions on the controller
GlobalConstraint[] public globalConstraintsPre;
// globalConstraintsPost that determine post conditions for all actions on the controller
GlobalConstraint[] public globalConstraintsPost;
// globalConstraintsRegisterPre indicate if a globalConstraints is registered as a pre global constraint
mapping(address=>GlobalConstraintRegister) public globalConstraintsRegisterPre;
// globalConstraintsRegisterPost indicate if a globalConstraints is registered as a post global constraint
mapping(address=>GlobalConstraintRegister) public globalConstraintsRegisterPost;
event MintReputation (address indexed _sender, address indexed _to, uint256 _amount);
event BurnReputation (address indexed _sender, address indexed _from, uint256 _amount);
event MintTokens (address indexed _sender, address indexed _beneficiary, uint256 _amount);
event RegisterScheme (address indexed _sender, address indexed _scheme);
event UnregisterScheme (address indexed _sender, address indexed _scheme);
event GenericAction (address indexed _sender, bytes32[] _params);
event SendEther (address indexed _sender, uint _amountInWei, address indexed _to);
event ExternalTokenTransfer (address indexed _sender, address indexed _externalToken, address indexed _to, uint _value);
event ExternalTokenTransferFrom (address indexed _sender, address indexed _externalToken, address _from, address _to, uint _value);
event ExternalTokenIncreaseApproval (address indexed _sender, StandardToken indexed _externalToken, address _spender, uint _value);
event ExternalTokenDecreaseApproval (address indexed _sender, StandardToken indexed _externalToken, address _spender, uint _value);
event UpgradeController(address indexed _oldController,address _newController);
event AddGlobalConstraint(address indexed _globalConstraint, bytes32 _params,GlobalConstraintInterface.CallPhase _when);
event RemoveGlobalConstraint(address indexed _globalConstraint ,uint256 _index,bool _isPre);
event GenericCall(address indexed _contract,bytes _data);
constructor( Avatar _avatar) public
{
avatar = _avatar;
nativeToken = avatar.nativeToken();
nativeReputation = avatar.nativeReputation();
schemes[msg.sender] = Scheme({paramsHash: bytes32(0),permissions: bytes4(0x1F)});
}
// Do not allow mistaken calls:
function() external {
revert();
}
// Modifiers:
modifier onlyRegisteredScheme() {
require(schemes[msg.sender].permissions&bytes4(1) == bytes4(1));
_;
}
modifier onlyRegisteringSchemes() {
require(schemes[msg.sender].permissions&bytes4(2) == bytes4(2));
_;
}
modifier onlyGlobalConstraintsScheme() {
require(schemes[msg.sender].permissions&bytes4(4) == bytes4(4));
_;
}
modifier onlyUpgradingScheme() {
require(schemes[msg.sender].permissions&bytes4(8) == bytes4(8));
_;
}
modifier onlyGenericCallScheme() {
require(schemes[msg.sender].permissions&bytes4(16) == bytes4(16));
_;
}
modifier onlySubjectToConstraint(bytes32 func) {
uint idx;
for (idx = 0;idx<globalConstraintsPre.length;idx++) {
require((GlobalConstraintInterface(globalConstraintsPre[idx].gcAddress)).pre(msg.sender,globalConstraintsPre[idx].params,func));
}
_;
for (idx = 0;idx<globalConstraintsPost.length;idx++) {
require((GlobalConstraintInterface(globalConstraintsPost[idx].gcAddress)).post(msg.sender,globalConstraintsPost[idx].params,func));
}
}
modifier isAvatarValid(address _avatar) {
require(_avatar == address(avatar));
_;
}
/**
* @dev Mint `_amount` of reputation that are assigned to `_to` .
* @param _amount amount of reputation to mint
* @param _to beneficiary address
* @return bool which represents a success
*/
function mintReputation(uint256 _amount, address _to,address _avatar)
external
onlyRegisteredScheme
onlySubjectToConstraint("mintReputation")
isAvatarValid(_avatar)
returns(bool)
{
emit MintReputation(msg.sender, _to, _amount);
return nativeReputation.mint(_to, _amount);
}
/**
* @dev Burns `_amount` of reputation from `_from`
* @param _amount amount of reputation to burn
* @param _from The address that will lose the reputation
* @return bool which represents a success
*/
function burnReputation(uint256 _amount, address _from,address _avatar)
external
onlyRegisteredScheme
onlySubjectToConstraint("burnReputation")
isAvatarValid(_avatar)
returns(bool)
{
emit BurnReputation(msg.sender, _from, _amount);
return nativeReputation.burn(_from, _amount);
}
/**
* @dev mint tokens .
* @param _amount amount of token to mint
* @param _beneficiary beneficiary address
* @return bool which represents a success
*/
function mintTokens(uint256 _amount, address _beneficiary,address _avatar)
external
onlyRegisteredScheme
onlySubjectToConstraint("mintTokens")
isAvatarValid(_avatar)
returns(bool)
{
emit MintTokens(msg.sender, _beneficiary, _amount);
return nativeToken.mint(_beneficiary, _amount);
}
/**
* @dev register a scheme
* @param _scheme the address of the scheme
* @param _paramsHash a hashed configuration of the usage of the scheme
* @param _permissions the permissions the new scheme will have
* @return bool which represents a success
*/
function registerScheme(address _scheme, bytes32 _paramsHash, bytes4 _permissions,address _avatar)
external
onlyRegisteringSchemes
onlySubjectToConstraint("registerScheme")
isAvatarValid(_avatar)
returns(bool)
{
Scheme memory scheme = schemes[_scheme];
// Check scheme has at least the permissions it is changing, and at least the current permissions:
// Implementation is a bit messy. One must recall logic-circuits ^^
// produces non-zero if sender does not have all of the perms that are changing between old and new
require(bytes4(0x1F)&(_permissions^scheme.permissions)&(~schemes[msg.sender].permissions) == bytes4(0));
// produces non-zero if sender does not have all of the perms in the old scheme
require(bytes4(0x1F)&(scheme.permissions&(~schemes[msg.sender].permissions)) == bytes4(0));
// Add or change the scheme:
schemes[_scheme].paramsHash = _paramsHash;
schemes[_scheme].permissions = _permissions|bytes4(1);
emit RegisterScheme(msg.sender, _scheme);
return true;
}
/**
* @dev unregister a scheme
* @param _scheme the address of the scheme
* @return bool which represents a success
*/
function unregisterScheme( address _scheme,address _avatar)
external
onlyRegisteringSchemes
onlySubjectToConstraint("unregisterScheme")
isAvatarValid(_avatar)
returns(bool)
{
//check if the scheme is registered
if (schemes[_scheme].permissions&bytes4(1) == bytes4(0)) {
return false;
}
// Check the unregistering scheme has enough permissions:
require(bytes4(0x1F)&(schemes[_scheme].permissions&(~schemes[msg.sender].permissions)) == bytes4(0));
// Unregister:
emit UnregisterScheme(msg.sender, _scheme);
delete schemes[_scheme];
return true;
}
/**
* @dev unregister the caller's scheme
* @return bool which represents a success
*/
function unregisterSelf(address _avatar) external isAvatarValid(_avatar) returns(bool) {
if (_isSchemeRegistered(msg.sender,_avatar) == false) {
return false;
}
delete schemes[msg.sender];
emit UnregisterScheme(msg.sender, msg.sender);
return true;
}
function isSchemeRegistered(address _scheme,address _avatar) external isAvatarValid(_avatar) view returns(bool) {
return _isSchemeRegistered(_scheme,_avatar);
}
function getSchemeParameters(address _scheme,address _avatar) external isAvatarValid(_avatar) view returns(bytes32) {
return schemes[_scheme].paramsHash;
}
function getSchemePermissions(address _scheme,address _avatar) external isAvatarValid(_avatar) view returns(bytes4) {
return schemes[_scheme].permissions;
}
function getGlobalConstraintParameters(address _globalConstraint,address) external view returns(bytes32) {
GlobalConstraintRegister memory register = globalConstraintsRegisterPre[_globalConstraint];
if (register.isRegistered) {
return globalConstraintsPre[register.index].params;
}
register = globalConstraintsRegisterPost[_globalConstraint];
if (register.isRegistered) {
return globalConstraintsPost[register.index].params;
}
}
/**
* @dev globalConstraintsCount return the global constraint pre and post count
* @return uint globalConstraintsPre count.
* @return uint globalConstraintsPost count.
*/
function globalConstraintsCount(address _avatar)
external
isAvatarValid(_avatar)
view
returns(uint,uint)
{
return (globalConstraintsPre.length,globalConstraintsPost.length);
}
function isGlobalConstraintRegistered(address _globalConstraint,address _avatar)
external
isAvatarValid(_avatar)
view
returns(bool)
{
return (globalConstraintsRegisterPre[_globalConstraint].isRegistered || globalConstraintsRegisterPost[_globalConstraint].isRegistered);
}
/**
* @dev add or update Global Constraint
* @param _globalConstraint the address of the global constraint to be added.
* @param _params the constraint parameters hash.
* @return bool which represents a success
*/
function addGlobalConstraint(address _globalConstraint, bytes32 _params,address _avatar)
external
onlyGlobalConstraintsScheme
isAvatarValid(_avatar)
returns(bool)
{
GlobalConstraintInterface.CallPhase when = GlobalConstraintInterface(_globalConstraint).when();
if ((when == GlobalConstraintInterface.CallPhase.Pre)||(when == GlobalConstraintInterface.CallPhase.PreAndPost)) {
if (!globalConstraintsRegisterPre[_globalConstraint].isRegistered) {
globalConstraintsPre.push(GlobalConstraint(_globalConstraint,_params));
globalConstraintsRegisterPre[_globalConstraint] = GlobalConstraintRegister(true,globalConstraintsPre.length-1);
}else {
globalConstraintsPre[globalConstraintsRegisterPre[_globalConstraint].index].params = _params;
}
}
if ((when == GlobalConstraintInterface.CallPhase.Post)||(when == GlobalConstraintInterface.CallPhase.PreAndPost)) {
if (!globalConstraintsRegisterPost[_globalConstraint].isRegistered) {
globalConstraintsPost.push(GlobalConstraint(_globalConstraint,_params));
globalConstraintsRegisterPost[_globalConstraint] = GlobalConstraintRegister(true,globalConstraintsPost.length-1);
}else {
globalConstraintsPost[globalConstraintsRegisterPost[_globalConstraint].index].params = _params;
}
}
emit AddGlobalConstraint(_globalConstraint, _params,when);
return true;
}
/**
* @dev remove Global Constraint
* @param _globalConstraint the address of the global constraint to be remove.
* @return bool which represents a success
*/
function removeGlobalConstraint (address _globalConstraint,address _avatar)
external
onlyGlobalConstraintsScheme
isAvatarValid(_avatar)
returns(bool)
{
GlobalConstraintRegister memory globalConstraintRegister;
GlobalConstraint memory globalConstraint;
GlobalConstraintInterface.CallPhase when = GlobalConstraintInterface(_globalConstraint).when();
bool retVal = false;
if ((when == GlobalConstraintInterface.CallPhase.Pre)||(when == GlobalConstraintInterface.CallPhase.PreAndPost)) {
globalConstraintRegister = globalConstraintsRegisterPre[_globalConstraint];
if (globalConstraintRegister.isRegistered) {
if (globalConstraintRegister.index < globalConstraintsPre.length-1) {
globalConstraint = globalConstraintsPre[globalConstraintsPre.length-1];
globalConstraintsPre[globalConstraintRegister.index] = globalConstraint;
globalConstraintsRegisterPre[globalConstraint.gcAddress].index = globalConstraintRegister.index;
}
globalConstraintsPre.length--;
delete globalConstraintsRegisterPre[_globalConstraint];
retVal = true;
}
}
if ((when == GlobalConstraintInterface.CallPhase.Post)||(when == GlobalConstraintInterface.CallPhase.PreAndPost)) {
globalConstraintRegister = globalConstraintsRegisterPost[_globalConstraint];
if (globalConstraintRegister.isRegistered) {
if (globalConstraintRegister.index < globalConstraintsPost.length-1) {
globalConstraint = globalConstraintsPost[globalConstraintsPost.length-1];
globalConstraintsPost[globalConstraintRegister.index] = globalConstraint;
globalConstraintsRegisterPost[globalConstraint.gcAddress].index = globalConstraintRegister.index;
}
globalConstraintsPost.length--;
delete globalConstraintsRegisterPost[_globalConstraint];
retVal = true;
}
}
if (retVal) {
emit RemoveGlobalConstraint(_globalConstraint,globalConstraintRegister.index,when == GlobalConstraintInterface.CallPhase.Pre);
}
return retVal;
}
/**
* @dev upgrade the Controller
* The function will trigger an event 'UpgradeController'.
* @param _newController the address of the new controller.
* @return bool which represents a success
*/
function upgradeController(address _newController,address _avatar)
external
onlyUpgradingScheme
isAvatarValid(_avatar)
returns(bool)
{
require(newController == address(0)); // so the upgrade could be done once for a contract.
require(_newController != address(0));
newController = _newController;
avatar.transferOwnership(_newController);
require(avatar.owner()==_newController);
if (nativeToken.owner() == address(this)) {
nativeToken.transferOwnership(_newController);
require(nativeToken.owner()==_newController);
}
if (nativeReputation.owner() == address(this)) {
nativeReputation.transferOwnership(_newController);
require(nativeReputation.owner()==_newController);
}
emit UpgradeController(this,newController);
return true;
}
/**
* @dev perform a generic call to an arbitrary contract
* @param _contract the contract's address to call
* @param _data ABI-encoded contract call to call `_contract` address.
* @param _avatar the controller's avatar address
* @return bytes32 - the return value of the called _contract's function.
*/
function genericCall(address _contract,bytes _data,address _avatar)
external
onlyGenericCallScheme
onlySubjectToConstraint("genericCall")
isAvatarValid(_avatar)
returns (bytes32)
{
emit GenericCall(_contract, _data);
avatar.genericCall(_contract, _data);
// solium-disable-next-line security/no-inline-assembly
assembly {
// Copy the returned data.
returndatacopy(0, 0, returndatasize)
return(0, returndatasize)
}
}
/**
* @dev send some ether
* @param _amountInWei the amount of ether (in Wei) to send
* @param _to address of the beneficiary
* @return bool which represents a success
*/
function sendEther(uint _amountInWei, address _to,address _avatar)
external
onlyRegisteredScheme
onlySubjectToConstraint("sendEther")
isAvatarValid(_avatar)
returns(bool)
{
emit SendEther(msg.sender, _amountInWei, _to);
return avatar.sendEther(_amountInWei, _to);
}
/**
* @dev send some amount of arbitrary ERC20 Tokens
* @param _externalToken the address of the Token Contract
* @param _to address of the beneficiary
* @param _value the amount of ether (in Wei) to send
* @return bool which represents a success
*/
function externalTokenTransfer(StandardToken _externalToken, address _to, uint _value,address _avatar)
external
onlyRegisteredScheme
onlySubjectToConstraint("externalTokenTransfer")
isAvatarValid(_avatar)
returns(bool)
{
emit ExternalTokenTransfer(msg.sender, _externalToken, _to, _value);
return avatar.externalTokenTransfer(_externalToken, _to, _value);
}
/**
* @dev transfer token "from" address "to" address
* One must to approve the amount of tokens which can be spend from the
* "from" account.This can be done using externalTokenApprove.
* @param _externalToken the address of the Token Contract
* @param _from address of the account to send from
* @param _to address of the beneficiary
* @param _value the amount of ether (in Wei) to send
* @return bool which represents a success
*/
function externalTokenTransferFrom(StandardToken _externalToken, address _from, address _to, uint _value,address _avatar)
external
onlyRegisteredScheme
onlySubjectToConstraint("externalTokenTransferFrom")
isAvatarValid(_avatar)
returns(bool)
{
emit ExternalTokenTransferFrom(msg.sender, _externalToken, _from, _to, _value);
return avatar.externalTokenTransferFrom(_externalToken, _from, _to, _value);
}
/**
* @dev increase approval for the spender address to spend a specified amount of tokens
* on behalf of msg.sender.
* @param _externalToken the address of the Token Contract
* @param _spender address
* @param _addedValue the amount of ether (in Wei) which the approval is referring to.
* @return bool which represents a success
*/
function externalTokenIncreaseApproval(StandardToken _externalToken, address _spender, uint _addedValue,address _avatar)
external
onlyRegisteredScheme
onlySubjectToConstraint("externalTokenIncreaseApproval")
isAvatarValid(_avatar)
returns(bool)
{
emit ExternalTokenIncreaseApproval(msg.sender,_externalToken,_spender,_addedValue);
return avatar.externalTokenIncreaseApproval(_externalToken, _spender, _addedValue);
}
/**
* @dev decrease approval for the spender address to spend a specified amount of tokens
* on behalf of msg.sender.
* @param _externalToken the address of the Token Contract
* @param _spender address
* @param _subtractedValue the amount of ether (in Wei) which the approval is referring to.
* @return bool which represents a success
*/
function externalTokenDecreaseApproval(StandardToken _externalToken, address _spender, uint _subtractedValue,address _avatar)
external
onlyRegisteredScheme
onlySubjectToConstraint("externalTokenDecreaseApproval")
isAvatarValid(_avatar)
returns(bool)
{
emit ExternalTokenDecreaseApproval(msg.sender,_externalToken,_spender,_subtractedValue);
return avatar.externalTokenDecreaseApproval(_externalToken, _spender, _subtractedValue);
}
/**
* @dev getNativeReputation
* @param _avatar the organization avatar.
* @return organization native reputation
*/
function getNativeReputation(address _avatar) external isAvatarValid(_avatar) view returns(address) {
return address(nativeReputation);
}
function _isSchemeRegistered(address _scheme,address _avatar) private isAvatarValid(_avatar) view returns(bool) {
return (schemes[_scheme].permissions&bytes4(1) != bytes4(0));
}
}
// File: contracts/universalSchemes/UniversalSchemeInterface.sol
contract UniversalSchemeInterface {
function updateParameters(bytes32 _hashedParameters) public;
function getParametersFromController(Avatar _avatar) internal view returns(bytes32);
}
// File: contracts/universalSchemes/UniversalScheme.sol
contract UniversalScheme is Ownable, UniversalSchemeInterface {
bytes32 public hashedParameters; // For other parameters.
function updateParameters(
bytes32 _hashedParameters
)
public
onlyOwner
{
hashedParameters = _hashedParameters;
}
/**
* @dev get the parameters for the current scheme from the controller
*/
function getParametersFromController(Avatar _avatar) internal view returns(bytes32) {
return ControllerInterface(_avatar.owner()).getSchemeParameters(this,address(_avatar));
}
}
// File: contracts/universalSchemes/ExecutableInterface.sol
contract ExecutableInterface {
function execute(bytes32 _proposalId, address _avatar, int _param) public returns(bool);
}
// File: contracts/VotingMachines/IntVoteInterface.sol
interface IntVoteInterface {
//When implementing this interface please do not only override function and modifier,
//but also to keep the modifiers on the overridden functions.
modifier onlyProposalOwner(bytes32 _proposalId) {revert(); _;}
modifier votable(bytes32 _proposalId) {revert(); _;}
event NewProposal(bytes32 indexed _proposalId, address indexed _avatar, uint _numOfChoices, address _proposer, bytes32 _paramsHash);
event ExecuteProposal(bytes32 indexed _proposalId, address indexed _avatar, uint _decision, uint _totalReputation);
event VoteProposal(bytes32 indexed _proposalId, address indexed _avatar, address indexed _voter, uint _vote, uint _reputation);
event CancelProposal(bytes32 indexed _proposalId, address indexed _avatar );
event CancelVoting(bytes32 indexed _proposalId, address indexed _avatar, address indexed _voter);
/**
* @dev register a new proposal with the given parameters. Every proposal has a unique ID which is being
* generated by calculating keccak256 of a incremented counter.
* @param _numOfChoices number of voting choices
* @param _proposalParameters defines the parameters of the voting machine used for this proposal
* @param _avatar an address to be sent as the payload to the _executable contract.
* @param _executable This contract will be executed when vote is over.
* @param _proposer address
* @return proposal's id.
*/
function propose(
uint _numOfChoices,
bytes32 _proposalParameters,
address _avatar,
ExecutableInterface _executable,
address _proposer
) external returns(bytes32);
// Only owned proposals and only the owner:
function cancelProposal(bytes32 _proposalId) external returns(bool);
// Only owned proposals and only the owner:
function ownerVote(bytes32 _proposalId, uint _vote, address _voter) external returns(bool);
function vote(bytes32 _proposalId, uint _vote) external returns(bool);
function voteWithSpecifiedAmounts(
bytes32 _proposalId,
uint _vote,
uint _rep,
uint _token) external returns(bool);
function cancelVote(bytes32 _proposalId) external;
//@dev execute check if the proposal has been decided, and if so, execute the proposal
//@param _proposalId the id of the proposal
//@return bool true - the proposal has been executed
// false - otherwise.
function execute(bytes32 _proposalId) external returns(bool);
function getNumberOfChoices(bytes32 _proposalId) external view returns(uint);
function isVotable(bytes32 _proposalId) external view returns(bool);
/**
* @dev voteStatus returns the reputation voted for a proposal for a specific voting choice.
* @param _proposalId the ID of the proposal
* @param _choice the index in the
* @return voted reputation for the given choice
*/
function voteStatus(bytes32 _proposalId,uint _choice) external view returns(uint);
/**
* @dev isAbstainAllow returns if the voting machine allow abstain (0)
* @return bool true or false
*/
function isAbstainAllow() external pure returns(bool);
/**
* @dev getAllowedRangeOfChoices returns the allowed range of choices for a voting machine.
* @return min - minimum number of choices
max - maximum number of choices
*/
function getAllowedRangeOfChoices() external pure returns(uint min,uint max);
}
// File: contracts/universalSchemes/GlobalConstraintRegistrar.sol
/**
* @title A scheme to manage global constraint for organizations
* @dev The scheme is used to register or remove new global constraints
*/
contract GlobalConstraintRegistrar is UniversalScheme {
event NewGlobalConstraintsProposal(
address indexed _avatar,
bytes32 indexed _proposalId,
address indexed _intVoteInterface,
address _gc,
bytes32 _params,
bytes32 _voteToRemoveParams
);
event RemoveGlobalConstraintsProposal(
address indexed _avatar,
bytes32 indexed _proposalId,
address indexed _intVoteInterface,
address _gc
);
event ProposalExecuted(address indexed _avatar, bytes32 indexed _proposalId,int _param);
event ProposalDeleted(address indexed _avatar, bytes32 indexed _proposalId);
// The struct that holds the information of a global constraint proposed to be added or removed.
struct GCProposal {
address gc; // The address of the global constraint contract.
bytes32 params; // Parameters for global constraint.
uint proposalType; // 1: add a GC, 2: remove a GC.
bytes32 voteToRemoveParams; // Voting parameters for removing this GC.
}
// GCProposal by avatar and proposalId
mapping(address=>mapping(bytes32=>GCProposal)) public organizationsProposals;
// voteToRemoveParams hash by avatar and proposal.gc
mapping(address=>mapping(address=>bytes32)) public voteToRemoveParams;
// A mapping from hashes to parameters (use to store a particular configuration on the controller)
struct Parameters {
bytes32 voteRegisterParams;
IntVoteInterface intVote;
}
mapping(bytes32=>Parameters) public parameters;
/**
* @dev execution of proposals, can only be called by the voting machine in which the vote is held.
* @param _proposalId the ID of the voting in the voting machine
* @param _avatar address of the controller
* @param _param a parameter of the voting result, 0 is no and 1 is yes.
* @return bool which represents a successful of the function.
*/
function execute(bytes32 _proposalId, address _avatar, int _param) external returns(bool) {
// Check the caller is indeed the voting machine:
require(parameters[getParametersFromController(Avatar(_avatar))].intVote == msg.sender);
bool retVal = true;
// Check if vote was successful:
GCProposal memory proposal = organizationsProposals[_avatar][_proposalId];
require(proposal.gc != address(0));
delete organizationsProposals[_avatar][_proposalId];
emit ProposalDeleted(_avatar,_proposalId);
if (_param == 1 ) {
// Define controller and get the params:
ControllerInterface controller = ControllerInterface(Avatar(_avatar).owner());
// Adding a GC
if (proposal.proposalType == 1) {
retVal = controller.addGlobalConstraint(proposal.gc, proposal.params,_avatar);
voteToRemoveParams[_avatar][proposal.gc] = proposal.voteToRemoveParams;
}
// Removing a GC
if (proposal.proposalType == 2) {
retVal = controller.removeGlobalConstraint(proposal.gc,_avatar);
}
}
emit ProposalExecuted(_avatar, _proposalId,_param);
return retVal;
}
/**
* @dev Hash the parameters, save them if necessary, and return the hash value
* @param _voteRegisterParams - voting parameters for register global constraint
* @param _intVote - voting machine contract.
* @return bytes32 -the parameters hash
*/
function setParameters(
bytes32 _voteRegisterParams,
IntVoteInterface _intVote
) public returns(bytes32)
{
bytes32 paramsHash = getParametersHash(_voteRegisterParams, _intVote);
parameters[paramsHash].voteRegisterParams = _voteRegisterParams;
parameters[paramsHash].intVote = _intVote;
return paramsHash;
}
/**
* @dev Hash the parameters and return the hash value
* @param _voteRegisterParams - voting parameters
* @param _intVote - voting machine contract.
* @return bytes32 -the parameters hash
*/
function getParametersHash(
bytes32 _voteRegisterParams,
IntVoteInterface _intVote
) public pure returns(bytes32)
{
return (keccak256(abi.encodePacked(_voteRegisterParams, _intVote)));
}
/**
* @dev propose to add a new global constraint:
* @param _avatar the avatar of the organization that the constraint is proposed for
* @param _gc the address of the global constraint that is being proposed
* @param _params the parameters for the global constraint
* @param _voteToRemoveParams the conditions (on the voting machine) for removing this global constraint
* @return bytes32 -the proposal id
*/
// TODO: do some checks on _voteToRemoveParams - it is very easy to make a mistake and not be able to remove the GC
function proposeGlobalConstraint(Avatar _avatar, address _gc, bytes32 _params, bytes32 _voteToRemoveParams)
public
returns(bytes32)
{
Parameters memory votingParams = parameters[getParametersFromController(_avatar)];
IntVoteInterface intVote = votingParams.intVote;
bytes32 proposalId = intVote.propose(2, votingParams.voteRegisterParams, _avatar, ExecutableInterface(this),msg.sender);
GCProposal memory proposal = GCProposal({
gc: _gc,
params: _params,
proposalType: 1,
voteToRemoveParams: _voteToRemoveParams
});
organizationsProposals[_avatar][proposalId] = proposal;
emit NewGlobalConstraintsProposal(
_avatar,
proposalId,
intVote,
_gc,
_params,
_voteToRemoveParams
);
intVote.ownerVote(proposalId, 1, msg.sender); // Automatically votes `yes` in the name of the opener.
return proposalId;
}
/**
* @dev propose to remove a global constraint:
* @param _avatar the avatar of the organization that the constraint is proposed for
* @param _gc the address of the global constraint that is being proposed
* @return bytes32 -the proposal id
*/
function proposeToRemoveGC(Avatar _avatar, address _gc) public returns(bytes32) {
Controller controller = Controller(Avatar(_avatar).owner());
require(controller.isGlobalConstraintRegistered(_gc,address(_avatar)));
Parameters memory params = parameters[getParametersFromController(_avatar)];
IntVoteInterface intVote = params.intVote;
bytes32 proposalId = intVote.propose(2, voteToRemoveParams[_avatar][_gc], _avatar, ExecutableInterface(this),msg.sender);
GCProposal memory proposal = GCProposal({
gc: _gc,
params: 0,
proposalType: 2,
voteToRemoveParams: 0
});
organizationsProposals[_avatar][proposalId] = proposal;
emit RemoveGlobalConstraintsProposal(_avatar, proposalId, intVote, _gc);
intVote.ownerVote(proposalId, 1, msg.sender); // Automatically votes `yes` in the name of the opener.
return proposalId;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"parameters","outputs":[{"name":"voteRegisterParams","type":"bytes32"},{"name":"intVote","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"bytes32"}],"name":"organizationsProposals","outputs":[{"name":"gc","type":"address"},{"name":"params","type":"bytes32"},{"name":"proposalType","type":"uint256"},{"name":"voteToRemoveParams","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_avatar","type":"address"},{"name":"_gc","type":"address"},{"name":"_params","type":"bytes32"},{"name":"_voteToRemoveParams","type":"bytes32"}],"name":"proposeGlobalConstraint","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_voteRegisterParams","type":"bytes32"},{"name":"_intVote","type":"address"}],"name":"getParametersHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_hashedParameters","type":"bytes32"}],"name":"updateParameters","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposalId","type":"bytes32"},{"name":"_avatar","type":"address"},{"name":"_param","type":"int256"}],"name":"execute","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_voteRegisterParams","type":"bytes32"},{"name":"_intVote","type":"address"}],"name":"setParameters","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"voteToRemoveParams","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_avatar","type":"address"},{"name":"_gc","type":"address"}],"name":"proposeToRemoveGC","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"hashedParameters","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_avatar","type":"address"},{"indexed":true,"name":"_proposalId","type":"bytes32"},{"indexed":true,"name":"_intVoteInterface","type":"address"},{"indexed":false,"name":"_gc","type":"address"},{"indexed":false,"name":"_params","type":"bytes32"},{"indexed":false,"name":"_voteToRemoveParams","type":"bytes32"}],"name":"NewGlobalConstraintsProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_avatar","type":"address"},{"indexed":true,"name":"_proposalId","type":"bytes32"},{"indexed":true,"name":"_intVoteInterface","type":"address"},{"indexed":false,"name":"_gc","type":"address"}],"name":"RemoveGlobalConstraintsProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_avatar","type":"address"},{"indexed":true,"name":"_proposalId","type":"bytes32"},{"indexed":false,"name":"_param","type":"int256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_avatar","type":"address"},{"indexed":true,"name":"_proposalId","type":"bytes32"}],"name":"ProposalDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]Contract Creation Code
608060405260008054600160a060020a03191633179055611195806100256000396000f3006080604052600436106100ab5763ffffffff60e060020a6000350416630250680481146100b057806306e3a978146100e95780630fd6e4981461013d5780632453732a1461017c5780632ac2af53146101a0578063310ce4e2146101ba57806368e14dac146101f5578063715018a6146102195780638da5cb5b1461022e578063a3379f901461025f578063f2fde38b14610286578063f731e470146102a7578063f98e87ba146102ce575b600080fd5b3480156100bc57600080fd5b506100c86004356102e3565b60408051928352600160a060020a0390911660208301528051918290030190f35b3480156100f557600080fd5b5061010d600160a060020a0360043516602435610305565b60408051600160a060020a0390951685526020850193909352838301919091526060830152519081900360800190f35b34801561014957600080fd5b5061016a600160a060020a0360043581169060243516604435606435610340565b60408051918252519081900360200190f35b34801561018857600080fd5b5061016a600435600160a060020a0360243516610649565b3480156101ac57600080fd5b506101b86004356106e7565b005b3480156101c657600080fd5b506101e1600435600160a060020a0360243516604435610703565b604080519115158252519081900360200190f35b34801561020157600080fd5b5061016a600435600160a060020a0360243516610a76565b34801561022557600080fd5b506101b8610acb565b34801561023a57600080fd5b50610243610b37565b60408051600160a060020a039092168252519081900360200190f35b34801561026b57600080fd5b5061016a600160a060020a0360043581169060243516610b46565b34801561029257600080fd5b506101b8600160a060020a0360043516610b63565b3480156102b357600080fd5b5061016a600160a060020a0360043581169060243516610b86565b3480156102da57600080fd5b5061016a610f9f565b60046020526000908152604090208054600190910154600160a060020a031682565b600260208181526000938452604080852090915291835291208054600182015492820154600390920154600160a060020a0390911692919084565b600061034a61112b565b600080610355611142565b600460006103628b610fa5565b815260208082019290925260409081016000908120825180840184528154808252600190920154600160a060020a0390811682870181905285517f0905c9f9000000000000000000000000000000000000000000000000000000008152600260048201526024810194909452908f16604484015230606484015233608484015293519098509296508693630905c9f99360a48084019492939192918390030190829087803b15801561041357600080fd5b505af1158015610427573d6000803e3d6000fd5b505050506040513d602081101561043d57600080fd5b8101908080519060200190929190505050915060806040519081016040528089600160a060020a0316815260200188600019168152602001600181526020018760001916815250905080600260008b600160a060020a0316600160a060020a031681526020019081526020016000206000846000191660001916815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010190600019169055604082015181600201556060820151816003019060001916905590505082600160a060020a031682600019168a600160a060020a03167f4e87f569c5a3f504eea38add71bbdd022e5d63d0ee92d4130c407b8d64941bc08b8b8b6040518084600160a060020a0316600160a060020a0316815260200183600019166000191681526020018260001916600019168152602001935050505060405180910390a4604080517f339e23d100000000000000000000000000000000000000000000000000000000815260048101849052600160248201523360448201529051600160a060020a0385169163339e23d19160648083019260209291908290030181600087803b15801561061057600080fd5b505af1158015610624573d6000803e3d6000fd5b505050506040513d602081101561063a57600080fd5b50919998505050505050505050565b6040805160208082018590526c01000000000000000000000000600160a060020a0385160282840152825160348184030181526054909201928390528151600093918291908401908083835b602083106106b45780518252601f199092019160209182019101610695565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209695505050505050565b600054600160a060020a031633146106fe57600080fd5b600155565b60008061070e611142565b60003360048261071d89610fa5565b8152602081019190915260400160002060010154600160a060020a03161461074457600080fd5b600160a060020a0380871660009081526002602081815260408084208c855282529283902083516080810185528154909516808652600182810154938701939093529281015493850193909352600390920154606084015290945090925015156107ad57600080fd5b600160a060020a03861660008181526002602081815260408084208c8552909152808320805473ffffffffffffffffffffffffffffffffffffffff19168155600181018490559182018390556003909101829055518992917f6bc0cb9e9967b59a69ace442598e1df4368d38661bd5c0800fbcbc9fe855fbbe91a38460011415610a2b5785600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561086f57600080fd5b505af1158015610883573d6000803e3d6000fd5b505050506040513d602081101561089957600080fd5b5051604083015190915060011415610980578151602080840151604080517fe4537a74000000000000000000000000000000000000000000000000000000008152600160a060020a03948516600482015260248101929092528984166044830152519284169263e4537a74926064808401939192918290030181600087803b15801561092457600080fd5b505af1158015610938573d6000803e3d6000fd5b505050506040513d602081101561094e57600080fd5b50516060830151600160a060020a03808916600090815260036020908152604080832088519094168352929052205592505b816040015160021415610a2b578151604080517f4f52b5be000000000000000000000000000000000000000000000000000000008152600160a060020a0392831660048201528883166024820152905191831691634f52b5be916044808201926020929091908290030181600087803b1580156109fc57600080fd5b505af1158015610a10573d6000803e3d6000fd5b505050506040513d6020811015610a2657600080fd5b505192505b6040805186815290518891600160a060020a038916917fd2632e80f5364f02aded1c64e8a04637b7c8bb9c2db2bedf4b6ac47c013acbc09181900360200190a3509095945050505050565b600080610a838484610649565b60008181526004602052604090208581556001018054600160a060020a03861673ffffffffffffffffffffffffffffffffffffffff1990911617905591508190505092915050565b600054600160a060020a03163314610ae257600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031681565b600360209081526000928352604080842090915290825290205481565b600054600160a060020a03163314610b7a57600080fd5b610b83816110ae565b50565b600080610b9161112b565b600080610b9c611142565b87600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610bda57600080fd5b505af1158015610bee573d6000803e3d6000fd5b505050506040513d6020811015610c0457600080fd5b5051604080517ff76488be000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660048301528b8116602483015291519297509087169163f76488be916044808201926020929091908290030181600087803b158015610c7657600080fd5b505af1158015610c8a573d6000803e3d6000fd5b505050506040513d6020811015610ca057600080fd5b50511515610cad57600080fd5b60046000610cba8a610fa5565b8152602080820192909252604090810160009081208251808401845281548152600190910154600160a060020a039081168286018190528d821680855260038752858520928e1685529186528484205485517f0905c9f9000000000000000000000000000000000000000000000000000000008152600260048201526024810191909152604481019290925230606483015233608483015293519198509296508693630905c9f99360a480820194929392918390030190829087803b158015610d8257600080fd5b505af1158015610d96573d6000803e3d6000fd5b505050506040513d6020811015610dac57600080fd5b8101908080519060200190929190505050915060806040519081016040528088600160a060020a03168152602001600060010260001916815260200160028152602001600060010260001916815250905080600260008a600160a060020a0316600160a060020a031681526020019081526020016000206000846000191660001916815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010190600019169055604082015181600201556060820151816003019060001916905590505082600160a060020a0316826000191689600160a060020a03167f661684a19fb0680f3f8beceaa9ee56c665ffec0875442e2cddc9a7a887d35c3e8a6040518082600160a060020a0316600160a060020a0316815260200191505060405180910390a4604080517f339e23d100000000000000000000000000000000000000000000000000000000815260048101849052600160248201523360448201529051600160a060020a0385169163339e23d19160648083019260209291908290030181600087803b158015610f6757600080fd5b505af1158015610f7b573d6000803e3d6000fd5b505050506040513d6020811015610f9157600080fd5b509198975050505050505050565b60015481565b600081600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610fe557600080fd5b505af1158015610ff9573d6000803e3d6000fd5b505050506040513d602081101561100f57600080fd5b5051604080517f1c4d5608000000000000000000000000000000000000000000000000000000008152306004820152600160a060020a03858116602483015291519190921691631c4d56089160448083019260209291908290030181600087803b15801561107c57600080fd5b505af1158015611090573d6000803e3d6000fd5b505050506040513d60208110156110a657600080fd5b505192915050565b600160a060020a03811615156110c357600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b604080518082019091526000808252602082015290565b604080516080810182526000808252602082018190529181018290526060810191909152905600a165627a7a72305820e23a6560763f43afb57384018e6b3c38bfd6cc991292df3cb26a9fc84eca751f0029
Deployed Bytecode
0x6080604052600436106100ab5763ffffffff60e060020a6000350416630250680481146100b057806306e3a978146100e95780630fd6e4981461013d5780632453732a1461017c5780632ac2af53146101a0578063310ce4e2146101ba57806368e14dac146101f5578063715018a6146102195780638da5cb5b1461022e578063a3379f901461025f578063f2fde38b14610286578063f731e470146102a7578063f98e87ba146102ce575b600080fd5b3480156100bc57600080fd5b506100c86004356102e3565b60408051928352600160a060020a0390911660208301528051918290030190f35b3480156100f557600080fd5b5061010d600160a060020a0360043516602435610305565b60408051600160a060020a0390951685526020850193909352838301919091526060830152519081900360800190f35b34801561014957600080fd5b5061016a600160a060020a0360043581169060243516604435606435610340565b60408051918252519081900360200190f35b34801561018857600080fd5b5061016a600435600160a060020a0360243516610649565b3480156101ac57600080fd5b506101b86004356106e7565b005b3480156101c657600080fd5b506101e1600435600160a060020a0360243516604435610703565b604080519115158252519081900360200190f35b34801561020157600080fd5b5061016a600435600160a060020a0360243516610a76565b34801561022557600080fd5b506101b8610acb565b34801561023a57600080fd5b50610243610b37565b60408051600160a060020a039092168252519081900360200190f35b34801561026b57600080fd5b5061016a600160a060020a0360043581169060243516610b46565b34801561029257600080fd5b506101b8600160a060020a0360043516610b63565b3480156102b357600080fd5b5061016a600160a060020a0360043581169060243516610b86565b3480156102da57600080fd5b5061016a610f9f565b60046020526000908152604090208054600190910154600160a060020a031682565b600260208181526000938452604080852090915291835291208054600182015492820154600390920154600160a060020a0390911692919084565b600061034a61112b565b600080610355611142565b600460006103628b610fa5565b815260208082019290925260409081016000908120825180840184528154808252600190920154600160a060020a0390811682870181905285517f0905c9f9000000000000000000000000000000000000000000000000000000008152600260048201526024810194909452908f16604484015230606484015233608484015293519098509296508693630905c9f99360a48084019492939192918390030190829087803b15801561041357600080fd5b505af1158015610427573d6000803e3d6000fd5b505050506040513d602081101561043d57600080fd5b8101908080519060200190929190505050915060806040519081016040528089600160a060020a0316815260200188600019168152602001600181526020018760001916815250905080600260008b600160a060020a0316600160a060020a031681526020019081526020016000206000846000191660001916815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010190600019169055604082015181600201556060820151816003019060001916905590505082600160a060020a031682600019168a600160a060020a03167f4e87f569c5a3f504eea38add71bbdd022e5d63d0ee92d4130c407b8d64941bc08b8b8b6040518084600160a060020a0316600160a060020a0316815260200183600019166000191681526020018260001916600019168152602001935050505060405180910390a4604080517f339e23d100000000000000000000000000000000000000000000000000000000815260048101849052600160248201523360448201529051600160a060020a0385169163339e23d19160648083019260209291908290030181600087803b15801561061057600080fd5b505af1158015610624573d6000803e3d6000fd5b505050506040513d602081101561063a57600080fd5b50919998505050505050505050565b6040805160208082018590526c01000000000000000000000000600160a060020a0385160282840152825160348184030181526054909201928390528151600093918291908401908083835b602083106106b45780518252601f199092019160209182019101610695565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209695505050505050565b600054600160a060020a031633146106fe57600080fd5b600155565b60008061070e611142565b60003360048261071d89610fa5565b8152602081019190915260400160002060010154600160a060020a03161461074457600080fd5b600160a060020a0380871660009081526002602081815260408084208c855282529283902083516080810185528154909516808652600182810154938701939093529281015493850193909352600390920154606084015290945090925015156107ad57600080fd5b600160a060020a03861660008181526002602081815260408084208c8552909152808320805473ffffffffffffffffffffffffffffffffffffffff19168155600181018490559182018390556003909101829055518992917f6bc0cb9e9967b59a69ace442598e1df4368d38661bd5c0800fbcbc9fe855fbbe91a38460011415610a2b5785600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561086f57600080fd5b505af1158015610883573d6000803e3d6000fd5b505050506040513d602081101561089957600080fd5b5051604083015190915060011415610980578151602080840151604080517fe4537a74000000000000000000000000000000000000000000000000000000008152600160a060020a03948516600482015260248101929092528984166044830152519284169263e4537a74926064808401939192918290030181600087803b15801561092457600080fd5b505af1158015610938573d6000803e3d6000fd5b505050506040513d602081101561094e57600080fd5b50516060830151600160a060020a03808916600090815260036020908152604080832088519094168352929052205592505b816040015160021415610a2b578151604080517f4f52b5be000000000000000000000000000000000000000000000000000000008152600160a060020a0392831660048201528883166024820152905191831691634f52b5be916044808201926020929091908290030181600087803b1580156109fc57600080fd5b505af1158015610a10573d6000803e3d6000fd5b505050506040513d6020811015610a2657600080fd5b505192505b6040805186815290518891600160a060020a038916917fd2632e80f5364f02aded1c64e8a04637b7c8bb9c2db2bedf4b6ac47c013acbc09181900360200190a3509095945050505050565b600080610a838484610649565b60008181526004602052604090208581556001018054600160a060020a03861673ffffffffffffffffffffffffffffffffffffffff1990911617905591508190505092915050565b600054600160a060020a03163314610ae257600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031681565b600360209081526000928352604080842090915290825290205481565b600054600160a060020a03163314610b7a57600080fd5b610b83816110ae565b50565b600080610b9161112b565b600080610b9c611142565b87600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610bda57600080fd5b505af1158015610bee573d6000803e3d6000fd5b505050506040513d6020811015610c0457600080fd5b5051604080517ff76488be000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660048301528b8116602483015291519297509087169163f76488be916044808201926020929091908290030181600087803b158015610c7657600080fd5b505af1158015610c8a573d6000803e3d6000fd5b505050506040513d6020811015610ca057600080fd5b50511515610cad57600080fd5b60046000610cba8a610fa5565b8152602080820192909252604090810160009081208251808401845281548152600190910154600160a060020a039081168286018190528d821680855260038752858520928e1685529186528484205485517f0905c9f9000000000000000000000000000000000000000000000000000000008152600260048201526024810191909152604481019290925230606483015233608483015293519198509296508693630905c9f99360a480820194929392918390030190829087803b158015610d8257600080fd5b505af1158015610d96573d6000803e3d6000fd5b505050506040513d6020811015610dac57600080fd5b8101908080519060200190929190505050915060806040519081016040528088600160a060020a03168152602001600060010260001916815260200160028152602001600060010260001916815250905080600260008a600160a060020a0316600160a060020a031681526020019081526020016000206000846000191660001916815260200190815260200160002060008201518160000160006101000a815481600160a060020a030219169083600160a060020a0316021790555060208201518160010190600019169055604082015181600201556060820151816003019060001916905590505082600160a060020a0316826000191689600160a060020a03167f661684a19fb0680f3f8beceaa9ee56c665ffec0875442e2cddc9a7a887d35c3e8a6040518082600160a060020a0316600160a060020a0316815260200191505060405180910390a4604080517f339e23d100000000000000000000000000000000000000000000000000000000815260048101849052600160248201523360448201529051600160a060020a0385169163339e23d19160648083019260209291908290030181600087803b158015610f6757600080fd5b505af1158015610f7b573d6000803e3d6000fd5b505050506040513d6020811015610f9157600080fd5b509198975050505050505050565b60015481565b600081600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610fe557600080fd5b505af1158015610ff9573d6000803e3d6000fd5b505050506040513d602081101561100f57600080fd5b5051604080517f1c4d5608000000000000000000000000000000000000000000000000000000008152306004820152600160a060020a03858116602483015291519190921691631c4d56089160448083019260209291908290030181600087803b15801561107c57600080fd5b505af1158015611090573d6000803e3d6000fd5b505050506040513d60208110156110a657600080fd5b505192915050565b600160a060020a03811615156110c357600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b604080518082019091526000808252602082015290565b604080516080810182526000808252602082018190529181018290526060810191909152905600a165627a7a72305820e23a6560763f43afb57384018e6b3c38bfd6cc991292df3cb26a9fc84eca751f0029
Swarm Source
bzzr://e23a6560763f43afb57384018e6b3c38bfd6cc991292df3cb26a9fc84eca751f
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.