Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 15 from a total of 15 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Add Access | 11407599 | 1258 days ago | IN | 0 ETH | 0.00272352 | ||||
Add Access | 11407556 | 1258 days ago | IN | 0 ETH | 0.00272352 | ||||
Create Service A... | 11236852 | 1284 days ago | IN | 0 ETH | 0.04165416 | ||||
Create Service A... | 11236815 | 1284 days ago | IN | 0 ETH | 0.0379248 | ||||
Create Service A... | 11236716 | 1284 days ago | IN | 0 ETH | 0.0347118 | ||||
Create Service A... | 11191180 | 1291 days ago | IN | 0 ETH | 0.0347118 | ||||
Add Access | 11184353 | 1292 days ago | IN | 0 ETH | 0.00181568 | ||||
Remove Access | 11184352 | 1292 days ago | IN | 0 ETH | 0.00061652 | ||||
Add Access | 11177933 | 1293 days ago | IN | 0 ETH | 0.00272352 | ||||
Add Access | 10776449 | 1355 days ago | IN | 0 ETH | 0.02224208 | ||||
Add Access | 10776449 | 1355 days ago | IN | 0 ETH | 0.0222362 | ||||
Create Service A... | 10776445 | 1355 days ago | IN | 0 ETH | 0.21838467 | ||||
Create Service A... | 10776431 | 1355 days ago | IN | 0 ETH | 0.27305059 | ||||
Create Service A... | 10776408 | 1355 days ago | IN | 0 ETH | 0.28083792 | ||||
0x60806040 | 10772010 | 1356 days ago | IN | Create: PreCoordinator | 0 ETH | 0.60983706 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
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:
PreCoordinator
Compiler Version
v0.6.6+commit.6c089d02
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-09-01 */ // File: contracts/vendor/Buffer.sol pragma solidity ^0.6.0; /** * @dev A library for working with mutable byte buffers in Solidity. * * Byte buffers are mutable and expandable, and provide a variety of primitives * for writing to them. At any time you can fetch a bytes object containing the * current contents of the buffer. The bytes object should not be stored between * operations, as it may change due to resizing of the buffer. */ library Buffer { /** * @dev Represents a mutable buffer. Buffers have a current value (buf) and * a capacity. The capacity may be longer than the current value, in * which case it can be extended without the need to allocate more memory. */ struct buffer { bytes buf; uint capacity; } /** * @dev Initializes a buffer with an initial capacity. * @param buf The buffer to initialize. * @param capacity The number of bytes of space to allocate the buffer. * @return The buffer, for chaining. */ function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) { if (capacity % 32 != 0) { capacity += 32 - (capacity % 32); } // Allocate space for the buffer data buf.capacity = capacity; assembly { let ptr := mload(0x40) mstore(buf, ptr) mstore(ptr, 0) mstore(0x40, add(32, add(ptr, capacity))) } return buf; } /** * @dev Initializes a new buffer from an existing bytes object. * Changes to the buffer may mutate the original value. * @param b The bytes object to initialize the buffer with. * @return A new buffer. */ function fromBytes(bytes memory b) internal pure returns(buffer memory) { buffer memory buf; buf.buf = b; buf.capacity = b.length; return buf; } function resize(buffer memory buf, uint capacity) private pure { bytes memory oldbuf = buf.buf; init(buf, capacity); append(buf, oldbuf); } function max(uint a, uint b) private pure returns(uint) { if (a > b) { return a; } return b; } /** * @dev Sets buffer length to 0. * @param buf The buffer to truncate. * @return The original buffer, for chaining.. */ function truncate(buffer memory buf) internal pure returns (buffer memory) { assembly { let bufptr := mload(buf) mstore(bufptr, 0) } return buf; } /** * @dev Writes a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The start offset to write to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) { require(len <= data.length); if (off + len > buf.capacity) { resize(buf, max(buf.capacity, len + off) * 2); } uint dest; uint src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(add(len, off), buflen) { mstore(bufptr, add(len, off)) } src := add(data, 32) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes uint mask = 256 ** (32 - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } return buf; } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, len); } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, data.length); } /** * @dev Writes a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write the byte at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) { if (off >= buf.capacity) { resize(buf, buf.capacity * 2); } assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Address = buffer address + sizeof(buffer length) + off let dest := add(add(bufptr, off), 32) mstore8(dest, data) // Update buffer length if we extended it if eq(off, buflen) { mstore(bufptr, add(buflen, 1)) } } return buf; } /** * @dev Appends a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) { return writeUint8(buf, buf.buf.length, data); } /** * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (left-aligned). * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } uint mask = 256 ** len - 1; // Right-align data data = data >> (8 * (32 - len)); assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + sizeof(buffer length) + off + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } return buf; } /** * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) { return write(buf, off, bytes32(data), 20); } /** * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chhaining. */ function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, bytes32(data), 20); } /** * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, 32); } /** * @dev Writes an integer to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (right-aligned). * @return The original buffer, for chaining. */ function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } uint mask = 256 ** len - 1; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + off + sizeof(buffer length) + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } return buf; } /** * @dev Appends a byte to the end of the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer. */ function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) { return writeInt(buf, buf.buf.length, data, len); } } // File: contracts/vendor/CBOR.sol pragma solidity ^0.6.0; library CBOR { using Buffer for Buffer.buffer; uint8 private constant MAJOR_TYPE_INT = 0; uint8 private constant MAJOR_TYPE_NEGATIVE_INT = 1; uint8 private constant MAJOR_TYPE_BYTES = 2; uint8 private constant MAJOR_TYPE_STRING = 3; uint8 private constant MAJOR_TYPE_ARRAY = 4; uint8 private constant MAJOR_TYPE_MAP = 5; uint8 private constant MAJOR_TYPE_CONTENT_FREE = 7; function encodeType(Buffer.buffer memory buf, uint8 major, uint value) private pure { if(value <= 23) { buf.appendUint8(uint8((major << 5) | value)); } else if(value <= 0xFF) { buf.appendUint8(uint8((major << 5) | 24)); buf.appendInt(value, 1); } else if(value <= 0xFFFF) { buf.appendUint8(uint8((major << 5) | 25)); buf.appendInt(value, 2); } else if(value <= 0xFFFFFFFF) { buf.appendUint8(uint8((major << 5) | 26)); buf.appendInt(value, 4); } else if(value <= 0xFFFFFFFFFFFFFFFF) { buf.appendUint8(uint8((major << 5) | 27)); buf.appendInt(value, 8); } } function encodeIndefiniteLengthType(Buffer.buffer memory buf, uint8 major) private pure { buf.appendUint8(uint8((major << 5) | 31)); } function encodeUInt(Buffer.buffer memory buf, uint value) internal pure { encodeType(buf, MAJOR_TYPE_INT, value); } function encodeInt(Buffer.buffer memory buf, int value) internal pure { if(value >= 0) { encodeType(buf, MAJOR_TYPE_INT, uint(value)); } else { encodeType(buf, MAJOR_TYPE_NEGATIVE_INT, uint(-1 - value)); } } function encodeBytes(Buffer.buffer memory buf, bytes memory value) internal pure { encodeType(buf, MAJOR_TYPE_BYTES, value.length); buf.append(value); } function encodeString(Buffer.buffer memory buf, string memory value) internal pure { encodeType(buf, MAJOR_TYPE_STRING, bytes(value).length); buf.append(bytes(value)); } function startArray(Buffer.buffer memory buf) internal pure { encodeIndefiniteLengthType(buf, MAJOR_TYPE_ARRAY); } function startMap(Buffer.buffer memory buf) internal pure { encodeIndefiniteLengthType(buf, MAJOR_TYPE_MAP); } function endSequence(Buffer.buffer memory buf) internal pure { encodeIndefiniteLengthType(buf, MAJOR_TYPE_CONTENT_FREE); } } // File: contracts/Chainlink.sol pragma solidity ^0.6.0; /** * @title Library for common Chainlink functions * @dev Uses imported CBOR library for encoding to buffer */ library Chainlink { uint256 internal constant defaultBufferSize = 256; // solhint-disable-line const-name-snakecase using CBOR for Buffer.buffer; struct Request { bytes32 id; address callbackAddress; bytes4 callbackFunctionId; uint256 nonce; Buffer.buffer buf; } /** * @notice Initializes a Chainlink request * @dev Sets the ID, callback address, and callback function signature on the request * @param self The uninitialized request * @param _id The Job Specification ID * @param _callbackAddress The callback address * @param _callbackFunction The callback function signature * @return The initialized request */ function initialize( Request memory self, bytes32 _id, address _callbackAddress, bytes4 _callbackFunction ) internal pure returns (Chainlink.Request memory) { Buffer.init(self.buf, defaultBufferSize); self.id = _id; self.callbackAddress = _callbackAddress; self.callbackFunctionId = _callbackFunction; return self; } /** * @notice Sets the data for the buffer without encoding CBOR on-chain * @dev CBOR can be closed with curly-brackets {} or they can be left off * @param self The initialized request * @param _data The CBOR data */ function setBuffer(Request memory self, bytes memory _data) internal pure { Buffer.init(self.buf, _data.length); Buffer.append(self.buf, _data); } /** * @notice Adds a string value to the request with a given key name * @param self The initialized request * @param _key The name of the key * @param _value The string value to add */ function add(Request memory self, string memory _key, string memory _value) internal pure { self.buf.encodeString(_key); self.buf.encodeString(_value); } /** * @notice Adds a bytes value to the request with a given key name * @param self The initialized request * @param _key The name of the key * @param _value The bytes value to add */ function addBytes(Request memory self, string memory _key, bytes memory _value) internal pure { self.buf.encodeString(_key); self.buf.encodeBytes(_value); } /** * @notice Adds a int256 value to the request with a given key name * @param self The initialized request * @param _key The name of the key * @param _value The int256 value to add */ function addInt(Request memory self, string memory _key, int256 _value) internal pure { self.buf.encodeString(_key); self.buf.encodeInt(_value); } /** * @notice Adds a uint256 value to the request with a given key name * @param self The initialized request * @param _key The name of the key * @param _value The uint256 value to add */ function addUint(Request memory self, string memory _key, uint256 _value) internal pure { self.buf.encodeString(_key); self.buf.encodeUInt(_value); } /** * @notice Adds an array of strings to the request with a given key name * @param self The initialized request * @param _key The name of the key * @param _values The array of string values to add */ function addStringArray(Request memory self, string memory _key, string[] memory _values) internal pure { self.buf.encodeString(_key); self.buf.startArray(); for (uint256 i = 0; i < _values.length; i++) { self.buf.encodeString(_values[i]); } self.buf.endSequence(); } } // File: contracts/interfaces/ENSInterface.sol pragma solidity ^0.6.0; interface ENSInterface { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); function setSubnodeOwner(bytes32 node, bytes32 label, address _owner) external; function setResolver(bytes32 node, address _resolver) external; function setOwner(bytes32 node, address _owner) external; function setTTL(bytes32 node, uint64 _ttl) external; function owner(bytes32 node) external view returns (address); function resolver(bytes32 node) external view returns (address); function ttl(bytes32 node) external view returns (uint64); } // File: contracts/interfaces/LinkTokenInterface.sol pragma solidity ^0.6.0; interface LinkTokenInterface { function allowance(address owner, address spender) external view returns (uint256 remaining); function approve(address spender, uint256 value) external returns (bool success); function balanceOf(address owner) external view returns (uint256 balance); function decimals() external view returns (uint8 decimalPlaces); function decreaseApproval(address spender, uint256 addedValue) external returns (bool success); function increaseApproval(address spender, uint256 subtractedValue) external; function name() external view returns (string memory tokenName); function symbol() external view returns (string memory tokenSymbol); function totalSupply() external view returns (uint256 totalTokensIssued); function transfer(address to, uint256 value) external returns (bool success); function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success); function transferFrom(address from, address to, uint256 value) external returns (bool success); } // File: contracts/interfaces/ChainlinkRequestInterface.sol pragma solidity ^0.6.0; interface ChainlinkRequestInterface { function oracleRequest( address sender, uint256 requestPrice, bytes32 serviceAgreementID, address callbackAddress, bytes4 callbackFunctionId, uint256 nonce, uint256 dataVersion, // Currently unused, always "1" bytes calldata data ) external; function cancelOracleRequest( bytes32 requestId, uint256 payment, bytes4 callbackFunctionId, uint256 expiration ) external; } // File: contracts/interfaces/PointerInterface.sol pragma solidity ^0.6.0; interface PointerInterface { function getAddress() external view returns (address); } // File: contracts/vendor/ENSResolver.sol pragma solidity ^0.6.0; abstract contract ENSResolver { function addr(bytes32 node) public view virtual returns (address); } // File: contracts/vendor/SafeMath.sol pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot 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, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // File: contracts/ChainlinkClient.sol pragma solidity ^0.6.0; /** * @title The ChainlinkClient contract * @notice Contract writers can inherit this contract in order to create requests for the * Chainlink network */ contract ChainlinkClient { using Chainlink for Chainlink.Request; using SafeMath for uint256; uint256 constant internal LINK = 10**18; uint256 constant private AMOUNT_OVERRIDE = 0; address constant private SENDER_OVERRIDE = address(0); uint256 constant private ARGS_VERSION = 1; bytes32 constant private ENS_TOKEN_SUBNAME = keccak256("link"); bytes32 constant private ENS_ORACLE_SUBNAME = keccak256("oracle"); address constant private LINK_TOKEN_POINTER = 0xC89bD4E1632D3A43CB03AAAd5262cbe4038Bc571; ENSInterface private ens; bytes32 private ensNode; LinkTokenInterface private link; ChainlinkRequestInterface private oracle; uint256 private requestCount = 1; mapping(bytes32 => address) private pendingRequests; event ChainlinkRequested(bytes32 indexed id); event ChainlinkFulfilled(bytes32 indexed id); event ChainlinkCancelled(bytes32 indexed id); /** * @notice Creates a request that can hold additional parameters * @param _specId The Job Specification ID that the request will be created for * @param _callbackAddress The callback address that the response will be sent to * @param _callbackFunctionSignature The callback function signature to use for the callback address * @return A Chainlink Request struct in memory */ function buildChainlinkRequest( bytes32 _specId, address _callbackAddress, bytes4 _callbackFunctionSignature ) internal pure returns (Chainlink.Request memory) { Chainlink.Request memory req; return req.initialize(_specId, _callbackAddress, _callbackFunctionSignature); } /** * @notice Creates a Chainlink request to the stored oracle address * @dev Calls `chainlinkRequestTo` with the stored oracle address * @param _req The initialized Chainlink Request * @param _payment The amount of LINK to send for the request * @return requestId The request ID */ function sendChainlinkRequest(Chainlink.Request memory _req, uint256 _payment) internal returns (bytes32) { return sendChainlinkRequestTo(address(oracle), _req, _payment); } /** * @notice Creates a Chainlink request to the specified oracle address * @dev Generates and stores a request ID, increments the local nonce, and uses `transferAndCall` to * send LINK which creates a request on the target oracle contract. * Emits ChainlinkRequested event. * @param _oracle The address of the oracle for the request * @param _req The initialized Chainlink Request * @param _payment The amount of LINK to send for the request * @return requestId The request ID */ function sendChainlinkRequestTo(address _oracle, Chainlink.Request memory _req, uint256 _payment) internal returns (bytes32 requestId) { requestId = keccak256(abi.encodePacked(this, requestCount)); _req.nonce = requestCount; pendingRequests[requestId] = _oracle; emit ChainlinkRequested(requestId); require(link.transferAndCall(_oracle, _payment, encodeRequest(_req)), "unable to transferAndCall to oracle"); requestCount += 1; return requestId; } /** * @notice Allows a request to be cancelled if it has not been fulfilled * @dev Requires keeping track of the expiration value emitted from the oracle contract. * Deletes the request from the `pendingRequests` mapping. * Emits ChainlinkCancelled event. * @param _requestId The request ID * @param _payment The amount of LINK sent for the request * @param _callbackFunc The callback function specified for the request * @param _expiration The time of the expiration for the request */ function cancelChainlinkRequest( bytes32 _requestId, uint256 _payment, bytes4 _callbackFunc, uint256 _expiration ) internal { ChainlinkRequestInterface requested = ChainlinkRequestInterface(pendingRequests[_requestId]); delete pendingRequests[_requestId]; emit ChainlinkCancelled(_requestId); requested.cancelOracleRequest(_requestId, _payment, _callbackFunc, _expiration); } /** * @notice Sets the stored oracle address * @param _oracle The address of the oracle contract */ function setChainlinkOracle(address _oracle) internal { oracle = ChainlinkRequestInterface(_oracle); } /** * @notice Sets the LINK token address * @param _link The address of the LINK token contract */ function setChainlinkToken(address _link) internal { link = LinkTokenInterface(_link); } /** * @notice Sets the Chainlink token address for the public * network as given by the Pointer contract */ function setPublicChainlinkToken() internal { setChainlinkToken(PointerInterface(LINK_TOKEN_POINTER).getAddress()); } /** * @notice Retrieves the stored address of the LINK token * @return The address of the LINK token */ function chainlinkTokenAddress() internal view returns (address) { return address(link); } /** * @notice Retrieves the stored address of the oracle contract * @return The address of the oracle contract */ function chainlinkOracleAddress() internal view returns (address) { return address(oracle); } /** * @notice Allows for a request which was created on another contract to be fulfilled * on this contract * @param _oracle The address of the oracle contract that will fulfill the request * @param _requestId The request ID used for the response */ function addChainlinkExternalRequest(address _oracle, bytes32 _requestId) internal notPendingRequest(_requestId) { pendingRequests[_requestId] = _oracle; } /** * @notice Sets the stored oracle and LINK token contracts with the addresses resolved by ENS * @dev Accounts for subnodes having different resolvers * @param _ens The address of the ENS contract * @param _node The ENS node hash */ function useChainlinkWithENS(address _ens, bytes32 _node) internal { ens = ENSInterface(_ens); ensNode = _node; bytes32 linkSubnode = keccak256(abi.encodePacked(ensNode, ENS_TOKEN_SUBNAME)); ENSResolver resolver = ENSResolver(ens.resolver(linkSubnode)); setChainlinkToken(resolver.addr(linkSubnode)); updateChainlinkOracleWithENS(); } /** * @notice Sets the stored oracle contract with the address resolved by ENS * @dev This may be called on its own as long as `useChainlinkWithENS` has been called previously */ function updateChainlinkOracleWithENS() internal { bytes32 oracleSubnode = keccak256(abi.encodePacked(ensNode, ENS_ORACLE_SUBNAME)); ENSResolver resolver = ENSResolver(ens.resolver(oracleSubnode)); setChainlinkOracle(resolver.addr(oracleSubnode)); } /** * @notice Encodes the request to be sent to the oracle contract * @dev The Chainlink node expects values to be in order for the request to be picked up. Order of types * will be validated in the oracle contract. * @param _req The initialized Chainlink Request * @return The bytes payload for the `transferAndCall` method */ function encodeRequest(Chainlink.Request memory _req) private view returns (bytes memory) { return abi.encodeWithSelector( oracle.oracleRequest.selector, SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent _req.id, _req.callbackAddress, _req.callbackFunctionId, _req.nonce, ARGS_VERSION, _req.buf.buf); } /** * @notice Ensures that the fulfillment is valid for this contract * @dev Use if the contract developer prefers methods instead of modifiers for validation * @param _requestId The request ID for fulfillment */ function validateChainlinkCallback(bytes32 _requestId) internal recordChainlinkFulfillment(_requestId) // solhint-disable-next-line no-empty-blocks {} /** * @dev Reverts if the sender is not the oracle of the request. * Emits ChainlinkFulfilled event. * @param _requestId The request ID for fulfillment */ modifier recordChainlinkFulfillment(bytes32 _requestId) { require(msg.sender == pendingRequests[_requestId], "Source must be the oracle of the request"); delete pendingRequests[_requestId]; emit ChainlinkFulfilled(_requestId); _; } /** * @dev Reverts if the request is already pending * @param _requestId The request ID for fulfillment */ modifier notPendingRequest(bytes32 _requestId) { require(pendingRequests[_requestId] == address(0), "Request is already pending"); _; } } // File: contracts/LinkTokenReceiver.sol pragma solidity ^0.6.0; abstract contract LinkTokenReceiver { bytes4 constant private ORACLE_REQUEST_SELECTOR = 0x40429946; uint256 constant private SELECTOR_LENGTH = 4; uint256 constant private EXPECTED_REQUEST_WORDS = 2; uint256 constant private MINIMUM_REQUEST_LENGTH = SELECTOR_LENGTH + (32 * EXPECTED_REQUEST_WORDS); /** * @notice Called when LINK is sent to the contract via `transferAndCall` * @dev The data payload's first 2 words will be overwritten by the `_sender` and `_amount` * values to ensure correctness. Calls oracleRequest. * @param _sender Address of the sender * @param _amount Amount of LINK sent (specified in wei) * @param _data Payload of the transaction */ function onTokenTransfer( address _sender, uint256 _amount, bytes memory _data ) public onlyLINK validRequestLength(_data) permittedFunctionsForLINK(_data) { assembly { // solhint-disable-next-line avoid-low-level-calls mstore(add(_data, 36), _sender) // ensure correct sender is passed // solhint-disable-next-line avoid-low-level-calls mstore(add(_data, 68), _amount) // ensure correct amount is passed } // solhint-disable-next-line avoid-low-level-calls (bool success, ) = address(this).delegatecall(_data); // calls oracleRequest require(success, "Unable to create request"); } function getChainlinkToken() public view virtual returns (address); /** * @dev Reverts if not sent from the LINK token */ modifier onlyLINK() { require(msg.sender == getChainlinkToken(), "Must use LINK token"); _; } /** * @dev Reverts if the given data does not begin with the `oracleRequest` function selector * @param _data The data payload of the request */ modifier permittedFunctionsForLINK(bytes memory _data) { bytes4 funcSelector; assembly { // solhint-disable-next-line avoid-low-level-calls funcSelector := mload(add(_data, 32)) } require(funcSelector == ORACLE_REQUEST_SELECTOR, "Must use whitelisted functions"); _; } /** * @dev Reverts if the given payload is less than needed to create a request * @param _data The request payload */ modifier validRequestLength(bytes memory _data) { require(_data.length >= MINIMUM_REQUEST_LENGTH, "Invalid request length"); _; } } // File: contracts/SignedSafeMath.sol pragma solidity ^0.6.0; library SignedSafeMath { int256 constant private _INT256_MIN = -2**255; /** * @dev Multiplies two signed integers, reverts on overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { // 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-contracts/pull/522 if (a == 0) { return 0; } require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow"); int256 c = a * b; require(c / a == b, "SignedSafeMath: multiplication overflow"); return c; } /** * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero. */ function div(int256 a, int256 b) internal pure returns (int256) { require(b != 0, "SignedSafeMath: division by zero"); require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow"); int256 c = a / b; return c; } /** * @dev Subtracts two signed integers, reverts on overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow"); return c; } /** * @dev Adds two signed integers, reverts on overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow"); return c; } /** * @notice Computes average of two signed integers, ensuring that the computation * doesn't overflow. * @dev If the result is not an integer, it is rounded towards zero. For example, * avg(-3, -4) = -3 */ function avg(int256 _a, int256 _b) internal pure returns (int256) { if ((_a < 0 && _b > 0) || (_a > 0 && _b < 0)) { return add(_a, _b) / 2; } int256 remainder = (_a % 2 + _b % 2) / 2; return add(add(_a / 2, _b / 2), remainder); } } // File: contracts/Median.sol pragma solidity ^0.6.0; library Median { using SignedSafeMath for int256; int256 constant INT_MAX = 2**255-1; /** * @notice Returns the sorted middle, or the average of the two middle indexed items if the * array has an even number of elements. * @dev The list passed as an argument isn't modified. * @dev This algorithm has expected runtime O(n), but for adversarially chosen inputs * the runtime is O(n^2). * @param list The list of elements to compare */ function calculate(int256[] memory list) internal pure returns (int256) { return calculateInplace(copy(list)); } /** * @notice See documentation for function calculate. * @dev The list passed as an argument may be permuted. */ function calculateInplace(int256[] memory list) internal pure returns (int256) { require(0 < list.length, "list must not be empty"); uint256 len = list.length; uint256 middleIndex = len / 2; if (len % 2 == 0) { int256 median1; int256 median2; (median1, median2) = quickselectTwo(list, 0, len - 1, middleIndex - 1, middleIndex); return SignedSafeMath.avg(median1, median2); } else { return quickselect(list, 0, len - 1, middleIndex); } } /** * @notice Maximum length of list that shortSelectTwo can handle */ uint256 constant SHORTSELECTTWO_MAX_LENGTH = 7; /** * @notice Select the k1-th and k2-th element from list of length at most 7 * @dev Uses an optimal sorting network */ function shortSelectTwo( int256[] memory list, uint256 lo, uint256 hi, uint256 k1, uint256 k2 ) private pure returns (int256 k1th, int256 k2th) { // Uses an optimal sorting network (https://en.wikipedia.org/wiki/Sorting_network) // for lists of length 7. Network layout is taken from // http://jgamble.ripco.net/cgi-bin/nw.cgi?inputs=7&algorithm=hibbard&output=svg uint256 len = hi + 1 - lo; int256 x0 = list[lo + 0]; int256 x1 = 1 < len ? list[lo + 1] : INT_MAX; int256 x2 = 2 < len ? list[lo + 2] : INT_MAX; int256 x3 = 3 < len ? list[lo + 3] : INT_MAX; int256 x4 = 4 < len ? list[lo + 4] : INT_MAX; int256 x5 = 5 < len ? list[lo + 5] : INT_MAX; int256 x6 = 6 < len ? list[lo + 6] : INT_MAX; if (x0 > x1) {(x0, x1) = (x1, x0);} if (x2 > x3) {(x2, x3) = (x3, x2);} if (x4 > x5) {(x4, x5) = (x5, x4);} if (x0 > x2) {(x0, x2) = (x2, x0);} if (x1 > x3) {(x1, x3) = (x3, x1);} if (x4 > x6) {(x4, x6) = (x6, x4);} if (x1 > x2) {(x1, x2) = (x2, x1);} if (x5 > x6) {(x5, x6) = (x6, x5);} if (x0 > x4) {(x0, x4) = (x4, x0);} if (x1 > x5) {(x1, x5) = (x5, x1);} if (x2 > x6) {(x2, x6) = (x6, x2);} if (x1 > x4) {(x1, x4) = (x4, x1);} if (x3 > x6) {(x3, x6) = (x6, x3);} if (x2 > x4) {(x2, x4) = (x4, x2);} if (x3 > x5) {(x3, x5) = (x5, x3);} if (x3 > x4) {(x3, x4) = (x4, x3);} uint256 index1 = k1 - lo; if (index1 == 0) {k1th = x0;} else if (index1 == 1) {k1th = x1;} else if (index1 == 2) {k1th = x2;} else if (index1 == 3) {k1th = x3;} else if (index1 == 4) {k1th = x4;} else if (index1 == 5) {k1th = x5;} else if (index1 == 6) {k1th = x6;} else {revert("k1 out of bounds");} uint256 index2 = k2 - lo; if (k1 == k2) {return (k1th, k1th);} else if (index2 == 0) {return (k1th, x0);} else if (index2 == 1) {return (k1th, x1);} else if (index2 == 2) {return (k1th, x2);} else if (index2 == 3) {return (k1th, x3);} else if (index2 == 4) {return (k1th, x4);} else if (index2 == 5) {return (k1th, x5);} else if (index2 == 6) {return (k1th, x6);} else {revert("k2 out of bounds");} } /** * @notice Selects the k-th ranked element from list, looking only at indices between lo and hi * (inclusive). Modifies list in-place. */ function quickselect(int256[] memory list, uint256 lo, uint256 hi, uint256 k) private pure returns (int256 kth) { require(lo <= k); require(k <= hi); while (lo < hi) { if (hi - lo < SHORTSELECTTWO_MAX_LENGTH) { int256 ignore; (kth, ignore) = shortSelectTwo(list, lo, hi, k, k); return kth; } uint256 pivotIndex = partition(list, lo, hi); if (k <= pivotIndex) { // since pivotIndex < (original hi passed to partition), // termination is guaranteed in this case hi = pivotIndex; } else { // since (original lo passed to partition) <= pivotIndex, // termination is guaranteed in this case lo = pivotIndex + 1; } } return list[lo]; } /** * @notice Selects the k1-th and k2-th ranked elements from list, looking only at indices between * lo and hi (inclusive). Modifies list in-place. */ function quickselectTwo( int256[] memory list, uint256 lo, uint256 hi, uint256 k1, uint256 k2 ) internal // for testing pure returns (int256 k1th, int256 k2th) { require(k1 < k2); require(lo <= k1 && k1 <= hi); require(lo <= k2 && k2 <= hi); while (true) { if (hi - lo < SHORTSELECTTWO_MAX_LENGTH) { return shortSelectTwo(list, lo, hi, k1, k2); } uint256 pivotIdx = partition(list, lo, hi); if (k2 <= pivotIdx) { hi = pivotIdx; } else if (pivotIdx < k1) { lo = pivotIdx + 1; } else { assert(k1 <= pivotIdx && pivotIdx < k2); k1th = quickselect(list, lo, pivotIdx, k1); k2th = quickselect(list, pivotIdx + 1, hi, k2); return (k1th, k2th); } } } /** * @notice Partitions list in-place using Hoare's partitioning scheme. * Only elements of list between indices lo and hi (inclusive) will be modified. * Returns an index i, such that: * - lo <= i < hi * - forall j in [lo, i]. list[j] <= list[i] * - forall j in [i, hi]. list[i] <= list[j] */ function partition(int256[] memory list, uint256 lo, uint256 hi) private pure returns (uint256) { // We don't care about overflow of the addition, because it would require a list // larger than any feasible computer's memory. int256 pivot = list[(lo + hi) / 2]; lo -= 1; // this can underflow. that's intentional. hi += 1; while (true) { do { lo += 1; } while (list[lo] < pivot); do { hi -= 1; } while (list[hi] > pivot); if (lo < hi) { (list[lo], list[hi]) = (list[hi], list[lo]); } else { // Let orig_lo and orig_hi be the original values of lo and hi passed to partition. // Then, hi < orig_hi, because hi decreases *strictly* monotonically // in each loop iteration and // - either list[orig_hi] > pivot, in which case the first loop iteration // will achieve hi < orig_hi; // - or list[orig_hi] <= pivot, in which case at least two loop iterations are // needed: // - lo will have to stop at least once in the interval // [orig_lo, (orig_lo + orig_hi)/2] // - (orig_lo + orig_hi)/2 < orig_hi return hi; } } } /** * @notice Makes an in-memory copy of the array passed in * @param list Reference to the array to be copied */ function copy(int256[] memory list) private pure returns(int256[] memory) { int256[] memory list2 = new int256[](list.length); for (uint256 i = 0; i < list.length; i++) { list2[i] = list[i]; } return list2; } } // File: contracts/Owned.sol pragma solidity ^0.6.0; /** * @title The Owned contract * @notice A contract with helpers for basic contract ownership. */ contract Owned { address payable public owner; address private pendingOwner; event OwnershipTransferRequested( address indexed from, address indexed to ); event OwnershipTransferred( address indexed from, address indexed to ); constructor() public { owner = msg.sender; } /** * @dev Allows an owner to begin transferring ownership to a new address, * pending. */ function transferOwnership(address _to) external onlyOwner() { pendingOwner = _to; emit OwnershipTransferRequested(owner, _to); } /** * @dev Allows an ownership transfer to be completed by the recipient. */ function acceptOwnership() external { require(msg.sender == pendingOwner, "Must be proposed owner"); address oldOwner = owner; owner = msg.sender; pendingOwner = address(0); emit OwnershipTransferred(oldOwner, msg.sender); } /** * @dev Reverts if called by anyone other than the contract owner. */ modifier onlyOwner() { require(msg.sender == owner, "Only callable by owner"); _; } } // File: contracts/interfaces/AccessControllerInterface.sol pragma solidity ^0.6.0; interface AccessControllerInterface { function hasAccess(address user, bytes calldata data) external view returns (bool); } // File: contracts/SimpleWriteAccessController.sol pragma solidity ^0.6.0; /** * @title SimpleWriteAccessController * @notice Gives access to accounts explicitly added to an access list by the * controller's owner. * @dev does not make any special permissions for externally, see * SimpleReadAccessController for that. */ contract SimpleWriteAccessController is AccessControllerInterface, Owned { bool public checkEnabled; mapping(address => bool) internal accessList; event AddedAccess(address user); event RemovedAccess(address user); event CheckAccessEnabled(); event CheckAccessDisabled(); constructor() public { checkEnabled = true; } /** * @notice Returns the access of an address * @param _user The address to query */ function hasAccess( address _user, bytes memory ) public view virtual override returns (bool) { return accessList[_user] || !checkEnabled; } /** * @notice Adds an address to the access list * @param _user The address to add */ function addAccess(address _user) external onlyOwner() { if (!accessList[_user]) { accessList[_user] = true; emit AddedAccess(_user); } } /** * @notice Removes an address from the access list * @param _user The address to remove */ function removeAccess(address _user) external onlyOwner() { if (accessList[_user]) { accessList[_user] = false; emit RemovedAccess(_user); } } /** * @notice makes the access check enforced */ function enableAccessCheck() external onlyOwner() { if (!checkEnabled) { checkEnabled = true; emit CheckAccessEnabled(); } } /** * @notice makes the access check unenforced */ function disableAccessCheck() external onlyOwner() { if (checkEnabled) { checkEnabled = false; emit CheckAccessDisabled(); } } /** * @dev reverts if the caller does not have access */ modifier checkAccess() { require(hasAccess(msg.sender, msg.data), "No access"); _; } } // File: contracts/PreCoordinator.sol pragma solidity 0.6.6; /** * @title PreCoordinator is a contract that builds on-chain service agreements * using the current architecture of 1 request to 1 oracle contract. * @dev This contract accepts requests as service agreement IDs and loops over * the corresponding list of oracles to create distinct requests to each one. */ contract PreCoordinator is ChainlinkClient, LinkTokenReceiver, SimpleWriteAccessController, ChainlinkRequestInterface { using SafeMath for uint256; uint256 constant private MAX_ORACLE_COUNT = 45; uint256 private globalNonce; struct ServiceAgreement { uint256 totalPayment; uint256 minResponses; address[] oracles; bytes32[] jobIds; uint256[] payments; } struct Requester { bytes4 callbackFunctionId; address sender; address callbackAddress; int256[] responses; } // Service Agreement ID => ServiceAgreement mapping(bytes32 => ServiceAgreement) internal serviceAgreements; // Local Request ID => Service Agreement ID mapping(bytes32 => bytes32) internal serviceAgreementRequests; // Requester's Request ID => Requester mapping(bytes32 => Requester) internal requesters; // Local Request ID => Requester's Request ID mapping(bytes32 => bytes32) internal requests; event NewServiceAgreement(bytes32 indexed saId, uint256 payment, uint256 minresponses); event ServiceAgreementRequested(bytes32 indexed saId, bytes32 indexed requestId, uint256 payment); event ServiceAgreementResponseReceived(bytes32 indexed saId, bytes32 indexed requestId, address indexed oracle, int256 answer); event ServiceAgreementAnswerUpdated(bytes32 indexed saId, bytes32 indexed requestId, int256 answer); event ServiceAgreementDeleted(bytes32 indexed saId); /** * @notice Deploy the contract with a specified address for the LINK * and Oracle contract addresses * @dev Sets the storage for the specified addresses * @param _link The address of the LINK token contract */ constructor(address _link) public { if(_link == address(0)) { setPublicChainlinkToken(); } else { setChainlinkToken(_link); } } /** * @notice Allows the owner of the contract to create new service agreements * with multiple oracles. Each oracle will have their own Job ID and can have * their own payment amount. * @dev The globalNonce keeps service agreement IDs unique. Assume one cannot * create the max uint256 number of service agreements in the same block. * @param _minResponses The minimum number of responses before the requesting * contract is called with the response data. * @param _oracles The list of oracle contract addresses. * @param _jobIds The corresponding list of Job IDs. * @param _payments The corresponding list of payment amounts. */ function createServiceAgreement( uint256 _minResponses, address[] calldata _oracles, bytes32[] calldata _jobIds, uint256[] calldata _payments ) external returns (bytes32 saId) { require(_minResponses > 0, "Min responses must be > 0"); require(_oracles.length == _jobIds.length && _oracles.length == _payments.length, "Unmet length"); require(_oracles.length <= MAX_ORACLE_COUNT, "Cannot have more than 45 oracles"); require(_oracles.length >= _minResponses, "Invalid min responses"); uint256 totalPayment; for (uint i = 0; i < _payments.length; i++) { totalPayment = totalPayment.add(_payments[i]); } saId = keccak256(abi.encodePacked(globalNonce, now)); globalNonce++; // yes, let it overflow serviceAgreements[saId] = ServiceAgreement(totalPayment, _minResponses, _oracles, _jobIds, _payments); emit NewServiceAgreement(saId, totalPayment, _minResponses); } /** * @notice This is a helper function to retrieve the details of a service agreement * by its given service agreement ID. * @dev This function is used instead of the public mapping to return the values * of the arrays: oracles, jobIds, and payments. */ function getServiceAgreement(bytes32 _saId) external view returns ( uint256 totalPayment, uint256 minResponses, address[] memory oracles, bytes32[] memory jobIds, uint256[] memory payments ) { return ( serviceAgreements[_saId].totalPayment, serviceAgreements[_saId].minResponses, serviceAgreements[_saId].oracles, serviceAgreements[_saId].jobIds, serviceAgreements[_saId].payments ); } /** * @notice Returns the address of the LINK token * @dev This is the public implementation for chainlinkTokenAddress, which is * an internal method of the ChainlinkClient contract */ function getChainlinkToken() public view override returns (address) { return chainlinkTokenAddress(); } /** * @notice Creates the Chainlink request * @dev Stores the hash of the params as the on-chain commitment for the request. * Emits OracleRequest event for the Chainlink node to detect. * @param _sender The sender of the request * @param _payment The amount of payment given (specified in wei) * @param _saId The Job Specification ID * @param _callbackAddress The callback address for the response * @param _callbackFunctionId The callback function ID for the response * @param _nonce The nonce sent by the requester * @param _data The CBOR payload of the request */ function oracleRequest( address _sender, uint256 _payment, bytes32 _saId, address _callbackAddress, bytes4 _callbackFunctionId, uint256 _nonce, uint256, bytes calldata _data ) external onlyLINK override checkCallbackAddress(_callbackAddress) { require(hasAccess(_sender, _data)); uint256 totalPayment = serviceAgreements[_saId].totalPayment; // this revert message does not bubble up require(_payment >= totalPayment, "Insufficient payment"); bytes32 callbackRequestId = keccak256(abi.encodePacked(_sender, _nonce)); require(requesters[callbackRequestId].sender == address(0), "Nonce already in-use"); requesters[callbackRequestId].callbackFunctionId = _callbackFunctionId; requesters[callbackRequestId].callbackAddress = _callbackAddress; requesters[callbackRequestId].sender = _sender; createRequests(_saId, callbackRequestId, _data); if (_payment > totalPayment) { uint256 overage = _payment.sub(totalPayment); LinkTokenInterface _link = LinkTokenInterface(chainlinkTokenAddress()); assert(_link.transfer(_sender, overage)); } } /** * @dev Creates Chainlink requests to each oracle in the service agreement with the * same data payload supplied by the requester * @param _saId The service agreement ID * @param _incomingRequestId The requester-supplied request ID * @param _data The data payload (request parameters) to send to each oracle */ function createRequests(bytes32 _saId, bytes32 _incomingRequestId, bytes memory _data) private { ServiceAgreement memory sa = serviceAgreements[_saId]; require(sa.minResponses > 0, "Invalid service agreement"); Chainlink.Request memory request; bytes32 outgoingRequestId; emit ServiceAgreementRequested(_saId, _incomingRequestId, sa.totalPayment); for (uint i = 0; i < sa.oracles.length; i++) { request = buildChainlinkRequest(sa.jobIds[i], address(this), this.chainlinkCallback.selector); request.setBuffer(_data); outgoingRequestId = sendChainlinkRequestTo(sa.oracles[i], request, sa.payments[i]); requests[outgoingRequestId] = _incomingRequestId; serviceAgreementRequests[outgoingRequestId] = _saId; } } /** * @notice The fulfill method from requests created by this contract * @dev The recordChainlinkFulfillment protects this function from being called * by anyone other than the oracle address that the request was sent to * @param _requestId The ID that was generated for the request * @param _data The answer provided by the oracle */ function chainlinkCallback(bytes32 _requestId, int256 _data) external recordChainlinkFulfillment(_requestId) returns (bool) { ServiceAgreement memory sa = serviceAgreements[serviceAgreementRequests[_requestId]]; bytes32 cbRequestId = requests[_requestId]; bytes32 saId = serviceAgreementRequests[_requestId]; delete requests[_requestId]; delete serviceAgreementRequests[_requestId]; emit ServiceAgreementResponseReceived(saId, cbRequestId, msg.sender, _data); requesters[cbRequestId].responses.push(_data); Requester memory req = requesters[cbRequestId]; if (req.responses.length == sa.oracles.length) delete requesters[cbRequestId]; bool success = true; if (req.responses.length == sa.minResponses) { int256 result = Median.calculate(req.responses); emit ServiceAgreementAnswerUpdated(saId, cbRequestId, result); // solhint-disable-next-line avoid-low-level-calls (success, ) = req.callbackAddress.call(abi.encodeWithSelector(req.callbackFunctionId, cbRequestId, result)); } return success; } /** * @notice Allows the owner to withdraw any LINK balance on the contract * @dev The only valid case for there to be remaining LINK on this contract * is if a user accidentally sent LINK directly to this contract's address. */ function withdrawLink() external onlyOwner { LinkTokenInterface _link = LinkTokenInterface(chainlinkTokenAddress()); require(_link.transfer(msg.sender, _link.balanceOf(address(this))), "Unable to transfer"); } /** * @notice Call this method if no response is received within 5 minutes * @param _requestId The ID that was generated for the request to cancel * @param _payment The payment specified for the request to cancel * @param _callbackFunctionId The bytes4 callback function ID specified for * the request to cancel * @param _expiration The expiration generated for the request to cancel */ function cancelOracleRequest( bytes32 _requestId, uint256 _payment, bytes4 _callbackFunctionId, uint256 _expiration ) external override { bytes32 cbRequestId = requests[_requestId]; delete requests[_requestId]; delete serviceAgreementRequests[_requestId]; Requester memory req = requesters[cbRequestId]; require(req.sender == msg.sender, "Only requester can cancel"); delete requesters[cbRequestId]; cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration); LinkTokenInterface _link = LinkTokenInterface(chainlinkTokenAddress()); require(_link.transfer(req.sender, _payment), "Unable to transfer"); } /** * @dev Reverts if the callback address is the LINK token * @param _to The callback address */ modifier checkCallbackAddress(address _to) { require(_to != chainlinkTokenAddress(), "Cannot callback to LINK"); _; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_link","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"AddedAccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkRequested","type":"event"},{"anonymous":false,"inputs":[],"name":"CheckAccessDisabled","type":"event"},{"anonymous":false,"inputs":[],"name":"CheckAccessEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"saId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"payment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minresponses","type":"uint256"}],"name":"NewServiceAgreement","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"RemovedAccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"saId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"int256","name":"answer","type":"int256"}],"name":"ServiceAgreementAnswerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"saId","type":"bytes32"}],"name":"ServiceAgreementDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"saId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"payment","type":"uint256"}],"name":"ServiceAgreementRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"saId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"int256","name":"answer","type":"int256"}],"name":"ServiceAgreementResponseReceived","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"addAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"uint256","name":"_payment","type":"uint256"},{"internalType":"bytes4","name":"_callbackFunctionId","type":"bytes4"},{"internalType":"uint256","name":"_expiration","type":"uint256"}],"name":"cancelOracleRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"int256","name":"_data","type":"int256"}],"name":"chainlinkCallback","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minResponses","type":"uint256"},{"internalType":"address[]","name":"_oracles","type":"address[]"},{"internalType":"bytes32[]","name":"_jobIds","type":"bytes32[]"},{"internalType":"uint256[]","name":"_payments","type":"uint256[]"}],"name":"createServiceAgreement","outputs":[{"internalType":"bytes32","name":"saId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableAccessCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableAccessCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChainlinkToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_saId","type":"bytes32"}],"name":"getServiceAgreement","outputs":[{"internalType":"uint256","name":"totalPayment","type":"uint256"},{"internalType":"uint256","name":"minResponses","type":"uint256"},{"internalType":"address[]","name":"oracles","type":"address[]"},{"internalType":"bytes32[]","name":"jobIds","type":"bytes32[]"},{"internalType":"uint256[]","name":"payments","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"hasAccess","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_payment","type":"uint256"},{"internalType":"bytes32","name":"_saId","type":"bytes32"},{"internalType":"address","name":"_callbackAddress","type":"address"},{"internalType":"bytes4","name":"_callbackFunctionId","type":"bytes4"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"oracleRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"removeAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawLink","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260016004553480156200001657600080fd5b506040516200336238038062003362833981810160405260208110156200003c57600080fd5b5051600680546001600160a01b031916331790556007805460ff60a01b1916600160a01b1790556001600160a01b0381166200008b57620000856001600160e01b03620000a616565b6200009f565b6200009f816001600160e01b036200013716565b5062000159565b6200013573c89bd4e1632d3a43cb03aaad5262cbe4038bc5716001600160a01b03166338cc48316040518163ffffffff1660e01b815260040160206040518083038186803b158015620000f857600080fd5b505afa1580156200010d573d6000803e3d6000fd5b505050506040513d60208110156200012457600080fd5b50516001600160e01b036200013716565b565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6131f980620001696000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c8063834b55e0116100a2578063a118f24911610071578063a118f2491461047e578063a4c0ed36146104a4578063af52c9811461055d578063dc7f012414610666578063f2fde38b1461066e5761010b565b8063834b55e0146103215780638823da6c146104485780638da5cb5b1461046e5780638dc654a2146104765761010b565b80636b14daf8116100de5780636b14daf8146102245780636ee4d553146102d857806379ba5097146103115780638038e4a1146103195761010b565b80630a75698314610110578063165d35e11461011a578063404299461461013e5780636a9705b4146101ed575b600080fd5b610118610694565b005b61012261072c565b604080516001600160a01b039092168252519081900360200190f35b610118600480360361010081101561015557600080fd5b6001600160a01b038235811692602081013592604082013592606083013516916001600160e01b03196080820135169160a08201359160c081013591810190610100810160e0820135600160201b8111156101af57600080fd5b8201836020820111156101c157600080fd5b803590602001918460018302840111600160201b831117156101e257600080fd5b50909250905061073c565b6102106004803603604081101561020357600080fd5b5080359060200135610b10565b604080519115158252519081900360200190f35b6102106004803603604081101561023a57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561026457600080fd5b82018360208201111561027657600080fd5b803590602001918460018302840111600160201b8311171561029757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610fd2945050505050565b610118600480360360808110156102ee57600080fd5b508035906020810135906001600160e01b0319604082013516906060013561100c565b61011861127c565b61011861132f565b6104366004803603608081101561033757600080fd5b81359190810190604081016020820135600160201b81111561035857600080fd5b82018360208201111561036a57600080fd5b803590602001918460208302840111600160201b8311171561038b57600080fd5b919390929091602081019035600160201b8111156103a857600080fd5b8201836020820111156103ba57600080fd5b803590602001918460208302840111600160201b831117156103db57600080fd5b919390929091602081019035600160201b8111156103f857600080fd5b82018360208201111561040a57600080fd5b803590602001918460208302840111600160201b8311171561042b57600080fd5b5090925090506113cb565b60408051918252519081900360200190f35b6101186004803603602081101561045e57600080fd5b50356001600160a01b03166116f9565b6101226117c0565b6101186117cf565b6101186004803603602081101561049457600080fd5b50356001600160a01b0316611966565b610118600480360360608110156104ba57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156104e957600080fd5b8201836020820111156104fb57600080fd5b803590602001918460018302840111600160201b8311171561051c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611a2e945050505050565b61057a6004803603602081101561057357600080fd5b5035611c52565b60405180868152602001858152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156105ce5781810151838201526020016105b6565b50505050905001848103835286818151815260200191508051906020019060200280838360005b8381101561060d5781810151838201526020016105f5565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561064c578181015183820152602001610634565b505050509050019850505050505050505060405180910390f35b610210611d91565b6101186004803603602081101561068457600080fd5b50356001600160a01b0316611da1565b6006546001600160a01b031633146106e1576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b600754600160a01b900460ff161561072a576007805460ff60a01b191690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b6000610736611e40565b90505b90565b61074461072c565b6001600160a01b0316336001600160a01b03161461079f576040805162461bcd60e51b815260206004820152601360248201527226bab9ba103ab9b2902624a725903a37b5b2b760691b604482015290519081900360640190fd5b856107a8611e40565b6001600160a01b0316816001600160a01b0316141561080e576040805162461bcd60e51b815260206004820152601760248201527f43616e6e6f742063616c6c6261636b20746f204c494e4b000000000000000000604482015290519081900360640190fd5b61084e8a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fd292505050565b61085757600080fd5b6000888152600a6020526040902054808a10156108b2576040805162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b604482015290519081900360640190fd5b604080516bffffffffffffffffffffffff1960608e901b1660208083019190915260348083018a905283518084039091018152605490920183528151918101919091206000818152600c90925291902054600160201b90046001600160a01b03161561095c576040805162461bcd60e51b81526020600482015260146024820152734e6f6e636520616c726561647920696e2d75736560601b604482015290519081900360640190fd5b87600c600083815260200190815260200160002060000160006101000a81548163ffffffff021916908360e01c021790555088600c600083815260200190815260200160002060010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508b600c600083815260200190815260200160002060000160046101000a8154816001600160a01b0302191690836001600160a01b03160217905550610a458a8287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e4f92505050565b818b1115610b02576000610a5f8c8463ffffffff6120d716565b90506000610a6b611e40565b9050806001600160a01b031663a9059cbb8f846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610acd57600080fd5b505af1158015610ae1573d6000803e3d6000fd5b505050506040513d6020811015610af757600080fd5b5051610aff57fe5b50505b505050505050505050505050565b60008281526005602052604081205483906001600160a01b03163314610b675760405162461bcd60e51b815260040180806020018281038252602881526020018061319c6028913960400191505060405180910390fd5b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a2610bb2612f8b565b6000858152600b60209081526040808320548352600a825291829020825160a0810184528154815260018201548184015260028201805485518186028101860187528181529295939493860193830182828015610c3857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610c1a575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610c9057602002820191906000526020600020905b815481526020019060010190808311610c7c575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015610ce857602002820191906000526020600020905b815481526020019060010190808311610cd4575b505050919092525050506000868152600d602090815260408083208054600b8452828520805492869055949094558151898152915194955092933392859285927f6bd4bffa5426494ba16814dba4b1994c92f88f7664ad231cf8aa811fff6e925e929181900390910190a46000828152600c6020908152604082206002018054600181018255908352912001869055610d7f612fba565b6000838152600c6020908152604091829020825160808101845281546001600160e01b031960e082901b1682526001600160a01b03600160201b909104811682850152600183015416818501526002820180548551818602810186019096528086529194929360608601939290830182828015610e1b57602002820191906000526020600020905b815481526020019060010190808311610e07575b50505050508152505090508360400151518160600151511415610e77576000838152600c6020526040812080546001600160c01b03191681556001810180546001600160a01b031916905590610e746002830182612fe0565b50505b60208401516060820151516001911415610fc6576000610e9a8360600151612134565b905084847fe991444bc589ce1a82e7cbe4e5ebaa8aaa2a5c44964bd32d2af07dd846a638ba836040518082815260200191505060405180910390a36040808401518451825160248101899052604480820186905284518083039091018152606490910184526020810180516001600160e01b03166001600160e01b0319909316929092178252925183516001600160a01b039093169392909182918083835b60208310610f585780518252601f199092019160209182019101610f39565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610fba576040519150601f19603f3d011682016040523d82523d6000602084013e610fbf565b606091505b5090925050505b98975050505050505050565b6001600160a01b03821660009081526008602052604081205460ff16806110035750600754600160a01b900460ff16155b90505b92915050565b6000848152600d60209081526040808320805490849055600b909252822091909155611036612fba565b6000828152600c6020908152604091829020825160808101845281546001600160e01b031960e082901b1682526001600160a01b03600160201b9091048116828501526001830154168185015260028201805485518186028101860190965280865291949293606086019392908301828280156110d257602002820191906000526020600020905b8154815260200190600101908083116110be575b5050505050815250509050336001600160a01b031681602001516001600160a01b031614611147576040805162461bcd60e51b815260206004820152601960248201527f4f6e6c79207265717565737465722063616e2063616e63656c00000000000000604482015290519081900360640190fd5b6000828152600c6020526040812080546001600160c01b03191681556001810180546001600160a01b0319169055906111836002830182612fe0565b50506111918686868661214f565b600061119b611e40565b9050806001600160a01b031663a9059cbb8360200151886040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561120157600080fd5b505af1158015611215573d6000803e3d6000fd5b505050506040513d602081101561122b57600080fd5b5051611273576040805162461bcd60e51b81526020600482015260126024820152712ab730b13632903a37903a3930b739b332b960711b604482015290519081900360640190fd5b50505050505050565b6007546001600160a01b031633146112d4576040805162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b604482015290519081900360640190fd5b600680546001600160a01b0319808216339081179093556007805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6006546001600160a01b0316331461137c576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b600754600160a01b900460ff1661072a576007805460ff60a01b1916600160a01b1790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b6000808811611421576040805162461bcd60e51b815260206004820152601960248201527f4d696e20726573706f6e736573206d757374206265203e203000000000000000604482015290519081900360640190fd5b858414801561142f57508582145b61146f576040805162461bcd60e51b815260206004820152600c60248201526b0aadcdacae840d8cadccee8d60a31b604482015290519081900360640190fd5b602d8611156114c5576040805162461bcd60e51b815260206004820181905260248201527f43616e6e6f742068617665206d6f7265207468616e203435206f7261636c6573604482015290519081900360640190fd5b87861015611512576040805162461bcd60e51b8152602060048201526015602482015274496e76616c6964206d696e20726573706f6e73657360581b604482015290519081900360640190fd5b6000805b8381101561154d5761154385858381811061152d57fe5b905060200201358361222790919063ffffffff16565b9150600101611516565b5060098054604080516020808201849052428284015282518083038401815260608301808552815191830191909120600190950190955561010082018352858552608082018e905282518c820281810183019094528c815293965060a090910192918c918c91829185019084908082843760009201919091525050509082525060408051602089810282810182019093528982529283019290918a918a91829185019084908082843760009201919091525050509082525060408051602087810282810182019093528782529283019290918891889182918501908490808284376000920182905250939094525050848152600a6020908152604091829020845181558482015160018201559184015180519293506116759260028501929190910190612ffe565b5060608201518051611691916003840191602090910190613063565b50608082015180516116ad916004840191602090910190613063565b505060408051838152602081018c905281518593507f1df950b8dca286fff2ebb83642851b5a9db00ff4bc87815828e845b45d183eaf929181900390910190a250979650505050505050565b6006546001600160a01b03163314611746576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526008602052604090205460ff16156117bd576001600160a01b038116600081815260086020908152604091829020805460ff19169055815192835290517f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d19281900390910190a15b50565b6006546001600160a01b031681565b6006546001600160a01b0316331461181c576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b6000611826611e40565b604080516370a0823160e01b815230600482015290519192506001600160a01b0383169163a9059cbb91339184916370a08231916024808301926020929190829003018186803b15801561187957600080fd5b505afa15801561188d573d6000803e3d6000fd5b505050506040513d60208110156118a357600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b1580156118f457600080fd5b505af1158015611908573d6000803e3d6000fd5b505050506040513d602081101561191e57600080fd5b50516117bd576040805162461bcd60e51b81526020600482015260126024820152712ab730b13632903a37903a3930b739b332b960711b604482015290519081900360640190fd5b6006546001600160a01b031633146119b3576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526008602052604090205460ff166117bd576001600160a01b038116600081815260086020908152604091829020805460ff19166001179055815192835290517f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49281900390910190a150565b611a3661072c565b6001600160a01b0316336001600160a01b031614611a91576040805162461bcd60e51b815260206004820152601360248201527226bab9ba103ab9b2902624a725903a37b5b2b760691b604482015290519081900360640190fd5b8051819060441115611ae3576040805162461bcd60e51b8152602060048201526016602482015275092dcecc2d8d2c840e4cae2eacae6e840d8cadccee8d60531b604482015290519081900360640190fd5b602082015182906001600160e01b031981166320214ca360e11b14611b4f576040805162461bcd60e51b815260206004820152601e60248201527f4d757374207573652077686974656c69737465642066756e6374696f6e730000604482015290519081900360640190fd5b8560248501528460448501526000306001600160a01b0316856040518082805190602001908083835b60208310611b975780518252601f199092019160209182019101611b78565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114611bf7576040519150601f19603f3d011682016040523d82523d6000602084013e611bfc565b606091505b5050905080611273576040805162461bcd60e51b815260206004820152601860248201527f556e61626c6520746f2063726561746520726571756573740000000000000000604482015290519081900360640190fd5b6000818152600a6020908152604080832080546001820154600283018054855181880281018801909652808652879660609687968796959493600382019360049092019291859190830182828015611cd357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611cb5575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015611d2557602002820191906000526020600020905b815481526020019060010190808311611d11575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015611d7757602002820191906000526020600020905b815481526020019060010190808311611d63575b505050505090509450945094509450945091939590929450565b600754600160a01b900460ff1681565b6006546001600160a01b03163314611dee576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6002546001600160a01b031690565b611e57612f8b565b6000848152600a6020908152604091829020825160a0810184528154815260018201548184015260028201805485518186028101860187528181529295939493860193830182828015611ed357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611eb5575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015611f2b57602002820191906000526020600020905b815481526020019060010190808311611f17575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015611f8357602002820191906000526020600020905b815481526020019060010190808311611f6f575b50505050508152505090506000816020015111611fe7576040805162461bcd60e51b815260206004820152601960248201527f496e76616c696420736572766963652061677265656d656e7400000000000000604482015290519081900360640190fd5b611fef6130aa565b81516040805191825251600091869188917f0d3e7811af83862cbc3778c66d787596cdb580e0dbc448d99f21c865770a8432919081900360200190a360005b836040015151811015611273576120648460600151828151811061204e57fe5b602002602001015130636a9705b460e01b612281565b9250612076838663ffffffff6122ae16565b6120af8460400151828151811061208957fe5b602002602001015184866080015184815181106120a257fe5b60200260200101516122d1565b6000818152600d602090815260408083208a9055600b9091529020889055915060010161202e565b60008282111561212e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000612147612142836124a8565b612536565b90505b919050565b60008481526005602052604080822080546001600160a01b0319811690915590516001600160a01b039091169186917fe1fe3afa0f7f761ff0a8b89086790efd5140d2907ebd5b7ff6bfcb5e075fd4c59190a260408051636ee4d55360e01b815260048101879052602481018690526001600160e01b0319851660448201526064810184905290516001600160a01b03831691636ee4d55391608480830192600092919082900301818387803b15801561220857600080fd5b505af115801561221c573d6000803e3d6000fd5b505050505050505050565b600082820183811015611003576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6122896130aa565b6122916130aa565b6122a38186868663ffffffff6125df16565b9150505b9392505050565b6122bd82608001518251612625565b506122cc82608001518261265f565b505050565b6004546040805130606090811b60208084019190915260348084018690528451808503909101815260549093018452825192810192909220908601939093526000838152600590915281812080546001600160a01b0319166001600160a01b038816179055905182917fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af991a26002546001600160a01b0316634000aea0858461237987612679565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156123e35781810151838201526020016123cb565b50505050905090810190601f1680156124105780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561243157600080fd5b505af1158015612445573d6000803e3d6000fd5b505050506040513d602081101561245b57600080fd5b50516124985760405162461bcd60e51b81526004018080602001828103825260238152602001806131386023913960400191505060405180910390fd5b6004805460010190559392505050565b606080825167ffffffffffffffff811180156124c357600080fd5b506040519080825280602002602001820160405280156124ed578160200160208202803683370190505b50905060005b835181101561252f5783818151811061250857fe5b602002602001015182828151811061251c57fe5b60209081029190910101526001016124f3565b5092915050565b60008151600010612587576040805162461bcd60e51b81526020600482015260166024820152756c697374206d757374206e6f7420626520656d70747960501b604482015290519081900360640190fd5b815160028104600182166125c6576000806125ac8660006001870360018703876127b9565b90925090506125bb8282612897565b94505050505061214a565b6125d68460006001850384612905565b9250505061214a565b6125e76130aa565b6125f78560800151610100612625565b50508284526001600160a01b03821660208501526001600160e01b031981166040850152835b949350505050565b61262d6130df565b60208206156126425760208206602003820191505b506020828101829052604080518085526000815290920101905290565b6126676130df565b61100383846000015151848551612996565b6060634042994660e01b6000808460000151856020015186604001518760600151600189608001516000015160405160240180896001600160a01b03166001600160a01b03168152602001888152602001878152602001866001600160a01b03166001600160a01b03168152602001856001600160e01b0319166001600160e01b031916815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561274757818101518382015260200161272f565b50505050905090810190601f1680156127745780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909d169c909c17909b5250989950505050505050505050919050565b6000808284106127c857600080fd5b8386111580156127d85750848411155b6127e157600080fd5b8286111580156127f15750848311155b6127fa57600080fd5b6007868603101561281b576128128787878787612a42565b9150915061288d565b6000612828888888612e15565b905080841161283957809550612887565b8481101561284c57806001019650612887565b80851115801561285b57508381105b61286157fe5b61286d88888388612905565b925061287e88826001018887612905565b915061288d9050565b506127fa565b9550959350505050565b600080831280156128a85750600082135b806128be57506000831380156128be5750600082125b156128de5760026128cf8484612ef2565b816128d657fe5b059050611006565b600060028085078185070105905061261d6128ff6002860560028605612ef2565b82612ef2565b60008184111561291457600080fd5b8282111561292157600080fd5b82841015612978576007848403101561294d5760006129438686868687612a42565b50915061261d9050565b600061295a868686612e15565b905080831161296b57809350612972565b8060010194505b50612921565b84848151811061298457fe5b60200260200101519050949350505050565b61299e6130df565b82518211156129ac57600080fd5b846020015182850111156129d6576129d6856129ce8760200151878601612f57565b600202612f6e565b6000808651805187602083010193508088870111156129f55787860182525b505050602084015b60208410612a1c5780518252601f1990930192602091820191016129fd565b51815160001960208690036101000a019081169019919091161790525083949350505050565b600080600086866001010390506000888860000181518110612a6057fe5b60200260200101519050600082600110612a81576001600160ff1b03612a99565b898960010181518110612a9057fe5b60200260200101515b9050600083600210612ab2576001600160ff1b03612aca565b8a8a60020181518110612ac157fe5b60200260200101515b9050600084600310612ae3576001600160ff1b03612afb565b8b8b60030181518110612af257fe5b60200260200101515b9050600085600410612b14576001600160ff1b03612b2c565b8c8c60040181518110612b2357fe5b60200260200101515b9050600086600510612b45576001600160ff1b03612b5d565b8d8d60050181518110612b5457fe5b60200260200101515b9050600087600610612b76576001600160ff1b03612b8e565b8e8e60060181518110612b8557fe5b60200260200101515b905085871315612b9c579495945b83851315612ba8579293925b81831315612bb4579091905b84871315612bc0579395935b83861315612bcc579294925b80831315612bd657915b84861315612be2579394935b80821315612bec57905b82871315612bf8579195915b81861315612c04579094905b80851315612c0e57935b82861315612c1a579194915b80841315612c2457925b82851315612c30579193915b81841315612c3c579092905b82841315612c48579192915b8d8c0380612c5857879a50612cfe565b8060011415612c6957869a50612cfe565b8060021415612c7a57859a50612cfe565b8060031415612c8b57849a50612cfe565b8060041415612c9c57839a50612cfe565b8060051415612cad57829a50612cfe565b8060061415612cbe57819a50612cfe565b6040805162461bcd60e51b815260206004820152601060248201526f6b31206f7574206f6620626f756e647360801b604482015290519081900360640190fd5b8e8c038d8d1415612d1c57508a995061288d98505050505050505050565b80612d33575096985061288d975050505050505050565b8060011415612d4e575095985061288d975050505050505050565b8060021415612d69575094985061288d975050505050505050565b8060031415612d84575093985061288d975050505050505050565b8060041415612d9f575092985061288d975050505050505050565b8060051415612dba575091985061288d975050505050505050565b8060061415612dd5575090985061288d975050505050505050565b6040805162461bcd60e51b815260206004820152601060248201526f6b32206f7574206f6620626f756e647360801b604482015290519081900360640190fd5b6000808460028585010481518110612e2957fe5b602002602001015190506001840393506001830192505b60018401935080858581518110612e5357fe5b602002602001015112612e40575b60018303925080858481518110612e7457fe5b602002602001015113612e615782841015612ee457848381518110612e9557fe5b6020026020010151858581518110612ea957fe5b6020026020010151868681518110612ebd57fe5b60200260200101878681518110612ed057fe5b602090810291909101019190915252612eed565b829150506122a7565b612e40565b6000828201818312801590612f075750838112155b80612f1c5750600083128015612f1c57508381125b6110035760405162461bcd60e51b815260040180806020018281038252602181526020018061315b6021913960400191505060405180910390fd5b600081831115612f68575081611006565b50919050565b8151612f7a8383612625565b50612f85838261265f565b50505050565b6040518060a0016040528060008152602001600081526020016060815260200160608152602001606081525090565b604080516080810182526000808252602082018190529181019190915260608082015290565b50805460008255906000526020600020908101906117bd91906130f9565b828054828255906000526020600020908101928215613053579160200282015b8281111561305357825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061301e565b5061305f929150613113565b5090565b82805482825590600052602060002090810192821561309e579160200282015b8281111561309e578251825591602001919060010190613083565b5061305f9291506130f9565b6040805160a0810182526000808252602082018190529181018290526060810191909152608081016130da6130df565b905290565b604051806040016040528060608152602001600081525090565b61073991905b8082111561305f57600081556001016130ff565b61073991905b8082111561305f5780546001600160a01b031916815560010161311956fe756e61626c6520746f207472616e73666572416e6443616c6c20746f206f7261636c655369676e6564536166654d6174683a206164646974696f6e206f766572666c6f774f6e6c792063616c6c61626c65206279206f776e657200000000000000000000536f75726365206d75737420626520746865206f7261636c65206f66207468652072657175657374a264697066735822122052c68c49bb1b01c87cc7eee255d0e467ca8ef28b94c7d14b1463b01b5b55d92664736f6c63430006060033000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061010b5760003560e01c8063834b55e0116100a2578063a118f24911610071578063a118f2491461047e578063a4c0ed36146104a4578063af52c9811461055d578063dc7f012414610666578063f2fde38b1461066e5761010b565b8063834b55e0146103215780638823da6c146104485780638da5cb5b1461046e5780638dc654a2146104765761010b565b80636b14daf8116100de5780636b14daf8146102245780636ee4d553146102d857806379ba5097146103115780638038e4a1146103195761010b565b80630a75698314610110578063165d35e11461011a578063404299461461013e5780636a9705b4146101ed575b600080fd5b610118610694565b005b61012261072c565b604080516001600160a01b039092168252519081900360200190f35b610118600480360361010081101561015557600080fd5b6001600160a01b038235811692602081013592604082013592606083013516916001600160e01b03196080820135169160a08201359160c081013591810190610100810160e0820135600160201b8111156101af57600080fd5b8201836020820111156101c157600080fd5b803590602001918460018302840111600160201b831117156101e257600080fd5b50909250905061073c565b6102106004803603604081101561020357600080fd5b5080359060200135610b10565b604080519115158252519081900360200190f35b6102106004803603604081101561023a57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561026457600080fd5b82018360208201111561027657600080fd5b803590602001918460018302840111600160201b8311171561029757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610fd2945050505050565b610118600480360360808110156102ee57600080fd5b508035906020810135906001600160e01b0319604082013516906060013561100c565b61011861127c565b61011861132f565b6104366004803603608081101561033757600080fd5b81359190810190604081016020820135600160201b81111561035857600080fd5b82018360208201111561036a57600080fd5b803590602001918460208302840111600160201b8311171561038b57600080fd5b919390929091602081019035600160201b8111156103a857600080fd5b8201836020820111156103ba57600080fd5b803590602001918460208302840111600160201b831117156103db57600080fd5b919390929091602081019035600160201b8111156103f857600080fd5b82018360208201111561040a57600080fd5b803590602001918460208302840111600160201b8311171561042b57600080fd5b5090925090506113cb565b60408051918252519081900360200190f35b6101186004803603602081101561045e57600080fd5b50356001600160a01b03166116f9565b6101226117c0565b6101186117cf565b6101186004803603602081101561049457600080fd5b50356001600160a01b0316611966565b610118600480360360608110156104ba57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156104e957600080fd5b8201836020820111156104fb57600080fd5b803590602001918460018302840111600160201b8311171561051c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611a2e945050505050565b61057a6004803603602081101561057357600080fd5b5035611c52565b60405180868152602001858152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156105ce5781810151838201526020016105b6565b50505050905001848103835286818151815260200191508051906020019060200280838360005b8381101561060d5781810151838201526020016105f5565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561064c578181015183820152602001610634565b505050509050019850505050505050505060405180910390f35b610210611d91565b6101186004803603602081101561068457600080fd5b50356001600160a01b0316611da1565b6006546001600160a01b031633146106e1576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b600754600160a01b900460ff161561072a576007805460ff60a01b191690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b6000610736611e40565b90505b90565b61074461072c565b6001600160a01b0316336001600160a01b03161461079f576040805162461bcd60e51b815260206004820152601360248201527226bab9ba103ab9b2902624a725903a37b5b2b760691b604482015290519081900360640190fd5b856107a8611e40565b6001600160a01b0316816001600160a01b0316141561080e576040805162461bcd60e51b815260206004820152601760248201527f43616e6e6f742063616c6c6261636b20746f204c494e4b000000000000000000604482015290519081900360640190fd5b61084e8a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fd292505050565b61085757600080fd5b6000888152600a6020526040902054808a10156108b2576040805162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b604482015290519081900360640190fd5b604080516bffffffffffffffffffffffff1960608e901b1660208083019190915260348083018a905283518084039091018152605490920183528151918101919091206000818152600c90925291902054600160201b90046001600160a01b03161561095c576040805162461bcd60e51b81526020600482015260146024820152734e6f6e636520616c726561647920696e2d75736560601b604482015290519081900360640190fd5b87600c600083815260200190815260200160002060000160006101000a81548163ffffffff021916908360e01c021790555088600c600083815260200190815260200160002060010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508b600c600083815260200190815260200160002060000160046101000a8154816001600160a01b0302191690836001600160a01b03160217905550610a458a8287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e4f92505050565b818b1115610b02576000610a5f8c8463ffffffff6120d716565b90506000610a6b611e40565b9050806001600160a01b031663a9059cbb8f846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610acd57600080fd5b505af1158015610ae1573d6000803e3d6000fd5b505050506040513d6020811015610af757600080fd5b5051610aff57fe5b50505b505050505050505050505050565b60008281526005602052604081205483906001600160a01b03163314610b675760405162461bcd60e51b815260040180806020018281038252602881526020018061319c6028913960400191505060405180910390fd5b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a2610bb2612f8b565b6000858152600b60209081526040808320548352600a825291829020825160a0810184528154815260018201548184015260028201805485518186028101860187528181529295939493860193830182828015610c3857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610c1a575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610c9057602002820191906000526020600020905b815481526020019060010190808311610c7c575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015610ce857602002820191906000526020600020905b815481526020019060010190808311610cd4575b505050919092525050506000868152600d602090815260408083208054600b8452828520805492869055949094558151898152915194955092933392859285927f6bd4bffa5426494ba16814dba4b1994c92f88f7664ad231cf8aa811fff6e925e929181900390910190a46000828152600c6020908152604082206002018054600181018255908352912001869055610d7f612fba565b6000838152600c6020908152604091829020825160808101845281546001600160e01b031960e082901b1682526001600160a01b03600160201b909104811682850152600183015416818501526002820180548551818602810186019096528086529194929360608601939290830182828015610e1b57602002820191906000526020600020905b815481526020019060010190808311610e07575b50505050508152505090508360400151518160600151511415610e77576000838152600c6020526040812080546001600160c01b03191681556001810180546001600160a01b031916905590610e746002830182612fe0565b50505b60208401516060820151516001911415610fc6576000610e9a8360600151612134565b905084847fe991444bc589ce1a82e7cbe4e5ebaa8aaa2a5c44964bd32d2af07dd846a638ba836040518082815260200191505060405180910390a36040808401518451825160248101899052604480820186905284518083039091018152606490910184526020810180516001600160e01b03166001600160e01b0319909316929092178252925183516001600160a01b039093169392909182918083835b60208310610f585780518252601f199092019160209182019101610f39565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610fba576040519150601f19603f3d011682016040523d82523d6000602084013e610fbf565b606091505b5090925050505b98975050505050505050565b6001600160a01b03821660009081526008602052604081205460ff16806110035750600754600160a01b900460ff16155b90505b92915050565b6000848152600d60209081526040808320805490849055600b909252822091909155611036612fba565b6000828152600c6020908152604091829020825160808101845281546001600160e01b031960e082901b1682526001600160a01b03600160201b9091048116828501526001830154168185015260028201805485518186028101860190965280865291949293606086019392908301828280156110d257602002820191906000526020600020905b8154815260200190600101908083116110be575b5050505050815250509050336001600160a01b031681602001516001600160a01b031614611147576040805162461bcd60e51b815260206004820152601960248201527f4f6e6c79207265717565737465722063616e2063616e63656c00000000000000604482015290519081900360640190fd5b6000828152600c6020526040812080546001600160c01b03191681556001810180546001600160a01b0319169055906111836002830182612fe0565b50506111918686868661214f565b600061119b611e40565b9050806001600160a01b031663a9059cbb8360200151886040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561120157600080fd5b505af1158015611215573d6000803e3d6000fd5b505050506040513d602081101561122b57600080fd5b5051611273576040805162461bcd60e51b81526020600482015260126024820152712ab730b13632903a37903a3930b739b332b960711b604482015290519081900360640190fd5b50505050505050565b6007546001600160a01b031633146112d4576040805162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b604482015290519081900360640190fd5b600680546001600160a01b0319808216339081179093556007805490911690556040516001600160a01b03909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6006546001600160a01b0316331461137c576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b600754600160a01b900460ff1661072a576007805460ff60a01b1916600160a01b1790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b6000808811611421576040805162461bcd60e51b815260206004820152601960248201527f4d696e20726573706f6e736573206d757374206265203e203000000000000000604482015290519081900360640190fd5b858414801561142f57508582145b61146f576040805162461bcd60e51b815260206004820152600c60248201526b0aadcdacae840d8cadccee8d60a31b604482015290519081900360640190fd5b602d8611156114c5576040805162461bcd60e51b815260206004820181905260248201527f43616e6e6f742068617665206d6f7265207468616e203435206f7261636c6573604482015290519081900360640190fd5b87861015611512576040805162461bcd60e51b8152602060048201526015602482015274496e76616c6964206d696e20726573706f6e73657360581b604482015290519081900360640190fd5b6000805b8381101561154d5761154385858381811061152d57fe5b905060200201358361222790919063ffffffff16565b9150600101611516565b5060098054604080516020808201849052428284015282518083038401815260608301808552815191830191909120600190950190955561010082018352858552608082018e905282518c820281810183019094528c815293965060a090910192918c918c91829185019084908082843760009201919091525050509082525060408051602089810282810182019093528982529283019290918a918a91829185019084908082843760009201919091525050509082525060408051602087810282810182019093528782529283019290918891889182918501908490808284376000920182905250939094525050848152600a6020908152604091829020845181558482015160018201559184015180519293506116759260028501929190910190612ffe565b5060608201518051611691916003840191602090910190613063565b50608082015180516116ad916004840191602090910190613063565b505060408051838152602081018c905281518593507f1df950b8dca286fff2ebb83642851b5a9db00ff4bc87815828e845b45d183eaf929181900390910190a250979650505050505050565b6006546001600160a01b03163314611746576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526008602052604090205460ff16156117bd576001600160a01b038116600081815260086020908152604091829020805460ff19169055815192835290517f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d19281900390910190a15b50565b6006546001600160a01b031681565b6006546001600160a01b0316331461181c576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b6000611826611e40565b604080516370a0823160e01b815230600482015290519192506001600160a01b0383169163a9059cbb91339184916370a08231916024808301926020929190829003018186803b15801561187957600080fd5b505afa15801561188d573d6000803e3d6000fd5b505050506040513d60208110156118a357600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b1580156118f457600080fd5b505af1158015611908573d6000803e3d6000fd5b505050506040513d602081101561191e57600080fd5b50516117bd576040805162461bcd60e51b81526020600482015260126024820152712ab730b13632903a37903a3930b739b332b960711b604482015290519081900360640190fd5b6006546001600160a01b031633146119b3576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526008602052604090205460ff166117bd576001600160a01b038116600081815260086020908152604091829020805460ff19166001179055815192835290517f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49281900390910190a150565b611a3661072c565b6001600160a01b0316336001600160a01b031614611a91576040805162461bcd60e51b815260206004820152601360248201527226bab9ba103ab9b2902624a725903a37b5b2b760691b604482015290519081900360640190fd5b8051819060441115611ae3576040805162461bcd60e51b8152602060048201526016602482015275092dcecc2d8d2c840e4cae2eacae6e840d8cadccee8d60531b604482015290519081900360640190fd5b602082015182906001600160e01b031981166320214ca360e11b14611b4f576040805162461bcd60e51b815260206004820152601e60248201527f4d757374207573652077686974656c69737465642066756e6374696f6e730000604482015290519081900360640190fd5b8560248501528460448501526000306001600160a01b0316856040518082805190602001908083835b60208310611b975780518252601f199092019160209182019101611b78565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114611bf7576040519150601f19603f3d011682016040523d82523d6000602084013e611bfc565b606091505b5050905080611273576040805162461bcd60e51b815260206004820152601860248201527f556e61626c6520746f2063726561746520726571756573740000000000000000604482015290519081900360640190fd5b6000818152600a6020908152604080832080546001820154600283018054855181880281018801909652808652879660609687968796959493600382019360049092019291859190830182828015611cd357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611cb5575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015611d2557602002820191906000526020600020905b815481526020019060010190808311611d11575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015611d7757602002820191906000526020600020905b815481526020019060010190808311611d63575b505050505090509450945094509450945091939590929450565b600754600160a01b900460ff1681565b6006546001600160a01b03163314611dee576040805162461bcd60e51b8152602060048201526016602482015260008051602061317c833981519152604482015290519081900360640190fd5b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b6002546001600160a01b031690565b611e57612f8b565b6000848152600a6020908152604091829020825160a0810184528154815260018201548184015260028201805485518186028101860187528181529295939493860193830182828015611ed357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611eb5575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015611f2b57602002820191906000526020600020905b815481526020019060010190808311611f17575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015611f8357602002820191906000526020600020905b815481526020019060010190808311611f6f575b50505050508152505090506000816020015111611fe7576040805162461bcd60e51b815260206004820152601960248201527f496e76616c696420736572766963652061677265656d656e7400000000000000604482015290519081900360640190fd5b611fef6130aa565b81516040805191825251600091869188917f0d3e7811af83862cbc3778c66d787596cdb580e0dbc448d99f21c865770a8432919081900360200190a360005b836040015151811015611273576120648460600151828151811061204e57fe5b602002602001015130636a9705b460e01b612281565b9250612076838663ffffffff6122ae16565b6120af8460400151828151811061208957fe5b602002602001015184866080015184815181106120a257fe5b60200260200101516122d1565b6000818152600d602090815260408083208a9055600b9091529020889055915060010161202e565b60008282111561212e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000612147612142836124a8565b612536565b90505b919050565b60008481526005602052604080822080546001600160a01b0319811690915590516001600160a01b039091169186917fe1fe3afa0f7f761ff0a8b89086790efd5140d2907ebd5b7ff6bfcb5e075fd4c59190a260408051636ee4d55360e01b815260048101879052602481018690526001600160e01b0319851660448201526064810184905290516001600160a01b03831691636ee4d55391608480830192600092919082900301818387803b15801561220857600080fd5b505af115801561221c573d6000803e3d6000fd5b505050505050505050565b600082820183811015611003576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6122896130aa565b6122916130aa565b6122a38186868663ffffffff6125df16565b9150505b9392505050565b6122bd82608001518251612625565b506122cc82608001518261265f565b505050565b6004546040805130606090811b60208084019190915260348084018690528451808503909101815260549093018452825192810192909220908601939093526000838152600590915281812080546001600160a01b0319166001600160a01b038816179055905182917fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af991a26002546001600160a01b0316634000aea0858461237987612679565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156123e35781810151838201526020016123cb565b50505050905090810190601f1680156124105780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561243157600080fd5b505af1158015612445573d6000803e3d6000fd5b505050506040513d602081101561245b57600080fd5b50516124985760405162461bcd60e51b81526004018080602001828103825260238152602001806131386023913960400191505060405180910390fd5b6004805460010190559392505050565b606080825167ffffffffffffffff811180156124c357600080fd5b506040519080825280602002602001820160405280156124ed578160200160208202803683370190505b50905060005b835181101561252f5783818151811061250857fe5b602002602001015182828151811061251c57fe5b60209081029190910101526001016124f3565b5092915050565b60008151600010612587576040805162461bcd60e51b81526020600482015260166024820152756c697374206d757374206e6f7420626520656d70747960501b604482015290519081900360640190fd5b815160028104600182166125c6576000806125ac8660006001870360018703876127b9565b90925090506125bb8282612897565b94505050505061214a565b6125d68460006001850384612905565b9250505061214a565b6125e76130aa565b6125f78560800151610100612625565b50508284526001600160a01b03821660208501526001600160e01b031981166040850152835b949350505050565b61262d6130df565b60208206156126425760208206602003820191505b506020828101829052604080518085526000815290920101905290565b6126676130df565b61100383846000015151848551612996565b6060634042994660e01b6000808460000151856020015186604001518760600151600189608001516000015160405160240180896001600160a01b03166001600160a01b03168152602001888152602001878152602001866001600160a01b03166001600160a01b03168152602001856001600160e01b0319166001600160e01b031916815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561274757818101518382015260200161272f565b50505050905090810190601f1680156127745780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909d169c909c17909b5250989950505050505050505050919050565b6000808284106127c857600080fd5b8386111580156127d85750848411155b6127e157600080fd5b8286111580156127f15750848311155b6127fa57600080fd5b6007868603101561281b576128128787878787612a42565b9150915061288d565b6000612828888888612e15565b905080841161283957809550612887565b8481101561284c57806001019650612887565b80851115801561285b57508381105b61286157fe5b61286d88888388612905565b925061287e88826001018887612905565b915061288d9050565b506127fa565b9550959350505050565b600080831280156128a85750600082135b806128be57506000831380156128be5750600082125b156128de5760026128cf8484612ef2565b816128d657fe5b059050611006565b600060028085078185070105905061261d6128ff6002860560028605612ef2565b82612ef2565b60008184111561291457600080fd5b8282111561292157600080fd5b82841015612978576007848403101561294d5760006129438686868687612a42565b50915061261d9050565b600061295a868686612e15565b905080831161296b57809350612972565b8060010194505b50612921565b84848151811061298457fe5b60200260200101519050949350505050565b61299e6130df565b82518211156129ac57600080fd5b846020015182850111156129d6576129d6856129ce8760200151878601612f57565b600202612f6e565b6000808651805187602083010193508088870111156129f55787860182525b505050602084015b60208410612a1c5780518252601f1990930192602091820191016129fd565b51815160001960208690036101000a019081169019919091161790525083949350505050565b600080600086866001010390506000888860000181518110612a6057fe5b60200260200101519050600082600110612a81576001600160ff1b03612a99565b898960010181518110612a9057fe5b60200260200101515b9050600083600210612ab2576001600160ff1b03612aca565b8a8a60020181518110612ac157fe5b60200260200101515b9050600084600310612ae3576001600160ff1b03612afb565b8b8b60030181518110612af257fe5b60200260200101515b9050600085600410612b14576001600160ff1b03612b2c565b8c8c60040181518110612b2357fe5b60200260200101515b9050600086600510612b45576001600160ff1b03612b5d565b8d8d60050181518110612b5457fe5b60200260200101515b9050600087600610612b76576001600160ff1b03612b8e565b8e8e60060181518110612b8557fe5b60200260200101515b905085871315612b9c579495945b83851315612ba8579293925b81831315612bb4579091905b84871315612bc0579395935b83861315612bcc579294925b80831315612bd657915b84861315612be2579394935b80821315612bec57905b82871315612bf8579195915b81861315612c04579094905b80851315612c0e57935b82861315612c1a579194915b80841315612c2457925b82851315612c30579193915b81841315612c3c579092905b82841315612c48579192915b8d8c0380612c5857879a50612cfe565b8060011415612c6957869a50612cfe565b8060021415612c7a57859a50612cfe565b8060031415612c8b57849a50612cfe565b8060041415612c9c57839a50612cfe565b8060051415612cad57829a50612cfe565b8060061415612cbe57819a50612cfe565b6040805162461bcd60e51b815260206004820152601060248201526f6b31206f7574206f6620626f756e647360801b604482015290519081900360640190fd5b8e8c038d8d1415612d1c57508a995061288d98505050505050505050565b80612d33575096985061288d975050505050505050565b8060011415612d4e575095985061288d975050505050505050565b8060021415612d69575094985061288d975050505050505050565b8060031415612d84575093985061288d975050505050505050565b8060041415612d9f575092985061288d975050505050505050565b8060051415612dba575091985061288d975050505050505050565b8060061415612dd5575090985061288d975050505050505050565b6040805162461bcd60e51b815260206004820152601060248201526f6b32206f7574206f6620626f756e647360801b604482015290519081900360640190fd5b6000808460028585010481518110612e2957fe5b602002602001015190506001840393506001830192505b60018401935080858581518110612e5357fe5b602002602001015112612e40575b60018303925080858481518110612e7457fe5b602002602001015113612e615782841015612ee457848381518110612e9557fe5b6020026020010151858581518110612ea957fe5b6020026020010151868681518110612ebd57fe5b60200260200101878681518110612ed057fe5b602090810291909101019190915252612eed565b829150506122a7565b612e40565b6000828201818312801590612f075750838112155b80612f1c5750600083128015612f1c57508381125b6110035760405162461bcd60e51b815260040180806020018281038252602181526020018061315b6021913960400191505060405180910390fd5b600081831115612f68575081611006565b50919050565b8151612f7a8383612625565b50612f85838261265f565b50505050565b6040518060a0016040528060008152602001600081526020016060815260200160608152602001606081525090565b604080516080810182526000808252602082018190529181019190915260608082015290565b50805460008255906000526020600020908101906117bd91906130f9565b828054828255906000526020600020908101928215613053579160200282015b8281111561305357825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061301e565b5061305f929150613113565b5090565b82805482825590600052602060002090810192821561309e579160200282015b8281111561309e578251825591602001919060010190613083565b5061305f9291506130f9565b6040805160a0810182526000808252602082018190529181018290526060810191909152608081016130da6130df565b905290565b604051806040016040528060608152602001600081525090565b61073991905b8082111561305f57600081556001016130ff565b61073991905b8082111561305f5780546001600160a01b031916815560010161311956fe756e61626c6520746f207472616e73666572416e6443616c6c20746f206f7261636c655369676e6564536166654d6174683a206164646974696f6e206f766572666c6f774f6e6c792063616c6c61626c65206279206f776e657200000000000000000000536f75726365206d75737420626520746865206f7261636c65206f66207468652072657175657374a264697066735822122052c68c49bb1b01c87cc7eee255d0e467ca8ef28b94c7d14b1463b01b5b55d92664736f6c63430006060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
-----Decoded View---------------
Arg [0] : _link (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Deployed Bytecode Sourcemap
48654:10848:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;48654:10848:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;47912:168:0;;;:::i;:::-;;53127:111;;;:::i;:::-;;;;-1:-1:-1;;;;;53127:111:0;;;;;;;;;;;;;;53859:1183;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;;;;;53859:1183:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;53859:1183:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;53859:1183:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;53859:1183:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;53859:1183:0;;-1:-1:-1;53859:1183:0;-1:-1:-1;53859:1183:0;:::i;56537:1107::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;56537:1107:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;46838:189;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;46838:189:0;;;;;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;46838:189:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;46838:189:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;46838:189:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;46838:189:0;;-1:-1:-1;46838:189:0;;-1:-1:-1;;;;;46838:189:0:i;58544:706::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;58544:706:0;;;;;;;;-1:-1:-1;;;;;;58544:706:0;;;;;;;;;;:::i;45346:264::-;;;:::i;47678:166::-;;;:::i;51199:957::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;51199:957:0;;;;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;51199:957:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;51199:957:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;51199:957:0;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;51199:957:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;51199:957:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;51199:957:0;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;51199:957:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;51199:957:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;51199:957:0;;-1:-1:-1;51199:957:0;-1:-1:-1;51199:957:0;:::i;:::-;;;;;;;;;;;;;;;;47428:184;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;47428:184:0;-1:-1:-1;;;;;47428:184:0;;:::i;44679:28::-;;;:::i;57898:222::-;;;:::i;47134:179::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;47134:179:0;-1:-1:-1;;;;;47134:179:0;;:::i;32758:682::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;32758:682:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;32758:682:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;32758:682:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;32758:682:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;32758:682:0;;-1:-1:-1;32758:682:0;;-1:-1:-1;;;;;32758:682:0:i;52440:477::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;52440:477:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;52440:477:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;52440:477:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;52440:477:0;;;;;;;;;;;;;;;;;;;;;;;46451:24;;;:::i;45095:157::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;45095:157:0;-1:-1:-1;;;;;45095:157:0;;:::i;47912:168::-;45750:5;;-1:-1:-1;;;;;45750:5:0;45736:10;:19;45728:54;;;;;-1:-1:-1;;;45728:54:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45728:54:0;;;;;;;;;;;;;;;47987:12:::1;::::0;-1:-1:-1;;;47987:12:0;::::1;;;47983:92;;;48010:12;:20:::0;;-1:-1:-1;;;;48010:20:0::1;::::0;;48046:21:::1;::::0;::::1;::::0;48025:5:::1;::::0;48046:21:::1;47983:92;47912:168::o:0;53127:111::-;53186:7;53209:23;:21;:23::i;:::-;53202:30;;53127:111;;:::o;53859:1183::-;33633:19;:17;:19::i;:::-;-1:-1:-1;;;;;33619:33:0;:10;-1:-1:-1;;;;;33619:33:0;;33611:65;;;;;-1:-1:-1;;;33611:65:0;;;;;;;;;;;;-1:-1:-1;;;33611:65:0;;;;;;;;;;;;;;;54146:16:::1;59434:23;:21;:23::i;:::-;-1:-1:-1::0;;;;;59427:30:0::1;:3;-1:-1:-1::0;;;;;59427:30:0::1;;;59419:66;;;::::0;;-1:-1:-1;;;59419:66:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;54182:25:::2;54192:7;54201:5;;54182:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16:::0;::::2;74:27:::0;;;;-1:-1;54182:9:0::2;::::0;-1:-1:-1;;;54182:25:0:i:2;:::-;54174:34;;12:1:-1;9::::0;2:12:::2;54174:34:0;54217:20;54240:24:::0;;;:17:::2;:24;::::0;;;;:37;54339:24;;::::2;;54331:57;;;::::0;;-1:-1:-1;;;54331:57:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;54331:57:0;;;;;;;;;;;;;::::2;;54433:33;::::0;;-1:-1:-1;;54433:33:0::2;::::0;;;;::::2;::::0;;::::2;::::0;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;54433:33:0;;;;;;54423:44;;;;::::2;::::0;;;;54395:25:::2;54482:29:::0;;;:10:::2;:29:::0;;;;;;:36;-1:-1:-1;;;54482:36:0;::::2;-1:-1:-1::0;;;;;54482:36:0::2;:50:::0;54474:83:::2;;;::::0;;-1:-1:-1;;;54474:83:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;54474:83:0;;;;;;;;;;;;;::::2;;54615:19;54564:10;:29;54575:17;54564:29;;;;;;;;;;;:48;;;:70;;;;;;;;;;;;;;;;;;54689:16;54641:10;:29;54652:17;54641:29;;;;;;;;;;;:45;;;:64;;;;;-1:-1:-1::0;;;;;54641:64:0::2;;;;;-1:-1:-1::0;;;;;54641:64:0::2;;;;;;54751:7;54712:10;:29;54723:17;54712:29;;;;;;;;;;;:36;;;:46;;;;;-1:-1:-1::0;;;;;54712:46:0::2;;;;;-1:-1:-1::0;;;;;54712:46:0::2;;;;;;54765:47;54780:5;54787:17;54806:5;;54765:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16:::0;::::2;74:27:::0;;;;-1:-1;54765:14:0::2;::::0;-1:-1:-1;;;54765:47:0:i:2;:::-;54834:12;54823:8;:23;54819:218;;;54857:15;54875:26;:8:::0;54888:12;54875:26:::2;:12;:26;:::i;:::-;54857:44;;54910:24;54956:23;:21;:23::i;:::-;54910:70;;54996:5;-1:-1:-1::0;;;;;54996:14:0::2;;55011:7;55020;54996:32;;;;;;;;;;;;;-1:-1:-1::0;;;;;54996:32:0::2;-1:-1:-1::0;;;;;54996:32:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::2;2:2;54996:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;54996:32:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::2;4:2;-1:-1:::0;54996:32:0;54989:40:::2;;;;54819:218;;;59492:1;;33683::::1;53859:1183:::0;;;;;;;;;:::o;56537:1107::-;56670:4;31515:27;;;:15;:27;;;;;;;;-1:-1:-1;;;;;31515:27:0;31501:10;:41;31493:107;;;;-1:-1:-1;;;31493:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31614:27;;;;:15;:27;;;;;;31607:34;;-1:-1:-1;;;;;;31607:34:0;;;31653:30;31630:10;;31653:30;;;56686:26:::1;;:::i;:::-;56715:55;56733:36:::0;;;:24:::1;:36;::::0;;;;;;;;56715:55;;:17:::1;:55:::0;;;;;;56686:84;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;;;;;;;;;;56715:55;;56686:84;;;;;::::1;::::0;;;::::1;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;56686:84:0::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;56686:84:0;;;;-1:-1:-1;;;56777:19:0::1;56799:20:::0;;;:8:::1;:20;::::0;;;;;;;;;56841:24:::1;:36:::0;;;;;;;56884:27;;;;56918:43;;;;56973:70;;;;;;;56686:84;;-1:-1:-1;56799:20:0;;57025:10:::1;::::0;56799:20;;56841:36;;56973:70:::1;::::0;;;;;;;;;::::1;57050:23;::::0;;;:10:::1;:23;::::0;;;;;;:33:::1;;27:10:-1::0;;39:1:::1;23:18:::0;::::1;45:23:::0;;57050:45:0;;;;;::::1;::::0;;;57102:20:::1;;:::i;:::-;57125:23;::::0;;;:10:::1;:23;::::0;;;;;;;;57102:46;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;;57102:46:0::1;::::0;;::::1;;::::0;;-1:-1:-1;;;;;;;;57102:46:0;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;;;;;;;;;;;57125:23;;57102:46;;;;;;;::::1;::::0;;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;57183:2;:10;;;:17;57159:3;:13;;;:20;:41;57155:77;;;57209:23;::::0;;;:10:::1;:23;::::0;;;;57202:30;;-1:-1:-1;;;;;;57202:30:0;;;;;::::1;::::0;;-1:-1:-1;;;;;;57202:30:0::1;::::0;;57209:23;57202:30:::1;;::::0;::::1;57209:23:::0;57202:30:::1;:::i;:::-;;;57155:77;57293:15;::::0;::::1;::::0;57269:13:::1;::::0;::::1;::::0;:20;57254:4:::1;::::0;57269:39:::1;57265:353;;;57319:13;57335:31;57352:3;:13;;;57335:16;:31::i;:::-;57319:47;;57416:11;57410:4;57380:56;57429:6;57380:56;;;;;;;;;;;;;;;;;;57517:19;::::0;;::::1;::::0;57565:22;;57542:67;;::::1;::::0;::::1;::::0;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;57542:67:0;;;;;;::::1;25:18:-1::0;::::1;61:17:::0;;-1:-1;;;;;182:15:::1;-1:-1:::0;;;;;;57542:67:0;;::::1;179:29:-1::0;;;::::1;160:49:::0;;57517:93:0;;;;-1:-1:-1;;;;;57517:24:0;;::::1;::::0;57542:67;57517:93;;;;;;25:18:-1;36:153:::1;66:2;61:3;58:11;36:153;;176:10:::0;;164:23;;-1:-1;;139:12;;;;98:2:::1;89:12:::0;;::::1;::::0;114::::1;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;57517:93:0;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;-1:-1:::0;57503:107:0;;-1:-1:-1;;;57265:353:0::1;57631:7:::0;56537:1107;-1:-1:-1;;;;;;;;56537:1107:0:o;46838:189::-;-1:-1:-1;;;;;46987:17:0;;46964:4;46987:17;;;:10;:17;;;;;;;;;:34;;-1:-1:-1;47009:12:0;;-1:-1:-1;;;47009:12:0;;;;47008:13;46987:34;46980:41;;46838:189;;;;;:::o;58544:706::-;58723:19;58745:20;;;:8;:20;;;;;;;;;;58772:27;;;;58813:24;:36;;;;;58806:43;;;;58856:20;;:::i;:::-;58879:23;;;;:10;:23;;;;;;;;;58856:46;;;;;;;;;-1:-1:-1;;;;;;58856:46:0;;;;;;;-1:-1:-1;;;;;;;;58856:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58879:23;;58856:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58931:10;-1:-1:-1;;;;;58917:24:0;:3;:10;;;-1:-1:-1;;;;;58917:24:0;;58909:62;;;;;-1:-1:-1;;;58909:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;58985:23;;;;:10;:23;;;;;58978:30;;-1:-1:-1;;;;;;58978:30:0;;;;;;;;-1:-1:-1;;;;;;58978:30:0;;;58985:23;58978:30;;;;58985:23;58978:30;:::i;:::-;;;59015:78;59038:10;59050:8;59060:19;59081:11;59015:22;:78::i;:::-;59100:24;59146:23;:21;:23::i;:::-;59100:70;;59185:5;-1:-1:-1;;;;;59185:14:0;;59200:3;:10;;;59212:8;59185:36;;;;;;;;;;;;;-1:-1:-1;;;;;59185:36:0;-1:-1:-1;;;;;59185:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;59185:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59185:36:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;59185:36:0;59177:67;;;;;-1:-1:-1;;;59177:67:0;;;;;;;;;;;;-1:-1:-1;;;59177:67:0;;;;;;;;;;;;;;;58544:706;;;;;;;:::o;45346:264::-;45419:12;;-1:-1:-1;;;;;45419:12:0;45405:10;:26;45397:61;;;;;-1:-1:-1;;;45397:61:0;;;;;;;;;;;;-1:-1:-1;;;45397:61:0;;;;;;;;;;;;;;;45486:5;;;-1:-1:-1;;;;;;45498:18:0;;;45506:10;45498:18;;;;;;45523:12;:25;;;;;;;45562:42;;-1:-1:-1;;;;;45486:5:0;;;;45506:10;45486:5;;45562:42;;45467:16;;45562:42;45346:264;:::o;47678:166::-;45750:5;;-1:-1:-1;;;;;45750:5:0;45736:10;:19;45728:54;;;;;-1:-1:-1;;;45728:54:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45728:54:0;;;;;;;;;;;;;;;47753:12:::1;::::0;-1:-1:-1;;;47753:12:0;::::1;;;47748:91;;47776:12;:19:::0;;-1:-1:-1;;;;47776:19:0::1;-1:-1:-1::0;;;47776:19:0::1;::::0;;47811:20:::1;::::0;::::1;::::0;47776:19;;47811:20:::1;47678:166::o:0;51199:957::-;51389:12;51437:1;51421:13;:17;51413:55;;;;;-1:-1:-1;;;51413:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51483:33;;;:72;;;;-1:-1:-1;51520:35:0;;;51483:72;51475:97;;;;;-1:-1:-1;;;51475:97:0;;;;;;;;;;;;-1:-1:-1;;;51475:97:0;;;;;;;;;;;;;;;48867:2;51587:35;;;51579:80;;;;;-1:-1:-1;;;51579:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51674:32;;;;51666:66;;;;;-1:-1:-1;;;51666:66:0;;;;;;;;;;;;-1:-1:-1;;;51666:66:0;;;;;;;;;;;;;;;51739:20;;51766:106;51783:20;;;51766:106;;;51834:30;51851:9;;51861:1;51851:12;;;;;;;;;;;;;51834;:16;;:30;;;;:::i;:::-;51819:45;-1:-1:-1;51805:3:0;;51766:106;;;-1:-1:-1;51912:11:0;;;51895:34;;;;;;;;;;51925:3;51895:34;;;;;;26:21:-1;;;22:32;;6:49;;51895:34:0;;;;;;51885:45;;;;;;;;;51937:13;;;;;;;52007:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51885:45;;-1:-1:-1;52007:75:0;;;;;;52053:8;;;;;;52007:75;;;52053:8;;52007:75;52053:8;52007:75;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;;52007:75:0;;;-1:-1:-1;52007:75:0;;;;;;;;;;;;;;;;;;;;;;;;52063:7;;;;;;52007:75;;;52063:7;;52007:75;52063:7;52007:75;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;;52007:75:0;;;-1:-1:-1;52007:75:0;;;;;;;;;;;;;;;;;;;;;;;;52072:9;;;;;;52007:75;;;52072:9;;52007:75;52072:9;52007:75;1:33:-1;99:1;81:16;;74:27;;;-1:-1;52007:75:0;;;;-1:-1:-1;;51981:23:0;;;:17;:23;;;;;;;;;:101;;;;;;;;;;;;;;;;;;:23;;-1:-1:-1;51981:101:0;;;;;;;;;;;;:::i;:::-;-1:-1:-1;51981:101:0;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;51981:101:0;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;52096:54:0;;;;;;;;;;;;;;52116:4;;-1:-1:-1;52096:54:0;;;;;;;;;;;51199:957;;;;;;;;;;:::o;47428:184::-;45750:5;;-1:-1:-1;;;;;45750:5:0;45736:10;:19;45728:54;;;;;-1:-1:-1;;;45728:54:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45728:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;47510:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;::::1;;47506:101;;;-1:-1:-1::0;;;;;47538:17:0;::::1;47558:5;47538:17:::0;;;:10:::1;:17;::::0;;;;;;;;:25;;-1:-1:-1;;47538:25:0::1;::::0;;47579:20;;;;;;;::::1;::::0;;;;;;;;::::1;47506:101;47428:184:::0;:::o;44679:28::-;;;-1:-1:-1;;;;;44679:28:0;;:::o;57898:222::-;45750:5;;-1:-1:-1;;;;;45750:5:0;45736:10;:19;45728:54;;;;;-1:-1:-1;;;45728:54:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45728:54:0;;;;;;;;;;;;;;;57948:24:::1;57994:23;:21;:23::i;:::-;58060:30;::::0;;-1:-1:-1;;;58060:30:0;;58084:4:::1;58060:30;::::0;::::1;::::0;;;57948:70;;-1:-1:-1;;;;;;58033:14:0;::::1;::::0;::::1;::::0;58048:10:::1;::::0;58033:14;;58060:15:::1;::::0;:30;;;;;::::1;::::0;;;;;;;;58033:14;58060:30;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;58060:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;58060:30:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;58060:30:0;58033:58:::1;::::0;;-1:-1:-1;;;;;;58033:58:0::1;::::0;;;;;;-1:-1:-1;;;;;58033:58:0;;::::1;;::::0;::::1;::::0;;;;;;;;;;;;;;58060:30:::1;::::0;58033:58;;;;;;;-1:-1:-1;58033:58:0;;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;58033:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;58033:58:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;58033:58:0;58025:89:::1;;;::::0;;-1:-1:-1;;;58025:89:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;58025:89:0;;;;;;;;;;;;;::::1;47134:179:::0;45750:5;;-1:-1:-1;;;;;45750:5:0;45736:10;:19;45728:54;;;;;-1:-1:-1;;;45728:54:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45728:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;47214:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;::::1;;47209:99;;-1:-1:-1::0;;;;;47242:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;;;;:24;;-1:-1:-1;;47242:24:0::1;47262:4;47242:24;::::0;;47282:18;;;;;;;::::1;::::0;;;;;;;;::::1;47134:179:::0;:::o;32758:682::-;33633:19;:17;:19::i;:::-;-1:-1:-1;;;;;33619:33:0;:10;-1:-1:-1;;;;;33619:33:0;;33611:65;;;;;-1:-1:-1;;;33611:65:0;;;;;;;;;;;;-1:-1:-1;;;33611:65:0;;;;;;;;;;;;;;;34368:12;;32907:5;;32314:47;-1:-1:-1;34368:38:0::1;34360:73;;;::::0;;-1:-1:-1;;;34360:73:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;34360:73:0;;;;;;;;;;;;;::::1;;34053:2:::2;34042:14:::0;::::2;34036:21:::0;32945:5;;-1:-1:-1;;;;;;34078:39:0;::::2;-1:-1:-1::0;;;34078:39:0::2;34070:82;;;::::0;;-1:-1:-1;;;34070:82:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;33061:7:::3;33056:2;33049:5;33045:14;33038:31;33193:7;33188:2;33181:5;33177:14;33170:31;33309:12;33335:4;-1:-1:-1::0;;;;;33327:26:0::3;33354:5;33327:33;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10:::0;;164:23;;-1:-1;;139:12;;;;98:2:::3;89:12:::0;;::::3;::::0;114::::3;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;33327:33:0;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;33308:52:0;;;33398:7;33390:44;;;::::0;;-1:-1:-1;;;33390:44:0;;::::3;;::::0;::::3;::::0;::::3;::::0;;;;::::3;::::0;;;;;;;;;;;;;::::3;52440:477:::0;52521:20;52698:24;;;:17;:24;;;;;;;;:37;;52744;;;;52790:32;;;52677:234;;;;;;;;;;;;;;;;;52521:20;;52575:24;;;;;;52698:37;52744;52790:32;52831:31;;;;52871:33;;;;;52677:234;52790:32;;52677:234;;;52790:32;52677:234;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52677:234:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52440:477;;;;;;;:::o;46451:24::-;;;-1:-1:-1;;;46451:24:0;;;;;:::o;45095:157::-;45750:5;;-1:-1:-1;;;;;45750:5:0;45736:10;:19;45728:54;;;;;-1:-1:-1;;;45728:54:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45728:54:0;;;;;;;;;;;;;;;45176:12:::1;:18:::0;;-1:-1:-1;;;;;;45176:18:0::1;-1:-1:-1::0;;;;;45176:18:0;;::::1;::::0;;::::1;::::0;;;45235:5:::1;::::0;45208:38:::1;::::0;45176:18;;45235:5:::1;::::0;45208:38:::1;::::0;-1:-1:-1;;45208:38:0::1;45095:157:::0;:::o;28002:116::-;28107:4;;-1:-1:-1;;;;;28107:4:0;28002:116;:::o;55389:779::-;55491:26;;:::i;:::-;55520:24;;;;:17;:24;;;;;;;;;55491:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55520:24;;55491:53;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55491:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55577:1;55559:2;:15;;;:19;55551:57;;;;;-1:-1:-1;;;55551:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55615:32;;:::i;:::-;55744:15;;55691:69;;;;;;;55654:25;;55724:18;;55717:5;;55691:69;;;;;;;;;;55772:6;55767:396;55788:2;:10;;;:17;55784:1;:21;55767:396;;;55831:83;55853:2;:9;;;55863:1;55853:12;;;;;;;;;;;;;;55875:4;55882:31;;;55831:21;:83::i;:::-;55821:93;-1:-1:-1;55923:24:0;55821:93;55941:5;55923:24;:17;:24;:::i;:::-;55976:62;55999:2;:10;;;56010:1;55999:13;;;;;;;;;;;;;;56014:7;56023:2;:11;;;56035:1;56023:14;;;;;;;;;;;;;;55976:22;:62::i;:::-;56047:27;;;;:8;:27;;;;;;;;:48;;;56104:24;:43;;;;;:51;;;55956:82;-1:-1:-1;55807:3:0;;55767:396;;20614:170;20672:7;20701:1;20696;:6;;20688:49;;;;;-1:-1:-1;;;20688:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20756:5:0;;;20614:170::o;37211:138::-;37290:6;37315:28;37332:10;37337:4;37332;:10::i;:::-;37315:16;:28::i;:::-;37308:35;;37211:138;;;;:::o;26747:429::-;26909:35;26973:27;;;:15;:27;;;;;;;;-1:-1:-1;;;;;;27008:34:0;;;;;27054:30;;-1:-1:-1;;;;;26973:27:0;;;;26989:10;;27054:30;;26909:35;27054:30;27091:79;;;-1:-1:-1;;;27091:79:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;27091:79:0;;;;;;;;;;;;;;-1:-1:-1;;;;;27091:29:0;;;;;:79;;;;;-1:-1:-1;;27091:79:0;;;;;;;-1:-1:-1;27091:29:0;:79;;;2:2:-1;;;;27:1;24;17:12;2:2;27091:79:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27091:79:0;;;;26747:429;;;;;:::o;20184:167::-;20242:7;20270:5;;;20290:6;;;;20282:46;;;;;-1:-1:-1;;;20282:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;24377:302;24529:24;;:::i;:::-;24562:28;;:::i;:::-;24604:69;:3;24619:7;24628:16;24646:26;24604:69;:14;:69;:::i;:::-;24597:76;;;24377:302;;;;;;:::o;13895:167::-;13984:35;13996:4;:8;;;14006:5;:12;13984:11;:35::i;:::-;;14026:30;14040:4;:8;;;14050:5;14026:13;:30::i;:::-;;13895:167;;:::o;25715:500::-;25915:12;;25892:36;;;25909:4;25892:36;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;25892:36:0;;;;;;25882:47;;;;;;;;;25936:10;;;:25;;;;-1:-1:-1;25968:26:0;;;:15;:26;;;;;;:36;;-1:-1:-1;;;;;;25968:36:0;-1:-1:-1;;;;;25968:36:0;;;;;26016:29;;25882:47;;26016:29;;;26060:4;;-1:-1:-1;;;;;26060:4:0;:20;26081:7;26090:8;26100:19;26114:4;26100:13;:19::i;:::-;26060:60;;;;;;;;;;;;;-1:-1:-1;;;;;26060:60:0;-1:-1:-1;;;;;26060:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;26060:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;26060:60:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;26060:60:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;26060:60:0;26052:108;;;;-1:-1:-1;;;26052:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26167:12;:17;;26183:1;26167:17;;;25715:500;;;;;:::o;44229:256::-;44301:15;44328:21;44365:4;:11;44352:25;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;44352:25:0;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;144:17;;-1:-1;44352:25:0;-1:-1:-1;44328:49:0;-1:-1:-1;44389:9:0;44384:77;44408:4;:11;44404:1;:15;44384:77;;;44446:4;44451:1;44446:7;;;;;;;;;;;;;;44435:5;44441:1;44435:8;;;;;;;;;;;;;;;;;:18;44421:3;;44384:77;;;-1:-1:-1;44474:5:0;44229:256;-1:-1:-1;;44229:256:0:o;37484:522::-;37570:6;37600:4;:11;37596:1;:15;37588:50;;;;;-1:-1:-1;;;37588:50:0;;;;;;;;;;;;-1:-1:-1;;;37588:50:0;;;;;;;;;;;;;;;37659:11;;37705:1;37699:7;;37717;;;37713:288;;37740:14;37763;37807:62;37822:4;37828:1;37837;37831:3;:7;37854:1;37840:11;:15;37857:11;37807:14;:62::i;:::-;37786:83;;-1:-1:-1;37786:83:0;-1:-1:-1;37885:36:0;37786:83;;37885:18;:36::i;:::-;37878:43;;;;;;;;37713:288;37951:42;37963:4;37969:1;37978;37972:3;:7;37981:11;37951;:42::i;:::-;37944:49;;;;;;13282:367;13436:24;;:::i;:::-;13469:40;13481:4;:8;;;12655:3;13469:11;:40::i;:::-;-1:-1:-1;;13516:13:0;;;-1:-1:-1;;;;;13536:39:0;;:20;;;:39;-1:-1:-1;;;;;;13582:43:0;;:23;;;:43;13516:4;13282:367;;;;;;;:::o;1008:408::-;1078:13;;:::i;:::-;1115:2;1104:8;:13;:18;1100:73;;1162:2;1151:8;:13;1145:2;:20;1133:32;;;;1100:73;-1:-1:-1;1222:12:0;;;;:23;;;1287:4;1281:11;;1300:16;;;-1:-1:-1;1324:14:0;;1367:18;;;1359:27;1346:41;;1222:12;1008:408::o;4687:157::-;4764:13;;:::i;:::-;4793:45;4799:3;4804;:7;;;:14;4820:4;4826;:11;4793:5;:45::i;30302:542::-;30393:12;30455:29;;;23305:1;23248;30708:4;:7;;;30724:4;:20;;;30753:4;:23;;;30785:4;:10;;;23352:1;30825:4;:8;;;:12;;;30424:414;;;;;;-1:-1:-1;;;;;30424:414:0;-1:-1:-1;;;;;30424:414:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;30424:414:0;-1:-1:-1;;;;;30424:414:0;;;;;;-1:-1:-1;;;;;30424:414:0;;-1:-1:-1;;;;;30424:414:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;30424:414:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30424:414:0;;;-1:-1:-1;;26:21;;;22:32;6:49;;30424:414:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;30424:414:0;;;179:29:-1;;;;160:49;;;-1:-1;30424:414:0;;-1:-1:-1;;;;;;;;;;30302:542:0;;;:::o;41675:831::-;41852:11;41865;41901:2;41896;:7;41888:16;;12:1:-1;9;2:12;41888:16:0;41925:2;41919;:8;;:20;;;;;41937:2;41931;:8;;41919:20;41911:29;;12:1:-1;9;2:12;41911:29:0;41961:2;41955;:8;;:20;;;;;41973:2;41967;:8;;41955:20;41947:29;;12:1:-1;9;2:12;41947:29:0;38139:1;42016:2;42011;:7;:35;42007:105;;;42066:36;42081:4;42087:2;42091;42095;42099;42066:14;:36::i;:::-;42059:43;;;;;;42007:105;42120:16;42139:23;42149:4;42155:2;42159;42139:9;:23::i;:::-;42120:42;;42181:8;42175:2;:14;42171:323;;42207:8;42202:13;;42171:323;;;42246:2;42235:8;:13;42231:263;;;42266:8;42277:1;42266:12;42261:17;;42231:263;;;42318:8;42312:2;:14;;:31;;;;;42341:2;42330:8;:13;42312:31;42305:39;;;;42362:35;42374:4;42380:2;42384:8;42394:2;42362:11;:35::i;:::-;42355:42;;42415:39;42427:4;42433:8;42444:1;42433:12;42447:2;42451;42415:11;:39::i;:::-;42408:46;-1:-1:-1;42465:19:0;;-1:-1:-1;42465:19:0;42231:263;41985:516;;;;41675:831;;;;;;;;:::o;36385:277::-;36458:6;36486:1;36481:2;:6;:16;;;;;36496:1;36491:2;:6;36481:16;36480:40;;;;36508:1;36503:2;:6;:16;;;;;36518:1;36513:2;:6;36503:16;36476:85;;;36552:1;36538:11;36542:2;36546;36538:3;:11::i;:::-;:15;;;;;;36531:22;;;;36476:85;36567:16;36606:1;36587:6;;;36596;;;36587:15;36586:21;;-1:-1:-1;36621:35:0;36625:19;36634:1;36629:2;:6;36642:1;36637:2;:6;36625:3;:19::i;:::-;36646:9;36621:3;:35::i;40703:798::-;40818:10;40854:1;40848:2;:7;;40840:16;;12:1:-1;9;2:12;40840:16:0;40876:2;40871:1;:7;;40863:16;;12:1:-1;9;2:12;40863:16:0;40898:2;40893;:7;40886:588;;;38139:1;40920:2;40915;:7;:35;40911:157;;;40963:13;41003:34;41018:4;41024:2;41028;41032:1;41035;41003:14;:34::i;:::-;-1:-1:-1;40987:50:0;-1:-1:-1;41048:10:0;;-1:-1:-1;41048:10:0;40911:157;41076:18;41097:23;41107:4;41113:2;41117;41097:9;:23::i;:::-;41076:44;;41138:10;41133:1;:15;41129:338;;41283:10;41278:15;;41129:338;;;41443:10;41456:1;41443:14;41438:19;;41129:338;40886:588;;;;41487:4;41492:2;41487:8;;;;;;;;;;;;;;41480:15;;40703:798;;;;;;:::o;2780:1181::-;2875:13;;:::i;:::-;2912:4;:11;2905:3;:18;;2897:27;;12:1:-1;9;2:12;2897:27:0;2949:3;:12;;;2943:3;2937;:9;:24;2933:92;;;2972:45;2979:3;2984:28;2988:3;:12;;;3008:3;3002;:9;2984:3;:28::i;:::-;3015:1;2984:32;2972:6;:45::i;:::-;3033:9;3049:8;3146:3;3140:10;3219:6;3213:13;3337:3;3332:2;3324:6;3320:15;3316:25;3308:33;;3423:6;3417:3;3412;3408:13;3405:25;3402:2;;;3466:3;3461;3457:13;3449:6;3442:29;3402:2;-1:-1:-1;;;3505:2:0;3495:13;;3570:135;3584:2;3577:3;:9;3570:135;;3641:10;;3628:24;;-1:-1:-1;;3588:9:0;;;;3677:2;3669:10;;;;3688:9;3570:135;;;3819:10;3869:11;;-1:-1:-1;;3762:2:0;:8;;;3754:3;:17;:21;3865:22;;;3831:9;;3815:26;;;;3908:21;3895:35;;-1:-1:-1;3952:3:0;2780:1181;;;;;;:::o;38283:2258::-;38444:11;38457;38716;38739:2;38730;38735:1;38730:6;:11;38716:25;;38748:9;38760:4;38765:2;38770:1;38765:6;38760:12;;;;;;;;;;;;;;38748:24;;38779:9;38795:3;38791:1;:7;:32;;-1:-1:-1;;;;;38791:32:0;;;38801:4;38806:2;38811:1;38806:6;38801:12;;;;;;;;;;;;;;38791:32;38779:44;;38830:9;38846:3;38842:1;:7;:32;;-1:-1:-1;;;;;38842:32:0;;;38852:4;38857:2;38862:1;38857:6;38852:12;;;;;;;;;;;;;;38842:32;38830:44;;38881:9;38897:3;38893:1;:7;:32;;-1:-1:-1;;;;;38893:32:0;;;38903:4;38908:2;38913:1;38908:6;38903:12;;;;;;;;;;;;;;38893:32;38881:44;;38932:9;38948:3;38944:1;:7;:32;;-1:-1:-1;;;;;38944:32:0;;;38954:4;38959:2;38964:1;38959:6;38954:12;;;;;;;;;;;;;;38944:32;38932:44;;38983:9;38999:3;38995:1;:7;:32;;-1:-1:-1;;;;;38995:32:0;;;39005:4;39010:2;39015:1;39010:6;39005:12;;;;;;;;;;;;;;38995:32;38983:44;;39034:9;39050:3;39046:1;:7;:32;;-1:-1:-1;;;;;39046:32:0;;;39056:4;39061:2;39066:1;39061:6;39056:12;;;;;;;;;;;;;;39046:32;39034:44;;39096:2;39091;:7;39087:35;;;39113:2;;39117;39087:35;39137:2;39132;:7;39128:35;;;39154:2;;39158;39128:35;39178:2;39173;:7;39169:35;;;39195:2;;39199;39169:35;39219:2;39214;:7;39210:35;;;39236:2;;39240;39210:35;39260:2;39255;:7;39251:35;;;39277:2;;39281;39251:35;39301:2;39296;:7;39292:35;;;39318:2;39292:35;39342:2;39337;:7;39333:35;;;39359:2;;39363;39333:35;39383:2;39378;:7;39374:35;;;39400:2;39374:35;39424:2;39419;:7;39415:35;;;39441:2;;39445;39415:35;39465:2;39460;:7;39456:35;;;39482:2;;39486;39456:35;39506:2;39501;:7;39497:35;;;39523:2;39497:35;39547:2;39542;:7;39538:35;;;39564:2;;39568;39538:35;39588:2;39583;:7;39579:35;;;39605:2;39579:35;39629:2;39624;:7;39620:35;;;39646:2;;39650;39620:35;39670:2;39665;:7;39661:35;;;39687:2;;39691;39661:35;39711:2;39706;:7;39702:35;;;39728:2;;39732;39702:35;39762:7;;;39780:11;39776:309;;39801:2;39794:9;;39776:309;;;39820:6;39830:1;39820:11;39816:269;;;39841:2;39834:9;;39816:269;;;39860:6;39870:1;39860:11;39856:229;;;39881:2;39874:9;;39856:229;;;39900:6;39910:1;39900:11;39896:189;;;39921:2;39914:9;;39896:189;;;39940:6;39950:1;39940:11;39936:149;;;39961:2;39954:9;;39936:149;;;39980:6;39990:1;39980:11;39976:109;;;40001:2;39994:9;;39976:109;;;40020:6;40030:1;40020:11;40016:69;;;40041:2;40034:9;;40016:69;;;40057:26;;;-1:-1:-1;;;40057:26:0;;;;;;;;;;;;-1:-1:-1;;;40057:26:0;;;;;;;;;;;;;;40016:69;40110:7;;;40128:8;;;40124:412;;;-1:-1:-1;40147:4:0;;-1:-1:-1;40139:19:0;;-1:-1:-1;;;;;;;;;40139:19:0;40124:412;40175:11;40171:365;;-1:-1:-1;40203:2:0;;-1:-1:-1;40189:17:0;;-1:-1:-1;;;;;;;;40189:17:0;40171:365;40223:6;40233:1;40223:11;40219:317;;;-1:-1:-1;40251:2:0;;-1:-1:-1;40237:17:0;;-1:-1:-1;;;;;;;;40237:17:0;40219:317;40271:6;40281:1;40271:11;40267:269;;;-1:-1:-1;40299:2:0;;-1:-1:-1;40285:17:0;;-1:-1:-1;;;;;;;;40285:17:0;40267:269;40319:6;40329:1;40319:11;40315:221;;;-1:-1:-1;40347:2:0;;-1:-1:-1;40333:17:0;;-1:-1:-1;;;;;;;;40333:17:0;40315:221;40367:6;40377:1;40367:11;40363:173;;;-1:-1:-1;40395:2:0;;-1:-1:-1;40381:17:0;;-1:-1:-1;;;;;;;;40381:17:0;40363:173;40415:6;40425:1;40415:11;40411:125;;;-1:-1:-1;40443:2:0;;-1:-1:-1;40429:17:0;;-1:-1:-1;;;;;;;;40429:17:0;40411:125;40463:6;40473:1;40463:11;40459:77;;;-1:-1:-1;40491:2:0;;-1:-1:-1;40477:17:0;;-1:-1:-1;;;;;;;;40477:17:0;40459:77;40508:26;;;-1:-1:-1;;;40508:26:0;;;;;;;;;;;;-1:-1:-1;;;40508:26:0;;;;;;;;;;;;;;42838:1256;42940:7;;43112:4;43129:1;43118:7;;;43117:13;43112:19;;;;;;;;;;;;;;43097:34;;43144:1;43138:7;;;;43201:1;43195:7;;;;43209:880;43251:1;43245:7;;;;43281:5;43270:4;43275:2;43270:8;;;;;;;;;;;;;;:16;43231:57;;43296;43316:1;43310:7;;;;43346:5;43335:4;43340:2;43335:8;;;;;;;;;;;;;;:16;43296:57;;43370:2;43365;:7;43361:721;;;43409:4;43414:2;43409:8;;;;;;;;;;;;;;43419:4;43424:2;43419:8;;;;;;;;;;;;;;43386:4;43391:2;43386:8;;;;;;;;;;;;;43396:4;43401:2;43396:8;;;;;;;;;;;;;;;;;43385:43;;;;;43361:721;;;44070:2;44063:9;;;;;43361:721;43209:880;;35947:201;36003:6;36029:5;;;36050:6;;;;;;:16;;;36065:1;36060;:6;;36050:16;36049:38;;;;36076:1;36072;:5;:14;;;;;36085:1;36081;:5;36072:14;36041:84;;;;-1:-1:-1;;;36041:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1989:119;2039:4;2060:1;2056;:5;2052:36;;;-1:-1:-1;2079:1:0;2072:8;;2052:36;-1:-1:-1;2101:1:0;1989:119;-1:-1:-1;1989:119:0:o;1826:157::-;1918:7;;1932:19;1918:3;1942:8;1932:4;:19::i;:::-;;1958;1965:3;1970:6;1958;:19::i;:::-;;1826:157;;;:::o;48654:10848::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;48654:10848:0;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;48654:10848:0;-1:-1:-1;;;;;48654:10848:0;;;;;;;;;;;-1:-1:-1;48654:10848:0;;;;;;;-1:-1:-1;48654:10848:0;;;-1:-1:-1;48654:10848:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48654:10848:0;;;-1:-1:-1;48654:10848:0;:::i;:::-;;;;;;;;;-1:-1:-1;48654:10848:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;48654:10848:0;;;;;;
Swarm Source
ipfs://52c68c49bb1b01c87cc7eee255d0e467ca8ef28b94c7d14b1463b01b5b55d926
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 25 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.