Overview
ETH Balance
0.951911931904360347 ETH
Eth Value
$2,750.01 (@ $2,888.93/ETH)More Info
Private Name Tags
ContractCreator
Latest 21 from a total of 21 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Thaw | 10941001 | 1312 days ago | IN | 0 ETH | 0.0013699 | ||||
Set Amgu Price | 9916134 | 1471 days ago | IN | 0 ETH | 0.00047713 | ||||
Set Amgu Price | 9884569 | 1475 days ago | IN | 0 ETH | 0.00017665 | ||||
Set Amgu Price | 9884551 | 1475 days ago | IN | 0 ETH | 0.00010704 | ||||
Thaw | 9365288 | 1555 days ago | IN | 0 ETH | 0.00010959 | ||||
Sell And Burn Ml... | 8906126 | 1634 days ago | IN | 0 ETH | 0.00002629 | ||||
Thaw | 8877245 | 1639 days ago | IN | 0 ETH | 0.00007201 | ||||
Thaw | 8659230 | 1673 days ago | IN | 0 ETH | 0.000024 | ||||
Thaw | 8077746 | 1764 days ago | IN | 0 ETH | 0.00007201 | ||||
Thaw | 7868594 | 1796 days ago | IN | 0 ETH | 0.00009602 | ||||
Thaw | 7649095 | 1831 days ago | IN | 0 ETH | 0.00007201 | ||||
Thaw | 7623923 | 1835 days ago | IN | 0 ETH | 0.00006658 | ||||
Thaw | 7440613 | 1863 days ago | IN | 0 ETH | 0.00007801 | ||||
Thaw | 7438017 | 1864 days ago | IN | 0 ETH | 0.00019974 | ||||
Set Amgu Price | 7270952 | 1890 days ago | IN | 0 ETH | 0.00095787 | ||||
Thaw | 7258629 | 1893 days ago | IN | 0 ETH | 0.00066582 | ||||
Set Amgu Price | 7258339 | 1893 days ago | IN | 0 ETH | 0.00140787 | ||||
Set Amgu Price | 7258235 | 1893 days ago | IN | 0 ETH | 0.00158365 | ||||
Set Amgu Price | 7258177 | 1893 days ago | IN | 0 ETH | 0.00158365 | ||||
Set Amgu Price | 7258158 | 1893 days ago | IN | 0 ETH | 0.00158365 | ||||
0x60806040 | 7258122 | 1893 days ago | IN | Create: Engine | 0 ETH | 0.06332795 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
9532933 | 1530 days ago | 0.00784092 ETH | ||||
9532932 | 1530 days ago | 0.00146493 ETH | ||||
9530408 | 1530 days ago | 0.02993047 ETH | ||||
9530379 | 1530 days ago | 0.00758176 ETH | ||||
9530357 | 1530 days ago | 0.03732269 ETH | ||||
9530354 | 1530 days ago | 0.01044757 ETH | ||||
9530342 | 1530 days ago | 0.01043837 ETH | ||||
9530320 | 1530 days ago | 0.03605825 ETH | ||||
9530311 | 1530 days ago | 0.01321084 ETH | ||||
9530309 | 1530 days ago | 0.02201153 ETH | ||||
9475866 | 1538 days ago | 0.03423425 ETH | ||||
9475854 | 1538 days ago | 0.00867315 ETH | ||||
9475846 | 1538 days ago | 0.04179355 ETH | ||||
9475635 | 1538 days ago | 0.0119515 ETH | ||||
9475573 | 1538 days ago | 0.01194097 ETH | ||||
9475565 | 1538 days ago | 0.04247189 ETH | ||||
9475543 | 1538 days ago | 0.01511253 ETH | ||||
9475536 | 1538 days ago | 0.02735593 ETH | ||||
9471649 | 1539 days ago | 0.00721579 ETH | ||||
9471646 | 1539 days ago | 0.00183648 ETH | ||||
9471475 | 1539 days ago | 0.03578809 ETH | ||||
9471472 | 1539 days ago | 0.00906681 ETH | ||||
9471470 | 1539 days ago | 0.04463316 ETH | ||||
9471467 | 1539 days ago | 0.01249396 ETH | ||||
9471465 | 1539 days ago | 0.01248295 ETH |
Loading...
Loading
Contract Name:
Engine
Compiler Version
v0.4.25+commit.59dbf8f1
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-03-11 */ pragma solidity ^0.4.25; /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { /** * @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); 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); // 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); 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); 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); return a % b; } } contract DSMath { function add(uint x, uint y) internal pure returns (uint z) { require((z = x + y) >= x, "ds-math-add-overflow"); } function sub(uint x, uint y) internal pure returns (uint z) { require((z = x - y) <= x, "ds-math-sub-underflow"); } function mul(uint x, uint y) internal pure returns (uint z) { require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow"); } function min(uint x, uint y) internal pure returns (uint z) { return x <= y ? x : y; } function max(uint x, uint y) internal pure returns (uint z) { return x >= y ? x : y; } function imin(int x, int y) internal pure returns (int z) { return x <= y ? x : y; } function imax(int x, int y) internal pure returns (int z) { return x >= y ? x : y; } uint constant WAD = 10 ** 18; uint constant RAY = 10 ** 27; function wmul(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, y), WAD / 2) / WAD; } function rmul(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, y), RAY / 2) / RAY; } function wdiv(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, WAD), y / 2) / y; } function rdiv(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, RAY), y / 2) / y; } // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. // function rpow(uint x, uint n) internal pure returns (uint z) { z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } } /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 * Altered from https://github.com/OpenZeppelin/openzeppelin-solidity/blob/a466e76d26c394b1faa6e2797aefe34668566392/contracts/token/ERC20/ERC20.sol */ interface 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 ); } /// @dev Just adds extra functions that we use elsewhere contract ERC20WithFields is ERC20 { string public symbol; string public name; uint8 public decimals; } /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol * Rearranged from https://github.com/OpenZeppelin/openzeppelin-solidity/blob/a466e76d26c394b1faa6e2797aefe34668566392/contracts/token/ERC20/StandardToken.sol */ contract StandardToken is ERC20 { using SafeMath for uint256; mapping (address => uint256) balances; mapping (address => mapping (address => uint256)) allowed; uint256 totalSupply_; /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return totalSupply_; } /** * @dev Gets the balance of the specified address. * @param _owner The address to query the the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param _owner address The address which owns the funds. * @param _spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance( address _owner, address _spender ) public view returns (uint256) { return allowed[_owner][_spender]; } /** * @dev Transfer token for a specified address * @param _to The address to transfer to. * @param _value The amount to be transferred. */ function transfer(address _to, uint256 _value) public returns (bool) { require(_value <= balances[msg.sender]); require(_to != address(0)); balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param _spender The address which will spend the funds. * @param _value The amount of tokens to be spent. */ function approve(address _spender, uint256 _value) public returns (bool) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } /** * @dev Transfer tokens from one address to another * @param _from address The address which you want to send tokens from * @param _to address The address which you want to transfer to * @param _value uint256 the amount of tokens to be transferred */ function transferFrom( address _from, address _to, uint256 _value ) public returns (bool) { require(_value <= balances[_from]); require(_value <= allowed[_from][msg.sender]); require(_to != address(0)); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); emit Approval(_from, msg.sender, allowed[_from][msg.sender]); emit Transfer(_from, _to, _value); return true; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when allowed[_spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param _spender The address which will spend the funds. * @param _addedValue The amount of tokens to increase the allowance by. */ function increaseApproval( address _spender, uint256 _addedValue ) public returns (bool) { allowed[msg.sender][_spender] = (allowed[msg.sender][_spender].add(_addedValue)); emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when allowed[_spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param _spender The address which will spend the funds. * @param _subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseApproval( address _spender, uint256 _subtractedValue ) public returns (bool) { uint256 oldValue = allowed[msg.sender][_spender]; if (_subtractedValue >= oldValue) { allowed[msg.sender][_spender] = 0; } else { allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); } emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } /** * @dev Internal function that mints an amount of the token and assigns it to * an account. This encapsulates the modification of balances such that the * proper events are emitted. * @param _account The account that will receive the created tokens. * @param _amount The amount that will be created. */ function _mint(address _account, uint256 _amount) internal { require(_account != 0); totalSupply_ = totalSupply_.add(_amount); balances[_account] = balances[_account].add(_amount); emit Transfer(address(0), _account, _amount); } /** * @dev Internal function that burns an amount of the token of a given * account. * @param _account The account whose tokens will be burnt. * @param _amount The amount that will be burnt. */ function _burn(address _account, uint256 _amount) internal { require(_account != 0); require(_amount <= balances[_account]); totalSupply_ = totalSupply_.sub(_amount); balances[_account] = balances[_account].sub(_amount); emit Transfer(_account, address(0), _amount); } /** * @dev Internal function that burns an amount of the token of a given * account, deducting from the sender's allowance for said account. Uses the * internal _burn function. * @param _account The account whose tokens will be burnt. * @param _amount The amount that will be burnt. */ function _burnFrom(address _account, uint256 _amount) internal { require(_amount <= allowed[_account][msg.sender]); allowed[_account][msg.sender] = allowed[_account][msg.sender].sub(_amount); emit Approval(_account, msg.sender, allowed[_account][msg.sender]); _burn(_account, _amount); } } contract PreminedToken is StandardToken { string public symbol; string public name; uint8 public decimals; constructor(string _symbol, uint8 _decimals, string _name) public { symbol = _symbol; decimals = _decimals; name = _name; totalSupply_ = 1000000 * 10**uint(decimals); balances[msg.sender] = totalSupply_; emit Transfer(address(0), msg.sender, totalSupply_); } } /// @dev Just a wrapper for premined tokens which can actually be burnt contract BurnableToken is PreminedToken { constructor(string _symbol, uint8 _decimals, string _name) public PreminedToken(_symbol, _decimals, _name) {} function burn(uint _amount) public { _burn(msg.sender, _amount); } function burnFrom(address from, uint256 value) public { _burnFrom(from, value); } } /// @notice Must return a value for an asset interface PriceSourceInterface { event PriceUpdate(address[] token, uint[] price); function getQuoteAsset() external view returns (address); function getLastUpdate() external view returns (uint); /// @notice Returns false if asset not applicable, or price not recent function hasValidPrice(address) public view returns (bool); function hasValidPrices(address[]) public view returns (bool); /// @notice Return the last known price, and when it was issued function getPrice(address _asset) public view returns (uint price, uint timestamp); function getPrices(address[] _assets) public view returns (uint[] prices, uint[] timestamps); /// @notice Get price info, and revert if not valid function getPriceInfo(address _asset) view returns (uint price, uint decimals); function getInvertedPriceInfo(address ofAsset) view returns (uint price, uint decimals); function getReferencePriceInfo(address _base, address _quote) public view returns (uint referencePrice, uint decimal); function getOrderPriceInfo(address sellAsset, address buyAsset, uint sellQuantity, uint buyQuantity) public view returns (uint orderPrice); function existsPriceOnAssetPair(address sellAsset, address buyAsset) public view returns (bool isExistent); function convertQuantity( uint fromAssetQuantity, address fromAsset, address toAsset ) public view returns (uint); } contract DSAuthority { function canCall( address src, address dst, bytes4 sig ) public view returns (bool); } contract DSAuthEvents { event LogSetAuthority (address indexed authority); event LogSetOwner (address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; constructor() public { owner = msg.sender; emit LogSetOwner(msg.sender); } function setOwner(address owner_) public auth { owner = owner_; emit LogSetOwner(owner); } function setAuthority(DSAuthority authority_) public auth { authority = authority_; emit LogSetAuthority(address(authority)); } modifier auth { require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized"); _; } function isAuthorized(address src, bytes4 sig) internal view returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(0)) { return false; } else { return authority.canCall(src, address(this), sig); } } } contract DSGuardEvents { event LogPermit( bytes32 indexed src, bytes32 indexed dst, bytes32 indexed sig ); event LogForbid( bytes32 indexed src, bytes32 indexed dst, bytes32 indexed sig ); } contract DSGuard is DSAuth, DSAuthority, DSGuardEvents { bytes32 constant public ANY = bytes32(uint(-1)); mapping (bytes32 => mapping (bytes32 => mapping (bytes32 => bool))) acl; function canCall( address src_, address dst_, bytes4 sig ) public view returns (bool) { bytes32 src = bytes32(bytes20(src_)); bytes32 dst = bytes32(bytes20(dst_)); return acl[src][dst][sig] || acl[src][dst][ANY] || acl[src][ANY][sig] || acl[src][ANY][ANY] || acl[ANY][dst][sig] || acl[ANY][dst][ANY] || acl[ANY][ANY][sig] || acl[ANY][ANY][ANY]; } function permit(bytes32 src, bytes32 dst, bytes32 sig) public auth { acl[src][dst][sig] = true; emit LogPermit(src, dst, sig); } function forbid(bytes32 src, bytes32 dst, bytes32 sig) public auth { acl[src][dst][sig] = false; emit LogForbid(src, dst, sig); } function permit(address src, address dst, bytes32 sig) public { permit(bytes32(bytes20(src)), bytes32(bytes20(dst)), sig); } function forbid(address src, address dst, bytes32 sig) public { forbid(bytes32(bytes20(src)), bytes32(bytes20(dst)), sig); } } contract DSGuardFactory { mapping (address => bool) public isGuard; function newGuard() public returns (DSGuard guard) { guard = new DSGuard(); guard.setOwner(msg.sender); isGuard[address(guard)] = true; } } /// @notice Has one Hub contract Spoke is DSAuth { Hub public hub; Hub.Routes public routes; bool public initialized; modifier onlyInitialized() { require(initialized, "Component not yet initialized"); _; } modifier notShutDown() { require(!hub.isShutDown(), "Hub is shut down"); _; } constructor(address _hub) { hub = Hub(_hub); setAuthority(hub); setOwner(hub); // temporary, to allow initialization } function initialize(address[12] _spokes) external auth { require(msg.sender == address(hub)); require(!initialized, "Already initialized"); routes = Hub.Routes( _spokes[0], _spokes[1], _spokes[2], _spokes[3], _spokes[4], _spokes[5], _spokes[6], _spokes[7], _spokes[8], _spokes[9], _spokes[10], _spokes[11] ); initialized = true; setOwner(address(0)); } function engine() public view returns (address) { return routes.engine; } function mlnToken() public view returns (address) { return routes.mlnToken; } function priceSource() public view returns (address) { return routes.priceSource; } function version() public view returns (address) { return routes.version; } function registry() public view returns (address) { return routes.registry; } } /// @notice Router for communication between components /// @notice Has one or more Spokes contract Hub is DSGuard { event FundShutDown(); struct Routes { address accounting; address feeManager; address participation; address policyManager; address shares; address trading; address vault; address priceSource; address registry; address version; address engine; address mlnToken; } Routes public routes; address public manager; address public creator; string public name; bool public isShutDown; bool public spokesSet; bool public routingSet; bool public permissionsSet; uint public creationTime; mapping (address => bool) public isSpoke; constructor(address _manager, string _name) { creator = msg.sender; manager = _manager; name = _name; creationTime = block.timestamp; } modifier onlyCreator() { require(msg.sender == creator, "Only creator can do this"); _; } function shutDownFund() external { require(msg.sender == routes.version); isShutDown = true; emit FundShutDown(); } function setSpokes(address[12] _spokes) external onlyCreator { require(!spokesSet, "Spokes already set"); for (uint i = 0; i < _spokes.length; i++) { isSpoke[_spokes[i]] = true; } routes.accounting = _spokes[0]; routes.feeManager = _spokes[1]; routes.participation = _spokes[2]; routes.policyManager = _spokes[3]; routes.shares = _spokes[4]; routes.trading = _spokes[5]; routes.vault = _spokes[6]; routes.priceSource = _spokes[7]; routes.registry = _spokes[8]; routes.version = _spokes[9]; routes.engine = _spokes[10]; routes.mlnToken = _spokes[11]; spokesSet = true; } function setRouting() external onlyCreator { require(spokesSet, "Spokes must be set"); require(!routingSet, "Routing already set"); address[12] memory spokes = [ routes.accounting, routes.feeManager, routes.participation, routes.policyManager, routes.shares, routes.trading, routes.vault, routes.priceSource, routes.registry, routes.version, routes.engine, routes.mlnToken ]; Spoke(routes.accounting).initialize(spokes); Spoke(routes.feeManager).initialize(spokes); Spoke(routes.participation).initialize(spokes); Spoke(routes.policyManager).initialize(spokes); Spoke(routes.shares).initialize(spokes); Spoke(routes.trading).initialize(spokes); Spoke(routes.vault).initialize(spokes); routingSet = true; } function setPermissions() external onlyCreator { require(spokesSet, "Spokes must be set"); require(routingSet, "Routing must be set"); require(!permissionsSet, "Permissioning already set"); permit(routes.participation, routes.vault, bytes4(keccak256('withdraw(address,uint256)'))); permit(routes.trading, routes.vault, bytes4(keccak256('withdraw(address,uint256)'))); permit(routes.participation, routes.shares, bytes4(keccak256('createFor(address,uint256)'))); permit(routes.participation, routes.shares, bytes4(keccak256('destroyFor(address,uint256)'))); permit(routes.feeManager, routes.shares, bytes4(keccak256('createFor(address,uint256)'))); permit(routes.participation, routes.accounting, bytes4(keccak256('addAssetToOwnedAssets(address)'))); permit(routes.trading, routes.accounting, bytes4(keccak256('addAssetToOwnedAssets(address)'))); permit(routes.trading, routes.accounting, bytes4(keccak256('removeFromOwnedAssets(address)'))); permit(routes.accounting, routes.feeManager, bytes4(keccak256('rewardAllFees()'))); permit(manager, routes.policyManager, bytes4(keccak256('register(bytes4,address)'))); permit(manager, routes.policyManager, bytes4(keccak256('batchRegister(bytes4[],address[])'))); permit(manager, routes.participation, bytes4(keccak256('enableInvestment(address[])'))); permit(manager, routes.participation, bytes4(keccak256('disableInvestment(address[])'))); permissionsSet = true; } function vault() external view returns (address) { return routes.vault; } function accounting() external view returns (address) { return routes.accounting; } function priceSource() external view returns (address) { return routes.priceSource; } function participation() external view returns (address) { return routes.participation; } function trading() external view returns (address) { return routes.trading; } function shares() external view returns (address) { return routes.shares; } function registry() external view returns (address) { return routes.registry; } function policyManager() external view returns (address) { return routes.policyManager; } } contract Registry is DSAuth { // EVENTS event AssetUpsert ( address indexed asset, string name, string symbol, uint decimals, string url, uint reserveMin, uint[] standards, bytes4[] sigs ); event ExchangeAdapterUpsert ( address indexed exchange, address indexed adapter, bool takesCustody, bytes4[] sigs ); event AssetRemoval (address indexed asset); event EfxWrapperRegistryChange(address indexed registry); event EngineChange(address indexed engine); event ExchangeAdapterRemoval (address indexed exchange); event IncentiveChange(uint incentiveAmount); event MGMChange(address indexed MGM); event MlnTokenChange(address indexed mlnToken); event NativeAssetChange(address indexed nativeAsset); event PriceSourceChange(address indexed priceSource); event VersionRegistration(address indexed version); // TYPES struct Asset { bool exists; string name; string symbol; uint decimals; string url; uint reserveMin; uint[] standards; bytes4[] sigs; } struct Exchange { bool exists; address exchangeAddress; bool takesCustody; bytes4[] sigs; } struct Version { bool exists; bytes32 name; } // CONSTANTS uint public constant MAX_REGISTERED_ENTITIES = 20; uint public constant MAX_FUND_NAME_BYTES = 66; // FIELDS mapping (address => Asset) public assetInformation; address[] public registeredAssets; // Mapping from adapter address to exchange Information (Adapters are unique) mapping (address => Exchange) public exchangeInformation; address[] public registeredExchangeAdapters; mapping (address => Version) public versionInformation; address[] public registeredVersions; mapping (address => bool) public isFeeRegistered; mapping (address => address) public fundsToVersions; mapping (bytes32 => bool) public versionNameExists; mapping (bytes32 => address) public fundNameHashToOwner; uint public incentive = 10 finney; address public priceSource; address public mlnToken; address public nativeAsset; address public engine; address public ethfinexWrapperRegistry; address public MGM; modifier onlyVersion() { require( versionInformation[msg.sender].exists, "Only a Version can do this" ); _; } // METHODS constructor(address _postDeployOwner) { setOwner(_postDeployOwner); } // PUBLIC METHODS /// @notice Whether _name has only valid characters function isValidFundName(string _name) public view returns (bool) { bytes memory b = bytes(_name); if (b.length > MAX_FUND_NAME_BYTES) return false; for (uint i; i < b.length; i++){ bytes1 char = b[i]; if( !(char >= 0x30 && char <= 0x39) && // 9-0 !(char >= 0x41 && char <= 0x5A) && // A-Z !(char >= 0x61 && char <= 0x7A) && // a-z !(char == 0x20 || char == 0x2D) && // space, dash !(char == 0x2E || char == 0x5F) && // period, underscore !(char == 0x2A) // * ) { return false; } } return true; } /// @notice Whether _user can use _name for their fund function canUseFundName(address _user, string _name) public view returns (bool) { bytes32 nameHash = keccak256(_name); return ( isValidFundName(_name) && ( fundNameHashToOwner[nameHash] == address(0) || fundNameHashToOwner[nameHash] == _user ) ); } function reserveFundName(address _owner, string _name) external onlyVersion { require(canUseFundName(_owner, _name), "Fund name cannot be used"); fundNameHashToOwner[keccak256(_name)] = _owner; } function registerFund(address _fund, address _owner, string _name) external onlyVersion { require(canUseFundName(_owner, _name), "Fund name cannot be used"); fundsToVersions[_fund] = msg.sender; } /// @notice Registers an Asset information entry /// @dev Pre: Only registrar owner should be able to register /// @dev Post: Address _asset is registered /// @param _asset Address of asset to be registered /// @param _name Human-readable name of the Asset /// @param _symbol Human-readable symbol of the Asset /// @param _url Url for extended information of the asset /// @param _standards Integers of EIP standards this asset adheres to /// @param _sigs Function signatures for whitelisted asset functions function registerAsset( address _asset, string _name, string _symbol, string _url, uint _reserveMin, uint[] _standards, bytes4[] _sigs ) external auth { require(registeredAssets.length < MAX_REGISTERED_ENTITIES); require(!assetInformation[_asset].exists); assetInformation[_asset].exists = true; registeredAssets.push(_asset); updateAsset( _asset, _name, _symbol, _url, _reserveMin, _standards, _sigs ); } /// @notice Register an exchange information entry (A mapping from exchange adapter -> Exchange information) /// @dev Adapters are unique so are used as the mapping key. There may be different adapters for same exchange (0x / Ethfinex) /// @dev Pre: Only registrar owner should be able to register /// @dev Post: Address _exchange is registered /// @param _exchange Address of the exchange for the adapter /// @param _adapter Address of exchange adapter /// @param _takesCustody Whether this exchange takes custody of tokens before trading /// @param _sigs Function signatures for whitelisted exchange functions function registerExchangeAdapter( address _exchange, address _adapter, bool _takesCustody, bytes4[] _sigs ) external auth { require(!exchangeInformation[_adapter].exists, "Adapter already exists"); exchangeInformation[_adapter].exists = true; require(registeredExchangeAdapters.length < MAX_REGISTERED_ENTITIES, "Exchange limit reached"); registeredExchangeAdapters.push(_adapter); updateExchangeAdapter( _exchange, _adapter, _takesCustody, _sigs ); } /// @notice Versions cannot be removed from registry /// @param _version Address of the version contract /// @param _name Name of the version function registerVersion( address _version, bytes32 _name ) external auth { require(!versionInformation[_version].exists, "Version already exists"); require(!versionNameExists[_name], "Version name already exists"); versionInformation[_version].exists = true; versionNameExists[_name] = true; versionInformation[_version].name = _name; registeredVersions.push(_version); emit VersionRegistration(_version); } function setIncentive(uint _weiAmount) external auth { incentive = _weiAmount; emit IncentiveChange(_weiAmount); } function setPriceSource(address _priceSource) external auth { priceSource = _priceSource; emit PriceSourceChange(_priceSource); } function setMlnToken(address _mlnToken) external auth { mlnToken = _mlnToken; emit MlnTokenChange(_mlnToken); } function setNativeAsset(address _nativeAsset) external auth { nativeAsset = _nativeAsset; emit NativeAssetChange(_nativeAsset); } function setEngine(address _engine) external auth { engine = _engine; emit EngineChange(_engine); } function setMGM(address _MGM) external auth { MGM = _MGM; emit MGMChange(_MGM); } function setEthfinexWrapperRegistry(address _registry) external auth { ethfinexWrapperRegistry = _registry; emit EfxWrapperRegistryChange(_registry); } /// @notice Updates description information of a registered Asset /// @dev Pre: Owner can change an existing entry /// @dev Post: Changed Name, Symbol, URL and/or IPFSHash /// @param _asset Address of the asset to be updated /// @param _name Human-readable name of the Asset /// @param _symbol Human-readable symbol of the Asset /// @param _url Url for extended information of the asset function updateAsset( address _asset, string _name, string _symbol, string _url, uint _reserveMin, uint[] _standards, bytes4[] _sigs ) public auth { require(assetInformation[_asset].exists); Asset asset = assetInformation[_asset]; asset.name = _name; asset.symbol = _symbol; asset.decimals = ERC20WithFields(_asset).decimals(); asset.url = _url; asset.reserveMin = _reserveMin; asset.standards = _standards; asset.sigs = _sigs; emit AssetUpsert( _asset, _name, _symbol, asset.decimals, _url, _reserveMin, _standards, _sigs ); } function updateExchangeAdapter( address _exchange, address _adapter, bool _takesCustody, bytes4[] _sigs ) public auth { require(exchangeInformation[_adapter].exists, "Exchange with adapter doesn't exist"); Exchange exchange = exchangeInformation[_adapter]; exchange.exchangeAddress = _exchange; exchange.takesCustody = _takesCustody; exchange.sigs = _sigs; emit ExchangeAdapterUpsert( _exchange, _adapter, _takesCustody, _sigs ); } /// @notice Deletes an existing entry /// @dev Owner can delete an existing entry /// @param _asset address for which specific information is requested function removeAsset( address _asset, uint _assetIndex ) external auth { require(assetInformation[_asset].exists); require(registeredAssets[_assetIndex] == _asset); delete assetInformation[_asset]; delete registeredAssets[_assetIndex]; for (uint i = _assetIndex; i < registeredAssets.length-1; i++) { registeredAssets[i] = registeredAssets[i+1]; } registeredAssets.length--; emit AssetRemoval(_asset); } /// @notice Deletes an existing entry /// @dev Owner can delete an existing entry /// @param _adapter address of the adapter of the exchange that is to be removed /// @param _adapterIndex index of the exchange in array function removeExchangeAdapter( address _adapter, uint _adapterIndex ) external auth { require(exchangeInformation[_adapter].exists, "Exchange with adapter doesn't exist"); require(registeredExchangeAdapters[_adapterIndex] == _adapter, "Incorrect adapter index"); delete exchangeInformation[_adapter]; delete registeredExchangeAdapters[_adapterIndex]; for (uint i = _adapterIndex; i < registeredExchangeAdapters.length-1; i++) { registeredExchangeAdapters[i] = registeredExchangeAdapters[i+1]; } registeredExchangeAdapters.length--; emit ExchangeAdapterRemoval(_adapter); } function registerFees(address[] _fees) external auth { for (uint i; i < _fees.length; i++) { isFeeRegistered[_fees[i]] = true; } } function deregisterFees(address[] _fees) external auth { for (uint i; i < _fees.length; i++) { delete isFeeRegistered[_fees[i]]; } } // PUBLIC VIEW METHODS // get asset specific information function getName(address _asset) external view returns (string) { return assetInformation[_asset].name; } function getSymbol(address _asset) external view returns (string) { return assetInformation[_asset].symbol; } function getDecimals(address _asset) external view returns (uint) { return assetInformation[_asset].decimals; } function getReserveMin(address _asset) external view returns (uint) { return assetInformation[_asset].reserveMin; } function assetIsRegistered(address _asset) external view returns (bool) { return assetInformation[_asset].exists; } function getRegisteredAssets() external view returns (address[]) { return registeredAssets; } function assetMethodIsAllowed(address _asset, bytes4 _sig) external view returns (bool) { bytes4[] memory signatures = assetInformation[_asset].sigs; for (uint i = 0; i < signatures.length; i++) { if (signatures[i] == _sig) { return true; } } return false; } // get exchange-specific information function exchangeAdapterIsRegistered(address _adapter) external view returns (bool) { return exchangeInformation[_adapter].exists; } function getRegisteredExchangeAdapters() external view returns (address[]) { return registeredExchangeAdapters; } function getExchangeInformation(address _adapter) public view returns (address, bool) { Exchange exchange = exchangeInformation[_adapter]; return ( exchange.exchangeAddress, exchange.takesCustody ); } function exchangeForAdapter(address _adapter) external view returns (address) { Exchange exchange = exchangeInformation[_adapter]; return exchange.exchangeAddress; } function getAdapterFunctionSignatures(address _adapter) public view returns (bytes4[]) { return exchangeInformation[_adapter].sigs; } function adapterMethodIsAllowed( address _adapter, bytes4 _sig ) external view returns (bool) { bytes4[] memory signatures = exchangeInformation[_adapter].sigs; for (uint i = 0; i < signatures.length; i++) { if (signatures[i] == _sig) { return true; } } return false; } // get version and fund information function getRegisteredVersions() external view returns (address[]) { return registeredVersions; } function isFund(address _who) external view returns (bool) { if (fundsToVersions[_who] != address(0)) { return true; // directly from a hub } else { address hub = Hub(Spoke(_who).hub()); require( Hub(hub).isSpoke(_who), "Call from either a spoke or hub" ); return fundsToVersions[hub] != address(0); } } function isFundFactory(address _who) external view returns (bool) { return versionInformation[_who].exists; } } /// @notice Liquidity contract and token sink contract Engine is DSMath { event RegistryChange(address registry); event SetAmguPrice(uint amguPrice); event AmguPaid(uint amount); event Thaw(uint amount); event Burn(uint amount); uint public constant MLN_DECIMALS = 18; Registry public registry; uint public amguPrice; uint public frozenEther; uint public liquidEther; uint public lastThaw; uint public thawingDelay; uint public totalEtherConsumed; uint public totalAmguConsumed; uint public totalMlnBurned; constructor(uint _delay, address _registry) { lastThaw = block.timestamp; thawingDelay = _delay; _setRegistry(_registry); } modifier onlyMGM() { require( msg.sender == registry.MGM(), "Only MGM can call this" ); _; } /// @dev Registry owner is MTC modifier onlyMTC() { require( msg.sender == registry.owner(), "Only MTC can call this" ); _; } function _setRegistry(address _registry) internal { registry = Registry(_registry); emit RegistryChange(registry); } /// @dev only callable by MTC function setRegistry(address _registry) external onlyMTC { _setRegistry(_registry); } /// @dev set price of AMGU in MLN (base units) /// @dev only callable by MGM function setAmguPrice(uint _price) external onlyMGM { amguPrice = _price; emit SetAmguPrice(_price); } function getAmguPrice() public view returns (uint) { return amguPrice; } function premiumPercent() public view returns (uint) { if (liquidEther < 1 ether) { return 0; } else if (liquidEther >= 1 ether && liquidEther < 5 ether) { return 5; } else if (liquidEther >= 5 ether && liquidEther < 10 ether) { return 10; } else if (liquidEther >= 10 ether) { return 15; } } function payAmguInEther() external payable { require( registry.isFundFactory(msg.sender) || registry.isFund(msg.sender), "Sender must be a fund or the factory" ); uint mlnPerAmgu = getAmguPrice(); uint ethPerMln; (ethPerMln,) = priceSource().getPrice(address(mlnToken())); uint amguConsumed; if (mlnPerAmgu > 0 && ethPerMln > 0) { amguConsumed = (mul(msg.value, 10 ** uint(MLN_DECIMALS))) / (mul(ethPerMln, mlnPerAmgu)); } else { amguConsumed = 0; } totalEtherConsumed = add(totalEtherConsumed, msg.value); totalAmguConsumed = add(totalAmguConsumed, amguConsumed); frozenEther = add(frozenEther, msg.value); emit AmguPaid(amguConsumed); } /// @notice Move frozen ether to liquid pool after delay /// @dev Delay only restarts when this function is called function thaw() external { require( block.timestamp >= add(lastThaw, thawingDelay), "Thawing delay has not passed" ); require(frozenEther > 0, "No frozen ether to thaw"); lastThaw = block.timestamp; liquidEther = add(liquidEther, frozenEther); emit Thaw(frozenEther); frozenEther = 0; } /// @return ETH per MLN including premium function enginePrice() public view returns (uint) { uint ethPerMln; (ethPerMln, ) = priceSource().getPrice(address(mlnToken())); uint premium = (mul(ethPerMln, premiumPercent()) / 100); return add(ethPerMln, premium); } function ethPayoutForMlnAmount(uint mlnAmount) public view returns (uint) { return mul(mlnAmount, enginePrice()) / 10 ** uint(MLN_DECIMALS); } /// @notice MLN must be approved first function sellAndBurnMln(uint mlnAmount) external { require(registry.isFund(msg.sender), "Only funds can use the engine"); require( mlnToken().transferFrom(msg.sender, address(this), mlnAmount), "MLN transferFrom failed" ); uint ethToSend = ethPayoutForMlnAmount(mlnAmount); require(ethToSend > 0, "No ether to pay out"); require(liquidEther >= ethToSend, "Not enough liquid ether to send"); liquidEther = sub(liquidEther, ethToSend); totalMlnBurned = add(totalMlnBurned, mlnAmount); msg.sender.transfer(ethToSend); mlnToken().burn(mlnAmount); emit Burn(mlnAmount); } /// @dev Get MLN from the registry function mlnToken() public view returns (BurnableToken) { return BurnableToken(registry.mlnToken()); } /// @dev Get PriceSource from the registry function priceSource() public view returns (PriceSourceInterface) { return PriceSourceInterface(registry.priceSource()); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[],"name":"priceSource","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalEtherConsumed","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalAmguConsumed","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"thaw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"payAmguInEther","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getAmguPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalMlnBurned","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"registry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"mlnAmount","type":"uint256"}],"name":"ethPayoutForMlnAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"liquidEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"frozenEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mlnToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MLN_DECIMALS","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"mlnAmount","type":"uint256"}],"name":"sellAndBurnMln","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_registry","type":"address"}],"name":"setRegistry","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lastThaw","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"premiumPercent","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"amguPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"enginePrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_price","type":"uint256"}],"name":"setAmguPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"thawingDelay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_delay","type":"uint256"},{"name":"_registry","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"registry","type":"address"}],"name":"RegistryChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amguPrice","type":"uint256"}],"name":"SetAmguPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"AmguPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Thaw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Burn","type":"event"}]
Contract Creation Code
608060405234801561001057600080fd5b506040516040806111a08339810160405280516020909101514260045560058290556100448164010000000061004b810204565b50506100a5565b60008054600160a060020a031916600160a060020a03838116919091179182905560408051929091168252517f5217946a1da07de64b3844039ef4846e81015e1130f212235a450aa822e86e55916020908290030190a150565b6110ec806100b46000396000f3006080604052600436106101035763ffffffff60e060020a60003504166320531bc9811461010857806337e1dfcc1461013957806338976b50146101605780635920375c146101755780635ce1fb541461018c578063709bb567146101945780637aada77b146101a95780637b103999146101be5780637e3fdf00146101d35780637eced8dc146101eb578063844541f1146102005780638a471df914610215578063927f8d121461022a57806394f7101d1461023f578063a91ee0dc14610257578063ab69c5be14610278578063c8412d021461028d578063cad9faf7146102a2578063d22741b8146102b7578063d69ec025146102cc578063e452bc48146102e4575b600080fd5b34801561011457600080fd5b5061011d6102f9565b60408051600160a060020a039092168252519081900360200190f35b34801561014557600080fd5b5061014e61037f565b60408051918252519081900360200190f35b34801561016c57600080fd5b5061014e610385565b34801561018157600080fd5b5061018a61038b565b005b61018a61049d565b3480156101a057600080fd5b5061014e61078c565b3480156101b557600080fd5b5061014e610792565b3480156101ca57600080fd5b5061011d610798565b3480156101df57600080fd5b5061014e6004356107a7565b3480156101f757600080fd5b5061014e6107d3565b34801561020c57600080fd5b5061014e6107d9565b34801561022157600080fd5b5061011d6107df565b34801561023657600080fd5b5061014e610833565b34801561024b57600080fd5b5061018a600435610838565b34801561026357600080fd5b5061018a600160a060020a0360043516610bc5565b34801561028457600080fd5b5061014e610cae565b34801561029957600080fd5b5061014e610cb4565b3480156102ae57600080fd5b5061014e610d49565b3480156102c357600080fd5b5061014e610d4f565b3480156102d857600080fd5b5061018a600435610e0c565b3480156102f057600080fd5b5061014e610f24565b60008060009054906101000a9004600160a060020a0316600160a060020a03166320531bc96040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561034d57600080fd5b505af1158015610361573d6000803e3d6000fd5b505050506040513d602081101561037757600080fd5b505190505b90565b60065481565b60075481565b610399600454600554610f2a565b4210156103f0576040805160e560020a62461bcd02815260206004820152601c60248201527f54686177696e672064656c617920686173206e6f742070617373656400000000604482015290519081900360640190fd5b60025460001061044a576040805160e560020a62461bcd02815260206004820152601760248201527f4e6f2066726f7a656e20657468657220746f2074686177000000000000000000604482015290519081900360640190fd5b4260045560035460025461045e9190610f2a565b60035560025460408051918252517f1d80c08fcaae77e805a6ea398f9bf4a855c663cfee51ccdf7144f627019190e79181900360200190a16000600255565b60008054604080517f9b8ce78f000000000000000000000000000000000000000000000000000000008152336004820152905183928392600160a060020a0390911691639b8ce78f9160248082019260209290919082900301818787803b15801561050757600080fd5b505af115801561051b573d6000803e3d6000fd5b505050506040513d602081101561053157600080fd5b5051806105cd575060008054604080517fc7153b890000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a039092169263c7153b89926024808401936020939083900390910190829087803b1580156105a057600080fd5b505af11580156105b4573d6000803e3d6000fd5b505050506040513d60208110156105ca57600080fd5b50515b1515610648576040805160e560020a62461bcd028152602060048201526024808201527f53656e646572206d75737420626520612066756e64206f72207468652066616360448201527f746f727900000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b61065061078c565b925061065a6102f9565b600160a060020a03166341976e096106706107df565b6040805160e060020a63ffffffff8516028152600160a060020a03909216600483015280516024808401938290030181600087803b1580156106b157600080fd5b505af11580156106c5573d6000803e3d6000fd5b505050506040513d60408110156106db57600080fd5b505191506000831180156106ef5750600082115b15610721576106fe8284610f8b565b61071034670de0b6b3a7640000610f8b565b81151561071957fe5b049050610725565b5060005b61073160065434610f2a565b6006556007546107419082610f2a565b6007556002546107519034610f2a565b6002556040805182815290517f3e8b952cc45d489522879efd5adf94411f28dd2b821d4e532c7cda1af51050d79181900360200190a1505050565b60015490565b60085481565b600054600160a060020a031681565b6000670de0b6b3a76400006107c3836107be610d4f565b610f8b565b8115156107cc57fe5b0492915050565b60035481565b60025481565b60008060009054906101000a9004600160a060020a0316600160a060020a0316638a471df96040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561034d57600080fd5b601281565b60008054604080517fc7153b890000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a039092169163c7153b899160248082019260209290919082900301818787803b15801561089e57600080fd5b505af11580156108b2573d6000803e3d6000fd5b505050506040513d60208110156108c857600080fd5b50511515610920576040805160e560020a62461bcd02815260206004820152601d60248201527f4f6e6c792066756e64732063616e207573652074686520656e67696e65000000604482015290519081900360640190fd5b6109286107df565b604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590529051600160a060020a0392909216916323b872dd916064808201926020929091908290030181600087803b15801561099957600080fd5b505af11580156109ad573d6000803e3d6000fd5b505050506040513d60208110156109c357600080fd5b50511515610a1b576040805160e560020a62461bcd02815260206004820152601760248201527f4d4c4e207472616e7366657246726f6d206661696c6564000000000000000000604482015290519081900360640190fd5b610a24826107a7565b905060008111610a7e576040805160e560020a62461bcd02815260206004820152601360248201527f4e6f20657468657220746f20706179206f757400000000000000000000000000604482015290519081900360640190fd5b600354811115610ad8576040805160e560020a62461bcd02815260206004820152601f60248201527f4e6f7420656e6f756768206c697175696420657468657220746f2073656e6400604482015290519081900360640190fd5b610ae460035482610ffe565b600355600854610af49083610f2a565b600855604051339082156108fc029083906000818181858888f19350505050158015610b24573d6000803e3d6000fd5b50610b2d6107df565b600160a060020a03166342966c68836040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015610b7557600080fd5b505af1158015610b89573d6000803e3d6000fd5b50506040805185815290517fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb9350908190036020019150a15050565b6000809054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610c1757600080fd5b505af1158015610c2b573d6000803e3d6000fd5b505050506040513d6020811015610c4157600080fd5b5051600160a060020a03163314610ca2576040805160e560020a62461bcd02815260206004820152601660248201527f4f6e6c79204d54432063616e2063616c6c207468697300000000000000000000604482015290519081900360640190fd5b610cab81611059565b50565b60045481565b6000670de0b6b3a76400006003541015610cd05750600061037c565b670de0b6b3a764000060035410158015610cf35750674563918244f40000600354105b15610d005750600561037c565b674563918244f4000060035410158015610d235750678ac7230489e80000600354105b15610d305750600a61037c565b600354678ac7230489e800001161037c5750600f61037c565b60015481565b6000806000610d5c6102f9565b600160a060020a03166341976e09610d726107df565b6040805160e060020a63ffffffff8516028152600160a060020a03909216600483015280516024808401938290030181600087803b158015610db357600080fd5b505af1158015610dc7573d6000803e3d6000fd5b505050506040513d6040811015610ddd57600080fd5b505191506064610def836107be610cb4565b811515610df857fe5b049050610e058282610f2a565b9250505090565b6000809054906101000a9004600160a060020a0316600160a060020a031663aa8862ba6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610e5e57600080fd5b505af1158015610e72573d6000803e3d6000fd5b505050506040513d6020811015610e8857600080fd5b5051600160a060020a03163314610ee9576040805160e560020a62461bcd02815260206004820152601660248201527f4f6e6c79204d474d2063616e2063616c6c207468697300000000000000000000604482015290519081900360640190fd5b60018190556040805182815290517f6e0f8250ad164a071ea409a83fa1deb674115a68d3eb82a93165573f228b2c5c9181900360200190a150565b60055481565b80820182811015610f85576040805160e560020a62461bcd02815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b92915050565b6000811580610fa8575050808202828282811515610fa557fe5b04145b1515610f85576040805160e560020a62461bcd02815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b80820382811115610f85576040805160e560020a62461bcd02815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b6000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03838116919091179182905560408051929091168252517f5217946a1da07de64b3844039ef4846e81015e1130f212235a450aa822e86e55916020908290030190a1505600a165627a7a7230582086e23a025da3dbfd60ddcbc7cd11bc0f4d67c99a0f9d119e4877aba3a45f115400290000000000000000000000000000000000000000000000000000000000278d000000000000000000000000001bfd21f7db126a5966d2c09492676807a68859ba
Deployed Bytecode
0x6080604052600436106101035763ffffffff60e060020a60003504166320531bc9811461010857806337e1dfcc1461013957806338976b50146101605780635920375c146101755780635ce1fb541461018c578063709bb567146101945780637aada77b146101a95780637b103999146101be5780637e3fdf00146101d35780637eced8dc146101eb578063844541f1146102005780638a471df914610215578063927f8d121461022a57806394f7101d1461023f578063a91ee0dc14610257578063ab69c5be14610278578063c8412d021461028d578063cad9faf7146102a2578063d22741b8146102b7578063d69ec025146102cc578063e452bc48146102e4575b600080fd5b34801561011457600080fd5b5061011d6102f9565b60408051600160a060020a039092168252519081900360200190f35b34801561014557600080fd5b5061014e61037f565b60408051918252519081900360200190f35b34801561016c57600080fd5b5061014e610385565b34801561018157600080fd5b5061018a61038b565b005b61018a61049d565b3480156101a057600080fd5b5061014e61078c565b3480156101b557600080fd5b5061014e610792565b3480156101ca57600080fd5b5061011d610798565b3480156101df57600080fd5b5061014e6004356107a7565b3480156101f757600080fd5b5061014e6107d3565b34801561020c57600080fd5b5061014e6107d9565b34801561022157600080fd5b5061011d6107df565b34801561023657600080fd5b5061014e610833565b34801561024b57600080fd5b5061018a600435610838565b34801561026357600080fd5b5061018a600160a060020a0360043516610bc5565b34801561028457600080fd5b5061014e610cae565b34801561029957600080fd5b5061014e610cb4565b3480156102ae57600080fd5b5061014e610d49565b3480156102c357600080fd5b5061014e610d4f565b3480156102d857600080fd5b5061018a600435610e0c565b3480156102f057600080fd5b5061014e610f24565b60008060009054906101000a9004600160a060020a0316600160a060020a03166320531bc96040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561034d57600080fd5b505af1158015610361573d6000803e3d6000fd5b505050506040513d602081101561037757600080fd5b505190505b90565b60065481565b60075481565b610399600454600554610f2a565b4210156103f0576040805160e560020a62461bcd02815260206004820152601c60248201527f54686177696e672064656c617920686173206e6f742070617373656400000000604482015290519081900360640190fd5b60025460001061044a576040805160e560020a62461bcd02815260206004820152601760248201527f4e6f2066726f7a656e20657468657220746f2074686177000000000000000000604482015290519081900360640190fd5b4260045560035460025461045e9190610f2a565b60035560025460408051918252517f1d80c08fcaae77e805a6ea398f9bf4a855c663cfee51ccdf7144f627019190e79181900360200190a16000600255565b60008054604080517f9b8ce78f000000000000000000000000000000000000000000000000000000008152336004820152905183928392600160a060020a0390911691639b8ce78f9160248082019260209290919082900301818787803b15801561050757600080fd5b505af115801561051b573d6000803e3d6000fd5b505050506040513d602081101561053157600080fd5b5051806105cd575060008054604080517fc7153b890000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a039092169263c7153b89926024808401936020939083900390910190829087803b1580156105a057600080fd5b505af11580156105b4573d6000803e3d6000fd5b505050506040513d60208110156105ca57600080fd5b50515b1515610648576040805160e560020a62461bcd028152602060048201526024808201527f53656e646572206d75737420626520612066756e64206f72207468652066616360448201527f746f727900000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b61065061078c565b925061065a6102f9565b600160a060020a03166341976e096106706107df565b6040805160e060020a63ffffffff8516028152600160a060020a03909216600483015280516024808401938290030181600087803b1580156106b157600080fd5b505af11580156106c5573d6000803e3d6000fd5b505050506040513d60408110156106db57600080fd5b505191506000831180156106ef5750600082115b15610721576106fe8284610f8b565b61071034670de0b6b3a7640000610f8b565b81151561071957fe5b049050610725565b5060005b61073160065434610f2a565b6006556007546107419082610f2a565b6007556002546107519034610f2a565b6002556040805182815290517f3e8b952cc45d489522879efd5adf94411f28dd2b821d4e532c7cda1af51050d79181900360200190a1505050565b60015490565b60085481565b600054600160a060020a031681565b6000670de0b6b3a76400006107c3836107be610d4f565b610f8b565b8115156107cc57fe5b0492915050565b60035481565b60025481565b60008060009054906101000a9004600160a060020a0316600160a060020a0316638a471df96040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561034d57600080fd5b601281565b60008054604080517fc7153b890000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a039092169163c7153b899160248082019260209290919082900301818787803b15801561089e57600080fd5b505af11580156108b2573d6000803e3d6000fd5b505050506040513d60208110156108c857600080fd5b50511515610920576040805160e560020a62461bcd02815260206004820152601d60248201527f4f6e6c792066756e64732063616e207573652074686520656e67696e65000000604482015290519081900360640190fd5b6109286107df565b604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590529051600160a060020a0392909216916323b872dd916064808201926020929091908290030181600087803b15801561099957600080fd5b505af11580156109ad573d6000803e3d6000fd5b505050506040513d60208110156109c357600080fd5b50511515610a1b576040805160e560020a62461bcd02815260206004820152601760248201527f4d4c4e207472616e7366657246726f6d206661696c6564000000000000000000604482015290519081900360640190fd5b610a24826107a7565b905060008111610a7e576040805160e560020a62461bcd02815260206004820152601360248201527f4e6f20657468657220746f20706179206f757400000000000000000000000000604482015290519081900360640190fd5b600354811115610ad8576040805160e560020a62461bcd02815260206004820152601f60248201527f4e6f7420656e6f756768206c697175696420657468657220746f2073656e6400604482015290519081900360640190fd5b610ae460035482610ffe565b600355600854610af49083610f2a565b600855604051339082156108fc029083906000818181858888f19350505050158015610b24573d6000803e3d6000fd5b50610b2d6107df565b600160a060020a03166342966c68836040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015610b7557600080fd5b505af1158015610b89573d6000803e3d6000fd5b50506040805185815290517fb90306ad06b2a6ff86ddc9327db583062895ef6540e62dc50add009db5b356eb9350908190036020019150a15050565b6000809054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610c1757600080fd5b505af1158015610c2b573d6000803e3d6000fd5b505050506040513d6020811015610c4157600080fd5b5051600160a060020a03163314610ca2576040805160e560020a62461bcd02815260206004820152601660248201527f4f6e6c79204d54432063616e2063616c6c207468697300000000000000000000604482015290519081900360640190fd5b610cab81611059565b50565b60045481565b6000670de0b6b3a76400006003541015610cd05750600061037c565b670de0b6b3a764000060035410158015610cf35750674563918244f40000600354105b15610d005750600561037c565b674563918244f4000060035410158015610d235750678ac7230489e80000600354105b15610d305750600a61037c565b600354678ac7230489e800001161037c5750600f61037c565b60015481565b6000806000610d5c6102f9565b600160a060020a03166341976e09610d726107df565b6040805160e060020a63ffffffff8516028152600160a060020a03909216600483015280516024808401938290030181600087803b158015610db357600080fd5b505af1158015610dc7573d6000803e3d6000fd5b505050506040513d6040811015610ddd57600080fd5b505191506064610def836107be610cb4565b811515610df857fe5b049050610e058282610f2a565b9250505090565b6000809054906101000a9004600160a060020a0316600160a060020a031663aa8862ba6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610e5e57600080fd5b505af1158015610e72573d6000803e3d6000fd5b505050506040513d6020811015610e8857600080fd5b5051600160a060020a03163314610ee9576040805160e560020a62461bcd02815260206004820152601660248201527f4f6e6c79204d474d2063616e2063616c6c207468697300000000000000000000604482015290519081900360640190fd5b60018190556040805182815290517f6e0f8250ad164a071ea409a83fa1deb674115a68d3eb82a93165573f228b2c5c9181900360200190a150565b60055481565b80820182811015610f85576040805160e560020a62461bcd02815260206004820152601460248201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b92915050565b6000811580610fa8575050808202828282811515610fa557fe5b04145b1515610f85576040805160e560020a62461bcd02815260206004820152601460248201527f64732d6d6174682d6d756c2d6f766572666c6f77000000000000000000000000604482015290519081900360640190fd5b80820382811115610f85576040805160e560020a62461bcd02815260206004820152601560248201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604482015290519081900360640190fd5b6000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03838116919091179182905560408051929091168252517f5217946a1da07de64b3844039ef4846e81015e1130f212235a450aa822e86e55916020908290030190a1505600a165627a7a7230582086e23a025da3dbfd60ddcbc7cd11bc0f4d67c99a0f9d119e4877aba3a45f11540029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000278d000000000000000000000000001bfd21f7db126a5966d2c09492676807a68859ba
-----Decoded View---------------
Arg [0] : _delay (uint256): 2592000
Arg [1] : _registry (address): 0x1Bfd21f7db126a5966d2C09492676807a68859Ba
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000278d00
Arg [1] : 0000000000000000000000001bfd21f7db126a5966d2c09492676807a68859ba
Swarm Source
bzzr://86e23a025da3dbfd60ddcbc7cd11bc0f4d67c99a0f9d119e4877aba3a45f1154
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 25 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $2,889.95 | 0.9519 | $2,750.97 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.