Overview
POL Balance
0 POL
POL Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Voting
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* * SPDX-License-Identitifer: GPL-3.0-or-later */ pragma solidity 0.4.24; import "@aragon/os/contracts/apps/AragonApp.sol"; import "@aragon/os/contracts/common/IForwarder.sol"; import "@aragon/os/contracts/lib/math/SafeMath.sol"; import "@aragon/os/contracts/lib/math/SafeMath64.sol"; import "@aragon/minime/contracts/MiniMeToken.sol"; contract Voting is IForwarder, AragonApp { using SafeMath for uint256; using SafeMath64 for uint64; bytes32 public constant CREATE_VOTES_ROLE = keccak256("CREATE_VOTES_ROLE"); bytes32 public constant MODIFY_SUPPORT_ROLE = keccak256("MODIFY_SUPPORT_ROLE"); bytes32 public constant MODIFY_QUORUM_ROLE = keccak256("MODIFY_QUORUM_ROLE"); uint64 public constant PCT_BASE = 10 ** 18; // 0% = 0; 1% = 10^16; 100% = 10^18 string private constant ERROR_NO_VOTE = "VOTING_NO_VOTE"; string private constant ERROR_INIT_PCTS = "VOTING_INIT_PCTS"; string private constant ERROR_CHANGE_SUPPORT_PCTS = "VOTING_CHANGE_SUPPORT_PCTS"; string private constant ERROR_CHANGE_QUORUM_PCTS = "VOTING_CHANGE_QUORUM_PCTS"; string private constant ERROR_INIT_SUPPORT_TOO_BIG = "VOTING_INIT_SUPPORT_TOO_BIG"; string private constant ERROR_CHANGE_SUPPORT_TOO_BIG = "VOTING_CHANGE_SUPP_TOO_BIG"; string private constant ERROR_CAN_NOT_VOTE = "VOTING_CAN_NOT_VOTE"; string private constant ERROR_CAN_NOT_EXECUTE = "VOTING_CAN_NOT_EXECUTE"; string private constant ERROR_CAN_NOT_FORWARD = "VOTING_CAN_NOT_FORWARD"; string private constant ERROR_NO_VOTING_POWER = "VOTING_NO_VOTING_POWER"; enum VoterState { Absent, Yea, Nay } struct Vote { bool executed; uint64 startDate; uint64 snapshotBlock; uint64 supportRequiredPct; uint64 minAcceptQuorumPct; uint256 yea; uint256 nay; uint256 votingPower; bytes executionScript; mapping (address => VoterState) voters; } MiniMeToken public token; uint64 public supportRequiredPct; uint64 public minAcceptQuorumPct; uint64 public voteTime; // We are mimicing an array, we use a mapping instead to make app upgrade more graceful mapping (uint256 => Vote) internal votes; uint256 public votesLength; event StartVote(uint256 indexed voteId, address indexed creator, string metadata); event CastVote(uint256 indexed voteId, address indexed voter, bool supports, uint256 stake); event ExecuteVote(uint256 indexed voteId); event ChangeSupportRequired(uint64 supportRequiredPct); event ChangeMinQuorum(uint64 minAcceptQuorumPct); modifier voteExists(uint256 _voteId) { require(_voteId < votesLength, ERROR_NO_VOTE); _; } /** * @notice Initialize Voting app with `_token.symbol(): string` for governance, minimum support of `@formatPct(_supportRequiredPct)`%, minimum acceptance quorum of `@formatPct(_minAcceptQuorumPct)`%, and a voting duration of `@transformTime(_voteTime)` * @param _token MiniMeToken Address that will be used as governance token * @param _supportRequiredPct Percentage of yeas in casted votes for a vote to succeed (expressed as a percentage of 10^18; eg. 10^16 = 1%, 10^18 = 100%) * @param _minAcceptQuorumPct Percentage of yeas in total possible votes for a vote to succeed (expressed as a percentage of 10^18; eg. 10^16 = 1%, 10^18 = 100%) * @param _voteTime Seconds that a vote will be open for token holders to vote (unless enough yeas or nays have been cast to make an early decision) */ function initialize(MiniMeToken _token, uint64 _supportRequiredPct, uint64 _minAcceptQuorumPct, uint64 _voteTime) external onlyInit { initialized(); require(_minAcceptQuorumPct <= _supportRequiredPct, ERROR_INIT_PCTS); require(_supportRequiredPct < PCT_BASE, ERROR_INIT_SUPPORT_TOO_BIG); token = _token; supportRequiredPct = _supportRequiredPct; minAcceptQuorumPct = _minAcceptQuorumPct; voteTime = _voteTime; } /** * @notice Change required support to `@formatPct(_supportRequiredPct)`% * @param _supportRequiredPct New required support */ function changeSupportRequiredPct(uint64 _supportRequiredPct) external authP(MODIFY_SUPPORT_ROLE, arr(uint256(_supportRequiredPct), uint256(supportRequiredPct))) { require(minAcceptQuorumPct <= _supportRequiredPct, ERROR_CHANGE_SUPPORT_PCTS); require(_supportRequiredPct < PCT_BASE, ERROR_CHANGE_SUPPORT_TOO_BIG); supportRequiredPct = _supportRequiredPct; emit ChangeSupportRequired(_supportRequiredPct); } /** * @notice Change minimum acceptance quorum to `@formatPct(_minAcceptQuorumPct)`% * @param _minAcceptQuorumPct New acceptance quorum */ function changeMinAcceptQuorumPct(uint64 _minAcceptQuorumPct) external authP(MODIFY_QUORUM_ROLE, arr(uint256(_minAcceptQuorumPct), uint256(minAcceptQuorumPct))) { require(_minAcceptQuorumPct <= supportRequiredPct, ERROR_CHANGE_QUORUM_PCTS); minAcceptQuorumPct = _minAcceptQuorumPct; emit ChangeMinQuorum(_minAcceptQuorumPct); } /** * @notice Create a new vote about "`_metadata`" * @param _executionScript EVM script to be executed on approval * @param _metadata Vote metadata * @return voteId Id for newly created vote */ function newVote(bytes _executionScript, string _metadata) external auth(CREATE_VOTES_ROLE) returns (uint256 voteId) { return _newVote(_executionScript, _metadata, true, true); } /** * @notice Create a new vote about "`_metadata`" * @param _executionScript EVM script to be executed on approval * @param _metadata Vote metadata * @param _castVote Whether to also cast newly created vote * @param _executesIfDecided Whether to also immediately execute newly created vote if decided * @return voteId id for newly created vote */ function newVote(bytes _executionScript, string _metadata, bool _castVote, bool _executesIfDecided) external auth(CREATE_VOTES_ROLE) returns (uint256 voteId) { return _newVote(_executionScript, _metadata, _castVote, _executesIfDecided); } /** * @notice Vote `_supports ? 'yes' : 'no'` in vote #`_voteId` * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be * created via `newVote(),` which requires initialization * @param _voteId Id for vote * @param _supports Whether voter supports the vote * @param _executesIfDecided Whether the vote should execute its action if it becomes decided */ function vote(uint256 _voteId, bool _supports, bool _executesIfDecided) external voteExists(_voteId) { require(_canVote(_voteId, msg.sender), ERROR_CAN_NOT_VOTE); _vote(_voteId, _supports, msg.sender, _executesIfDecided); } /** * @notice Execute vote #`_voteId` * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be * created via `newVote(),` which requires initialization * @param _voteId Id for vote */ function executeVote(uint256 _voteId) external voteExists(_voteId) { _executeVote(_voteId); } // Forwarding fns /** * @notice Tells whether the Voting app is a forwarder or not * @dev IForwarder interface conformance * @return Always true */ function isForwarder() external pure returns (bool) { return true; } /** * @notice Creates a vote to execute the desired action, and casts a support vote if possible * @dev IForwarder interface conformance * @param _evmScript Start vote with script */ function forward(bytes _evmScript) public { require(canForward(msg.sender, _evmScript), ERROR_CAN_NOT_FORWARD); _newVote(_evmScript, "", true, true); } /** * @notice Tells whether `_sender` can forward actions or not * @dev IForwarder interface conformance * @param _sender Address of the account intending to forward an action * @return True if the given address can create votes, false otherwise */ function canForward(address _sender, bytes) public view returns (bool) { // Note that `canPerform()` implicitly does an initialization check itself return canPerform(_sender, CREATE_VOTES_ROLE, arr()); } // Getter fns /** * @notice Tells whether a vote #`_voteId` can be executed or not * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be * created via `newVote(),` which requires initialization * @return True if the given vote can be executed, false otherwise */ function canExecute(uint256 _voteId) public view voteExists(_voteId) returns (bool) { return _canExecute(_voteId); } /** * @notice Tells whether `_sender` can participate in the vote #`_voteId` or not * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be * created via `newVote(),` which requires initialization * @return True if the given voter can participate a certain vote, false otherwise */ function canVote(uint256 _voteId, address _voter) public view voteExists(_voteId) returns (bool) { return _canVote(_voteId, _voter); } /** * @dev Return all information for a vote by its ID * @param _voteId Vote identifier * @return Vote open status * @return Vote executed status * @return Vote start date * @return Vote snapshot block * @return Vote support required * @return Vote minimum acceptance quorum * @return Vote yeas amount * @return Vote nays amount * @return Vote power * @return Vote script */ function getVote(uint256 _voteId) public view voteExists(_voteId) returns ( bool open, bool executed, uint64 startDate, uint64 snapshotBlock, uint64 supportRequired, uint64 minAcceptQuorum, uint256 yea, uint256 nay, uint256 votingPower, bytes script ) { Vote storage vote_ = votes[_voteId]; open = _isVoteOpen(vote_); executed = vote_.executed; startDate = vote_.startDate; snapshotBlock = vote_.snapshotBlock; supportRequired = vote_.supportRequiredPct; minAcceptQuorum = vote_.minAcceptQuorumPct; yea = vote_.yea; nay = vote_.nay; votingPower = vote_.votingPower; script = vote_.executionScript; } /** * @dev Return the state of a voter for a given vote by its ID * @param _voteId Vote identifier * @return VoterState of the requested voter for a certain vote */ function getVoterState(uint256 _voteId, address _voter) public view voteExists(_voteId) returns (VoterState) { return votes[_voteId].voters[_voter]; } // Internal fns /** * @dev Internal function to create a new vote * @return voteId id for newly created vote */ function _newVote(bytes _executionScript, string _metadata, bool _castVote, bool _executesIfDecided) internal returns (uint256 voteId) { uint64 snapshotBlock = getBlockNumber64() - 1; // avoid double voting in this very block uint256 votingPower = token.totalSupplyAt(snapshotBlock); require(votingPower > 0, ERROR_NO_VOTING_POWER); voteId = votesLength++; Vote storage vote_ = votes[voteId]; vote_.startDate = getTimestamp64(); vote_.snapshotBlock = snapshotBlock; vote_.supportRequiredPct = supportRequiredPct; vote_.minAcceptQuorumPct = minAcceptQuorumPct; vote_.votingPower = votingPower; vote_.executionScript = _executionScript; emit StartVote(voteId, msg.sender, _metadata); if (_castVote && _canVote(voteId, msg.sender)) { _vote(voteId, true, msg.sender, _executesIfDecided); } } /** * @dev Internal function to cast a vote. It assumes the queried vote exists. */ function _vote(uint256 _voteId, bool _supports, address _voter, bool _executesIfDecided) internal { Vote storage vote_ = votes[_voteId]; // This could re-enter, though we can assume the governance token is not malicious uint256 voterStake = token.balanceOfAt(_voter, vote_.snapshotBlock); VoterState state = vote_.voters[_voter]; // If voter had previously voted, decrease count if (state == VoterState.Yea) { vote_.yea = vote_.yea.sub(voterStake); } else if (state == VoterState.Nay) { vote_.nay = vote_.nay.sub(voterStake); } if (_supports) { vote_.yea = vote_.yea.add(voterStake); } else { vote_.nay = vote_.nay.add(voterStake); } vote_.voters[_voter] = _supports ? VoterState.Yea : VoterState.Nay; emit CastVote(_voteId, _voter, _supports, voterStake); if (_executesIfDecided && _canExecute(_voteId)) { // We've already checked if the vote can be executed with `_canExecute()` _unsafeExecuteVote(_voteId); } } /** * @dev Internal function to execute a vote. It assumes the queried vote exists. */ function _executeVote(uint256 _voteId) internal { require(_canExecute(_voteId), ERROR_CAN_NOT_EXECUTE); _unsafeExecuteVote(_voteId); } /** * @dev Unsafe version of _executeVote that assumes you have already checked if the vote can be executed and exists */ function _unsafeExecuteVote(uint256 _voteId) internal { Vote storage vote_ = votes[_voteId]; vote_.executed = true; bytes memory input = new bytes(0); // TODO: Consider input for voting scripts runScript(vote_.executionScript, input, new address[](0)); emit ExecuteVote(_voteId); } /** * @dev Internal function to check if a vote can be executed. It assumes the queried vote exists. * @return True if the given vote can be executed, false otherwise */ function _canExecute(uint256 _voteId) internal view returns (bool) { Vote storage vote_ = votes[_voteId]; if (vote_.executed) { return false; } // Voting is already decided if (_isValuePct(vote_.yea, vote_.votingPower, vote_.supportRequiredPct)) { return true; } // Vote ended? if (_isVoteOpen(vote_)) { return false; } // Has enough support? uint256 totalVotes = vote_.yea.add(vote_.nay); if (!_isValuePct(vote_.yea, totalVotes, vote_.supportRequiredPct)) { return false; } // Has min quorum? if (!_isValuePct(vote_.yea, vote_.votingPower, vote_.minAcceptQuorumPct)) { return false; } return true; } /** * @dev Internal function to check if a voter can participate on a vote. It assumes the queried vote exists. * @return True if the given voter can participate a certain vote, false otherwise */ function _canVote(uint256 _voteId, address _voter) internal view returns (bool) { Vote storage vote_ = votes[_voteId]; return _isVoteOpen(vote_) && token.balanceOfAt(_voter, vote_.snapshotBlock) > 0; } /** * @dev Internal function to check if a vote is still open * @return True if the given vote is open, false otherwise */ function _isVoteOpen(Vote storage vote_) internal view returns (bool) { return getTimestamp64() < vote_.startDate.add(voteTime) && !vote_.executed; } /** * @dev Calculates whether `_value` is more than a percentage `_pct` of `_total` */ function _isValuePct(uint256 _value, uint256 _total, uint256 _pct) internal pure returns (bool) { if (_total == 0) { return false; } uint256 computedPct = _value.mul(PCT_BASE) / _total; return computedPct > _pct; } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "./AppStorage.sol"; import "../acl/ACLSyntaxSugar.sol"; import "../common/Autopetrified.sol"; import "../common/ConversionHelpers.sol"; import "../common/ReentrancyGuard.sol"; import "../common/VaultRecoverable.sol"; import "../evmscript/EVMScriptRunner.sol"; // Contracts inheriting from AragonApp are, by default, immediately petrified upon deployment so // that they can never be initialized. // Unless overriden, this behaviour enforces those contracts to be usable only behind an AppProxy. // ReentrancyGuard, EVMScriptRunner, and ACLSyntaxSugar are not directly used by this contract, but // are included so that they are automatically usable by subclassing contracts contract AragonApp is AppStorage, Autopetrified, VaultRecoverable, ReentrancyGuard, EVMScriptRunner, ACLSyntaxSugar { string private constant ERROR_AUTH_FAILED = "APP_AUTH_FAILED"; modifier auth(bytes32 _role) { require(canPerform(msg.sender, _role, new uint256[](0)), ERROR_AUTH_FAILED); _; } modifier authP(bytes32 _role, uint256[] _params) { require(canPerform(msg.sender, _role, _params), ERROR_AUTH_FAILED); _; } /** * @dev Check whether an action can be performed by a sender for a particular role on this app * @param _sender Sender of the call * @param _role Role on this app * @param _params Permission params for the role * @return Boolean indicating whether the sender has the permissions to perform the action. * Always returns false if the app hasn't been initialized yet. */ function canPerform(address _sender, bytes32 _role, uint256[] _params) public view returns (bool) { if (!hasInitialized()) { return false; } IKernel linkedKernel = kernel(); if (address(linkedKernel) == address(0)) { return false; } return linkedKernel.hasPermission( _sender, address(this), _role, ConversionHelpers.dangerouslyCastUintArrayToBytes(_params) ); } /** * @dev Get the recovery vault for the app * @return Recovery vault address for the app */ function getRecoveryVault() public view returns (address) { // Funds recovery via a vault is only available when used with a kernel return kernel().getRecoveryVault(); // if kernel is not set, it will revert } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; interface IForwarder { function isForwarder() external pure returns (bool); // TODO: this should be external // See https://github.com/ethereum/solidity/issues/4832 function canForward(address sender, bytes evmCallScript) public view returns (bool); // TODO: this should be external // See https://github.com/ethereum/solidity/issues/4832 function forward(bytes evmCallScript) public; }
// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/d51e38758e1d985661534534d5c61e27bece5042/contracts/math/SafeMath.sol // Adapted to use pragma ^0.4.24 and satisfy our linter rules pragma solidity ^0.4.24; /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { string private constant ERROR_ADD_OVERFLOW = "MATH_ADD_OVERFLOW"; string private constant ERROR_SUB_UNDERFLOW = "MATH_SUB_UNDERFLOW"; string private constant ERROR_MUL_OVERFLOW = "MATH_MUL_OVERFLOW"; string private constant ERROR_DIV_ZERO = "MATH_DIV_ZERO"; /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint256 _a, uint256 _b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring '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; } uint256 c = _a * _b; require(c / _a == _b, ERROR_MUL_OVERFLOW); return c; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint256 _a, uint256 _b) internal pure returns (uint256) { require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts 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 c; } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 _a, uint256 _b) internal pure returns (uint256) { require(_b <= _a, ERROR_SUB_UNDERFLOW); uint256 c = _a - _b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint256 _a, uint256 _b) internal pure returns (uint256) { uint256 c = _a + _b; require(c >= _a, ERROR_ADD_OVERFLOW); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, ERROR_DIV_ZERO); return a % b; } }
// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/d51e38758e1d985661534534d5c61e27bece5042/contracts/math/SafeMath.sol // Adapted for uint64, pragma ^0.4.24, and satisfying our linter rules // Also optimized the mul() implementation, see https://github.com/aragon/aragonOS/pull/417 pragma solidity ^0.4.24; /** * @title SafeMath64 * @dev Math operations for uint64 with safety checks that revert on error */ library SafeMath64 { string private constant ERROR_ADD_OVERFLOW = "MATH64_ADD_OVERFLOW"; string private constant ERROR_SUB_UNDERFLOW = "MATH64_SUB_UNDERFLOW"; string private constant ERROR_MUL_OVERFLOW = "MATH64_MUL_OVERFLOW"; string private constant ERROR_DIV_ZERO = "MATH64_DIV_ZERO"; /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint64 _a, uint64 _b) internal pure returns (uint64) { uint256 c = uint256(_a) * uint256(_b); require(c < 0x010000000000000000, ERROR_MUL_OVERFLOW); // 2**64 (less gas this way) return uint64(c); } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint64 _a, uint64 _b) internal pure returns (uint64) { require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts when dividing by 0 uint64 c = _a / _b; // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint64 _a, uint64 _b) internal pure returns (uint64) { require(_b <= _a, ERROR_SUB_UNDERFLOW); uint64 c = _a - _b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint64 _a, uint64 _b) internal pure returns (uint64) { uint64 c = _a + _b; require(c >= _a, ERROR_ADD_OVERFLOW); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint64 a, uint64 b) internal pure returns (uint64) { require(b != 0, ERROR_DIV_ZERO); return a % b; } }
pragma solidity ^0.4.24; /* Copyright 2016, Jordi Baylina This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /// @title MiniMeToken Contract /// @author Jordi Baylina /// @dev This token contract's goal is to make it easy for anyone to clone this /// token using the token distribution at a given block, this will allow DAO's /// and DApps to upgrade their features in a decentralized manner without /// affecting the original token /// @dev It is ERC20 compliant, but still needs to under go further testing. import "./ITokenController.sol"; contract Controlled { /// @notice The address of the controller is the only address that can call /// a function with this modifier modifier onlyController { require(msg.sender == controller); _; } address public controller; function Controlled() public { controller = msg.sender;} /// @notice Changes the controller of the contract /// @param _newController The new controller of the contract function changeController(address _newController) onlyController public { controller = _newController; } } contract ApproveAndCallFallBack { function receiveApproval( address from, uint256 _amount, address _token, bytes _data ) public; } /// @dev The actual token contract, the default controller is the msg.sender /// that deploys the contract, so usually this token will be deployed by a /// token controller contract, which Giveth will call a "Campaign" contract MiniMeToken is Controlled { string public name; //The Token's name: e.g. DigixDAO Tokens uint8 public decimals; //Number of decimals of the smallest unit string public symbol; //An identifier: e.g. REP string public version = "MMT_0.1"; //An arbitrary versioning scheme /// @dev `Checkpoint` is the structure that attaches a block number to a /// given value, the block number attached is the one that last changed the /// value struct Checkpoint { // `fromBlock` is the block number that the value was generated from uint128 fromBlock; // `value` is the amount of tokens at a specific block number uint128 value; } // `parentToken` is the Token address that was cloned to produce this token; // it will be 0x0 for a token that was not cloned MiniMeToken public parentToken; // `parentSnapShotBlock` is the block number from the Parent Token that was // used to determine the initial distribution of the Clone Token uint public parentSnapShotBlock; // `creationBlock` is the block number that the Clone Token was created uint public creationBlock; // `balances` is the map that tracks the balance of each address, in this // contract when the balance changes the block number that the change // occurred is also included in the map mapping (address => Checkpoint[]) balances; // `allowed` tracks any extra transfer rights as in all ERC20 tokens mapping (address => mapping (address => uint256)) allowed; // Tracks the history of the `totalSupply` of the token Checkpoint[] totalSupplyHistory; // Flag that determines if the token is transferable or not. bool public transfersEnabled; // The factory used to create new clone tokens MiniMeTokenFactory public tokenFactory; //////////////// // Constructor //////////////// /// @notice Constructor to create a MiniMeToken /// @param _tokenFactory The address of the MiniMeTokenFactory contract that /// will create the Clone token contracts, the token factory needs to be /// deployed first /// @param _parentToken Address of the parent token, set to 0x0 if it is a /// new token /// @param _parentSnapShotBlock Block of the parent token that will /// determine the initial distribution of the clone token, set to 0 if it /// is a new token /// @param _tokenName Name of the new token /// @param _decimalUnits Number of decimals of the new token /// @param _tokenSymbol Token Symbol for the new token /// @param _transfersEnabled If true, tokens will be able to be transferred function MiniMeToken( MiniMeTokenFactory _tokenFactory, MiniMeToken _parentToken, uint _parentSnapShotBlock, string _tokenName, uint8 _decimalUnits, string _tokenSymbol, bool _transfersEnabled ) public { tokenFactory = _tokenFactory; name = _tokenName; // Set the name decimals = _decimalUnits; // Set the decimals symbol = _tokenSymbol; // Set the symbol parentToken = _parentToken; parentSnapShotBlock = _parentSnapShotBlock; transfersEnabled = _transfersEnabled; creationBlock = block.number; } /////////////////// // ERC20 Methods /////////////////// /// @notice Send `_amount` tokens to `_to` from `msg.sender` /// @param _to The address of the recipient /// @param _amount The amount of tokens to be transferred /// @return Whether the transfer was successful or not function transfer(address _to, uint256 _amount) public returns (bool success) { require(transfersEnabled); return doTransfer(msg.sender, _to, _amount); } /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it /// is approved by `_from` /// @param _from The address holding the tokens being transferred /// @param _to The address of the recipient /// @param _amount The amount of tokens to be transferred /// @return True if the transfer was successful function transferFrom(address _from, address _to, uint256 _amount) public returns (bool success) { // The controller of this contract can move tokens around at will, // this is important to recognize! Confirm that you trust the // controller of this contract, which in most situations should be // another open source smart contract or 0x0 if (msg.sender != controller) { require(transfersEnabled); // The standard ERC 20 transferFrom functionality if (allowed[_from][msg.sender] < _amount) return false; allowed[_from][msg.sender] -= _amount; } return doTransfer(_from, _to, _amount); } /// @dev This is the actual transfer function in the token contract, it can /// only be called by other functions in this contract. /// @param _from The address holding the tokens being transferred /// @param _to The address of the recipient /// @param _amount The amount of tokens to be transferred /// @return True if the transfer was successful function doTransfer(address _from, address _to, uint _amount) internal returns(bool) { if (_amount == 0) { return true; } require(parentSnapShotBlock < block.number); // Do not allow transfer to 0x0 or the token contract itself require((_to != 0) && (_to != address(this))); // If the amount being transfered is more than the balance of the // account the transfer returns false var previousBalanceFrom = balanceOfAt(_from, block.number); if (previousBalanceFrom < _amount) { return false; } // Alerts the token controller of the transfer if (isContract(controller)) { // Adding the ` == true` makes the linter shut up so... require(ITokenController(controller).onTransfer(_from, _to, _amount) == true); } // First update the balance array with the new value for the address // sending the tokens updateValueAtNow(balances[_from], previousBalanceFrom - _amount); // Then update the balance array with the new value for the address // receiving the tokens var previousBalanceTo = balanceOfAt(_to, block.number); require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow updateValueAtNow(balances[_to], previousBalanceTo + _amount); // An event to make the transfer easy to find on the blockchain Transfer(_from, _to, _amount); return true; } /// @param _owner The address that's balance is being requested /// @return The balance of `_owner` at the current block function balanceOf(address _owner) public constant returns (uint256 balance) { return balanceOfAt(_owner, block.number); } /// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on /// its behalf. This is a modified version of the ERC20 approve function /// to be a little bit safer /// @param _spender The address of the account able to transfer the tokens /// @param _amount The amount of tokens to be approved for transfer /// @return True if the approval was successful function approve(address _spender, uint256 _amount) public returns (bool success) { require(transfersEnabled); // To change the approve amount you first have to reduce the addresses` // allowance to zero by calling `approve(_spender,0)` if it is not // already 0 to mitigate the race condition described here: // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 require((_amount == 0) || (allowed[msg.sender][_spender] == 0)); // Alerts the token controller of the approve function call if (isContract(controller)) { // Adding the ` == true` makes the linter shut up so... require(ITokenController(controller).onApprove(msg.sender, _spender, _amount) == true); } allowed[msg.sender][_spender] = _amount; Approval(msg.sender, _spender, _amount); return true; } /// @dev This function makes it easy to read the `allowed[]` map /// @param _owner The address of the account that owns the token /// @param _spender The address of the account able to transfer the tokens /// @return Amount of remaining tokens of _owner that _spender is allowed /// to spend function allowance(address _owner, address _spender) public constant returns (uint256 remaining) { return allowed[_owner][_spender]; } /// @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(ApproveAndCallFallBack _spender, uint256 _amount, bytes _extraData) public returns (bool success) { require(approve(_spender, _amount)); _spender.receiveApproval( msg.sender, _amount, this, _extraData ); return true; } /// @dev This function makes it easy to get the total number of tokens /// @return The total number of tokens function totalSupply() public constant returns (uint) { return totalSupplyAt(block.number); } //////////////// // Query balance and totalSupply in History //////////////// /// @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) { // These next few lines are used when the balance of the token is // requested before a check point was ever created for this token, it // requires that the `parentToken.balanceOfAt` be queried at the // genesis block for that token as this contains initial balance of // this token if ((balances[_owner].length == 0) || (balances[_owner][0].fromBlock > _blockNumber)) { if (address(parentToken) != 0) { return parentToken.balanceOfAt(_owner, min(_blockNumber, parentSnapShotBlock)); } else { // Has no parent return 0; } // This will return the expected balance during normal situations } else { return getValueAt(balances[_owner], _blockNumber); } } /// @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 constant returns(uint) { // These next few lines are used when the totalSupply of the token is // requested before a check point was ever created for this token, it // requires that the `parentToken.totalSupplyAt` be queried at the // genesis block for this token as that contains totalSupply of this // token at this block number. if ((totalSupplyHistory.length == 0) || (totalSupplyHistory[0].fromBlock > _blockNumber)) { if (address(parentToken) != 0) { return parentToken.totalSupplyAt(min(_blockNumber, parentSnapShotBlock)); } else { return 0; } // This will return the expected totalSupply during normal situations } else { return getValueAt(totalSupplyHistory, _blockNumber); } } //////////////// // Clone Token Method //////////////// /// @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(MiniMeToken) { uint256 snapshot = _snapshotBlock == 0 ? block.number - 1 : _snapshotBlock; MiniMeToken cloneToken = tokenFactory.createCloneToken( this, snapshot, _cloneTokenName, _cloneDecimalUnits, _cloneTokenSymbol, _transfersEnabled ); cloneToken.changeController(msg.sender); // An event to make the token easy to find on the blockchain NewCloneToken(address(cloneToken), snapshot); return cloneToken; } //////////////// // Generate and destroy tokens //////////////// /// @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) onlyController public returns (bool) { uint curTotalSupply = totalSupply(); require(curTotalSupply + _amount >= curTotalSupply); // Check for overflow uint previousBalanceTo = balanceOf(_owner); require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow updateValueAtNow(totalSupplyHistory, curTotalSupply + _amount); updateValueAtNow(balances[_owner], previousBalanceTo + _amount); Transfer(0, _owner, _amount); return true; } /// @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) onlyController public returns (bool) { uint curTotalSupply = totalSupply(); require(curTotalSupply >= _amount); uint previousBalanceFrom = balanceOf(_owner); require(previousBalanceFrom >= _amount); updateValueAtNow(totalSupplyHistory, curTotalSupply - _amount); updateValueAtNow(balances[_owner], previousBalanceFrom - _amount); Transfer(_owner, 0, _amount); return true; } //////////////// // Enable tokens transfers //////////////// /// @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) onlyController public { transfersEnabled = _transfersEnabled; } //////////////// // Internal helper functions to query and set a value in a snapshot array //////////////// /// @dev `getValueAt` retrieves the number of tokens at a given block number /// @param checkpoints The history of values being queried /// @param _block The block number to retrieve the value at /// @return The number of tokens being queried function getValueAt(Checkpoint[] storage checkpoints, uint _block) constant internal returns (uint) { if (checkpoints.length == 0) return 0; // Shortcut for the actual value if (_block >= checkpoints[checkpoints.length-1].fromBlock) return checkpoints[checkpoints.length-1].value; if (_block < checkpoints[0].fromBlock) return 0; // Binary search of the value in the 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; } } return checkpoints[min].value; } /// @dev `updateValueAtNow` used to update the `balances` map and the /// `totalSupplyHistory` /// @param checkpoints The history of data being updated /// @param _value The new number of tokens function updateValueAtNow(Checkpoint[] storage checkpoints, uint _value) internal { require(_value <= uint128(-1)); if ((checkpoints.length == 0) || (checkpoints[checkpoints.length - 1].fromBlock < block.number)) { Checkpoint storage newCheckPoint = checkpoints[checkpoints.length++]; newCheckPoint.fromBlock = uint128(block.number); newCheckPoint.value = uint128(_value); } else { Checkpoint storage oldCheckPoint = checkpoints[checkpoints.length - 1]; oldCheckPoint.value = uint128(_value); } } /// @dev Internal function to determine if an address is a contract /// @param _addr The address being queried /// @return True if `_addr` is a contract function isContract(address _addr) constant internal returns(bool) { uint size; if (_addr == 0) return false; assembly { size := extcodesize(_addr) } return size>0; } /// @dev Helper function to return a min betwen the two uints function min(uint a, uint b) pure internal returns (uint) { return a < b ? a : b; } /// @notice The fallback function: If the contract's controller has not been /// set to 0, then the `proxyPayment` method is called which relays the /// ether and creates tokens as described in the token controller contract function () external payable { require(isContract(controller)); // Adding the ` == true` makes the linter shut up so... require(ITokenController(controller).proxyPayment.value(msg.value)(msg.sender) == true); } ////////// // Safety Methods ////////// /// @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) onlyController public { if (_token == 0x0) { controller.transfer(this.balance); return; } MiniMeToken token = MiniMeToken(_token); uint balance = token.balanceOf(this); token.transfer(controller, balance); ClaimedTokens(_token, controller, balance); } //////////////// // Events //////////////// event ClaimedTokens(address indexed _token, address indexed _controller, uint _amount); event Transfer(address indexed _from, address indexed _to, uint256 _amount); event NewCloneToken(address indexed _cloneToken, uint _snapshotBlock); event Approval( address indexed _owner, address indexed _spender, uint256 _amount ); } //////////////// // MiniMeTokenFactory //////////////// /// @dev This contract is used to generate clone contracts from a contract. /// In solidity this is the way to create a contract from a contract of the /// same class contract MiniMeTokenFactory { event NewFactoryCloneToken(address indexed _cloneToken, address indexed _parentToken, uint _snapshotBlock); /// @notice Update the DApp by creating a new token with new functionalities /// the msg.sender becomes the controller of this clone token /// @param _parentToken Address of the token being cloned /// @param _snapshotBlock Block of the parent token that will /// determine the initial distribution of the clone token /// @param _tokenName Name of the new token /// @param _decimalUnits Number of decimals of the new token /// @param _tokenSymbol Token Symbol for the new token /// @param _transfersEnabled If true, tokens will be able to be transferred /// @return The address of the new token contract function createCloneToken( MiniMeToken _parentToken, uint _snapshotBlock, string _tokenName, uint8 _decimalUnits, string _tokenSymbol, bool _transfersEnabled ) public returns (MiniMeToken) { MiniMeToken newToken = new MiniMeToken( this, _parentToken, _snapshotBlock, _tokenName, _decimalUnits, _tokenSymbol, _transfersEnabled ); newToken.changeController(msg.sender); NewFactoryCloneToken(address(newToken), address(_parentToken), _snapshotBlock); return newToken; } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "../common/UnstructuredStorage.sol"; import "../kernel/IKernel.sol"; contract AppStorage { using UnstructuredStorage for bytes32; /* Hardcoded constants to save gas bytes32 internal constant KERNEL_POSITION = keccak256("aragonOS.appStorage.kernel"); bytes32 internal constant APP_ID_POSITION = keccak256("aragonOS.appStorage.appId"); */ bytes32 internal constant KERNEL_POSITION = 0x4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b; bytes32 internal constant APP_ID_POSITION = 0xd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b; function kernel() public view returns (IKernel) { return IKernel(KERNEL_POSITION.getStorageAddress()); } function appId() public view returns (bytes32) { return APP_ID_POSITION.getStorageBytes32(); } function setKernel(IKernel _kernel) internal { KERNEL_POSITION.setStorageAddress(address(_kernel)); } function setAppId(bytes32 _appId) internal { APP_ID_POSITION.setStorageBytes32(_appId); } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; contract ACLSyntaxSugar { function arr() internal pure returns (uint256[]) { return new uint256[](0); } function arr(bytes32 _a) internal pure returns (uint256[] r) { return arr(uint256(_a)); } function arr(bytes32 _a, bytes32 _b) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b)); } function arr(address _a) internal pure returns (uint256[] r) { return arr(uint256(_a)); } function arr(address _a, address _b) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b)); } function arr(address _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) { return arr(uint256(_a), _b, _c); } function arr(address _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) { return arr(uint256(_a), _b, _c, _d); } function arr(address _a, uint256 _b) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b)); } function arr(address _a, address _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b), _c, _d, _e); } function arr(address _a, address _b, address _c) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b), uint256(_c)); } function arr(address _a, address _b, uint256 _c) internal pure returns (uint256[] r) { return arr(uint256(_a), uint256(_b), uint256(_c)); } function arr(uint256 _a) internal pure returns (uint256[] r) { r = new uint256[](1); r[0] = _a; } function arr(uint256 _a, uint256 _b) internal pure returns (uint256[] r) { r = new uint256[](2); r[0] = _a; r[1] = _b; } function arr(uint256 _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) { r = new uint256[](3); r[0] = _a; r[1] = _b; r[2] = _c; } function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) { r = new uint256[](4); r[0] = _a; r[1] = _b; r[2] = _c; r[3] = _d; } function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) { r = new uint256[](5); r[0] = _a; r[1] = _b; r[2] = _c; r[3] = _d; r[4] = _e; } } contract ACLHelpers { function decodeParamOp(uint256 _x) internal pure returns (uint8 b) { return uint8(_x >> (8 * 30)); } function decodeParamId(uint256 _x) internal pure returns (uint8 b) { return uint8(_x >> (8 * 31)); } function decodeParamsList(uint256 _x) internal pure returns (uint32 a, uint32 b, uint32 c) { a = uint32(_x); b = uint32(_x >> (8 * 4)); c = uint32(_x >> (8 * 8)); } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "./Petrifiable.sol"; contract Autopetrified is Petrifiable { constructor() public { // Immediately petrify base (non-proxy) instances of inherited contracts on deploy. // This renders them uninitializable (and unusable without a proxy). petrify(); } }
pragma solidity ^0.4.24; library ConversionHelpers { string private constant ERROR_IMPROPER_LENGTH = "CONVERSION_IMPROPER_LENGTH"; function dangerouslyCastUintArrayToBytes(uint256[] memory _input) internal pure returns (bytes memory output) { // Force cast the uint256[] into a bytes array, by overwriting its length // Note that the bytes array doesn't need to be initialized as we immediately overwrite it // with the input and a new length. The input becomes invalid from this point forward. uint256 byteLength = _input.length * 32; assembly { output := _input mstore(output, byteLength) } } function dangerouslyCastBytesToUintArray(bytes memory _input) internal pure returns (uint256[] memory output) { // Force cast the bytes array into a uint256[], by overwriting its length // Note that the uint256[] doesn't need to be initialized as we immediately overwrite it // with the input and a new length. The input becomes invalid from this point forward. uint256 intsLength = _input.length / 32; require(_input.length == intsLength * 32, ERROR_IMPROPER_LENGTH); assembly { output := _input mstore(output, intsLength) } } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "../common/UnstructuredStorage.sol"; contract ReentrancyGuard { using UnstructuredStorage for bytes32; /* Hardcoded constants to save gas bytes32 internal constant REENTRANCY_MUTEX_POSITION = keccak256("aragonOS.reentrancyGuard.mutex"); */ bytes32 private constant REENTRANCY_MUTEX_POSITION = 0xe855346402235fdd185c890e68d2c4ecad599b88587635ee285bce2fda58dacb; string private constant ERROR_REENTRANT = "REENTRANCY_REENTRANT_CALL"; modifier nonReentrant() { // Ensure mutex is unlocked require(!REENTRANCY_MUTEX_POSITION.getStorageBool(), ERROR_REENTRANT); // Lock mutex before function call REENTRANCY_MUTEX_POSITION.setStorageBool(true); // Perform function call _; // Unlock mutex after function call REENTRANCY_MUTEX_POSITION.setStorageBool(false); } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "../lib/token/ERC20.sol"; import "./EtherTokenConstant.sol"; import "./IsContract.sol"; import "./IVaultRecoverable.sol"; import "./SafeERC20.sol"; contract VaultRecoverable is IVaultRecoverable, EtherTokenConstant, IsContract { using SafeERC20 for ERC20; string private constant ERROR_DISALLOWED = "RECOVER_DISALLOWED"; string private constant ERROR_VAULT_NOT_CONTRACT = "RECOVER_VAULT_NOT_CONTRACT"; string private constant ERROR_TOKEN_TRANSFER_FAILED = "RECOVER_TOKEN_TRANSFER_FAILED"; /** * @notice Send funds to recovery Vault. This contract should never receive funds, * but in case it does, this function allows one to recover them. * @param _token Token balance to be sent to recovery vault. */ function transferToVault(address _token) external { require(allowRecoverability(_token), ERROR_DISALLOWED); address vault = getRecoveryVault(); require(isContract(vault), ERROR_VAULT_NOT_CONTRACT); uint256 balance; if (_token == ETH) { balance = address(this).balance; vault.transfer(balance); } else { ERC20 token = ERC20(_token); balance = token.staticBalanceOf(this); require(token.safeTransfer(vault, balance), ERROR_TOKEN_TRANSFER_FAILED); } emit RecoverToVault(vault, _token, balance); } /** * @dev By default deriving from AragonApp makes it recoverable * @param token Token address that would be recovered * @return bool whether the app allows the recovery */ function allowRecoverability(address token) public view returns (bool) { return true; } // Cast non-implemented interface to be public so we can use it internally function getRecoveryVault() public view returns (address); }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "./IEVMScriptExecutor.sol"; import "./IEVMScriptRegistry.sol"; import "../apps/AppStorage.sol"; import "../kernel/KernelConstants.sol"; import "../common/Initializable.sol"; contract EVMScriptRunner is AppStorage, Initializable, EVMScriptRegistryConstants, KernelNamespaceConstants { string private constant ERROR_EXECUTOR_UNAVAILABLE = "EVMRUN_EXECUTOR_UNAVAILABLE"; string private constant ERROR_PROTECTED_STATE_MODIFIED = "EVMRUN_PROTECTED_STATE_MODIFIED"; /* This is manually crafted in assembly string private constant ERROR_EXECUTOR_INVALID_RETURN = "EVMRUN_EXECUTOR_INVALID_RETURN"; */ event ScriptResult(address indexed executor, bytes script, bytes input, bytes returnData); function getEVMScriptExecutor(bytes _script) public view returns (IEVMScriptExecutor) { return IEVMScriptExecutor(getEVMScriptRegistry().getScriptExecutor(_script)); } function getEVMScriptRegistry() public view returns (IEVMScriptRegistry) { address registryAddr = kernel().getApp(KERNEL_APP_ADDR_NAMESPACE, EVMSCRIPT_REGISTRY_APP_ID); return IEVMScriptRegistry(registryAddr); } function runScript(bytes _script, bytes _input, address[] _blacklist) internal isInitialized protectState returns (bytes) { IEVMScriptExecutor executor = getEVMScriptExecutor(_script); require(address(executor) != address(0), ERROR_EXECUTOR_UNAVAILABLE); bytes4 sig = executor.execScript.selector; bytes memory data = abi.encodeWithSelector(sig, _script, _input, _blacklist); bytes memory output; assembly { let success := delegatecall( gas, // forward all gas executor, // address add(data, 0x20), // calldata start mload(data), // calldata length 0, // don't write output (we'll handle this ourselves) 0 // don't write output ) output := mload(0x40) // free mem ptr get switch success case 0 { // If the call errored, forward its full error data returndatacopy(output, 0, returndatasize) revert(output, returndatasize) } default { switch gt(returndatasize, 0x3f) case 0 { // Need at least 0x40 bytes returned for properly ABI-encoded bytes values, // revert with "EVMRUN_EXECUTOR_INVALID_RETURN" // See remix: doing a `revert("EVMRUN_EXECUTOR_INVALID_RETURN")` always results in // this memory layout mstore(output, 0x08c379a000000000000000000000000000000000000000000000000000000000) // error identifier mstore(add(output, 0x04), 0x0000000000000000000000000000000000000000000000000000000000000020) // starting offset mstore(add(output, 0x24), 0x000000000000000000000000000000000000000000000000000000000000001e) // reason length mstore(add(output, 0x44), 0x45564d52554e5f4558454355544f525f494e56414c49445f52455455524e0000) // reason revert(output, 100) // 100 = 4 + 3 * 32 (error identifier + 3 words for the ABI encoded error) } default { // Copy result // // Needs to perform an ABI decode for the expected `bytes` return type of // `executor.execScript()` as solidity will automatically ABI encode the returned bytes as: // [ position of the first dynamic length return value = 0x20 (32 bytes) ] // [ output length (32 bytes) ] // [ output content (N bytes) ] // // Perform the ABI decode by ignoring the first 32 bytes of the return data let copysize := sub(returndatasize, 0x20) returndatacopy(output, 0x20, copysize) mstore(0x40, add(output, copysize)) // free mem ptr set } } } emit ScriptResult(address(executor), _script, _input, output); return output; } modifier protectState { address preKernel = address(kernel()); bytes32 preAppId = appId(); _; // exec require(address(kernel()) == preKernel, ERROR_PROTECTED_STATE_MODIFIED); require(appId() == preAppId, ERROR_PROTECTED_STATE_MODIFIED); } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; library UnstructuredStorage { function getStorageBool(bytes32 position) internal view returns (bool data) { assembly { data := sload(position) } } function getStorageAddress(bytes32 position) internal view returns (address data) { assembly { data := sload(position) } } function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) { assembly { data := sload(position) } } function getStorageUint256(bytes32 position) internal view returns (uint256 data) { assembly { data := sload(position) } } function setStorageBool(bytes32 position, bool data) internal { assembly { sstore(position, data) } } function setStorageAddress(bytes32 position, address data) internal { assembly { sstore(position, data) } } function setStorageBytes32(bytes32 position, bytes32 data) internal { assembly { sstore(position, data) } } function setStorageUint256(bytes32 position, uint256 data) internal { assembly { sstore(position, data) } } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "../acl/IACL.sol"; import "../common/IVaultRecoverable.sol"; interface IKernelEvents { event SetApp(bytes32 indexed namespace, bytes32 indexed appId, address app); } // This should be an interface, but interfaces can't inherit yet :( contract IKernel is IKernelEvents, IVaultRecoverable { function acl() public view returns (IACL); function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool); function setApp(bytes32 namespace, bytes32 appId, address app) public; function getApp(bytes32 namespace, bytes32 appId) public view returns (address); }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; interface IACL { function initialize(address permissionsCreator) external; // TODO: this should be external // See https://github.com/ethereum/solidity/issues/4832 function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool); }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; interface IVaultRecoverable { event RecoverToVault(address indexed vault, address indexed token, uint256 amount); function transferToVault(address token) external; function allowRecoverability(address token) external view returns (bool); function getRecoveryVault() external view returns (address); }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "./Initializable.sol"; contract Petrifiable is Initializable { // Use block UINT256_MAX (which should be never) as the initializable date uint256 internal constant PETRIFIED_BLOCK = uint256(-1); function isPetrified() public view returns (bool) { return getInitializationBlock() == PETRIFIED_BLOCK; } /** * @dev Function to be called by top level contract to prevent being initialized. * Useful for freezing base contracts when they're used behind proxies. */ function petrify() internal onlyInit { initializedAt(PETRIFIED_BLOCK); } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "./TimeHelpers.sol"; import "./UnstructuredStorage.sol"; contract Initializable is TimeHelpers { using UnstructuredStorage for bytes32; // keccak256("aragonOS.initializable.initializationBlock") bytes32 internal constant INITIALIZATION_BLOCK_POSITION = 0xebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e; string private constant ERROR_ALREADY_INITIALIZED = "INIT_ALREADY_INITIALIZED"; string private constant ERROR_NOT_INITIALIZED = "INIT_NOT_INITIALIZED"; modifier onlyInit { require(getInitializationBlock() == 0, ERROR_ALREADY_INITIALIZED); _; } modifier isInitialized { require(hasInitialized(), ERROR_NOT_INITIALIZED); _; } /** * @return Block number in which the contract was initialized */ function getInitializationBlock() public view returns (uint256) { return INITIALIZATION_BLOCK_POSITION.getStorageUint256(); } /** * @return Whether the contract has been initialized by the time of the current block */ function hasInitialized() public view returns (bool) { uint256 initializationBlock = getInitializationBlock(); return initializationBlock != 0 && getBlockNumber() >= initializationBlock; } /** * @dev Function to be called by top level contract after initialization has finished. */ function initialized() internal onlyInit { INITIALIZATION_BLOCK_POSITION.setStorageUint256(getBlockNumber()); } /** * @dev Function to be called by top level contract after initialization to enable the contract * at a future block number rather than immediately. */ function initializedAt(uint256 _blockNumber) internal onlyInit { INITIALIZATION_BLOCK_POSITION.setStorageUint256(_blockNumber); } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "./Uint256Helpers.sol"; contract TimeHelpers { using Uint256Helpers for uint256; /** * @dev Returns the current block number. * Using a function rather than `block.number` allows us to easily mock the block number in * tests. */ function getBlockNumber() internal view returns (uint256) { return block.number; } /** * @dev Returns the current block number, converted to uint64. * Using a function rather than `block.number` allows us to easily mock the block number in * tests. */ function getBlockNumber64() internal view returns (uint64) { return getBlockNumber().toUint64(); } /** * @dev Returns the current timestamp. * Using a function rather than `block.timestamp` allows us to easily mock it in * tests. */ function getTimestamp() internal view returns (uint256) { return block.timestamp; // solium-disable-line security/no-block-members } /** * @dev Returns the current timestamp, converted to uint64. * Using a function rather than `block.timestamp` allows us to easily mock it in * tests. */ function getTimestamp64() internal view returns (uint64) { return getTimestamp().toUint64(); } }
pragma solidity ^0.4.24; library Uint256Helpers { uint256 private constant MAX_UINT64 = uint64(-1); string private constant ERROR_NUMBER_TOO_BIG = "UINT64_NUMBER_TOO_BIG"; function toUint64(uint256 a) internal pure returns (uint64) { require(a <= MAX_UINT64, ERROR_NUMBER_TOO_BIG); return uint64(a); } }
// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/a9f910d34f0ab33a1ae5e714f69f9596a02b4d91/contracts/token/ERC20/ERC20.sol pragma solidity ^0.4.24; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20 { function totalSupply() public view returns (uint256); function balanceOf(address _who) public view returns (uint256); function allowance(address _owner, address _spender) public view returns (uint256); function transfer(address _to, uint256 _value) public returns (bool); function approve(address _spender, uint256 _value) public returns (bool); function transferFrom(address _from, address _to, uint256 _value) public returns (bool); event Transfer( address indexed from, address indexed to, uint256 value ); event Approval( address indexed owner, address indexed spender, uint256 value ); }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; // aragonOS and aragon-apps rely on address(0) to denote native ETH, in // contracts where both tokens and ETH are accepted contract EtherTokenConstant { address internal constant ETH = address(0); }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; contract IsContract { /* * NOTE: this should NEVER be used for authentication * (see pitfalls: https://github.com/fergarrui/ethereum-security/tree/master/contracts/extcodesize). * * This is only intended to be used as a sanity check that an address is actually a contract, * RATHER THAN an address not being a contract. */ function isContract(address _target) internal view returns (bool) { if (_target == address(0)) { return false; } uint256 size; assembly { size := extcodesize(_target) } return size > 0; } }
// Inspired by AdEx (https://github.com/AdExNetwork/adex-protocol-eth/blob/b9df617829661a7518ee10f4cb6c4108659dd6d5/contracts/libs/SafeERC20.sol) // and 0x (https://github.com/0xProject/0x-monorepo/blob/737d1dc54d72872e24abce5a1dbe1b66d35fa21a/contracts/protocol/contracts/protocol/AssetProxy/ERC20Proxy.sol#L143) pragma solidity ^0.4.24; import "../lib/token/ERC20.sol"; library SafeERC20 { // Before 0.5, solidity has a mismatch between `address.transfer()` and `token.transfer()`: // https://github.com/ethereum/solidity/issues/3544 bytes4 private constant TRANSFER_SELECTOR = 0xa9059cbb; string private constant ERROR_TOKEN_BALANCE_REVERTED = "SAFE_ERC_20_BALANCE_REVERTED"; string private constant ERROR_TOKEN_ALLOWANCE_REVERTED = "SAFE_ERC_20_ALLOWANCE_REVERTED"; function invokeAndCheckSuccess(address _addr, bytes memory _calldata) private returns (bool) { bool ret; assembly { let ptr := mload(0x40) // free memory pointer let success := call( gas, // forward all gas _addr, // address 0, // no value add(_calldata, 0x20), // calldata start mload(_calldata), // calldata length ptr, // write output over free memory 0x20 // uint256 return ) if gt(success, 0) { // Check number of bytes returned from last function call switch returndatasize // No bytes returned: assume success case 0 { ret := 1 } // 32 bytes returned: check if non-zero case 0x20 { // Only return success if returned data was true // Already have output in ptr ret := eq(mload(ptr), 1) } // Not sure what was returned: don't mark as success default { } } } return ret; } function staticInvoke(address _addr, bytes memory _calldata) private view returns (bool, uint256) { bool success; uint256 ret; assembly { let ptr := mload(0x40) // free memory pointer success := staticcall( gas, // forward all gas _addr, // address add(_calldata, 0x20), // calldata start mload(_calldata), // calldata length ptr, // write output over free memory 0x20 // uint256 return ) if gt(success, 0) { ret := mload(ptr) } } return (success, ret); } /** * @dev Same as a standards-compliant ERC20.transfer() that never reverts (returns false). * Note that this makes an external call to the token. */ function safeTransfer(ERC20 _token, address _to, uint256 _amount) internal returns (bool) { bytes memory transferCallData = abi.encodeWithSelector( TRANSFER_SELECTOR, _to, _amount ); return invokeAndCheckSuccess(_token, transferCallData); } /** * @dev Same as a standards-compliant ERC20.transferFrom() that never reverts (returns false). * Note that this makes an external call to the token. */ function safeTransferFrom(ERC20 _token, address _from, address _to, uint256 _amount) internal returns (bool) { bytes memory transferFromCallData = abi.encodeWithSelector( _token.transferFrom.selector, _from, _to, _amount ); return invokeAndCheckSuccess(_token, transferFromCallData); } /** * @dev Same as a standards-compliant ERC20.approve() that never reverts (returns false). * Note that this makes an external call to the token. */ function safeApprove(ERC20 _token, address _spender, uint256 _amount) internal returns (bool) { bytes memory approveCallData = abi.encodeWithSelector( _token.approve.selector, _spender, _amount ); return invokeAndCheckSuccess(_token, approveCallData); } /** * @dev Static call into ERC20.balanceOf(). * Reverts if the call fails for some reason (should never fail). */ function staticBalanceOf(ERC20 _token, address _owner) internal view returns (uint256) { bytes memory balanceOfCallData = abi.encodeWithSelector( _token.balanceOf.selector, _owner ); (bool success, uint256 tokenBalance) = staticInvoke(_token, balanceOfCallData); require(success, ERROR_TOKEN_BALANCE_REVERTED); return tokenBalance; } /** * @dev Static call into ERC20.allowance(). * Reverts if the call fails for some reason (should never fail). */ function staticAllowance(ERC20 _token, address _owner, address _spender) internal view returns (uint256) { bytes memory allowanceCallData = abi.encodeWithSelector( _token.allowance.selector, _owner, _spender ); (bool success, uint256 allowance) = staticInvoke(_token, allowanceCallData); require(success, ERROR_TOKEN_ALLOWANCE_REVERTED); return allowance; } /** * @dev Static call into ERC20.totalSupply(). * Reverts if the call fails for some reason (should never fail). */ function staticTotalSupply(ERC20 _token) internal view returns (uint256) { bytes memory totalSupplyCallData = abi.encodeWithSelector(_token.totalSupply.selector); (bool success, uint256 totalSupply) = staticInvoke(_token, totalSupplyCallData); require(success, ERROR_TOKEN_ALLOWANCE_REVERTED); return totalSupply; } }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; interface IEVMScriptExecutor { function execScript(bytes script, bytes input, address[] blacklist) external returns (bytes); function executorType() external pure returns (bytes32); }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; import "./IEVMScriptExecutor.sol"; contract EVMScriptRegistryConstants { /* Hardcoded constants to save gas bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = apmNamehash("evmreg"); */ bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = 0xddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd61; } interface IEVMScriptRegistry { function addScriptExecutor(IEVMScriptExecutor executor) external returns (uint id); function disableScriptExecutor(uint256 executorId) external; // TODO: this should be external // See https://github.com/ethereum/solidity/issues/4832 function getScriptExecutor(bytes script) public view returns (IEVMScriptExecutor); }
/* * SPDX-License-Identifier: MIT */ pragma solidity ^0.4.24; contract KernelAppIds { /* Hardcoded constants to save gas bytes32 internal constant KERNEL_CORE_APP_ID = apmNamehash("kernel"); bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = apmNamehash("acl"); bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = apmNamehash("vault"); */ bytes32 internal constant KERNEL_CORE_APP_ID = 0x3b4bf6bf3ad5000ecf0f989d5befde585c6860fea3e574a4fab4c49d1c177d9c; bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = 0xe3262375f45a6e2026b7e7b18c2b807434f2508fe1a2a3dfb493c7df8f4aad6a; bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = 0x7e852e0fcfce6551c13800f1e7476f982525c2b5277ba14b24339c68416336d1; } contract KernelNamespaceConstants { /* Hardcoded constants to save gas bytes32 internal constant KERNEL_CORE_NAMESPACE = keccak256("core"); bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = keccak256("base"); bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = keccak256("app"); */ bytes32 internal constant KERNEL_CORE_NAMESPACE = 0xc681a85306374a5ab27f0bbc385296a54bcd314a1948b6cf61c4ea1bc44bb9f8; bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = 0xf1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f; bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb; }
pragma solidity ^0.4.24; /// @dev The token controller contract must implement these functions interface ITokenController { /// @notice Called when `_owner` sends ether to the MiniMe Token contract /// @param _owner The address that sent the ether to create tokens /// @return True if the ether is accepted, false if it throws function proxyPayment(address _owner) external payable returns(bool); /// @notice Notifies the controller about a token transfer allowing the /// controller to react if desired /// @param _from The origin of the transfer /// @param _to The destination of the transfer /// @param _amount The amount of the transfer /// @return False if the controller does not authorize the transfer function onTransfer(address _from, address _to, uint _amount) external returns(bool); /// @notice Notifies the controller about an approval allowing the /// controller to react if desired /// @param _owner The address that calls `approve()` /// @param _spender The spender in the `approve()` call /// @param _amount The amount in the `approve()` call /// @return False if the controller does not authorize the approval function onApprove(address _owner, address _spender, uint _amount) external returns(bool); }
{ "optimizer": { "enabled": true, "runs": 10000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MODIFY_QUORUM_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"},{"name":"_voter","type":"address"}],"name":"getVoterState","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"getVote","outputs":[{"name":"open","type":"bool"},{"name":"executed","type":"bool"},{"name":"startDate","type":"uint64"},{"name":"snapshotBlock","type":"uint64"},{"name":"supportRequired","type":"uint64"},{"name":"minAcceptQuorum","type":"uint64"},{"name":"yea","type":"uint256"},{"name":"nay","type":"uint256"},{"name":"votingPower","type":"uint256"},{"name":"script","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_minAcceptQuorumPct","type":"uint64"}],"name":"changeMinAcceptQuorumPct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MODIFY_SUPPORT_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_supportRequiredPct","type":"uint64"}],"name":"changeSupportRequiredPct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"voteTime","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CREATE_VOTES_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"","type":"bytes"}],"name":"canForward","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"canExecute","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"},{"name":"_voter","type":"address"}],"name":"canVote","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_executionScript","type":"bytes"},{"name":"_metadata","type":"string"}],"name":"newVote","outputs":[{"name":"voteId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_evmScript","type":"bytes"}],"name":"forward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"minAcceptQuorumPct","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"votesLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_voteId","type":"uint256"},{"name":"_supports","type":"bool"},{"name":"_executesIfDecided","type":"bool"}],"name":"vote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_supportRequiredPct","type":"uint64"},{"name":"_minAcceptQuorumPct","type":"uint64"},{"name":"_voteTime","type":"uint64"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_executionScript","type":"bytes"},{"name":"_metadata","type":"string"},{"name":"_castVote","type":"bool"},{"name":"_executesIfDecided","type":"bool"}],"name":"newVote","outputs":[{"name":"voteId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"executeVote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"supportRequiredPct","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PCT_BASE","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isForwarder","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"},{"indexed":true,"name":"creator","type":"address"},{"indexed":false,"name":"metadata","type":"string"}],"name":"StartVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"},{"indexed":true,"name":"voter","type":"address"},{"indexed":false,"name":"supports","type":"bool"},{"indexed":false,"name":"stake","type":"uint256"}],"name":"CastVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"}],"name":"ExecuteVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"supportRequiredPct","type":"uint64"}],"name":"ChangeSupportRequired","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minAcceptQuorumPct","type":"uint64"}],"name":"ChangeMinQuorum","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}]
Contract Creation Code
6080604052620000176401000000006200001d810204565b6200023b565b6200003064010000000062000125810204565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156200010c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620000d0578181015183820152602001620000b6565b50505050905090810190601f168015620000fe5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506200012360001964010000000062000154810204565b565b60006200014f60008051602062004030833981519152640100000000620025006200023382021704565b905090565b6200016764010000000062000125810204565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a454400000000000000006020820152901562000206576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015620000d0578181015183820152602001620000b6565b50620002306000805160206200403083398151915282640100000000620034db6200023782021704565b50565b5490565b9055565b613de5806200024b6000396000f3006080604052600436106101ab5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630803fac081146101b05780632914b9bd146101d957806332f0a3b51461025b5780633c624c75146102705780634b12311c146102975780635a55c1f0146102ec5780635eb243321461041357806362de7e5a146104375780637c1d0b871461044c5780637e7db6e11461046e57806380afdea81461049c5780638b3dd749146104b15780639d4941d8146104c6578063a1658fad146104f4578063a479e50814610568578063bcf93dd61461057d578063be2c64d4146105af578063c0774df3146105c4578063cc63604a14610638578063cdb2867b14610650578063d4aae0c414610681578063d5db2c8014610696578063d948d468146106c2578063dc474b1a1461071b578063de4796ed14610730578063de4f634714610745578063df133bca1461075a578063df3d33051461077c578063f4b00513146107c3578063f98a4eca146107f9578063fad167ab14610811578063fc0c546a14610826578063fc157cb41461083b578063fd64eccb14610850575b600080fd5b3480156101bc57600080fd5b506101c5610865565b604080519115158252519081900360200190f35b3480156101e557600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261023294369492936024939284019190819084018382808284375094975061088f9650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561026757600080fd5b5061023261099b565b34801561027c57600080fd5b50610285610a3a565b60408051918252519081900360200190f35b3480156102a357600080fd5b506102c860043573ffffffffffffffffffffffffffffffffffffffff60243516610a6f565b604051808260028111156102d857fe5b60ff16815260200191505060405180910390f35b3480156102f857600080fd5b50610304600435610b91565b604051808b1515151581526020018a1515151581526020018967ffffffffffffffff1667ffffffffffffffff1681526020018867ffffffffffffffff1667ffffffffffffffff1681526020018767ffffffffffffffff1667ffffffffffffffff1681526020018667ffffffffffffffff1667ffffffffffffffff16815260200185815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103cf5781810151838201526020016103b7565b50505050905090810190601f1680156103fc5780820380516001836020036101000a031916815260200191505b509b50505050505050505050505060405180910390f35b34801561041f57600080fd5b5061043567ffffffffffffffff60043516610da7565b005b34801561044357600080fd5b50610285610fd3565b34801561045857600080fd5b5061043567ffffffffffffffff60043516611008565b34801561047a57600080fd5b506101c573ffffffffffffffffffffffffffffffffffffffff600435166112fd565b3480156104a857600080fd5b50610285611303565b3480156104bd57600080fd5b50610285611333565b3480156104d257600080fd5b5061043573ffffffffffffffffffffffffffffffffffffffff6004351661135e565b34801561050057600080fd5b5060408051602060046044358181013583810280860185019096528085526101c595833573ffffffffffffffffffffffffffffffffffffffff169560248035963696956064959394920192918291850190849080828437509497506116809650505050505050565b34801561057457600080fd5b50610232611810565b34801561058957600080fd5b506105926118d2565b6040805167ffffffffffffffff9092168252519081900360200190f35b3480156105bb57600080fd5b506102856118ee565b3480156105d057600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526101c595833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506119239650505050505050565b34801561064457600080fd5b506101c5600435611973565b34801561065c57600080fd5b506101c560043573ffffffffffffffffffffffffffffffffffffffff60243516611a2b565b34801561068d57600080fd5b50610232611ae3565b3480156106a257600080fd5b506102856024600480358281019290820135918135918201910135611b0e565b3480156106ce57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610435943694929360249392840191908190840183828082843750949750611c719650505050505050565b34801561072757600080fd5b50610592611d3a565b34801561073c57600080fd5b506101c5611d4a565b34801561075157600080fd5b50610285611d7b565b34801561076657600080fd5b5061043560043560243515156044351515611d81565b34801561078857600080fd5b5061043573ffffffffffffffffffffffffffffffffffffffff6004351667ffffffffffffffff60243581169060443581169060643516611edd565b3480156107cf57600080fd5b506102856024600480358281019290820135918135918201910135604435151560643515156121d8565b34801561080557600080fd5b5061043560043561233a565b34801561081d57600080fd5b506105926123e5565b34801561083257600080fd5b5061023261240d565b34801561084757600080fd5b50610592612429565b34801561085c57600080fd5b506101c5612435565b600080610870611333565b9050801580159061088857508061088561243a565b10155b91505b5090565b6000610899611810565b73ffffffffffffffffffffffffffffffffffffffff166304bf2a7f836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561091d578181015183820152602001610905565b50505050905090810190601f16801561094a5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561096957600080fd5b505af115801561097d573d6000803e3d6000fd5b505050506040513d602081101561099357600080fd5b505192915050565b60006109a5611ae3565b73ffffffffffffffffffffffffffffffffffffffff166332f0a3b56040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610a0857600080fd5b505af1158015610a1c573d6000803e3d6000fd5b505050506040513d6020811015610a3257600080fd5b505190505b90565b604080517f4d4f444946595f51554f52554d5f524f4c4500000000000000000000000000008152905190819003601201902081565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918491908210610b50576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b15578181015183820152602001610afd565b50505050905090810190601f168015610b425780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600084815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845260060190915290205460ff1691505b5092915050565b6000806000806000806000806000606060008b60035481106040805190810160405280600e81526020017f564f54494e475f4e4f5f564f5445000000000000000000000000000000000000815250901515610c48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060008d81526002602052604090209150610c628261243e565b9b508160000160009054906101000a900460ff169a508160000160019054906101000a900467ffffffffffffffff1699508160000160099054906101000a900467ffffffffffffffff1698508160000160119054906101000a900467ffffffffffffffff1697508160010160009054906101000a900467ffffffffffffffff169650816002015495508160030154945081600401549350816005018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610d915780601f10610d6657610100808354040283529160200191610d91565b820191906000526020600020905b815481529060010190602001808311610d7457829003601f168201915b5050505050925050509193959799509193959799565b604080517f4d4f444946595f51554f52554d5f524f4c45000000000000000000000000000081529051908190036012019020600154610df39067ffffffffffffffff80851691166124a5565b610dfe338383611680565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515610e9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060005460408051808201909152601981527f564f54494e475f4348414e47455f51554f52554d5f504354530000000000000060208201529067ffffffffffffffff7401000000000000000000000000000000000000000090910481169085161115610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b506001805467ffffffffffffffff85167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909116811790915560408051918252517f3172f2e9273c729c2a47cc8bf7e7f18506e3e3035126d562602bd2155bc78a509181900360200190a1505050565b604080517f4d4f444946595f535550504f52545f524f4c45000000000000000000000000008152905190819003601301902081565b604080517f4d4f444946595f535550504f52545f524f4c45000000000000000000000000008152905190819003601301902060005461106c9067ffffffffffffffff80851691740100000000000000000000000000000000000000009004166124a5565b611077338383611680565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515611114576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060015460408051808201909152601a81527f564f54494e475f4348414e47455f535550504f52545f5043545300000000000060208201529067ffffffffffffffff808616911611156111c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060408051808201909152601a81527f564f54494e475f4348414e47455f535550505f544f4f5f4249470000000000006020820152670de0b6b3a764000067ffffffffffffffff851610611273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b506000805467ffffffffffffffff85167401000000000000000000000000000000000000000081027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff9092169190911790915560408051918252517f903b617f7f36eb047a29b89d1bf7885fdae31d250c3320fccf11d045c11b396e9181900360200190a1505050565b50600190565b600061132e7fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b612500565b905090565b600061132e7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e612500565b600080600061136c846112fd565b60408051808201909152601281527f5245434f5645525f444953414c4c4f57454400000000000000000000000000006020820152901515611409576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5061141261099b565b925061141d83612508565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e545241435400000000000060208201529015156114ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5073ffffffffffffffffffffffffffffffffffffffff84161515611525576040513031925073ffffffffffffffffffffffffffffffffffffffff84169083156108fc029084906000818181858888f1935050505015801561151f573d6000803e3d6000fd5b50611615565b508261154d73ffffffffffffffffffffffffffffffffffffffff82163063ffffffff61253b16565b915061157673ffffffffffffffffffffffffffffffffffffffff8216848463ffffffff61267416565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c45440000006020820152901515611613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b505b8373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b60008061168b610865565b151561169a5760009150611808565b6116a2611ae3565b905073ffffffffffffffffffffffffffffffffffffffff811615156116ca5760009150611808565b8073ffffffffffffffffffffffffffffffffffffffff1663fdef91068630876116f28861270c565b6040517c010000000000000000000000000000000000000000000000000000000063ffffffff871602815273ffffffffffffffffffffffffffffffffffffffff808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b8381101561178a578181015183820152602001611772565b50505050905090810190601f1680156117b75780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156117d957600080fd5b505af11580156117ed573d6000803e3d6000fd5b505050506040513d602081101561180357600080fd5b505191505b509392505050565b60008061181b611ae3565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd616024820152905173ffffffffffffffffffffffffffffffffffffffff929092169163be00bbd8916044808201926020929091908290030181600087803b15801561096957600080fd5b60015468010000000000000000900467ffffffffffffffff1681565b604080517f4352454154455f564f5445535f524f4c450000000000000000000000000000008152905190819003601101902081565b600061196c8360405180807f4352454154455f564f5445535f524f4c4500000000000000000000000000000081525060110190506040518091039020611967612716565b611680565b9392505050565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918391908210611a18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611a2283612728565b91505b50919050565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918491908210611ad0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611adb8484612841565b949350505050565b600061132e7f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b612500565b604080517f4352454154455f564f5445535f524f4c450000000000000000000000000000008152815190819003601101812060008083526020830190935290611b5d9033908390855b50611680565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515611bfa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611c6786868080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a815294508a93508992508291508401838280828437820191505050505050600180612928565b9695505050505050565b611c7b3382611923565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f464f5257415244000000000000000000006020820152901515611d18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611d36816020604051908101604052806000815250600180612928565b5050565b60015467ffffffffffffffff1681565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611d75611333565b14905090565b60035481565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f5445000000000000000000000000000000000000602082015284918210611e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611e2d8433612841565b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f5445000000000000000000000000006020820152901515611eca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611ed784843385612ca1565b50505050565b611ee5611333565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015611f81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611f8a612f2f565b60408051808201909152601081527f564f54494e475f494e49545f5043545300000000000000000000000000000000602082015267ffffffffffffffff8085169084161115612035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060408051808201909152601b81527f564f54494e475f494e49545f535550504f52545f544f4f5f42494700000000006020820152670de0b6b3a764000067ffffffffffffffff8516106120e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff95909516949094177fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000067ffffffffffffffff9485160217909355600180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016918316919091177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000009390921692909202179055565b604080517f4352454154455f564f5445535f524f4c450000000000000000000000000000008152815190819003601101812060008083526020830190935290612225903390839085611b57565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5061232e88888080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8e018190048102820181019092528c815294508c93508b925082915084018382808284378201915050505050508686612928565b98975050505050505050565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f54450000000000000000000000000000000000006020820152829182106123db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611d368261300e565b60005474010000000000000000000000000000000000000000900467ffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b670de0b6b3a764000081565b600190565b4390565b600154815460009161247491610100900467ffffffffffffffff908116916801000000000000000090041663ffffffff6130c116565b67ffffffffffffffff16612486613173565b67ffffffffffffffff1610801561249f5750815460ff16155b92915050565b6040805160028082526060808301845292602083019080388339019050509050828160008151811015156124d557fe5b6020908102909101015280518290829060019081106124f057fe5b6020908102909101015292915050565b5490565b5490565b60008073ffffffffffffffffffffffffffffffffffffffff831615156125315760009150611a25565b50506000903b1190565b6040805173ffffffffffffffffffffffffffffffffffffffff83166024808301919091528251808303909101815260449091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905260009081806125c88684613185565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f5245564552544544000000006020820152919350915082151561266a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5095945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260009061270385826131b6565b95945050505050565b8051602002815290565b60408051600081526020810190915290565b60008181526002602052604081208054829060ff161561274b576000925061283a565b60028201546004830154835461278192919071010000000000000000000000000000000000900467ffffffffffffffff16613204565b1561278f576001925061283a565b6127988261243e565b156127a6576000925061283a565b600382015460028301546127bf9163ffffffff61324616565b600283015483549192506127f391839071010000000000000000000000000000000000900467ffffffffffffffff16613204565b1515612802576000925061283a565b60028201546004830154600184015461282692919067ffffffffffffffff16613204565b1515612835576000925061283a565b600192505b5050919050565b60008281526002602052604081206128588161243e565b8015611adb5750600080548254604080517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152690100000000000000000090930467ffffffffffffffff16602482015290519190921691634ee2cd7e91604480830192602092919082900301818787803b1580156128f357600080fd5b505af1158015612907573d6000803e3d6000fd5b505050506040513d602081101561291d57600080fd5b505111949350505050565b60008060008060016129386132eb565b60008054604080517f981b24d00000000000000000000000000000000000000000000000000000000081529490930367ffffffffffffffff81166004860152925192965073ffffffffffffffffffffffffffffffffffffffff169263981b24d09260248083019360209383900390910190829087803b1580156129ba57600080fd5b505af11580156129ce573d6000803e3d6000fd5b505050506040513d60208110156129e457600080fd5b505160408051808201909152601681527f564f54494e475f4e4f5f564f54494e475f504f57455200000000000000000000602082015290925060008311612a87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b505060038054600181019091556000818152600260205260409020909350612aad613173565b81547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1661010067ffffffffffffffff92831602177fffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffff16690100000000000000000085831602178083556000547fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000090910482167101000000000000000000000000000000000002178255600180549083018054919092167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909116179055600481018290558751612bc090600583019060208b0190613d2b565b503373ffffffffffffffffffffffffffffffffffffffff16847f4d72fe0577a3a3f7da968d7b892779dde102519c25527b29cf7054f245c791b9896040518080602001828103825283818151815260200191508051906020019080838360005b83811015612c38578181015183820152602001612c20565b50505050905090810190601f168015612c655780820380516001836020036101000a031916815260200191505b509250505060405180910390a3858015612c845750612c848433612841565b15612c9657612c968460013388612ca1565b505050949350505050565b60008481526002602090815260408083208354815483517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8981166004830152690100000000000000000090920467ffffffffffffffff166024820152935192959485949190921692634ee2cd7e9260448084019391929182900301818787803b158015612d4557600080fd5b505af1158015612d59573d6000803e3d6000fd5b505050506040513d6020811015612d6f57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff8616600090815260068501602052604090205490925060ff1690506001816002811115612daf57fe5b1415612dd4576002830154612dca908363ffffffff6132f816565b6002840155612e03565b6002816002811115612de257fe5b1415612e03576003830154612dfd908363ffffffff6132f816565b60038401555b8515612e28576002830154612e1e908363ffffffff61324616565b6002840155612e43565b6003830154612e3d908363ffffffff61324616565b60038401555b85612e4f576002612e52565b60015b73ffffffffffffffffffffffffffffffffffffffff86166000908152600685016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115612eab57fe5b021790555060408051871515815260208101849052815173ffffffffffffffffffffffffffffffffffffffff8816928a927fb34ee265e3d4f5ec4e8b52d59b2a9be8fceca2f274ebc080d8fba797fea9391f929081900390910190a3838015612f185750612f1887612728565b15612f2657612f26876133a3565b50505050505050565b612f37611333565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015612fd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5061300c612fdf61243a565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff6134db16565b565b61301781612728565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f455845435554450000000000000000000060208201529015156130b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b506130be816133a3565b50565b60408051808201909152601381527f4d41544836345f4144445f4f564552464c4f570000000000000000000000000060208201526000908383019067ffffffffffffffff8086169083161015611808576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b600061132e6131806134df565b6134e3565b6000806000806040516020818751602089018a5afa925060008311156131aa57805191505b50909590945092505050565b6000806040516020818551602087016000895af160008111156131fa573d80156131e757602081146131f0576131f8565b600193506131f8565b600183511493505b505b5090949350505050565b6000808315156132175760009150611808565b8361323086670de0b6b3a764000063ffffffff61359316565b81151561323957fe5b0492909211949350505050565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f5700000000000000000000000000000060208201526000908383019084821015611808576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b600061132e61318061243a565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f570000000000000000000000000000602082015260009081908484111561339b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b505050900390565b600081815260026020818152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081178255825195865260058201805491821615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190911694909404601f810184900484028601830183529285018381529094936134aa93919290919085018282801561348d5780601f106134625761010080835404028352916020019161348d565b820191906000526020600020905b81548152906001019060200180831161347057829003601f168201915b505060408051600081526020810190915286935091506136559050565b5060405183907fbf8e2b108bb7c980e08903a8a46527699d5e84905a082d56dacb4150725c8cab90600090a2505050565b9055565b4290565b60408051808201909152601581527f55494e5436345f4e554d4245525f544f4f5f4249470000000000000000000000602082015260009067ffffffffffffffff83111561358c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5090919050565b6000808315156135a65760009150610b8a565b508282028284828115156135b657fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f5700000000000000000000000000000060208201529291900414611808576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b6060600080606080613665610865565b60408051808201909152601481527f494e49545f4e4f545f494e495449414c495a45440000000000000000000000006020820152901515613702576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060008061370e611ae3565b9150613718611303565b90506137238a61088f565b60408051808201909152601b81527f45564d52554e5f4558454355544f525f554e415641494c41424c450000000000602082015290965073ffffffffffffffffffffffffffffffffffffffff871615156137d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b506040516060602482019081528b5160848301528b517f279cea3500000000000000000000000000000000000000000000000000000000975087928d928d928d9282916044820191606481019160a490910190602089019080838360005b8381101561384f578181015183820152602001613837565b50505050905090810190601f16801561387c5780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b838110156138af578181015183820152602001613897565b50505050905090810190601f1680156138dc5780820380516001836020036101000a031916815260200191505b508481038252855181528551602091820191808801910280838360005b838110156139115781810151838201526020016138f9565b505050509050019650505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509350600080855160208701895af46040519350808015613a1657603f3d1180156139b45760203d03806020883e8601604052613a10565b7f08c379a000000000000000000000000000000000000000000000000000000000865260206004870152601e60248701527f45564d52554e5f4558454355544f525f494e56414c49445f52455455524e00006044870152606486fd5b50613a1f565b3d6000863e3d85fd5b50508573ffffffffffffffffffffffffffffffffffffffff167f5229a5dba83a54ae8cb5b51bdd6de9474cacbe9dd332f5185f3a4f4f2e3f4ad98b8b8660405180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015613aa1578181015183820152602001613a89565b50505050905090810190601f168015613ace5780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015613b01578181015183820152602001613ae9565b50505050905090810190601f168015613b2e5780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b83811015613b61578181015183820152602001613b49565b50505050905090810190601f168015613b8e5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a28296508173ffffffffffffffffffffffffffffffffffffffff16613bc1611ae3565b73ffffffffffffffffffffffffffffffffffffffff16146040805190810160405280601f81526020017f45564d52554e5f50524f5445435445445f53544154455f4d4f44494649454400815250901515613c77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5080613c81611303565b60408051808201909152601f81527f45564d52554e5f50524f5445435445445f53544154455f4d4f4449464945440060208201529114613d1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b505050505050509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613d6c57805160ff1916838001178555613d99565b82800160010185558215613d99579182015b82811115613d99578251825591602001919060010190613d7e565b5061088b92610a379250905b8082111561088b5760008155600101613da55600a165627a7a7230582061473efe1518636e1242146f71a6bfdf0a763e96be7f94d6db6b86f1ef8e337e0029ebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e
Deployed Bytecode
0x6080604052600436106101ab5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630803fac081146101b05780632914b9bd146101d957806332f0a3b51461025b5780633c624c75146102705780634b12311c146102975780635a55c1f0146102ec5780635eb243321461041357806362de7e5a146104375780637c1d0b871461044c5780637e7db6e11461046e57806380afdea81461049c5780638b3dd749146104b15780639d4941d8146104c6578063a1658fad146104f4578063a479e50814610568578063bcf93dd61461057d578063be2c64d4146105af578063c0774df3146105c4578063cc63604a14610638578063cdb2867b14610650578063d4aae0c414610681578063d5db2c8014610696578063d948d468146106c2578063dc474b1a1461071b578063de4796ed14610730578063de4f634714610745578063df133bca1461075a578063df3d33051461077c578063f4b00513146107c3578063f98a4eca146107f9578063fad167ab14610811578063fc0c546a14610826578063fc157cb41461083b578063fd64eccb14610850575b600080fd5b3480156101bc57600080fd5b506101c5610865565b604080519115158252519081900360200190f35b3480156101e557600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261023294369492936024939284019190819084018382808284375094975061088f9650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561026757600080fd5b5061023261099b565b34801561027c57600080fd5b50610285610a3a565b60408051918252519081900360200190f35b3480156102a357600080fd5b506102c860043573ffffffffffffffffffffffffffffffffffffffff60243516610a6f565b604051808260028111156102d857fe5b60ff16815260200191505060405180910390f35b3480156102f857600080fd5b50610304600435610b91565b604051808b1515151581526020018a1515151581526020018967ffffffffffffffff1667ffffffffffffffff1681526020018867ffffffffffffffff1667ffffffffffffffff1681526020018767ffffffffffffffff1667ffffffffffffffff1681526020018667ffffffffffffffff1667ffffffffffffffff16815260200185815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103cf5781810151838201526020016103b7565b50505050905090810190601f1680156103fc5780820380516001836020036101000a031916815260200191505b509b50505050505050505050505060405180910390f35b34801561041f57600080fd5b5061043567ffffffffffffffff60043516610da7565b005b34801561044357600080fd5b50610285610fd3565b34801561045857600080fd5b5061043567ffffffffffffffff60043516611008565b34801561047a57600080fd5b506101c573ffffffffffffffffffffffffffffffffffffffff600435166112fd565b3480156104a857600080fd5b50610285611303565b3480156104bd57600080fd5b50610285611333565b3480156104d257600080fd5b5061043573ffffffffffffffffffffffffffffffffffffffff6004351661135e565b34801561050057600080fd5b5060408051602060046044358181013583810280860185019096528085526101c595833573ffffffffffffffffffffffffffffffffffffffff169560248035963696956064959394920192918291850190849080828437509497506116809650505050505050565b34801561057457600080fd5b50610232611810565b34801561058957600080fd5b506105926118d2565b6040805167ffffffffffffffff9092168252519081900360200190f35b3480156105bb57600080fd5b506102856118ee565b3480156105d057600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526101c595833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506119239650505050505050565b34801561064457600080fd5b506101c5600435611973565b34801561065c57600080fd5b506101c560043573ffffffffffffffffffffffffffffffffffffffff60243516611a2b565b34801561068d57600080fd5b50610232611ae3565b3480156106a257600080fd5b506102856024600480358281019290820135918135918201910135611b0e565b3480156106ce57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610435943694929360249392840191908190840183828082843750949750611c719650505050505050565b34801561072757600080fd5b50610592611d3a565b34801561073c57600080fd5b506101c5611d4a565b34801561075157600080fd5b50610285611d7b565b34801561076657600080fd5b5061043560043560243515156044351515611d81565b34801561078857600080fd5b5061043573ffffffffffffffffffffffffffffffffffffffff6004351667ffffffffffffffff60243581169060443581169060643516611edd565b3480156107cf57600080fd5b506102856024600480358281019290820135918135918201910135604435151560643515156121d8565b34801561080557600080fd5b5061043560043561233a565b34801561081d57600080fd5b506105926123e5565b34801561083257600080fd5b5061023261240d565b34801561084757600080fd5b50610592612429565b34801561085c57600080fd5b506101c5612435565b600080610870611333565b9050801580159061088857508061088561243a565b10155b91505b5090565b6000610899611810565b73ffffffffffffffffffffffffffffffffffffffff166304bf2a7f836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561091d578181015183820152602001610905565b50505050905090810190601f16801561094a5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561096957600080fd5b505af115801561097d573d6000803e3d6000fd5b505050506040513d602081101561099357600080fd5b505192915050565b60006109a5611ae3565b73ffffffffffffffffffffffffffffffffffffffff166332f0a3b56040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610a0857600080fd5b505af1158015610a1c573d6000803e3d6000fd5b505050506040513d6020811015610a3257600080fd5b505190505b90565b604080517f4d4f444946595f51554f52554d5f524f4c4500000000000000000000000000008152905190819003601201902081565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918491908210610b50576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b15578181015183820152602001610afd565b50505050905090810190601f168015610b425780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600084815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845260060190915290205460ff1691505b5092915050565b6000806000806000806000806000606060008b60035481106040805190810160405280600e81526020017f564f54494e475f4e4f5f564f5445000000000000000000000000000000000000815250901515610c48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060008d81526002602052604090209150610c628261243e565b9b508160000160009054906101000a900460ff169a508160000160019054906101000a900467ffffffffffffffff1699508160000160099054906101000a900467ffffffffffffffff1698508160000160119054906101000a900467ffffffffffffffff1697508160010160009054906101000a900467ffffffffffffffff169650816002015495508160030154945081600401549350816005018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610d915780601f10610d6657610100808354040283529160200191610d91565b820191906000526020600020905b815481529060010190602001808311610d7457829003601f168201915b5050505050925050509193959799509193959799565b604080517f4d4f444946595f51554f52554d5f524f4c45000000000000000000000000000081529051908190036012019020600154610df39067ffffffffffffffff80851691166124a5565b610dfe338383611680565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515610e9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060005460408051808201909152601981527f564f54494e475f4348414e47455f51554f52554d5f504354530000000000000060208201529067ffffffffffffffff7401000000000000000000000000000000000000000090910481169085161115610f63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b506001805467ffffffffffffffff85167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909116811790915560408051918252517f3172f2e9273c729c2a47cc8bf7e7f18506e3e3035126d562602bd2155bc78a509181900360200190a1505050565b604080517f4d4f444946595f535550504f52545f524f4c45000000000000000000000000008152905190819003601301902081565b604080517f4d4f444946595f535550504f52545f524f4c45000000000000000000000000008152905190819003601301902060005461106c9067ffffffffffffffff80851691740100000000000000000000000000000000000000009004166124a5565b611077338383611680565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515611114576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060015460408051808201909152601a81527f564f54494e475f4348414e47455f535550504f52545f5043545300000000000060208201529067ffffffffffffffff808616911611156111c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060408051808201909152601a81527f564f54494e475f4348414e47455f535550505f544f4f5f4249470000000000006020820152670de0b6b3a764000067ffffffffffffffff851610611273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b506000805467ffffffffffffffff85167401000000000000000000000000000000000000000081027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff9092169190911790915560408051918252517f903b617f7f36eb047a29b89d1bf7885fdae31d250c3320fccf11d045c11b396e9181900360200190a1505050565b50600190565b600061132e7fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b612500565b905090565b600061132e7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e612500565b600080600061136c846112fd565b60408051808201909152601281527f5245434f5645525f444953414c4c4f57454400000000000000000000000000006020820152901515611409576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5061141261099b565b925061141d83612508565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e545241435400000000000060208201529015156114ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5073ffffffffffffffffffffffffffffffffffffffff84161515611525576040513031925073ffffffffffffffffffffffffffffffffffffffff84169083156108fc029084906000818181858888f1935050505015801561151f573d6000803e3d6000fd5b50611615565b508261154d73ffffffffffffffffffffffffffffffffffffffff82163063ffffffff61253b16565b915061157673ffffffffffffffffffffffffffffffffffffffff8216848463ffffffff61267416565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c45440000006020820152901515611613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b505b8373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b60008061168b610865565b151561169a5760009150611808565b6116a2611ae3565b905073ffffffffffffffffffffffffffffffffffffffff811615156116ca5760009150611808565b8073ffffffffffffffffffffffffffffffffffffffff1663fdef91068630876116f28861270c565b6040517c010000000000000000000000000000000000000000000000000000000063ffffffff871602815273ffffffffffffffffffffffffffffffffffffffff808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b8381101561178a578181015183820152602001611772565b50505050905090810190601f1680156117b75780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156117d957600080fd5b505af11580156117ed573d6000803e3d6000fd5b505050506040513d602081101561180357600080fd5b505191505b509392505050565b60008061181b611ae3565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd616024820152905173ffffffffffffffffffffffffffffffffffffffff929092169163be00bbd8916044808201926020929091908290030181600087803b15801561096957600080fd5b60015468010000000000000000900467ffffffffffffffff1681565b604080517f4352454154455f564f5445535f524f4c450000000000000000000000000000008152905190819003601101902081565b600061196c8360405180807f4352454154455f564f5445535f524f4c4500000000000000000000000000000081525060110190506040518091039020611967612716565b611680565b9392505050565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918391908210611a18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611a2283612728565b91505b50919050565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918491908210611ad0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611adb8484612841565b949350505050565b600061132e7f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b612500565b604080517f4352454154455f564f5445535f524f4c450000000000000000000000000000008152815190819003601101812060008083526020830190935290611b5d9033908390855b50611680565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515611bfa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611c6786868080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a815294508a93508992508291508401838280828437820191505050505050600180612928565b9695505050505050565b611c7b3382611923565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f464f5257415244000000000000000000006020820152901515611d18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611d36816020604051908101604052806000815250600180612928565b5050565b60015467ffffffffffffffff1681565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611d75611333565b14905090565b60035481565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f5445000000000000000000000000000000000000602082015284918210611e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611e2d8433612841565b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f5445000000000000000000000000006020820152901515611eca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611ed784843385612ca1565b50505050565b611ee5611333565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015611f81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611f8a612f2f565b60408051808201909152601081527f564f54494e475f494e49545f5043545300000000000000000000000000000000602082015267ffffffffffffffff8085169084161115612035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060408051808201909152601b81527f564f54494e475f494e49545f535550504f52545f544f4f5f42494700000000006020820152670de0b6b3a764000067ffffffffffffffff8516106120e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff95909516949094177fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000067ffffffffffffffff9485160217909355600180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016918316919091177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000009390921692909202179055565b604080517f4352454154455f564f5445535f524f4c450000000000000000000000000000008152815190819003601101812060008083526020830190935290612225903390839085611b57565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156122c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5061232e88888080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8e018190048102820181019092528c815294508c93508b925082915084018382808284378201915050505050508686612928565b98975050505050505050565b60035460408051808201909152600e81527f564f54494e475f4e4f5f564f54450000000000000000000000000000000000006020820152829182106123db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b50611d368261300e565b60005474010000000000000000000000000000000000000000900467ffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b670de0b6b3a764000081565b600190565b4390565b600154815460009161247491610100900467ffffffffffffffff908116916801000000000000000090041663ffffffff6130c116565b67ffffffffffffffff16612486613173565b67ffffffffffffffff1610801561249f5750815460ff16155b92915050565b6040805160028082526060808301845292602083019080388339019050509050828160008151811015156124d557fe5b6020908102909101015280518290829060019081106124f057fe5b6020908102909101015292915050565b5490565b5490565b60008073ffffffffffffffffffffffffffffffffffffffff831615156125315760009150611a25565b50506000903b1190565b6040805173ffffffffffffffffffffffffffffffffffffffff83166024808301919091528251808303909101815260449091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a082310000000000000000000000000000000000000000000000000000000017905260009081806125c88684613185565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f5245564552544544000000006020820152919350915082151561266a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5095945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260009061270385826131b6565b95945050505050565b8051602002815290565b60408051600081526020810190915290565b60008181526002602052604081208054829060ff161561274b576000925061283a565b60028201546004830154835461278192919071010000000000000000000000000000000000900467ffffffffffffffff16613204565b1561278f576001925061283a565b6127988261243e565b156127a6576000925061283a565b600382015460028301546127bf9163ffffffff61324616565b600283015483549192506127f391839071010000000000000000000000000000000000900467ffffffffffffffff16613204565b1515612802576000925061283a565b60028201546004830154600184015461282692919067ffffffffffffffff16613204565b1515612835576000925061283a565b600192505b5050919050565b60008281526002602052604081206128588161243e565b8015611adb5750600080548254604080517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152690100000000000000000090930467ffffffffffffffff16602482015290519190921691634ee2cd7e91604480830192602092919082900301818787803b1580156128f357600080fd5b505af1158015612907573d6000803e3d6000fd5b505050506040513d602081101561291d57600080fd5b505111949350505050565b60008060008060016129386132eb565b60008054604080517f981b24d00000000000000000000000000000000000000000000000000000000081529490930367ffffffffffffffff81166004860152925192965073ffffffffffffffffffffffffffffffffffffffff169263981b24d09260248083019360209383900390910190829087803b1580156129ba57600080fd5b505af11580156129ce573d6000803e3d6000fd5b505050506040513d60208110156129e457600080fd5b505160408051808201909152601681527f564f54494e475f4e4f5f564f54494e475f504f57455200000000000000000000602082015290925060008311612a87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b505060038054600181019091556000818152600260205260409020909350612aad613173565b81547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1661010067ffffffffffffffff92831602177fffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffff16690100000000000000000085831602178083556000547fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000090910482167101000000000000000000000000000000000002178255600180549083018054919092167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909116179055600481018290558751612bc090600583019060208b0190613d2b565b503373ffffffffffffffffffffffffffffffffffffffff16847f4d72fe0577a3a3f7da968d7b892779dde102519c25527b29cf7054f245c791b9896040518080602001828103825283818151815260200191508051906020019080838360005b83811015612c38578181015183820152602001612c20565b50505050905090810190601f168015612c655780820380516001836020036101000a031916815260200191505b509250505060405180910390a3858015612c845750612c848433612841565b15612c9657612c968460013388612ca1565b505050949350505050565b60008481526002602090815260408083208354815483517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8981166004830152690100000000000000000090920467ffffffffffffffff166024820152935192959485949190921692634ee2cd7e9260448084019391929182900301818787803b158015612d4557600080fd5b505af1158015612d59573d6000803e3d6000fd5b505050506040513d6020811015612d6f57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff8616600090815260068501602052604090205490925060ff1690506001816002811115612daf57fe5b1415612dd4576002830154612dca908363ffffffff6132f816565b6002840155612e03565b6002816002811115612de257fe5b1415612e03576003830154612dfd908363ffffffff6132f816565b60038401555b8515612e28576002830154612e1e908363ffffffff61324616565b6002840155612e43565b6003830154612e3d908363ffffffff61324616565b60038401555b85612e4f576002612e52565b60015b73ffffffffffffffffffffffffffffffffffffffff86166000908152600685016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115612eab57fe5b021790555060408051871515815260208101849052815173ffffffffffffffffffffffffffffffffffffffff8816928a927fb34ee265e3d4f5ec4e8b52d59b2a9be8fceca2f274ebc080d8fba797fea9391f929081900390910190a3838015612f185750612f1887612728565b15612f2657612f26876133a3565b50505050505050565b612f37611333565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015612fd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5061300c612fdf61243a565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff6134db16565b565b61301781612728565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f455845435554450000000000000000000060208201529015156130b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b506130be816133a3565b50565b60408051808201909152601381527f4d41544836345f4144445f4f564552464c4f570000000000000000000000000060208201526000908383019067ffffffffffffffff8086169083161015611808576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b600061132e6131806134df565b6134e3565b6000806000806040516020818751602089018a5afa925060008311156131aa57805191505b50909590945092505050565b6000806040516020818551602087016000895af160008111156131fa573d80156131e757602081146131f0576131f8565b600193506131f8565b600183511493505b505b5090949350505050565b6000808315156132175760009150611808565b8361323086670de0b6b3a764000063ffffffff61359316565b81151561323957fe5b0492909211949350505050565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f5700000000000000000000000000000060208201526000908383019084821015611808576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b600061132e61318061243a565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f570000000000000000000000000000602082015260009081908484111561339b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b505050900390565b600081815260026020818152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081178255825195865260058201805491821615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190911694909404601f810184900484028601830183529285018381529094936134aa93919290919085018282801561348d5780601f106134625761010080835404028352916020019161348d565b820191906000526020600020905b81548152906001019060200180831161347057829003601f168201915b505060408051600081526020810190915286935091506136559050565b5060405183907fbf8e2b108bb7c980e08903a8a46527699d5e84905a082d56dacb4150725c8cab90600090a2505050565b9055565b4290565b60408051808201909152601581527f55494e5436345f4e554d4245525f544f4f5f4249470000000000000000000000602082015260009067ffffffffffffffff83111561358c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5090919050565b6000808315156135a65760009150610b8a565b508282028284828115156135b657fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f5700000000000000000000000000000060208201529291900414611808576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b6060600080606080613665610865565b60408051808201909152601481527f494e49545f4e4f545f494e495449414c495a45440000000000000000000000006020820152901515613702576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5060008061370e611ae3565b9150613718611303565b90506137238a61088f565b60408051808201909152601b81527f45564d52554e5f4558454355544f525f554e415641494c41424c450000000000602082015290965073ffffffffffffffffffffffffffffffffffffffff871615156137d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b506040516060602482019081528b5160848301528b517f279cea3500000000000000000000000000000000000000000000000000000000975087928d928d928d9282916044820191606481019160a490910190602089019080838360005b8381101561384f578181015183820152602001613837565b50505050905090810190601f16801561387c5780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b838110156138af578181015183820152602001613897565b50505050905090810190601f1680156138dc5780820380516001836020036101000a031916815260200191505b508481038252855181528551602091820191808801910280838360005b838110156139115781810151838201526020016138f9565b505050509050019650505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509350600080855160208701895af46040519350808015613a1657603f3d1180156139b45760203d03806020883e8601604052613a10565b7f08c379a000000000000000000000000000000000000000000000000000000000865260206004870152601e60248701527f45564d52554e5f4558454355544f525f494e56414c49445f52455455524e00006044870152606486fd5b50613a1f565b3d6000863e3d85fd5b50508573ffffffffffffffffffffffffffffffffffffffff167f5229a5dba83a54ae8cb5b51bdd6de9474cacbe9dd332f5185f3a4f4f2e3f4ad98b8b8660405180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015613aa1578181015183820152602001613a89565b50505050905090810190601f168015613ace5780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015613b01578181015183820152602001613ae9565b50505050905090810190601f168015613b2e5780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b83811015613b61578181015183820152602001613b49565b50505050905090810190601f168015613b8e5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a28296508173ffffffffffffffffffffffffffffffffffffffff16613bc1611ae3565b73ffffffffffffffffffffffffffffffffffffffff16146040805190810160405280601f81526020017f45564d52554e5f50524f5445435445445f53544154455f4d4f44494649454400815250901515613c77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b5080613c81611303565b60408051808201909152601f81527f45564d52554e5f50524f5445435445445f53544154455f4d4f4449464945440060208201529114613d1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610b15578181015183820152602001610afd565b505050505050509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613d6c57805160ff1916838001178555613d99565b82800160010185558215613d99579182015b82811115613d99578251825591602001919060010190613d7e565b5061088b92610a379250905b8082111561088b5760008155600101613da55600a165627a7a7230582061473efe1518636e1242146f71a6bfdf0a763e96be7f94d6db6b86f1ef8e337e0029
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.