Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 330,694 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Fulfill | 14669063 | 17 mins ago | IN | 0 ETH | 0.00007742 | ||||
Fulfill | 14667832 | 1 hr ago | IN | 0 ETH | 0.00008846 | ||||
Fulfill | 14666990 | 1 hr ago | IN | 0 ETH | 0.00008844 | ||||
Fulfill | 14666347 | 1 hr ago | IN | 0 ETH | 0.00007737 | ||||
Fulfill | 14666344 | 1 hr ago | IN | 0 ETH | 0.00007744 | ||||
Fulfill | 14662469 | 4 hrs ago | IN | 0 ETH | 0.00008846 | ||||
Fulfill | 14662439 | 4 hrs ago | IN | 0 ETH | 0.00007744 | ||||
Fail | 14662408 | 4 hrs ago | IN | 0 ETH | 0.00002636 | ||||
Fulfill | 14662382 | 4 hrs ago | IN | 0 ETH | 0.00007739 | ||||
Fulfill | 14661973 | 4 hrs ago | IN | 0 ETH | 0.00007739 | ||||
Fulfill | 14661803 | 4 hrs ago | IN | 0 ETH | 0.00008841 | ||||
Fulfill | 14661743 | 4 hrs ago | IN | 0 ETH | 0.00007744 | ||||
Fulfill | 14660346 | 5 hrs ago | IN | 0 ETH | 0.00007742 | ||||
Fulfill | 14659217 | 6 hrs ago | IN | 0 ETH | 0.00007191 | ||||
Fulfill | 14658838 | 6 hrs ago | IN | 0 ETH | 0.00005083 | ||||
Fulfill | 14658516 | 6 hrs ago | IN | 0 ETH | 0.00005094 | ||||
Fulfill | 14658459 | 6 hrs ago | IN | 0 ETH | 0.00008909 | ||||
Fulfill | 14658136 | 6 hrs ago | IN | 0 ETH | 0.0000474 | ||||
Fulfill | 14657181 | 7 hrs ago | IN | 0 ETH | 0.00003549 | ||||
Fulfill | 14657154 | 7 hrs ago | IN | 0 ETH | 0.00003532 | ||||
Fulfill | 14657126 | 7 hrs ago | IN | 0 ETH | 0.00003517 | ||||
Fulfill | 14657097 | 7 hrs ago | IN | 0 ETH | 0.00003507 | ||||
Fulfill | 14657068 | 7 hrs ago | IN | 0 ETH | 0.00003481 | ||||
Fulfill | 14657037 | 7 hrs ago | IN | 0 ETH | 0.0000346 | ||||
Fulfill | 14657007 | 7 hrs ago | IN | 0 ETH | 0.0000343 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
14669063 | 17 mins ago | 0 ETH | ||||
14669063 | 17 mins ago | 0 ETH | ||||
14669029 | 18 mins ago | 0 ETH | ||||
14667832 | 1 hr ago | 0 ETH | ||||
14667832 | 1 hr ago | 0 ETH | ||||
14667809 | 1 hr ago | 0 ETH | ||||
14666990 | 1 hr ago | 0 ETH | ||||
14666990 | 1 hr ago | 0 ETH | ||||
14666959 | 1 hr ago | 0 ETH | ||||
14666347 | 1 hr ago | 0 ETH | ||||
14666347 | 1 hr ago | 0 ETH | ||||
14666344 | 1 hr ago | 0 ETH | ||||
14666344 | 1 hr ago | 0 ETH | ||||
14666326 | 1 hr ago | 0 ETH | ||||
14666325 | 1 hr ago | 0 ETH | ||||
14662469 | 4 hrs ago | 0 ETH | ||||
14662469 | 4 hrs ago | 0 ETH | ||||
14662447 | 4 hrs ago | 0 ETH | ||||
14662439 | 4 hrs ago | 0 ETH | ||||
14662439 | 4 hrs ago | 0 ETH | ||||
14662382 | 4 hrs ago | 0 ETH | ||||
14662382 | 4 hrs ago | 0 ETH | ||||
14662380 | 4 hrs ago | 0 ETH | ||||
14662367 | 4 hrs ago | 0 ETH | ||||
14662358 | 4 hrs ago | 0 ETH |
Loading...
Loading
Contract Name:
AirnodeRrpV0
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "./AuthorizationUtilsV0.sol"; import "./TemplateUtilsV0.sol"; import "./WithdrawalUtilsV0.sol"; import "./interfaces/IAirnodeRrpV0.sol"; /// @title Contract that implements the Airnode request–response protocol (RRP) contract AirnodeRrpV0 is AuthorizationUtilsV0, TemplateUtilsV0, WithdrawalUtilsV0, IAirnodeRrpV0 { using ECDSA for bytes32; /// @notice Called to get the sponsorship status for a sponsor–requester /// pair mapping(address => mapping(address => bool)) public override sponsorToRequesterToSponsorshipStatus; /// @notice Called to get the request count of the requester plus one /// @dev Can be used to calculate the ID of the next request the requester /// will make mapping(address => uint256) public override requesterToRequestCountPlusOne; /// @dev Hash of expected fulfillment parameters are kept to verify that /// the fulfillment will be done with the correct parameters. This value is /// also used to check if the fulfillment for the particular request is /// expected, i.e., if there are recorded fulfillment parameters. mapping(bytes32 => bytes32) private requestIdToFulfillmentParameters; /// @notice Called by the sponsor to set the sponsorship status of a /// requester, i.e., allow or disallow a requester to make requests that /// will be fulfilled by the sponsor wallet /// @dev This is not Airnode-specific, i.e., the sponsor allows the /// requester's requests to be fulfilled through its sponsor wallets across /// all Airnodes /// @param requester Requester address /// @param sponsorshipStatus Sponsorship status function setSponsorshipStatus(address requester, bool sponsorshipStatus) external override { // Initialize the requester request count for consistent request gas // cost if (requesterToRequestCountPlusOne[requester] == 0) { requesterToRequestCountPlusOne[requester] = 1; } sponsorToRequesterToSponsorshipStatus[msg.sender][ requester ] = sponsorshipStatus; emit SetSponsorshipStatus(msg.sender, requester, sponsorshipStatus); } /// @notice Called by the requester to make a request that refers to a /// template for the Airnode address, endpoint ID and parameters /// @dev `fulfillAddress` is not allowed to be the address of this /// contract. This is not actually needed to protect users that use the /// protocol as intended, but it is done for good measure. /// @param templateId Template ID /// @param sponsor Sponsor address /// @param sponsorWallet Sponsor wallet that is requested to fulfill the /// request /// @param fulfillAddress Address that will be called to fulfill /// @param fulfillFunctionId Signature of the function that will be called /// to fulfill /// @param parameters Parameters provided by the requester in addition to /// the parameters in the template /// @return requestId Request ID function makeTemplateRequest( bytes32 templateId, address sponsor, address sponsorWallet, address fulfillAddress, bytes4 fulfillFunctionId, bytes calldata parameters ) external override returns (bytes32 requestId) { address airnode = templates[templateId].airnode; // If the Airnode address of the template is zero the template does not // exist because template creation does not allow zero Airnode address require(airnode != address(0), "Template does not exist"); require(fulfillAddress != address(this), "Fulfill address AirnodeRrp"); require( sponsorToRequesterToSponsorshipStatus[sponsor][msg.sender], "Requester not sponsored" ); uint256 requesterRequestCount = requesterToRequestCountPlusOne[ msg.sender ]; requestId = keccak256( abi.encodePacked( block.chainid, address(this), msg.sender, requesterRequestCount, templateId, sponsor, sponsorWallet, fulfillAddress, fulfillFunctionId, parameters ) ); requestIdToFulfillmentParameters[requestId] = keccak256( abi.encodePacked( airnode, sponsorWallet, fulfillAddress, fulfillFunctionId ) ); requesterToRequestCountPlusOne[msg.sender]++; emit MadeTemplateRequest( airnode, requestId, requesterRequestCount, block.chainid, msg.sender, templateId, sponsor, sponsorWallet, fulfillAddress, fulfillFunctionId, parameters ); } /// @notice Called by the requester to make a full request, which provides /// all of its parameters as arguments and does not refer to a template /// @dev `fulfillAddress` is not allowed to be the address of this /// contract. This is not actually needed to protect users that use the /// protocol as intended, but it is done for good measure. /// @param airnode Airnode address /// @param endpointId Endpoint ID (allowed to be `bytes32(0)`) /// @param sponsor Sponsor address /// @param sponsorWallet Sponsor wallet that is requested to fulfill /// the request /// @param fulfillAddress Address that will be called to fulfill /// @param fulfillFunctionId Signature of the function that will be called /// to fulfill /// @param parameters All request parameters /// @return requestId Request ID function makeFullRequest( address airnode, bytes32 endpointId, address sponsor, address sponsorWallet, address fulfillAddress, bytes4 fulfillFunctionId, bytes calldata parameters ) external override returns (bytes32 requestId) { require(airnode != address(0), "Airnode address zero"); require(fulfillAddress != address(this), "Fulfill address AirnodeRrp"); require( sponsorToRequesterToSponsorshipStatus[sponsor][msg.sender], "Requester not sponsored" ); uint256 requesterRequestCount = requesterToRequestCountPlusOne[ msg.sender ]; requestId = keccak256( abi.encodePacked( block.chainid, address(this), msg.sender, requesterRequestCount, airnode, endpointId, sponsor, sponsorWallet, fulfillAddress, fulfillFunctionId, parameters ) ); requestIdToFulfillmentParameters[requestId] = keccak256( abi.encodePacked( airnode, sponsorWallet, fulfillAddress, fulfillFunctionId ) ); requesterToRequestCountPlusOne[msg.sender]++; emit MadeFullRequest( airnode, requestId, requesterRequestCount, block.chainid, msg.sender, endpointId, sponsor, sponsorWallet, fulfillAddress, fulfillFunctionId, parameters ); } /// @notice Called by Airnode to fulfill the request (template or full) /// @dev The data is ABI-encoded as a `bytes` type, with its format /// depending on the request specifications. /// This will not revert depending on the external call. However, it will /// return `false` if the external call reverts or if there is no function /// with a matching signature at `fulfillAddress`. On the other hand, it /// will return `true` if the external call returns successfully or if /// there is no contract deployed at `fulfillAddress`. /// If `callSuccess` is `false`, `callData` can be decoded to retrieve the /// revert string. /// This function emits its event after an untrusted low-level call, /// meaning that the order of these events within the transaction should /// not be taken seriously, yet the content will be sound. /// @param requestId Request ID /// @param airnode Airnode address /// @param data Fulfillment data /// @param fulfillAddress Address that will be called to fulfill /// @param fulfillFunctionId Signature of the function that will be called /// to fulfill /// @return callSuccess If the fulfillment call succeeded /// @return callData Data returned by the fulfillment call (if there is /// any) function fulfill( bytes32 requestId, address airnode, address fulfillAddress, bytes4 fulfillFunctionId, bytes calldata data, bytes calldata signature ) external override returns (bool callSuccess, bytes memory callData) { require( keccak256( abi.encodePacked( airnode, msg.sender, fulfillAddress, fulfillFunctionId ) ) == requestIdToFulfillmentParameters[requestId], "Invalid request fulfillment" ); require( ( keccak256(abi.encodePacked(requestId, data)) .toEthSignedMessageHash() ).recover(signature) == airnode, "Invalid signature" ); delete requestIdToFulfillmentParameters[requestId]; (callSuccess, callData) = fulfillAddress.call( // solhint-disable-line avoid-low-level-calls abi.encodeWithSelector(fulfillFunctionId, requestId, data) ); if (callSuccess) { emit FulfilledRequest(airnode, requestId, data); } else { // We do not bubble up the revert string from `callData` emit FailedRequest( airnode, requestId, "Fulfillment failed unexpectedly" ); } } /// @notice Called by Airnode if the request cannot be fulfilled /// @dev Airnode should fall back to this if a request cannot be fulfilled /// because static call to `fulfill()` returns `false` for `callSuccess` /// @param requestId Request ID /// @param airnode Airnode address /// @param fulfillAddress Address that will be called to fulfill /// @param fulfillFunctionId Signature of the function that will be called /// to fulfill /// @param errorMessage A message that explains why the request has failed function fail( bytes32 requestId, address airnode, address fulfillAddress, bytes4 fulfillFunctionId, string calldata errorMessage ) external override { require( keccak256( abi.encodePacked( airnode, msg.sender, fulfillAddress, fulfillFunctionId ) ) == requestIdToFulfillmentParameters[requestId], "Invalid request fulfillment" ); delete requestIdToFulfillmentParameters[requestId]; emit FailedRequest(airnode, requestId, errorMessage); } /// @notice Called to check if the request with the ID is made but not /// fulfilled/failed yet /// @dev If a requester has made a request, received a request ID but did /// not hear back, it can call this method to check if the Airnode has /// called back `fail()` instead. /// @param requestId Request ID /// @return isAwaitingFulfillment If the request is awaiting fulfillment /// (i.e., `true` if `fulfill()` or `fail()` is not called back yet, /// `false` otherwise) function requestIsAwaitingFulfillment(bytes32 requestId) external view override returns (bool isAwaitingFulfillment) { isAwaitingFulfillment = requestIdToFulfillmentParameters[requestId] != bytes32(0); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IAuthorizerV0 { function isAuthorizedV0( bytes32 requestId, address airnode, bytes32 endpointId, address sponsor, address requester ) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interfaces/IAuthorizationUtilsV0.sol"; import "../authorizers/interfaces/IAuthorizerV0.sol"; /// @title Contract that implements authorization checks contract AuthorizationUtilsV0 is IAuthorizationUtilsV0 { /// @notice Uses the authorizer contracts of an Airnode to decide if a /// request is authorized. Once an Airnode receives a request, it calls /// this method to determine if it should respond. Similarly, third parties /// can use this method to determine if a particular request would be /// authorized. /// @dev This method is meant to be called off-chain, statically by the /// Airnode to decide if it should respond to a request. The requester can /// also call it, yet this function returning true should not be taken as a /// guarantee of the subsequent request being fulfilled. /// It is enough for only one of the authorizer contracts to return true /// for the request to be authorized. /// @param authorizers Authorizer contract addresses /// @param airnode Airnode address /// @param requestId Request ID /// @param endpointId Endpoint ID /// @param sponsor Sponsor address /// @param requester Requester address /// @return status Authorization status of the request function checkAuthorizationStatus( address[] calldata authorizers, address airnode, bytes32 requestId, bytes32 endpointId, address sponsor, address requester ) public view override returns (bool status) { for (uint256 ind = 0; ind < authorizers.length; ind++) { IAuthorizerV0 authorizer = IAuthorizerV0(authorizers[ind]); if ( authorizer.isAuthorizedV0( requestId, airnode, endpointId, sponsor, requester ) ) { return true; } } return false; } /// @notice A convenience function to make multiple authorization status /// checks with a single call /// @param authorizers Authorizer contract addresses /// @param airnode Airnode address /// @param requestIds Request IDs /// @param endpointIds Endpoint IDs /// @param sponsors Sponsor addresses /// @param requesters Requester addresses /// @return statuses Authorization statuses of the request function checkAuthorizationStatuses( address[] calldata authorizers, address airnode, bytes32[] calldata requestIds, bytes32[] calldata endpointIds, address[] calldata sponsors, address[] calldata requesters ) external view override returns (bool[] memory statuses) { require( requestIds.length == endpointIds.length && requestIds.length == sponsors.length && requestIds.length == requesters.length, "Unequal parameter lengths" ); statuses = new bool[](requestIds.length); for (uint256 ind = 0; ind < requestIds.length; ind++) { statuses[ind] = checkAuthorizationStatus( authorizers, airnode, requestIds[ind], endpointIds[ind], sponsors[ind], requesters[ind] ); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IAuthorizationUtilsV0.sol"; import "./ITemplateUtilsV0.sol"; import "./IWithdrawalUtilsV0.sol"; interface IAirnodeRrpV0 is IAuthorizationUtilsV0, ITemplateUtilsV0, IWithdrawalUtilsV0 { event SetSponsorshipStatus( address indexed sponsor, address indexed requester, bool sponsorshipStatus ); event MadeTemplateRequest( address indexed airnode, bytes32 indexed requestId, uint256 requesterRequestCount, uint256 chainId, address requester, bytes32 templateId, address sponsor, address sponsorWallet, address fulfillAddress, bytes4 fulfillFunctionId, bytes parameters ); event MadeFullRequest( address indexed airnode, bytes32 indexed requestId, uint256 requesterRequestCount, uint256 chainId, address requester, bytes32 endpointId, address sponsor, address sponsorWallet, address fulfillAddress, bytes4 fulfillFunctionId, bytes parameters ); event FulfilledRequest( address indexed airnode, bytes32 indexed requestId, bytes data ); event FailedRequest( address indexed airnode, bytes32 indexed requestId, string errorMessage ); function setSponsorshipStatus(address requester, bool sponsorshipStatus) external; function makeTemplateRequest( bytes32 templateId, address sponsor, address sponsorWallet, address fulfillAddress, bytes4 fulfillFunctionId, bytes calldata parameters ) external returns (bytes32 requestId); function makeFullRequest( address airnode, bytes32 endpointId, address sponsor, address sponsorWallet, address fulfillAddress, bytes4 fulfillFunctionId, bytes calldata parameters ) external returns (bytes32 requestId); function fulfill( bytes32 requestId, address airnode, address fulfillAddress, bytes4 fulfillFunctionId, bytes calldata data, bytes calldata signature ) external returns (bool callSuccess, bytes memory callData); function fail( bytes32 requestId, address airnode, address fulfillAddress, bytes4 fulfillFunctionId, string calldata errorMessage ) external; function sponsorToRequesterToSponsorshipStatus( address sponsor, address requester ) external view returns (bool sponsorshipStatus); function requesterToRequestCountPlusOne(address requester) external view returns (uint256 requestCountPlusOne); function requestIsAwaitingFulfillment(bytes32 requestId) external view returns (bool isAwaitingFulfillment); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IAuthorizationUtilsV0 { function checkAuthorizationStatus( address[] calldata authorizers, address airnode, bytes32 requestId, bytes32 endpointId, address sponsor, address requester ) external view returns (bool status); function checkAuthorizationStatuses( address[] calldata authorizers, address airnode, bytes32[] calldata requestIds, bytes32[] calldata endpointIds, address[] calldata sponsors, address[] calldata requesters ) external view returns (bool[] memory statuses); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ITemplateUtilsV0 { event CreatedTemplate( bytes32 indexed templateId, address airnode, bytes32 endpointId, bytes parameters ); function createTemplate( address airnode, bytes32 endpointId, bytes calldata parameters ) external returns (bytes32 templateId); function getTemplates(bytes32[] calldata templateIds) external view returns ( address[] memory airnodes, bytes32[] memory endpointIds, bytes[] memory parameters ); function templates(bytes32 templateId) external view returns ( address airnode, bytes32 endpointId, bytes memory parameters ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IWithdrawalUtilsV0 { event RequestedWithdrawal( address indexed airnode, address indexed sponsor, bytes32 indexed withdrawalRequestId, address sponsorWallet ); event FulfilledWithdrawal( address indexed airnode, address indexed sponsor, bytes32 indexed withdrawalRequestId, address sponsorWallet, uint256 amount ); function requestWithdrawal(address airnode, address sponsorWallet) external; function fulfillWithdrawal( bytes32 withdrawalRequestId, address airnode, address sponsor ) external payable; function sponsorToWithdrawalRequestCount(address sponsor) external view returns (uint256 withdrawalRequestCount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interfaces/ITemplateUtilsV0.sol"; /// @title Contract that implements request templates contract TemplateUtilsV0 is ITemplateUtilsV0 { struct Template { address airnode; bytes32 endpointId; bytes parameters; } /// @notice Called to get a template mapping(bytes32 => Template) public override templates; /// @notice Creates a request template with the given parameters, /// addressable by the ID it returns /// @dev A specific set of request parameters will always have the same /// template ID. This means a few things: (1) You can compute the expected /// ID of a template before creating it, (2) Creating a new template with /// the same parameters will overwrite the old one and return the same ID, /// (3) After you query a template with its ID, you can verify its /// integrity by applying the hash and comparing the result with the ID. /// @param airnode Airnode address /// @param endpointId Endpoint ID (allowed to be `bytes32(0)`) /// @param parameters Static request parameters (i.e., parameters that will /// not change between requests, unlike the dynamic parameters determined /// at request-time) /// @return templateId Request template ID function createTemplate( address airnode, bytes32 endpointId, bytes calldata parameters ) external override returns (bytes32 templateId) { require(airnode != address(0), "Airnode address zero"); templateId = keccak256( abi.encodePacked(airnode, endpointId, parameters) ); templates[templateId] = Template({ airnode: airnode, endpointId: endpointId, parameters: parameters }); emit CreatedTemplate(templateId, airnode, endpointId, parameters); } /// @notice A convenience method to retrieve multiple templates with a /// single call /// @dev Does not revert if the templates being indexed do not exist /// @param templateIds Request template IDs /// @return airnodes Array of Airnode addresses /// @return endpointIds Array of endpoint IDs /// @return parameters Array of request parameters function getTemplates(bytes32[] calldata templateIds) external view override returns ( address[] memory airnodes, bytes32[] memory endpointIds, bytes[] memory parameters ) { airnodes = new address[](templateIds.length); endpointIds = new bytes32[](templateIds.length); parameters = new bytes[](templateIds.length); for (uint256 ind = 0; ind < templateIds.length; ind++) { Template storage template = templates[templateIds[ind]]; airnodes[ind] = template.airnode; endpointIds[ind] = template.endpointId; parameters[ind] = template.parameters; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interfaces/IWithdrawalUtilsV0.sol"; /// @title Contract that implements logic for withdrawals from sponsor wallets contract WithdrawalUtilsV0 is IWithdrawalUtilsV0 { /// @notice Called to get the withdrawal request count of the sponsor /// @dev Can be used to calculate the ID of the next withdrawal request the /// sponsor will make mapping(address => uint256) public override sponsorToWithdrawalRequestCount; /// @dev Hash of expected fulfillment parameters are kept to verify that /// the fulfillment will be done with the correct parameters mapping(bytes32 => bytes32) private withdrawalRequestIdToParameters; /// @notice Called by a sponsor to create a request for the Airnode to send /// the funds kept in the respective sponsor wallet to the sponsor /// @dev We do not need to use the withdrawal request parameters in the /// request ID hash to validate them at the node-side because all of the /// parameters are used during fulfillment and will get validated on-chain. /// The first withdrawal request a sponsor will make will cost slightly /// higher gas than the rest due to how the request counter is implemented. /// @param airnode Airnode address /// @param sponsorWallet Sponsor wallet that the withdrawal is requested /// from function requestWithdrawal(address airnode, address sponsorWallet) external override { bytes32 withdrawalRequestId = keccak256( abi.encodePacked( block.chainid, address(this), msg.sender, ++sponsorToWithdrawalRequestCount[msg.sender] ) ); withdrawalRequestIdToParameters[withdrawalRequestId] = keccak256( abi.encodePacked(airnode, msg.sender, sponsorWallet) ); emit RequestedWithdrawal( airnode, msg.sender, withdrawalRequestId, sponsorWallet ); } /// @notice Called by the Airnode using the sponsor wallet to fulfill the /// withdrawal request made by the sponsor /// @dev The Airnode sends the funds to the sponsor through this method /// to emit an event that indicates that the withdrawal request has been /// fulfilled /// @param withdrawalRequestId Withdrawal request ID /// @param airnode Airnode address /// @param sponsor Sponsor address function fulfillWithdrawal( bytes32 withdrawalRequestId, address airnode, address sponsor ) external payable override { require( withdrawalRequestIdToParameters[withdrawalRequestId] == keccak256(abi.encodePacked(airnode, sponsor, msg.sender)), "Invalid withdrawal fulfillment" ); delete withdrawalRequestIdToParameters[withdrawalRequestId]; emit FulfilledWithdrawal( airnode, sponsor, withdrawalRequestId, msg.sender, msg.value ); (bool success, ) = sponsor.call{value: msg.value}(""); // solhint-disable-line avoid-low-level-calls require(success, "Transfer failed"); } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"templateId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"airnode","type":"address"},{"indexed":false,"internalType":"bytes32","name":"endpointId","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"parameters","type":"bytes"}],"name":"CreatedTemplate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"airnode","type":"address"},{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"errorMessage","type":"string"}],"name":"FailedRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"airnode","type":"address"},{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"FulfilledRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"airnode","type":"address"},{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":true,"internalType":"bytes32","name":"withdrawalRequestId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"sponsorWallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FulfilledWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"airnode","type":"address"},{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"requesterRequestCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"bytes32","name":"endpointId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"sponsor","type":"address"},{"indexed":false,"internalType":"address","name":"sponsorWallet","type":"address"},{"indexed":false,"internalType":"address","name":"fulfillAddress","type":"address"},{"indexed":false,"internalType":"bytes4","name":"fulfillFunctionId","type":"bytes4"},{"indexed":false,"internalType":"bytes","name":"parameters","type":"bytes"}],"name":"MadeFullRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"airnode","type":"address"},{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"requesterRequestCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"bytes32","name":"templateId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"sponsor","type":"address"},{"indexed":false,"internalType":"address","name":"sponsorWallet","type":"address"},{"indexed":false,"internalType":"address","name":"fulfillAddress","type":"address"},{"indexed":false,"internalType":"bytes4","name":"fulfillFunctionId","type":"bytes4"},{"indexed":false,"internalType":"bytes","name":"parameters","type":"bytes"}],"name":"MadeTemplateRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"airnode","type":"address"},{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":true,"internalType":"bytes32","name":"withdrawalRequestId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"sponsorWallet","type":"address"}],"name":"RequestedWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"bool","name":"sponsorshipStatus","type":"bool"}],"name":"SetSponsorshipStatus","type":"event"},{"inputs":[{"internalType":"address[]","name":"authorizers","type":"address[]"},{"internalType":"address","name":"airnode","type":"address"},{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"bytes32","name":"endpointId","type":"bytes32"},{"internalType":"address","name":"sponsor","type":"address"},{"internalType":"address","name":"requester","type":"address"}],"name":"checkAuthorizationStatus","outputs":[{"internalType":"bool","name":"status","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"authorizers","type":"address[]"},{"internalType":"address","name":"airnode","type":"address"},{"internalType":"bytes32[]","name":"requestIds","type":"bytes32[]"},{"internalType":"bytes32[]","name":"endpointIds","type":"bytes32[]"},{"internalType":"address[]","name":"sponsors","type":"address[]"},{"internalType":"address[]","name":"requesters","type":"address[]"}],"name":"checkAuthorizationStatuses","outputs":[{"internalType":"bool[]","name":"statuses","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"airnode","type":"address"},{"internalType":"bytes32","name":"endpointId","type":"bytes32"},{"internalType":"bytes","name":"parameters","type":"bytes"}],"name":"createTemplate","outputs":[{"internalType":"bytes32","name":"templateId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"address","name":"airnode","type":"address"},{"internalType":"address","name":"fulfillAddress","type":"address"},{"internalType":"bytes4","name":"fulfillFunctionId","type":"bytes4"},{"internalType":"string","name":"errorMessage","type":"string"}],"name":"fail","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"address","name":"airnode","type":"address"},{"internalType":"address","name":"fulfillAddress","type":"address"},{"internalType":"bytes4","name":"fulfillFunctionId","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"fulfill","outputs":[{"internalType":"bool","name":"callSuccess","type":"bool"},{"internalType":"bytes","name":"callData","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"withdrawalRequestId","type":"bytes32"},{"internalType":"address","name":"airnode","type":"address"},{"internalType":"address","name":"sponsor","type":"address"}],"name":"fulfillWithdrawal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"templateIds","type":"bytes32[]"}],"name":"getTemplates","outputs":[{"internalType":"address[]","name":"airnodes","type":"address[]"},{"internalType":"bytes32[]","name":"endpointIds","type":"bytes32[]"},{"internalType":"bytes[]","name":"parameters","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"airnode","type":"address"},{"internalType":"bytes32","name":"endpointId","type":"bytes32"},{"internalType":"address","name":"sponsor","type":"address"},{"internalType":"address","name":"sponsorWallet","type":"address"},{"internalType":"address","name":"fulfillAddress","type":"address"},{"internalType":"bytes4","name":"fulfillFunctionId","type":"bytes4"},{"internalType":"bytes","name":"parameters","type":"bytes"}],"name":"makeFullRequest","outputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"templateId","type":"bytes32"},{"internalType":"address","name":"sponsor","type":"address"},{"internalType":"address","name":"sponsorWallet","type":"address"},{"internalType":"address","name":"fulfillAddress","type":"address"},{"internalType":"bytes4","name":"fulfillFunctionId","type":"bytes4"},{"internalType":"bytes","name":"parameters","type":"bytes"}],"name":"makeTemplateRequest","outputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"requestIsAwaitingFulfillment","outputs":[{"internalType":"bool","name":"isAwaitingFulfillment","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"airnode","type":"address"},{"internalType":"address","name":"sponsorWallet","type":"address"}],"name":"requestWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"requesterToRequestCountPlusOne","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"requester","type":"address"},{"internalType":"bool","name":"sponsorshipStatus","type":"bool"}],"name":"setSponsorshipStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"sponsorToRequesterToSponsorshipStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"sponsorToWithdrawalRequestCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"templates","outputs":[{"internalType":"address","name":"airnode","type":"address"},{"internalType":"bytes32","name":"endpointId","type":"bytes32"},{"internalType":"bytes","name":"parameters","type":"bytes"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061274d806100206000396000f3fe6080604052600436106100f35760003560e01c806376428c9b1161008a578063acbe180011610059578063acbe1800146102f7578063addf027c14610317578063ca31d58614610337578063f8fa73a11461036457600080fd5b806376428c9b146102405780637e7166f31461026f5780638a33be011461029c578063a81e9f79146102bc57600080fd5b80633c7fe5e3116100c65780633c7fe5e3146101ae57806350743bb9146101c157806352e41f99146102005780636e6be03f1461022057600080fd5b80630a631576146100f85780631d414cbd146101305780631decbf181461015257806332393f2b14610180575b600080fd5b34801561010457600080fd5b50610118610113366004611bd0565b610391565b60405161012793929190611c41565b60405180910390f35b34801561013c57600080fd5b5061015061014b366004611c8e565b610446565b005b34801561015e57600080fd5b5061017261016d366004611d1b565b610566565b604051610127929190611dc6565b34801561018c57600080fd5b506101a061019b366004611de9565b6108d8565b604051908152602001610127565b6101506101bc366004611e43565b610a68565b3480156101cd57600080fd5b506101f06101dc366004611bd0565b600090815260056020526040902054151590565b6040519015158152602001610127565b34801561020c57600080fd5b5061015061021b366004611e7f565b610c15565b34801561022c57600080fd5b506101a061023b366004611efe565b610d30565b34801561024c57600080fd5b5061026061025b366004611fcf565b610fa4565b60405161012793929190612069565b34801561027b57600080fd5b506101a061028a366004612100565b60046020526000908152604090205481565b3480156102a857600080fd5b506101f06102b7366004612122565b6111ed565b3480156102c857600080fd5b506101f06102d7366004611c8e565b600360209081526000928352604080842090915290825290205460ff1681565b34801561030357600080fd5b506101a06103123660046121ab565b61130a565b34801561032357600080fd5b50610150610332366004612249565b611589565b34801561034357600080fd5b50610357610352366004612280565b61162f565b6040516101279190612384565b34801561037057600080fd5b506101a061037f366004612100565b60016020526000908152604090205481565b6000602081905290815260409020805460018201546002830180546001600160a01b039093169391926103c3906123ca565b80601f01602080910402602001604051908101604052809291908181526020018280546103ef906123ca565b801561043c5780601f106104115761010080835404028352916020019161043c565b820191906000526020600020905b81548152906001019060200180831161041f57829003601f168201915b5050505050905083565b336000818152600160205260408120805491924692309290859061046990612405565b91829055506040805160208101959095526bffffffffffffffffffffffff19606094851b8116918601919091529190921b166054830152606882015260880160408051601f198184030181529082905280516020918201206bffffffffffffffffffffffff19606087811b82169385019390935233831b811660348501529185901b90911660488301529150605c0160408051808303601f19018152828252805160209182012060008581526002835292909220919091556001600160a01b03848116835283923392918716917fd48d52c7c6d0c940f3f8d07591e1800ef3a70daf79929a97ccd80b4494769fc7910160405180910390a4505050565b60008881526005602090815260408083205490516bffffffffffffffffffffffff1960608c811b82169483019490945233841b811660348301528a841b1660488201526001600160e01b03198916605c820152820160405160208183030381529060405280519060200120146106235760405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420726571756573742066756c66696c6c6d656e74000000000060448201526064015b60405180910390fd5b886001600160a01b03166106e585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040516106df925061067f91508f908c908c9060200161243d565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b906117b0565b6001600160a01b03161461073b5760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e6174757265000000000000000000000000000000604482015260640161061a565b60008a81526005602052604080822091909155516001600160a01b03891690889061076e908d908a908a90602401612480565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b03199094169390931790925290516107c1919061249a565b6000604051808303816000865af19150503d80600081146107fe576040519150601f19603f3d011682016040523d82523d6000602084013e610803565b606091505b50909250905081156108585789896001600160a01b03167fc0977dab79883641ece94bb6a932ca83049f561ffff8d8daaeafdbc1acce9e0a888860405161084b9291906124b6565b60405180910390a36108cb565b89896001600160a01b03167fc7143b2270cddda57e0087ca5e2a4325657dcab10d10f6b1f9d5ce6b41cb97fc6040516108c2906020808252601f908201527f46756c66696c6c6d656e74206661696c656420756e65787065637465646c7900604082015260600190565b60405180910390a35b9850989650505050505050565b60006001600160a01b0385166109305760405162461bcd60e51b815260206004820152601460248201527f4169726e6f64652061646472657373207a65726f000000000000000000000000604482015260640161061a565b8484848460405160200161094794939291906124ca565b6040516020818303038152906040528051906020012090506040518060600160405280866001600160a01b0316815260200185815260200184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250508381526020818152604091829020845181547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178155848201516001820155918401518051929350610a1e9260028501929190910190611b37565b50905050807fba204bad31c4ec4b9b54164af94ae10c4e7312f22c0f9c065d6319c928ec9e7a86868686604051610a5894939291906124fd565b60405180910390a2949350505050565b6040516bffffffffffffffffffffffff19606084811b8216602084015283811b8216603484015233901b166048820152605c0160408051601f1981840301815291815281516020928301206000868152600290935291205414610b0d5760405162461bcd60e51b815260206004820152601e60248201527f496e76616c6964207769746864726177616c2066756c66696c6c6d656e740000604482015260640161061a565b6000838152600260209081526040808320929092558151338152349181019190915284916001600160a01b0380851692908616917fadb4840bbd5f924665ae7e0e0c83de5c0fb40a98c9b57dba53a6c978127a622e910160405180910390a46000816001600160a01b03163460405160006040518083038185875af1925050503d8060008114610bb9576040519150601f19603f3d011682016040523d82523d6000602084013e610bbe565b606091505b5050905080610c0f5760405162461bcd60e51b815260206004820152600f60248201527f5472616e73666572206661696c65640000000000000000000000000000000000604482015260640161061a565b50505050565b6000868152600560209081526040918290205491516bffffffffffffffffffffffff19606089811b82169383019390935233831b8116603483015287831b1660488201526001600160e01b03198616605c820152016040516020818303038152906040528051906020012014610ccd5760405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420726571756573742066756c66696c6c6d656e740000000000604482015260640161061a565b600560008781526020019081526020016000206000905585856001600160a01b03167fc7143b2270cddda57e0087ca5e2a4325657dcab10d10f6b1f9d5ce6b41cb97fc8484604051610d209291906124b6565b60405180910390a3505050505050565b60006001600160a01b038916610d885760405162461bcd60e51b815260206004820152601460248201527f4169726e6f64652061646472657373207a65726f000000000000000000000000604482015260640161061a565b6001600160a01b038516301415610de15760405162461bcd60e51b815260206004820152601a60248201527f46756c66696c6c2061646472657373204169726e6f6465527270000000000000604482015260640161061a565b6001600160a01b038716600090815260036020908152604080832033845290915290205460ff16610e545760405162461bcd60e51b815260206004820152601760248201527f526571756573746572206e6f742073706f6e736f726564000000000000000000604482015260640161061a565b600060046000336001600160a01b03166001600160a01b03168152602001908152602001600020549050463033838d8d8d8d8d8d8d8d604051602001610ea59c9b9a99989796959493929190612530565b60408051601f198184030181529082905280516020918201206bffffffffffffffffffffffff1960608e811b8216938501939093528a831b8116603485015289831b1660488401526001600160e01b03198816605c84015293500160408051601f1981840301815291815281516020928301206000858152600584528281209190915533815260049092528120805491610f3e83612405565b9190505550818a6001600160a01b03167f3a52c462346de2e9436a3868970892956828a11b9c43da1ed43740b12e1125ae8346338e8e8e8e8e8e8e604051610f8f9a999897969594939291906125bf565b60405180910390a35098975050505050505050565b606080808367ffffffffffffffff811115610fc157610fc1612631565b604051908082528060200260200182016040528015610fea578160200160208202803683370190505b5092508367ffffffffffffffff81111561100657611006612631565b60405190808252806020026020018201604052801561102f578160200160208202803683370190505b5091508367ffffffffffffffff81111561104b5761104b612631565b60405190808252806020026020018201604052801561107e57816020015b60608152602001906001900390816110695790505b50905060005b848110156111e55760008060008888858181106110a3576110a3612647565b90506020020135815260200190815260200160002090508060000160009054906101000a90046001600160a01b03168583815181106110e4576110e4612647565b60200260200101906001600160a01b031690816001600160a01b031681525050806001015484838151811061111b5761111b612647565b602002602001018181525050806002018054611136906123ca565b80601f0160208091040260200160405190810160405280929190818152602001828054611162906123ca565b80156111af5780601f10611184576101008083540402835291602001916111af565b820191906000526020600020905b81548152906001019060200180831161119257829003601f168201915b50505050508383815181106111c6576111c6612647565b60200260200101819052505080806111dd90612405565b915050611084565b509250925092565b6000805b878110156112f957600089898381811061120d5761120d612647565b90506020020160208101906112229190612100565b6040517f29b915b3000000000000000000000000000000000000000000000000000000008152600481018990526001600160a01b038a811660248301526044820189905287811660648301528681166084830152919250908216906329b915b39060a40160206040518083038186803b15801561129e57600080fd5b505afa1580156112b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d6919061265d565b156112e6576001925050506112ff565b50806112f181612405565b9150506111f1565b50600090505b979650505050505050565b6000878152602081905260408120546001600160a01b03168061136f5760405162461bcd60e51b815260206004820152601760248201527f54656d706c61746520646f6573206e6f74206578697374000000000000000000604482015260640161061a565b6001600160a01b0386163014156113c85760405162461bcd60e51b815260206004820152601a60248201527f46756c66696c6c2061646472657373204169726e6f6465527270000000000000604482015260640161061a565b6001600160a01b038816600090815260036020908152604080832033845290915290205460ff1661143b5760405162461bcd60e51b815260206004820152601760248201527f526571756573746572206e6f742073706f6e736f726564000000000000000000604482015260640161061a565b600060046000336001600160a01b03166001600160a01b03168152602001908152602001600020549050463033838d8d8d8d8d8d8d60405160200161148a9b9a9998979695949392919061267a565b60408051601f198184030181529082905280516020918201206bffffffffffffffffffffffff19606086811b8216938501939093528b831b811660348501528a831b1660488401526001600160e01b03198916605c84015294500160408051601f198184030181529181528151602092830120600086815260058452828120919091553381526004909252812080549161152383612405565b919050555082826001600160a01b03167feb39930cdcbb560e6422558a2468b93a215af60063622e63cbb165eba14c32038346338f8f8f8f8f8f8f6040516115749a999897969594939291906125bf565b60405180910390a35050979650505050505050565b6001600160a01b0382166000908152600460205260409020546115c3576001600160a01b0382166000908152600460205260409020600190555b3360008181526003602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917fc2e532a12bbcce2bfa2ef9e4bee80180e4e1b1f78618f0d20bc49a648b577c56910160405180910390a35050565b6060878614801561163f57508784145b801561164a57508782145b6116965760405162461bcd60e51b815260206004820152601960248201527f556e657175616c20706172616d65746572206c656e6774687300000000000000604482015260640161061a565b8767ffffffffffffffff8111156116af576116af612631565b6040519080825280602002602001820160405280156116d8578160200160208202803683370190505b50905060005b888110156117a05761176c8d8d8d8d8d868181106116fe576116fe612647565b905060200201358c8c8781811061171757611717612647565b905060200201358b8b8881811061173057611730612647565b90506020020160208101906117459190612100565b8a8a8981811061175757611757612647565b90506020020160208101906102b79190612100565b82828151811061177e5761177e612647565b911515602092830291909101909101528061179881612405565b9150506116de565b509b9a5050505050505050505050565b60008060006117bf85856117d4565b915091506117cc81611844565b509392505050565b60008082516041141561180b5760208301516040840151606085015160001a6117ff87828585611a02565b9450945050505061183d565b825160401415611835576020830151604084015161182a868383611aef565b93509350505061183d565b506000905060025b9250929050565b600081600481111561185857611858612701565b14156118615750565b600181600481111561187557611875612701565b14156118c35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161061a565b60028160048111156118d7576118d7612701565b14156119255760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161061a565b600381600481111561193957611939612701565b14156119925760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161061a565b60048160048111156119a6576119a6612701565b14156119ff5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161061a565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611a395750600090506003611ae6565b8460ff16601b14158015611a5157508460ff16601c14155b15611a625750600090506004611ae6565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611ab6573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611adf57600060019250925050611ae6565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831660ff84901c601b01611b2987828885611a02565b935093505050935093915050565b828054611b43906123ca565b90600052602060002090601f016020900481019282611b655760008555611bab565b82601f10611b7e57805160ff1916838001178555611bab565b82800160010185558215611bab579182015b82811115611bab578251825591602001919060010190611b90565b50611bb7929150611bbb565b5090565b5b80821115611bb75760008155600101611bbc565b600060208284031215611be257600080fd5b5035919050565b60005b83811015611c04578181015183820152602001611bec565b83811115610c0f5750506000910152565b60008151808452611c2d816020860160208601611be9565b601f01601f19169290920160200192915050565b6001600160a01b0384168152826020820152606060408201526000611c696060830184611c15565b95945050505050565b80356001600160a01b0381168114611c8957600080fd5b919050565b60008060408385031215611ca157600080fd5b611caa83611c72565b9150611cb860208401611c72565b90509250929050565b80356001600160e01b031981168114611c8957600080fd5b60008083601f840112611ceb57600080fd5b50813567ffffffffffffffff811115611d0357600080fd5b60208301915083602082850101111561183d57600080fd5b60008060008060008060008060c0898b031215611d3757600080fd5b88359750611d4760208a01611c72565b9650611d5560408a01611c72565b9550611d6360608a01611cc1565b9450608089013567ffffffffffffffff80821115611d8057600080fd5b611d8c8c838d01611cd9565b909650945060a08b0135915080821115611da557600080fd5b50611db28b828c01611cd9565b999c989b5096995094979396929594505050565b8215158152604060208201526000611de16040830184611c15565b949350505050565b60008060008060608587031215611dff57600080fd5b611e0885611c72565b935060208501359250604085013567ffffffffffffffff811115611e2b57600080fd5b611e3787828801611cd9565b95989497509550505050565b600080600060608486031215611e5857600080fd5b83359250611e6860208501611c72565b9150611e7660408501611c72565b90509250925092565b60008060008060008060a08789031215611e9857600080fd5b86359550611ea860208801611c72565b9450611eb660408801611c72565b9350611ec460608801611cc1565b9250608087013567ffffffffffffffff811115611ee057600080fd5b611eec89828a01611cd9565b979a9699509497509295939492505050565b60008060008060008060008060e0898b031215611f1a57600080fd5b611f2389611c72565b975060208901359650611f3860408a01611c72565b9550611f4660608a01611c72565b9450611f5460808a01611c72565b9350611f6260a08a01611cc1565b925060c089013567ffffffffffffffff811115611f7e57600080fd5b611db28b828c01611cd9565b60008083601f840112611f9c57600080fd5b50813567ffffffffffffffff811115611fb457600080fd5b6020830191508360208260051b850101111561183d57600080fd5b60008060208385031215611fe257600080fd5b823567ffffffffffffffff811115611ff957600080fd5b61200585828601611f8a565b90969095509350505050565b600082825180855260208086019550808260051b84010181860160005b8481101561205c57601f1986840301895261204a838351611c15565b9884019892509083019060010161202e565b5090979650505050505050565b606080825284519082018190526000906020906080840190828801845b828110156120ab5781516001600160a01b031684529284019290840190600101612086565b5050508381038285015285518082528683019183019060005b818110156120e0578351835292840192918401916001016120c4565b505084810360408601526120f48187612011565b98975050505050505050565b60006020828403121561211257600080fd5b61211b82611c72565b9392505050565b600080600080600080600060c0888a03121561213d57600080fd5b873567ffffffffffffffff81111561215457600080fd5b6121608a828b01611f8a565b9098509650612173905060208901611c72565b9450604088013593506060880135925061218f60808901611c72565b915061219d60a08901611c72565b905092959891949750929550565b600080600080600080600060c0888a0312156121c657600080fd5b873596506121d660208901611c72565b95506121e460408901611c72565b94506121f260608901611c72565b935061220060808901611cc1565b925060a088013567ffffffffffffffff81111561221c57600080fd5b6122288a828b01611cd9565b989b979a50959850939692959293505050565b80151581146119ff57600080fd5b6000806040838503121561225c57600080fd5b61226583611c72565b915060208301356122758161223b565b809150509250929050565b600080600080600080600080600080600060c08c8e0312156122a157600080fd5b67ffffffffffffffff808d3511156122b857600080fd5b6122c58e8e358f01611f8a565b909c509a506122d660208e01611c72565b99508060408e013511156122e957600080fd5b6122f98e60408f01358f01611f8a565b909950975060608d013581101561230f57600080fd5b61231f8e60608f01358f01611f8a565b909750955060808d013581101561233557600080fd5b6123458e60808f01358f01611f8a565b909550935060a08d013581101561235b57600080fd5b5061236c8d60a08e01358e01611f8a565b81935080925050509295989b509295989b9093969950565b6020808252825182820181905260009190848201906040850190845b818110156123be5783511515835292840192918401916001016123a0565b50909695505050505050565b600181811c908216806123de57607f821691505b602082108114156123ff57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561242757634e487b7160e01b600052601160045260246000fd5b5060010190565b81818437506000910190815290565b838152818360208301376000910160200190815292915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b838152604060208201526000611c69604083018486612457565b600082516124ac818460208701611be9565b9190910192915050565b602081526000611de1602083018486612457565b6bffffffffffffffffffffffff198560601b16815283601482015281836034830137600091016034019081529392505050565b6001600160a01b0385168152836020820152606060408201526000612526606083018486612457565b9695505050505050565b8c815260006bffffffffffffffffffffffff196060818f821b166020850152818e821b1660348501528c6048850152818c821b1660688501528a607c850152818a821b16609c8501528189821b1660b08501528188821b1660c485015250506001600160e01b0319851660d88301526125ad60dc8301848661242e565b9e9d5050505050505050505050505050565b60006101208c83528b60208401526001600160a01b03808c1660408501528a6060850152808a16608085015280891660a085015280881660c0850152506001600160e01b0319861660e0840152806101008401526126208184018587612457565b9d9c50505050505050505050505050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561266f57600080fd5b815161211b8161223b565b8b815260006bffffffffffffffffffffffff19808d60601b166020840152808c60601b1660348401528a6048840152896068840152808960601b166088840152808860601b16609c840152808760601b1660b0840152506001600160e01b0319851660c4830152828460c8840137506000910160c8019081529a9950505050505050505050565b634e487b7160e01b600052602160045260246000fdfea26469706673582212208125c69072f5b73d89af7cc14fb8da75fc37036277de16e38207c96e9f01298764736f6c63430008090033
Deployed Bytecode
0x6080604052600436106100f35760003560e01c806376428c9b1161008a578063acbe180011610059578063acbe1800146102f7578063addf027c14610317578063ca31d58614610337578063f8fa73a11461036457600080fd5b806376428c9b146102405780637e7166f31461026f5780638a33be011461029c578063a81e9f79146102bc57600080fd5b80633c7fe5e3116100c65780633c7fe5e3146101ae57806350743bb9146101c157806352e41f99146102005780636e6be03f1461022057600080fd5b80630a631576146100f85780631d414cbd146101305780631decbf181461015257806332393f2b14610180575b600080fd5b34801561010457600080fd5b50610118610113366004611bd0565b610391565b60405161012793929190611c41565b60405180910390f35b34801561013c57600080fd5b5061015061014b366004611c8e565b610446565b005b34801561015e57600080fd5b5061017261016d366004611d1b565b610566565b604051610127929190611dc6565b34801561018c57600080fd5b506101a061019b366004611de9565b6108d8565b604051908152602001610127565b6101506101bc366004611e43565b610a68565b3480156101cd57600080fd5b506101f06101dc366004611bd0565b600090815260056020526040902054151590565b6040519015158152602001610127565b34801561020c57600080fd5b5061015061021b366004611e7f565b610c15565b34801561022c57600080fd5b506101a061023b366004611efe565b610d30565b34801561024c57600080fd5b5061026061025b366004611fcf565b610fa4565b60405161012793929190612069565b34801561027b57600080fd5b506101a061028a366004612100565b60046020526000908152604090205481565b3480156102a857600080fd5b506101f06102b7366004612122565b6111ed565b3480156102c857600080fd5b506101f06102d7366004611c8e565b600360209081526000928352604080842090915290825290205460ff1681565b34801561030357600080fd5b506101a06103123660046121ab565b61130a565b34801561032357600080fd5b50610150610332366004612249565b611589565b34801561034357600080fd5b50610357610352366004612280565b61162f565b6040516101279190612384565b34801561037057600080fd5b506101a061037f366004612100565b60016020526000908152604090205481565b6000602081905290815260409020805460018201546002830180546001600160a01b039093169391926103c3906123ca565b80601f01602080910402602001604051908101604052809291908181526020018280546103ef906123ca565b801561043c5780601f106104115761010080835404028352916020019161043c565b820191906000526020600020905b81548152906001019060200180831161041f57829003601f168201915b5050505050905083565b336000818152600160205260408120805491924692309290859061046990612405565b91829055506040805160208101959095526bffffffffffffffffffffffff19606094851b8116918601919091529190921b166054830152606882015260880160408051601f198184030181529082905280516020918201206bffffffffffffffffffffffff19606087811b82169385019390935233831b811660348501529185901b90911660488301529150605c0160408051808303601f19018152828252805160209182012060008581526002835292909220919091556001600160a01b03848116835283923392918716917fd48d52c7c6d0c940f3f8d07591e1800ef3a70daf79929a97ccd80b4494769fc7910160405180910390a4505050565b60008881526005602090815260408083205490516bffffffffffffffffffffffff1960608c811b82169483019490945233841b811660348301528a841b1660488201526001600160e01b03198916605c820152820160405160208183030381529060405280519060200120146106235760405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420726571756573742066756c66696c6c6d656e74000000000060448201526064015b60405180910390fd5b886001600160a01b03166106e585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040516106df925061067f91508f908c908c9060200161243d565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b906117b0565b6001600160a01b03161461073b5760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e6174757265000000000000000000000000000000604482015260640161061a565b60008a81526005602052604080822091909155516001600160a01b03891690889061076e908d908a908a90602401612480565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b03199094169390931790925290516107c1919061249a565b6000604051808303816000865af19150503d80600081146107fe576040519150601f19603f3d011682016040523d82523d6000602084013e610803565b606091505b50909250905081156108585789896001600160a01b03167fc0977dab79883641ece94bb6a932ca83049f561ffff8d8daaeafdbc1acce9e0a888860405161084b9291906124b6565b60405180910390a36108cb565b89896001600160a01b03167fc7143b2270cddda57e0087ca5e2a4325657dcab10d10f6b1f9d5ce6b41cb97fc6040516108c2906020808252601f908201527f46756c66696c6c6d656e74206661696c656420756e65787065637465646c7900604082015260600190565b60405180910390a35b9850989650505050505050565b60006001600160a01b0385166109305760405162461bcd60e51b815260206004820152601460248201527f4169726e6f64652061646472657373207a65726f000000000000000000000000604482015260640161061a565b8484848460405160200161094794939291906124ca565b6040516020818303038152906040528051906020012090506040518060600160405280866001600160a01b0316815260200185815260200184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250508381526020818152604091829020845181547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178155848201516001820155918401518051929350610a1e9260028501929190910190611b37565b50905050807fba204bad31c4ec4b9b54164af94ae10c4e7312f22c0f9c065d6319c928ec9e7a86868686604051610a5894939291906124fd565b60405180910390a2949350505050565b6040516bffffffffffffffffffffffff19606084811b8216602084015283811b8216603484015233901b166048820152605c0160408051601f1981840301815291815281516020928301206000868152600290935291205414610b0d5760405162461bcd60e51b815260206004820152601e60248201527f496e76616c6964207769746864726177616c2066756c66696c6c6d656e740000604482015260640161061a565b6000838152600260209081526040808320929092558151338152349181019190915284916001600160a01b0380851692908616917fadb4840bbd5f924665ae7e0e0c83de5c0fb40a98c9b57dba53a6c978127a622e910160405180910390a46000816001600160a01b03163460405160006040518083038185875af1925050503d8060008114610bb9576040519150601f19603f3d011682016040523d82523d6000602084013e610bbe565b606091505b5050905080610c0f5760405162461bcd60e51b815260206004820152600f60248201527f5472616e73666572206661696c65640000000000000000000000000000000000604482015260640161061a565b50505050565b6000868152600560209081526040918290205491516bffffffffffffffffffffffff19606089811b82169383019390935233831b8116603483015287831b1660488201526001600160e01b03198616605c820152016040516020818303038152906040528051906020012014610ccd5760405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420726571756573742066756c66696c6c6d656e740000000000604482015260640161061a565b600560008781526020019081526020016000206000905585856001600160a01b03167fc7143b2270cddda57e0087ca5e2a4325657dcab10d10f6b1f9d5ce6b41cb97fc8484604051610d209291906124b6565b60405180910390a3505050505050565b60006001600160a01b038916610d885760405162461bcd60e51b815260206004820152601460248201527f4169726e6f64652061646472657373207a65726f000000000000000000000000604482015260640161061a565b6001600160a01b038516301415610de15760405162461bcd60e51b815260206004820152601a60248201527f46756c66696c6c2061646472657373204169726e6f6465527270000000000000604482015260640161061a565b6001600160a01b038716600090815260036020908152604080832033845290915290205460ff16610e545760405162461bcd60e51b815260206004820152601760248201527f526571756573746572206e6f742073706f6e736f726564000000000000000000604482015260640161061a565b600060046000336001600160a01b03166001600160a01b03168152602001908152602001600020549050463033838d8d8d8d8d8d8d8d604051602001610ea59c9b9a99989796959493929190612530565b60408051601f198184030181529082905280516020918201206bffffffffffffffffffffffff1960608e811b8216938501939093528a831b8116603485015289831b1660488401526001600160e01b03198816605c84015293500160408051601f1981840301815291815281516020928301206000858152600584528281209190915533815260049092528120805491610f3e83612405565b9190505550818a6001600160a01b03167f3a52c462346de2e9436a3868970892956828a11b9c43da1ed43740b12e1125ae8346338e8e8e8e8e8e8e604051610f8f9a999897969594939291906125bf565b60405180910390a35098975050505050505050565b606080808367ffffffffffffffff811115610fc157610fc1612631565b604051908082528060200260200182016040528015610fea578160200160208202803683370190505b5092508367ffffffffffffffff81111561100657611006612631565b60405190808252806020026020018201604052801561102f578160200160208202803683370190505b5091508367ffffffffffffffff81111561104b5761104b612631565b60405190808252806020026020018201604052801561107e57816020015b60608152602001906001900390816110695790505b50905060005b848110156111e55760008060008888858181106110a3576110a3612647565b90506020020135815260200190815260200160002090508060000160009054906101000a90046001600160a01b03168583815181106110e4576110e4612647565b60200260200101906001600160a01b031690816001600160a01b031681525050806001015484838151811061111b5761111b612647565b602002602001018181525050806002018054611136906123ca565b80601f0160208091040260200160405190810160405280929190818152602001828054611162906123ca565b80156111af5780601f10611184576101008083540402835291602001916111af565b820191906000526020600020905b81548152906001019060200180831161119257829003601f168201915b50505050508383815181106111c6576111c6612647565b60200260200101819052505080806111dd90612405565b915050611084565b509250925092565b6000805b878110156112f957600089898381811061120d5761120d612647565b90506020020160208101906112229190612100565b6040517f29b915b3000000000000000000000000000000000000000000000000000000008152600481018990526001600160a01b038a811660248301526044820189905287811660648301528681166084830152919250908216906329b915b39060a40160206040518083038186803b15801561129e57600080fd5b505afa1580156112b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d6919061265d565b156112e6576001925050506112ff565b50806112f181612405565b9150506111f1565b50600090505b979650505050505050565b6000878152602081905260408120546001600160a01b03168061136f5760405162461bcd60e51b815260206004820152601760248201527f54656d706c61746520646f6573206e6f74206578697374000000000000000000604482015260640161061a565b6001600160a01b0386163014156113c85760405162461bcd60e51b815260206004820152601a60248201527f46756c66696c6c2061646472657373204169726e6f6465527270000000000000604482015260640161061a565b6001600160a01b038816600090815260036020908152604080832033845290915290205460ff1661143b5760405162461bcd60e51b815260206004820152601760248201527f526571756573746572206e6f742073706f6e736f726564000000000000000000604482015260640161061a565b600060046000336001600160a01b03166001600160a01b03168152602001908152602001600020549050463033838d8d8d8d8d8d8d60405160200161148a9b9a9998979695949392919061267a565b60408051601f198184030181529082905280516020918201206bffffffffffffffffffffffff19606086811b8216938501939093528b831b811660348501528a831b1660488401526001600160e01b03198916605c84015294500160408051601f198184030181529181528151602092830120600086815260058452828120919091553381526004909252812080549161152383612405565b919050555082826001600160a01b03167feb39930cdcbb560e6422558a2468b93a215af60063622e63cbb165eba14c32038346338f8f8f8f8f8f8f6040516115749a999897969594939291906125bf565b60405180910390a35050979650505050505050565b6001600160a01b0382166000908152600460205260409020546115c3576001600160a01b0382166000908152600460205260409020600190555b3360008181526003602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917fc2e532a12bbcce2bfa2ef9e4bee80180e4e1b1f78618f0d20bc49a648b577c56910160405180910390a35050565b6060878614801561163f57508784145b801561164a57508782145b6116965760405162461bcd60e51b815260206004820152601960248201527f556e657175616c20706172616d65746572206c656e6774687300000000000000604482015260640161061a565b8767ffffffffffffffff8111156116af576116af612631565b6040519080825280602002602001820160405280156116d8578160200160208202803683370190505b50905060005b888110156117a05761176c8d8d8d8d8d868181106116fe576116fe612647565b905060200201358c8c8781811061171757611717612647565b905060200201358b8b8881811061173057611730612647565b90506020020160208101906117459190612100565b8a8a8981811061175757611757612647565b90506020020160208101906102b79190612100565b82828151811061177e5761177e612647565b911515602092830291909101909101528061179881612405565b9150506116de565b509b9a5050505050505050505050565b60008060006117bf85856117d4565b915091506117cc81611844565b509392505050565b60008082516041141561180b5760208301516040840151606085015160001a6117ff87828585611a02565b9450945050505061183d565b825160401415611835576020830151604084015161182a868383611aef565b93509350505061183d565b506000905060025b9250929050565b600081600481111561185857611858612701565b14156118615750565b600181600481111561187557611875612701565b14156118c35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161061a565b60028160048111156118d7576118d7612701565b14156119255760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161061a565b600381600481111561193957611939612701565b14156119925760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161061a565b60048160048111156119a6576119a6612701565b14156119ff5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161061a565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611a395750600090506003611ae6565b8460ff16601b14158015611a5157508460ff16601c14155b15611a625750600090506004611ae6565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611ab6573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611adf57600060019250925050611ae6565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831660ff84901c601b01611b2987828885611a02565b935093505050935093915050565b828054611b43906123ca565b90600052602060002090601f016020900481019282611b655760008555611bab565b82601f10611b7e57805160ff1916838001178555611bab565b82800160010185558215611bab579182015b82811115611bab578251825591602001919060010190611b90565b50611bb7929150611bbb565b5090565b5b80821115611bb75760008155600101611bbc565b600060208284031215611be257600080fd5b5035919050565b60005b83811015611c04578181015183820152602001611bec565b83811115610c0f5750506000910152565b60008151808452611c2d816020860160208601611be9565b601f01601f19169290920160200192915050565b6001600160a01b0384168152826020820152606060408201526000611c696060830184611c15565b95945050505050565b80356001600160a01b0381168114611c8957600080fd5b919050565b60008060408385031215611ca157600080fd5b611caa83611c72565b9150611cb860208401611c72565b90509250929050565b80356001600160e01b031981168114611c8957600080fd5b60008083601f840112611ceb57600080fd5b50813567ffffffffffffffff811115611d0357600080fd5b60208301915083602082850101111561183d57600080fd5b60008060008060008060008060c0898b031215611d3757600080fd5b88359750611d4760208a01611c72565b9650611d5560408a01611c72565b9550611d6360608a01611cc1565b9450608089013567ffffffffffffffff80821115611d8057600080fd5b611d8c8c838d01611cd9565b909650945060a08b0135915080821115611da557600080fd5b50611db28b828c01611cd9565b999c989b5096995094979396929594505050565b8215158152604060208201526000611de16040830184611c15565b949350505050565b60008060008060608587031215611dff57600080fd5b611e0885611c72565b935060208501359250604085013567ffffffffffffffff811115611e2b57600080fd5b611e3787828801611cd9565b95989497509550505050565b600080600060608486031215611e5857600080fd5b83359250611e6860208501611c72565b9150611e7660408501611c72565b90509250925092565b60008060008060008060a08789031215611e9857600080fd5b86359550611ea860208801611c72565b9450611eb660408801611c72565b9350611ec460608801611cc1565b9250608087013567ffffffffffffffff811115611ee057600080fd5b611eec89828a01611cd9565b979a9699509497509295939492505050565b60008060008060008060008060e0898b031215611f1a57600080fd5b611f2389611c72565b975060208901359650611f3860408a01611c72565b9550611f4660608a01611c72565b9450611f5460808a01611c72565b9350611f6260a08a01611cc1565b925060c089013567ffffffffffffffff811115611f7e57600080fd5b611db28b828c01611cd9565b60008083601f840112611f9c57600080fd5b50813567ffffffffffffffff811115611fb457600080fd5b6020830191508360208260051b850101111561183d57600080fd5b60008060208385031215611fe257600080fd5b823567ffffffffffffffff811115611ff957600080fd5b61200585828601611f8a565b90969095509350505050565b600082825180855260208086019550808260051b84010181860160005b8481101561205c57601f1986840301895261204a838351611c15565b9884019892509083019060010161202e565b5090979650505050505050565b606080825284519082018190526000906020906080840190828801845b828110156120ab5781516001600160a01b031684529284019290840190600101612086565b5050508381038285015285518082528683019183019060005b818110156120e0578351835292840192918401916001016120c4565b505084810360408601526120f48187612011565b98975050505050505050565b60006020828403121561211257600080fd5b61211b82611c72565b9392505050565b600080600080600080600060c0888a03121561213d57600080fd5b873567ffffffffffffffff81111561215457600080fd5b6121608a828b01611f8a565b9098509650612173905060208901611c72565b9450604088013593506060880135925061218f60808901611c72565b915061219d60a08901611c72565b905092959891949750929550565b600080600080600080600060c0888a0312156121c657600080fd5b873596506121d660208901611c72565b95506121e460408901611c72565b94506121f260608901611c72565b935061220060808901611cc1565b925060a088013567ffffffffffffffff81111561221c57600080fd5b6122288a828b01611cd9565b989b979a50959850939692959293505050565b80151581146119ff57600080fd5b6000806040838503121561225c57600080fd5b61226583611c72565b915060208301356122758161223b565b809150509250929050565b600080600080600080600080600080600060c08c8e0312156122a157600080fd5b67ffffffffffffffff808d3511156122b857600080fd5b6122c58e8e358f01611f8a565b909c509a506122d660208e01611c72565b99508060408e013511156122e957600080fd5b6122f98e60408f01358f01611f8a565b909950975060608d013581101561230f57600080fd5b61231f8e60608f01358f01611f8a565b909750955060808d013581101561233557600080fd5b6123458e60808f01358f01611f8a565b909550935060a08d013581101561235b57600080fd5b5061236c8d60a08e01358e01611f8a565b81935080925050509295989b509295989b9093969950565b6020808252825182820181905260009190848201906040850190845b818110156123be5783511515835292840192918401916001016123a0565b50909695505050505050565b600181811c908216806123de57607f821691505b602082108114156123ff57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561242757634e487b7160e01b600052601160045260246000fd5b5060010190565b81818437506000910190815290565b838152818360208301376000910160200190815292915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b838152604060208201526000611c69604083018486612457565b600082516124ac818460208701611be9565b9190910192915050565b602081526000611de1602083018486612457565b6bffffffffffffffffffffffff198560601b16815283601482015281836034830137600091016034019081529392505050565b6001600160a01b0385168152836020820152606060408201526000612526606083018486612457565b9695505050505050565b8c815260006bffffffffffffffffffffffff196060818f821b166020850152818e821b1660348501528c6048850152818c821b1660688501528a607c850152818a821b16609c8501528189821b1660b08501528188821b1660c485015250506001600160e01b0319851660d88301526125ad60dc8301848661242e565b9e9d5050505050505050505050505050565b60006101208c83528b60208401526001600160a01b03808c1660408501528a6060850152808a16608085015280891660a085015280881660c0850152506001600160e01b0319861660e0840152806101008401526126208184018587612457565b9d9c50505050505050505050505050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561266f57600080fd5b815161211b8161223b565b8b815260006bffffffffffffffffffffffff19808d60601b166020840152808c60601b1660348401528a6048840152896068840152808960601b166088840152808860601b16609c840152808760601b1660b0840152506001600160e01b0319851660c4830152828460c8840137506000910160c8019081529a9950505050505050505050565b634e487b7160e01b600052602160045260246000fdfea26469706673582212208125c69072f5b73d89af7cc14fb8da75fc37036277de16e38207c96e9f01298764736f6c63430008090033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.