This nametag was submitted by Kleros Scout.
Overview
ETH Balance
ETH Value
$0.00Latest 25 from a total of 331,211 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Fulfill | 14839013 | 369 days ago | IN | 0 ETH | 0.00003184 | ||||
| Fulfill | 14838937 | 369 days ago | IN | 0 ETH | 0.00003196 | ||||
| Fulfill | 14838883 | 369 days ago | IN | 0 ETH | 0.00003208 | ||||
| Fulfill | 14838826 | 369 days ago | IN | 0 ETH | 0.00003223 | ||||
| Fulfill | 14838799 | 369 days ago | IN | 0 ETH | 0.00003233 | ||||
| Fulfill | 14838743 | 369 days ago | IN | 0 ETH | 0.00003249 | ||||
| Fulfill | 14838713 | 369 days ago | IN | 0 ETH | 0.00003265 | ||||
| Fulfill | 14838655 | 369 days ago | IN | 0 ETH | 0.00003284 | ||||
| Fulfill | 14837669 | 369 days ago | IN | 0 ETH | 0.00003359 | ||||
| Fulfill | 14837611 | 369 days ago | IN | 0 ETH | 0.00003413 | ||||
| Fulfill | 14836862 | 369 days ago | IN | 0 ETH | 0.00003688 | ||||
| Fulfill | 14836363 | 369 days ago | IN | 0 ETH | 0.00004457 | ||||
| Fulfill | 14836275 | 369 days ago | IN | 0 ETH | 0.00004706 | ||||
| Fulfill | 14836246 | 369 days ago | IN | 0 ETH | 0.00004814 | ||||
| Fulfill | 14836246 | 369 days ago | IN | 0 ETH | 0.00004814 | ||||
| Fulfill | 14836218 | 369 days ago | IN | 0 ETH | 0.00004925 | ||||
| Fulfill | 14836216 | 369 days ago | IN | 0 ETH | 0.00004924 | ||||
| Fulfill | 14836187 | 369 days ago | IN | 0 ETH | 0.00004997 | ||||
| Fulfill | 14836187 | 369 days ago | IN | 0 ETH | 0.00005001 | ||||
| Fulfill | 14836158 | 369 days ago | IN | 0 ETH | 0.00005074 | ||||
| Fulfill | 14836158 | 369 days ago | IN | 0 ETH | 0.00005079 | ||||
| Fulfill | 14836128 | 369 days ago | IN | 0 ETH | 0.0000516 | ||||
| Fulfill | 14836045 | 369 days ago | IN | 0 ETH | 0.00005425 | ||||
| Fulfill | 14836016 | 369 days ago | IN | 0 ETH | 0.00005565 | ||||
| Fulfill | 14835900 | 369 days ago | IN | 0 ETH | 0.00006312 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 25195715 | 83 days ago | 0 ETH | ||||
| 20054261 | 223 days ago | 0 ETH | ||||
| 19913994 | 227 days ago | 0 ETH | ||||
| 18297492 | 277 days ago | 0 ETH | ||||
| 17968728 | 287 days ago | 0 ETH | ||||
| 17827458 | 292 days ago | 0 ETH | ||||
| 17665223 | 297 days ago | 0 ETH | ||||
| 17411007 | 304 days ago | 0 ETH | ||||
| 17410999 | 304 days ago | 0 ETH | ||||
| 17355281 | 305 days ago | 0 ETH | ||||
| 17301912 | 307 days ago | 0 ETH | ||||
| 17300355 | 307 days ago | 0 ETH | ||||
| 17300306 | 307 days ago | 0 ETH | ||||
| 17300202 | 307 days ago | 0 ETH | ||||
| 17300170 | 307 days ago | 0 ETH | ||||
| 17300157 | 307 days ago | 0 ETH | ||||
| 17297776 | 307 days ago | 0 ETH | ||||
| 17297773 | 307 days ago | 0 ETH | ||||
| 17297767 | 307 days ago | 0 ETH | ||||
| 17293036 | 307 days ago | 0 ETH | ||||
| 17285892 | 307 days ago | 0 ETH | ||||
| 17284266 | 307 days ago | 0 ETH | ||||
| 17284233 | 307 days ago | 0 ETH | ||||
| 16878940 | 318 days ago | 0 ETH | ||||
| 16878930 | 318 days ago | 0 ETH |
Cross-Chain Transactions
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
Contract ABI
API[{"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
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.