Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Set Gateways | 24420251 | 27 days ago | IN | 0 ETH | 0.00001798 |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
OffchainResolver
Compiler Version
v0.8.30+commit.73712a01
Optimization Enabled:
No with 200 runs
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.13;
import {Ownable} from "@oz/access/Ownable.sol";
import {ERC165} from "@oz/utils/introspection/ERC165.sol";
import {ECDSA} from "@oz/utils/cryptography/ECDSA.sol";
import {IERC7996} from "@ens/utils/IERC7996.sol";
import {ResolverFeatures} from "@ens/resolvers/ResolverFeatures.sol";
import {IExtendedResolver} from "@ens/resolvers/profiles/IExtendedResolver.sol";
import {OffchainLookup} from "@ens/ccipRead/EIP3668.sol";
import {IGatewayProvider} from "@ens/ccipRead/IGatewayProvider.sol";
import {EfficientHashLib} from "solady/utils/EfficientHashLib.sol";
contract OffchainResolver is Ownable, ERC165, IExtendedResolver, IGatewayProvider, IERC7996 {
error CCIPReadExpired(uint64 expiry);
error CCIPReadUntrusted(address signed, address expected);
string[] _gateways;
/// @notice The current offchain signer.
address public signer;
constructor(address signer_, string[] memory gateways_) Ownable(msg.sender) {
signer = signer_;
_gateways = gateways_;
}
/// @inheritdoc ERC165
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
return interfaceId == type(IExtendedResolver).interfaceId || interfaceId == type(IERC7996).interfaceId
|| interfaceId == type(IGatewayProvider).interfaceId || super.supportsInterface(interfaceId);
}
/// @inheritdoc IERC7996
function supportsFeature(bytes4 featureId) external pure returns (bool) {
return featureId == ResolverFeatures.RESOLVE_MULTICALL;
}
/// @notice Set the offchain signer.
function setSigner(address signer_) external onlyOwner {
signer = signer_;
}
/// @notice Set the gateways.
function setGateways(string[] memory gateways_) external onlyOwner {
_gateways = gateways_;
}
/// @inheritdoc IGatewayProvider
function gateways() external view returns (string[] memory) {
return _gateways;
}
/// @inheritdoc IExtendedResolver
function resolve(
bytes calldata,
/*name*/
bytes calldata /*data*/
)
external
view
returns (bytes memory)
{
revert OffchainLookup(address(this), _gateways, msg.data, this.resolveCallback.selector, msg.data);
}
/// @dev CCIP-Read callback for `resolve()`.
function resolveCallback(bytes calldata response, bytes calldata request) external view returns (bytes memory) {
return _verifyResponse(request, response);
}
/// @dev Verify the offchain response was signed by `signer`.
/// @param request The original request data.
/// @param response The ABI-encoded response: (bytes answer, uint64 expiry, bytes sig).
/// @return answer The decoded answer from the response.
/// The signature is verified over: keccak256(0x1900 || address(this) || expiry || keccak256(request) || keccak256(answer))
function _verifyResponse(bytes memory request, bytes calldata response) internal view returns (bytes memory) {
(bytes memory answer, uint64 expiry, bytes memory sig) = abi.decode(response, (bytes, uint64, bytes));
if (expiry < block.timestamp) {
revert CCIPReadExpired(expiry);
}
bytes32 hash = EfficientHashLib.hash(
abi.encodePacked(
hex"1900", address(this), expiry, EfficientHashLib.hash(request), EfficientHashLib.hash(answer)
)
);
address signed = ECDSA.recover(hash, sig);
if (signed != signer) {
revert CCIPReadUntrusted(signed, signer);
}
return answer;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.5.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.20;
/**
* @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
}
/**
* @dev The signature derives the `address(0)`.
*/
error ECDSAInvalidSignature();
/**
* @dev The signature has an invalid length.
*/
error ECDSAInvalidSignatureLength(uint256 length);
/**
* @dev The signature has an S value that is in the upper half order.
*/
error ECDSAInvalidSignatureS(bytes32 s);
/**
* @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
* return address(0) without also returning an error description. Errors are documented using an enum (error type)
* and a bytes32 providing additional information about the error.
*
* If no error is returned, then the address can be used for verification purposes.
*
* The `ecrecover` EVM precompile 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.
*
* NOTE: This function only supports 65-byte signatures. ERC-2098 short signatures are rejected. This restriction
* is DEPRECATED and will be removed in v6.0. Developers SHOULD NOT use signatures as unique identifiers; use hash
* invalidation or nonces for replay protection.
*
* 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 {MessageHashUtils-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]
*/
function tryRecover(
bytes32 hash,
bytes memory signature
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
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 ("memory-safe") {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
/**
* @dev Variant of {tryRecover} that takes a signature in calldata
*/
function tryRecoverCalldata(
bytes32 hash,
bytes calldata signature
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, calldata slices would work here, but are
// significantly more expensive (length check) than using calldataload in assembly.
assembly ("memory-safe") {
r := calldataload(signature.offset)
s := calldataload(add(signature.offset, 0x20))
v := byte(0, calldataload(add(signature.offset, 0x40)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM precompile 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.
*
* NOTE: This function only supports 65-byte signatures. ERC-2098 short signatures are rejected. This restriction
* is DEPRECATED and will be removed in v6.0. Developers SHOULD NOT use signatures as unique identifiers; use hash
* invalidation or nonces for replay protection.
*
* 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 {MessageHashUtils-toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Variant of {recover} that takes a signature in calldata
*/
function recoverCalldata(bytes32 hash, bytes calldata signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecoverCalldata(hash, signature);
_throwError(error, errorArg);
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[ERC-2098 short signatures]
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
unchecked {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
// We do not check for an overflow here since the shift operation results in 0 or 1.
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*/
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
// 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, s);
}
// 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, bytes32(0));
}
return (signer, RecoverError.NoError, bytes32(0));
}
/**
* @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, bytes32 errorArg) = tryRecover(hash, v, r, s);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Parse a signature into its `v`, `r` and `s` components. Supports 65-byte and 64-byte (ERC-2098)
* formats. Returns (0,0,0) for invalid signatures.
*
* For 64-byte signatures, `v` is automatically normalized to 27 or 28.
* For 65-byte signatures, `v` is returned as-is and MUST already be 27 or 28 for use with ecrecover.
*
* Consider validating the result before use, or use {tryRecover}/{recover} which perform full validation.
*/
function parse(bytes memory signature) internal pure returns (uint8 v, bytes32 r, bytes32 s) {
assembly ("memory-safe") {
// Check the signature length
switch mload(signature)
// - case 65: r,s,v signature (standard)
case 65 {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
// - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098)
case 64 {
let vs := mload(add(signature, 0x40))
r := mload(add(signature, 0x20))
s := and(vs, shr(1, not(0)))
v := add(shr(255, vs), 27)
}
default {
r := 0
s := 0
v := 0
}
}
}
/**
* @dev Variant of {parse} that takes a signature in calldata
*/
function parseCalldata(bytes calldata signature) internal pure returns (uint8 v, bytes32 r, bytes32 s) {
assembly ("memory-safe") {
// Check the signature length
switch signature.length
// - case 65: r,s,v signature (standard)
case 65 {
r := calldataload(signature.offset)
s := calldataload(add(signature.offset, 0x20))
v := byte(0, calldataload(add(signature.offset, 0x40)))
}
// - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098)
case 64 {
let vs := calldataload(add(signature.offset, 0x20))
r := calldataload(signature.offset)
s := and(vs, shr(1, not(0)))
v := add(shr(255, vs), 27)
}
default {
r := 0
s := 0
v := 0
}
}
}
/**
* @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
*/
function _throwError(RecoverError error, bytes32 errorArg) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert ECDSAInvalidSignature();
} else if (error == RecoverError.InvalidSignatureLength) {
revert ECDSAInvalidSignatureLength(uint256(errorArg));
} else if (error == RecoverError.InvalidSignatureS) {
revert ECDSAInvalidSignatureS(errorArg);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @notice Interface for expressing contract features not visible from the ABI.
/// @dev Interface selector: `0x582de3e7`
interface IERC7996 {
/// @notice Check if a feature is supported.
/// @param featureId The feature identifier.
/// @return `true` if the feature is supported by the contract.
function supportsFeature(bytes4 featureId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library ResolverFeatures {
/// @notice Implements `resolve(multicall([...]))`.
/// @dev Feature: `0x96b62db8`
bytes4 constant RESOLVE_MULTICALL =
bytes4(keccak256("eth.ens.resolver.extended.multicall"));
/// @notice Returns the same records independent of name or node.
/// @dev Feature: `0x86fb8da8`
bytes4 constant SINGULAR = bytes4(keccak256("eth.ens.resolver.singular"));
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
interface IExtendedResolver {
function resolve(
bytes memory name,
bytes memory data
) external view returns (bytes memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @dev https://eips.ethereum.org/EIPS/eip-3668
/// Error selector: `0x556f1830`
error OffchainLookup(
address sender,
string[] urls,
bytes callData,
bytes4 callbackFunction,
bytes extraData
);
/// @dev Simple library for decoding `OffchainLookup` error data.
/// Avoids "stack too deep" issues as the natural decoding consumes 5 variables.
library EIP3668 {
/// @dev Struct with members matching `OffchainLookup`.
struct Params {
address sender;
string[] urls;
bytes callData;
bytes4 callbackFunction;
bytes extraData;
}
/// @dev Decode an `OffchainLookup` into a struct from the data after the error selector.
function decode(bytes memory v) internal pure returns (Params memory p) {
(p.sender, p.urls, p.callData, p.callbackFunction, p.extraData) = abi
.decode(v, (address, string[], bytes, bytes4, bytes));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @notice Interface for shared gateway URLs.
/// @dev Interface selector: `0x093a86d3`
interface IGatewayProvider {
/// @notice Get the gateways.
/// @return The gateway URLs.
function gateways() external view returns (string[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Library for efficiently performing keccak256 hashes.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EfficientHashLib.sol)
/// @dev To avoid stack-too-deep, you can use:
/// ```
/// bytes32[] memory buffer = EfficientHashLib.malloc(10);
/// EfficientHashLib.set(buffer, 0, value0);
/// ..
/// EfficientHashLib.set(buffer, 9, value9);
/// bytes32 finalHash = EfficientHashLib.hash(buffer);
/// ```
library EfficientHashLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* MALLOC-LESS HASHING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `keccak256(abi.encode(v0))`.
function hash(bytes32 v0) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, v0)
result := keccak256(0x00, 0x20)
}
}
/// @dev Returns `keccak256(abi.encode(v0))`.
function hash(uint256 v0) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, v0)
result := keccak256(0x00, 0x20)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1))`.
function hash(bytes32 v0, bytes32 v1) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, v0)
mstore(0x20, v1)
result := keccak256(0x00, 0x40)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1))`.
function hash(uint256 v0, uint256 v1) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, v0)
mstore(0x20, v1)
result := keccak256(0x00, 0x40)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1, v2))`.
function hash(bytes32 v0, bytes32 v1, bytes32 v2) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
result := keccak256(m, 0x60)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1, v2))`.
function hash(uint256 v0, uint256 v1, uint256 v2) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
result := keccak256(m, 0x60)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`.
function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
result := keccak256(m, 0x80)
}
}
/// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`.
function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
result := keccak256(m, 0x80)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v4))`.
function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
result := keccak256(m, 0xa0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v4))`.
function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
result := keccak256(m, 0xa0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v5))`.
function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4, bytes32 v5)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
result := keccak256(m, 0xc0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v5))`.
function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4, uint256 v5)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
result := keccak256(m, 0xc0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v6))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
result := keccak256(m, 0xe0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v6))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
result := keccak256(m, 0xe0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v7))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
result := keccak256(m, 0x100)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v7))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
result := keccak256(m, 0x100)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v8))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
result := keccak256(m, 0x120)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v8))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
result := keccak256(m, 0x120)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v9))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
result := keccak256(m, 0x140)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v9))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
result := keccak256(m, 0x140)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v10))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9,
bytes32 v10
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
result := keccak256(m, 0x160)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v10))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9,
uint256 v10
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
result := keccak256(m, 0x160)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v11))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9,
bytes32 v10,
bytes32 v11
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
result := keccak256(m, 0x180)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v11))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9,
uint256 v10,
uint256 v11
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
result := keccak256(m, 0x180)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v12))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9,
bytes32 v10,
bytes32 v11,
bytes32 v12
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
mstore(add(m, 0x180), v12)
result := keccak256(m, 0x1a0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v12))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9,
uint256 v10,
uint256 v11,
uint256 v12
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
mstore(add(m, 0x180), v12)
result := keccak256(m, 0x1a0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v13))`.
function hash(
bytes32 v0,
bytes32 v1,
bytes32 v2,
bytes32 v3,
bytes32 v4,
bytes32 v5,
bytes32 v6,
bytes32 v7,
bytes32 v8,
bytes32 v9,
bytes32 v10,
bytes32 v11,
bytes32 v12,
bytes32 v13
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
mstore(add(m, 0x180), v12)
mstore(add(m, 0x1a0), v13)
result := keccak256(m, 0x1c0)
}
}
/// @dev Returns `keccak256(abi.encode(v0, .., v13))`.
function hash(
uint256 v0,
uint256 v1,
uint256 v2,
uint256 v3,
uint256 v4,
uint256 v5,
uint256 v6,
uint256 v7,
uint256 v8,
uint256 v9,
uint256 v10,
uint256 v11,
uint256 v12,
uint256 v13
) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, v0)
mstore(add(m, 0x20), v1)
mstore(add(m, 0x40), v2)
mstore(add(m, 0x60), v3)
mstore(add(m, 0x80), v4)
mstore(add(m, 0xa0), v5)
mstore(add(m, 0xc0), v6)
mstore(add(m, 0xe0), v7)
mstore(add(m, 0x100), v8)
mstore(add(m, 0x120), v9)
mstore(add(m, 0x140), v10)
mstore(add(m, 0x160), v11)
mstore(add(m, 0x180), v12)
mstore(add(m, 0x1a0), v13)
result := keccak256(m, 0x1c0)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* BYTES32 BUFFER HASHING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `keccak256(abi.encode(buffer[0], .., buffer[buffer.length - 1]))`.
function hash(bytes32[] memory buffer) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
result := keccak256(add(buffer, 0x20), shl(5, mload(buffer)))
}
}
/// @dev Sets `buffer[i]` to `value`, without a bounds check.
/// Returns the `buffer` for function chaining.
function set(bytes32[] memory buffer, uint256 i, bytes32 value)
internal
pure
returns (bytes32[] memory)
{
/// @solidity memory-safe-assembly
assembly {
mstore(add(buffer, shl(5, add(1, i))), value)
}
return buffer;
}
/// @dev Sets `buffer[i]` to `value`, without a bounds check.
/// Returns the `buffer` for function chaining.
function set(bytes32[] memory buffer, uint256 i, uint256 value)
internal
pure
returns (bytes32[] memory)
{
/// @solidity memory-safe-assembly
assembly {
mstore(add(buffer, shl(5, add(1, i))), value)
}
return buffer;
}
/// @dev Returns `new bytes32[](n)`, without zeroing out the memory.
function malloc(uint256 n) internal pure returns (bytes32[] memory buffer) {
/// @solidity memory-safe-assembly
assembly {
buffer := mload(0x40)
mstore(buffer, n)
mstore(0x40, add(shl(5, add(1, n)), buffer))
}
}
/// @dev Frees memory that has been allocated for `buffer`.
/// No-op if `buffer.length` is zero, or if new memory has been allocated after `buffer`.
function free(bytes32[] memory buffer) internal pure {
/// @solidity memory-safe-assembly
assembly {
let n := mload(buffer)
mstore(shl(6, lt(iszero(n), eq(add(shl(5, add(1, n)), buffer), mload(0x40)))), buffer)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EQUALITY CHECKS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `a == abi.decode(b, (bytes32))`.
function eq(bytes32 a, bytes memory b) internal pure returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
result := and(eq(0x20, mload(b)), eq(a, mload(add(b, 0x20))))
}
}
/// @dev Returns `abi.decode(a, (bytes32)) == b`.
function eq(bytes memory a, bytes32 b) internal pure returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
result := and(eq(0x20, mload(a)), eq(b, mload(add(a, 0x20))))
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* BYTE SLICE HASHING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function hash(bytes memory b, uint256 start, uint256 end)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let n := mload(b)
end := xor(end, mul(xor(end, n), lt(n, end)))
start := xor(start, mul(xor(start, n), lt(n, start)))
result := keccak256(add(add(b, 0x20), start), mul(gt(end, start), sub(end, start)))
}
}
/// @dev Returns the keccak256 of the slice from `start` to the end of the bytes.
function hash(bytes memory b, uint256 start) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let n := mload(b)
start := xor(start, mul(xor(start, n), lt(n, start)))
result := keccak256(add(add(b, 0x20), start), mul(gt(n, start), sub(n, start)))
}
}
/// @dev Returns the keccak256 of the bytes.
function hash(bytes memory b) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
result := keccak256(add(b, 0x20), mload(b))
}
}
/// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function hashCalldata(bytes calldata b, uint256 start, uint256 end)
internal
pure
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
end := xor(end, mul(xor(end, b.length), lt(b.length, end)))
start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
let n := mul(gt(end, start), sub(end, start))
calldatacopy(mload(0x40), add(b.offset, start), n)
result := keccak256(mload(0x40), n)
}
}
/// @dev Returns the keccak256 of the slice from `start` to the end of the bytes.
function hashCalldata(bytes calldata b, uint256 start) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
let n := mul(gt(b.length, start), sub(b.length, start))
calldatacopy(mload(0x40), add(b.offset, start), n)
result := keccak256(mload(0x40), n)
}
}
/// @dev Returns the keccak256 of the bytes.
function hashCalldata(bytes calldata b) internal pure returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
calldatacopy(mload(0x40), b.offset, b.length)
result := keccak256(mload(0x40), b.length)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* SHA2-256 HELPERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `sha256(abi.encode(b))`. Yes, it's more efficient.
function sha2(bytes32 b) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, b)
result := mload(staticcall(gas(), 2, 0x00, 0x20, 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the slice from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function sha2(bytes memory b, uint256 start, uint256 end)
internal
view
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
let n := mload(b)
end := xor(end, mul(xor(end, n), lt(n, end)))
start := xor(start, mul(xor(start, n), lt(n, start)))
// forgefmt: disable-next-item
result := mload(staticcall(gas(), 2, add(add(b, 0x20), start),
mul(gt(end, start), sub(end, start)), 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the slice from `start` to the end of the bytes.
function sha2(bytes memory b, uint256 start) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
let n := mload(b)
start := xor(start, mul(xor(start, n), lt(n, start)))
// forgefmt: disable-next-item
result := mload(staticcall(gas(), 2, add(add(b, 0x20), start),
mul(gt(n, start), sub(n, start)), 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the bytes.
function sha2(bytes memory b) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
result := mload(staticcall(gas(), 2, add(b, 0x20), mload(b), 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the slice from `start` to `end` (exclusive).
/// `start` and `end` are byte offsets.
function sha2Calldata(bytes calldata b, uint256 start, uint256 end)
internal
view
returns (bytes32 result)
{
/// @solidity memory-safe-assembly
assembly {
end := xor(end, mul(xor(end, b.length), lt(b.length, end)))
start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
let n := mul(gt(end, start), sub(end, start))
calldatacopy(mload(0x40), add(b.offset, start), n)
result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the slice from `start` to the end of the bytes.
function sha2Calldata(bytes calldata b, uint256 start) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
let n := mul(gt(b.length, start), sub(b.length, start))
calldatacopy(mload(0x40), add(b.offset, start), n)
result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
/// @dev Returns the sha256 of the bytes.
function sha2Calldata(bytes calldata b) internal view returns (bytes32 result) {
/// @solidity memory-safe-assembly
assembly {
calldatacopy(mload(0x40), b.offset, b.length)
result := mload(staticcall(gas(), 2, mload(0x40), b.length, 0x01, 0x20))
if iszero(returndatasize()) { invalid() }
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"forge-std/=lib/forge-std/src/",
"@ens/=lib/ens-contracts/contracts/",
"@oz/=lib/openzeppelin-contracts/contracts/",
"solady/=lib/solady/src/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"ens-contracts/=lib/ens-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": false,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "prague",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"signer_","type":"address"},{"internalType":"string[]","name":"gateways_","type":"string[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint64","name":"expiry","type":"uint64"}],"name":"CCIPReadExpired","type":"error"},{"inputs":[{"internalType":"address","name":"signed","type":"address"},{"internalType":"address","name":"expected","type":"address"}],"name":"CCIPReadUntrusted","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string[]","name":"urls","type":"string[]"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes4","name":"callbackFunction","type":"bytes4"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"OffchainLookup","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"gateways","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"resolve","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"request","type":"bytes"}],"name":"resolveCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string[]","name":"gateways_","type":"string[]"}],"name":"setGateways","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer_","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"featureId","type":"bytes4"}],"name":"supportsFeature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561000f575f5ffd5b5060405161252e38038061252e8339818101604052810190610031919061052c565b335f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100a2575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100999190610595565b60405180910390fd5b6100b18161011060201b60201c565b508160025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600190805190602001906101089291906101d1565b50505061088d565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054828255905f5260205f20908101928215610217579160200282015b8281111561021657825182908161020691906107be565b50916020019190600101906101ef565b5b5090506102249190610228565b5090565b5b80821115610247575f818161023e919061024b565b50600101610229565b5090565b508054610257906105e5565b5f825580601f106102685750610285565b601f0160209004905f5260205f20908101906102849190610288565b5b50565b5b8082111561029f575f815f905550600101610289565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6102dd826102b4565b9050919050565b6102ed816102d3565b81146102f7575f5ffd5b50565b5f81519050610308816102e4565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61035882610312565b810181811067ffffffffffffffff8211171561037757610376610322565b5b80604052505050565b5f6103896102a3565b9050610395828261034f565b919050565b5f67ffffffffffffffff8211156103b4576103b3610322565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156103e7576103e6610322565b5b6103f082610312565b9050602081019050919050565b8281835e5f83830152505050565b5f61041d610418846103cd565b610380565b905082815260208101848484011115610439576104386103c9565b5b6104448482856103fd565b509392505050565b5f82601f8301126104605761045f61030e565b5b815161047084826020860161040b565b91505092915050565b5f61048b6104868461039a565b610380565b905080838252602082019050602084028301858111156104ae576104ad6103c5565b5b835b818110156104f557805167ffffffffffffffff8111156104d3576104d261030e565b5b8086016104e0898261044c565b855260208501945050506020810190506104b0565b5050509392505050565b5f82601f8301126105135761051261030e565b5b8151610523848260208601610479565b91505092915050565b5f5f60408385031215610542576105416102ac565b5b5f61054f858286016102fa565b925050602083015167ffffffffffffffff8111156105705761056f6102b0565b5b61057c858286016104ff565b9150509250929050565b61058f816102d3565b82525050565b5f6020820190506105a85f830184610586565b92915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806105fc57607f821691505b60208210810361060f5761060e6105b8565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026106717fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610636565b61067b8683610636565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6106bf6106ba6106b584610693565b61069c565b610693565b9050919050565b5f819050919050565b6106d8836106a5565b6106ec6106e4826106c6565b848454610642565b825550505050565b5f5f905090565b6107036106f4565b61070e8184846106cf565b505050565b5b81811015610731576107265f826106fb565b600181019050610714565b5050565b601f8211156107765761074781610615565b61075084610627565b8101602085101561075f578190505b61077361076b85610627565b830182610713565b50505b505050565b5f82821c905092915050565b5f6107965f198460080261077b565b1980831691505092915050565b5f6107ae8383610787565b9150826002028217905092915050565b6107c7826105ae565b67ffffffffffffffff8111156107e0576107df610322565b5b6107ea82546105e5565b6107f5828285610735565b5f60209050601f831160018114610826575f8415610814578287015190505b61081e85826107a3565b865550610885565b601f19841661083486610615565b5f5b8281101561085b57848901518255600182019150602085019450602081019050610836565b868310156108785784890151610874601f891682610787565b8355505b6001600288020188555050505b505050505050565b611c948061089a5f395ff3fe608060405234801561000f575f5ffd5b50600436106100a7575f3560e01c80636c19e7831161006f5780636c19e78314610163578063715018a61461017f5780638da5cb5b146101895780639061b923146101a7578063b4a85801146101d7578063f2fde38b14610207576100a7565b806301ffc9a7146100ab578063093a86d3146100db578063238ac933146100f95780632792207414610117578063582de3e714610133575b5f5ffd5b6100c560048036038101906100c09190610de7565b610223565b6040516100d29190610e2c565b60405180910390f35b6100e361036c565b6040516100f09190610f70565b60405180910390f35b610101610440565b60405161010e9190610fcf565b60405180910390f35b610131600480360381019061012c91906111f6565b610465565b005b61014d60048036038101906101489190610de7565b610487565b60405161015a9190610e2c565b60405180910390f35b61017d60048036038101906101789190611267565b6104f0565b005b61018761053b565b005b61019161054e565b60405161019e9190610fcf565b60405180910390f35b6101c160048036038101906101bc91906112eb565b610575565b6040516101ce91906113bb565b60405180910390f35b6101f160048036038101906101ec91906112eb565b6105c8565b6040516101fe91906113bb565b60405180910390f35b610221600480360381019061021c9190611267565b610622565b005b5f7f9061b923000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806102ed57507f582de3e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061035557507f093a86d3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103655750610364826106a6565b5b9050919050565b60606001805480602002602001604051908101604052809291908181526020015f905b82821015610437578382905f5260205f200180546103ac90611408565b80601f01602080910402602001604051908101604052809291908181526020018280546103d890611408565b80156104235780601f106103fa57610100808354040283529160200191610423565b820191905f5260205f20905b81548152906001019060200180831161040657829003601f168201915b50505050508152602001906001019061038f565b50505050905090565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61046d61070f565b8060019080519060200190610483929190610caf565b5050565b5f7f96b62db84925e7addc1a7d6189ebbe954ad1b17a9bb8cd65bb2d92eac894d9147bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6104f861070f565b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61054361070f565b61054c5f610796565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60603060015f3663b4a8580160e01b5f366040517f556f18300000000000000000000000000000000000000000000000000000000081526004016105bf97969594939291906115b3565b60405180910390fd5b606061061883838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508686610857565b9050949350505050565b61062a61070f565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361069a575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016106919190610fcf565b60405180910390fd5b6106a381610796565b50565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6107176109d1565b73ffffffffffffffffffffffffffffffffffffffff1661073561054e565b73ffffffffffffffffffffffffffffffffffffffff1614610794576107586109d1565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161078b9190610fcf565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60605f5f5f858581019061086b91906116f8565b925092509250428267ffffffffffffffff1610156108c057816040517fa477f5f30000000000000000000000000000000000000000000000000000000081526004016108b7919061178f565b60405180910390fd5b5f6108ff30846108cf8b6109d8565b6108d8886109d8565b6040516020016108eb949392919061189e565b6040516020818303038152906040526109d8565b90505f61090c82846109e7565b905060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109c2578060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fb2187bcd0000000000000000000000000000000000000000000000000000000081526004016109b99291906118f6565b60405180910390fd5b84955050505050509392505050565b5f33905090565b5f815160208301209050919050565b5f5f5f5f6109f58686610a11565b925092509250610a058282610a66565b82935050505092915050565b5f5f5f6041845103610a51575f5f5f602087015192506040870151915060608701515f1a9050610a4388828585610bc8565b955095509550505050610a5f565b5f600285515f1b9250925092505b9250925092565b5f6003811115610a7957610a7861191d565b5b826003811115610a8c57610a8b61191d565b5b0315610bc45760016003811115610aa657610aa561191d565b5b826003811115610ab957610ab861191d565b5b03610af0576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115610b0457610b0361191d565b5b826003811115610b1757610b1661191d565b5b03610b5b57805f1c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401610b529190611962565b60405180910390fd5b600380811115610b6e57610b6d61191d565b5b826003811115610b8157610b8061191d565b5b03610bc357806040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600401610bba919061198a565b60405180910390fd5b5b5050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115610c04575f600385925092509250610ca5565b5f6001888888886040515f8152602001604052604051610c2794939291906119be565b6020604051602081039080840390855afa158015610c47573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c98575f60015f5f1b93509350935050610ca5565b805f5f5f1b935093509350505b9450945094915050565b828054828255905f5260205f20908101928215610cf5579160200282015b82811115610cf4578251829081610ce49190611b8f565b5091602001919060010190610ccd565b5b509050610d029190610d06565b5090565b5b80821115610d25575f8181610d1c9190610d29565b50600101610d07565b5090565b508054610d3590611408565b5f825580601f10610d465750610d63565b601f0160209004905f5260205f2090810190610d629190610d66565b5b50565b5b80821115610d7d575f815f905550600101610d67565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610dc681610d92565b8114610dd0575f5ffd5b50565b5f81359050610de181610dbd565b92915050565b5f60208284031215610dfc57610dfb610d8a565b5b5f610e0984828501610dd3565b91505092915050565b5f8115159050919050565b610e2681610e12565b82525050565b5f602082019050610e3f5f830184610e1d565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610eb082610e6e565b610eba8185610e78565b9350610eca818560208601610e88565b610ed381610e96565b840191505092915050565b5f610ee98383610ea6565b905092915050565b5f602082019050919050565b5f610f0782610e45565b610f118185610e4f565b935083602082028501610f2385610e5f565b805f5b85811015610f5e5784840389528151610f3f8582610ede565b9450610f4a83610ef1565b925060208a01995050600181019050610f26565b50829750879550505050505092915050565b5f6020820190508181035f830152610f888184610efd565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610fb982610f90565b9050919050565b610fc981610faf565b82525050565b5f602082019050610fe25f830184610fc0565b92915050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61102282610e96565b810181811067ffffffffffffffff8211171561104157611040610fec565b5b80604052505050565b5f611053610d81565b905061105f8282611019565b919050565b5f67ffffffffffffffff82111561107e5761107d610fec565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156110b1576110b0610fec565b5b6110ba82610e96565b9050602081019050919050565b828183375f83830152505050565b5f6110e76110e284611097565b61104a565b90508281526020810184848401111561110357611102611093565b5b61110e8482856110c7565b509392505050565b5f82601f83011261112a57611129610fe8565b5b813561113a8482602086016110d5565b91505092915050565b5f61115561115084611064565b61104a565b905080838252602082019050602084028301858111156111785761117761108f565b5b835b818110156111bf57803567ffffffffffffffff81111561119d5761119c610fe8565b5b8086016111aa8982611116565b8552602085019450505060208101905061117a565b5050509392505050565b5f82601f8301126111dd576111dc610fe8565b5b81356111ed848260208601611143565b91505092915050565b5f6020828403121561120b5761120a610d8a565b5b5f82013567ffffffffffffffff81111561122857611227610d8e565b5b611234848285016111c9565b91505092915050565b61124681610faf565b8114611250575f5ffd5b50565b5f813590506112618161123d565b92915050565b5f6020828403121561127c5761127b610d8a565b5b5f61128984828501611253565b91505092915050565b5f5ffd5b5f5f83601f8401126112ab576112aa610fe8565b5b8235905067ffffffffffffffff8111156112c8576112c7611292565b5b6020830191508360018202830111156112e4576112e361108f565b5b9250929050565b5f5f5f5f6040858703121561130357611302610d8a565b5b5f85013567ffffffffffffffff8111156113205761131f610d8e565b5b61132c87828801611296565b9450945050602085013567ffffffffffffffff81111561134f5761134e610d8e565b5b61135b87828801611296565b925092505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b5f61138d82611369565b6113978185611373565b93506113a7818560208601610e88565b6113b081610e96565b840191505092915050565b5f6020820190508181035f8301526113d38184611383565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061141f57607f821691505b602082108103611432576114316113db565b5b50919050565b5f81549050919050565b5f819050815f5260205f209050919050565b5f819050815f5260205f209050919050565b5f815461147281611408565b61147c8186610e78565b9450600182165f811461149657600181146114ac576114de565b60ff1983168652811515602002860193506114de565b6114b585611454565b5f5b838110156114d6578154818901526001820191506020810190506114b7565b808801955050505b50505092915050565b5f6114f28383611466565b905092915050565b5f600182019050919050565b5f61151082611438565b61151a8185610e4f565b93508360208202850161152c85611442565b805f5b858110156115665784840389528161154785826114e7565b9450611552836114fa565b925060208a0199505060018101905061152f565b50829750879550505050505092915050565b5f6115838385611373565b93506115908385846110c7565b61159983610e96565b840190509392505050565b6115ad81610d92565b82525050565b5f60a0820190506115c65f83018a610fc0565b81810360208301526115d88189611506565b905081810360408301526115ed818789611578565b90506115fc60608301866115a4565b818103608083015261160f818486611578565b905098975050505050505050565b5f67ffffffffffffffff82111561163757611636610fec565b5b61164082610e96565b9050602081019050919050565b5f61165f61165a8461161d565b61104a565b90508281526020810184848401111561167b5761167a611093565b5b6116868482856110c7565b509392505050565b5f82601f8301126116a2576116a1610fe8565b5b81356116b284826020860161164d565b91505092915050565b5f67ffffffffffffffff82169050919050565b6116d7816116bb565b81146116e1575f5ffd5b50565b5f813590506116f2816116ce565b92915050565b5f5f5f6060848603121561170f5761170e610d8a565b5b5f84013567ffffffffffffffff81111561172c5761172b610d8e565b5b6117388682870161168e565b9350506020611749868287016116e4565b925050604084013567ffffffffffffffff81111561176a57611769610d8e565b5b6117768682870161168e565b9150509250925092565b611789816116bb565b82525050565b5f6020820190506117a25f830184611780565b92915050565b5f81905092915050565b7f19000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6117e66002836117a8565b91506117f1826117b2565b600282019050919050565b5f8160601b9050919050565b5f611812826117fc565b9050919050565b5f61182382611808565b9050919050565b61183b61183682610faf565b611819565b82525050565b5f8160c01b9050919050565b5f61185782611841565b9050919050565b61186f61186a826116bb565b61184d565b82525050565b5f819050919050565b5f819050919050565b61189861189382611875565b61187e565b82525050565b5f6118a8826117da565b91506118b4828761182a565b6014820191506118c4828661185e565b6008820191506118d48285611887565b6020820191506118e48284611887565b60208201915081905095945050505050565b5f6040820190506119095f830185610fc0565b6119166020830184610fc0565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050919050565b61195c8161194a565b82525050565b5f6020820190506119755f830184611953565b92915050565b61198481611875565b82525050565b5f60208201905061199d5f83018461197b565b92915050565b5f60ff82169050919050565b6119b8816119a3565b82525050565b5f6080820190506119d15f83018761197b565b6119de60208301866119af565b6119eb604083018561197b565b6119f8606083018461197b565b95945050505050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302611a4b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611a10565b611a558683611a10565b95508019841693508086168417925050509392505050565b5f819050919050565b5f611a90611a8b611a868461194a565b611a6d565b61194a565b9050919050565b5f819050919050565b611aa983611a76565b611abd611ab582611a97565b848454611a1c565b825550505050565b5f5f905090565b611ad4611ac5565b611adf818484611aa0565b505050565b5b81811015611b0257611af75f82611acc565b600181019050611ae5565b5050565b601f821115611b4757611b1881611454565b611b2184611a01565b81016020851015611b30578190505b611b44611b3c85611a01565b830182611ae4565b50505b505050565b5f82821c905092915050565b5f611b675f1984600802611b4c565b1980831691505092915050565b5f611b7f8383611b58565b9150826002028217905092915050565b611b9882610e6e565b67ffffffffffffffff811115611bb157611bb0610fec565b5b611bbb8254611408565b611bc6828285611b06565b5f60209050601f831160018114611bf7575f8415611be5578287015190505b611bef8582611b74565b865550611c56565b601f198416611c0586611454565b5f5b82811015611c2c57848901518255600182019150602085019450602081019050611c07565b86831015611c495784890151611c45601f891682611b58565b8355505b6001600288020188555050505b50505050505056fea26469706673582212208e949cfdb26a2620484e64238127fb119268358a92cab6fa128aceed74302a5964736f6c634300081e0033000000000000000000000000dfc622f06efdd0e830d82f30679a3c9302bc7940000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003a68747470733a2f2f6170692e73746179636c6f616b65642e78797a2f656e732f676174657761792f7b68617264636f6465642d73656e6465727d000000000000
Deployed Bytecode
0x608060405234801561000f575f5ffd5b50600436106100a7575f3560e01c80636c19e7831161006f5780636c19e78314610163578063715018a61461017f5780638da5cb5b146101895780639061b923146101a7578063b4a85801146101d7578063f2fde38b14610207576100a7565b806301ffc9a7146100ab578063093a86d3146100db578063238ac933146100f95780632792207414610117578063582de3e714610133575b5f5ffd5b6100c560048036038101906100c09190610de7565b610223565b6040516100d29190610e2c565b60405180910390f35b6100e361036c565b6040516100f09190610f70565b60405180910390f35b610101610440565b60405161010e9190610fcf565b60405180910390f35b610131600480360381019061012c91906111f6565b610465565b005b61014d60048036038101906101489190610de7565b610487565b60405161015a9190610e2c565b60405180910390f35b61017d60048036038101906101789190611267565b6104f0565b005b61018761053b565b005b61019161054e565b60405161019e9190610fcf565b60405180910390f35b6101c160048036038101906101bc91906112eb565b610575565b6040516101ce91906113bb565b60405180910390f35b6101f160048036038101906101ec91906112eb565b6105c8565b6040516101fe91906113bb565b60405180910390f35b610221600480360381019061021c9190611267565b610622565b005b5f7f9061b923000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806102ed57507f582de3e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061035557507f093a86d3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103655750610364826106a6565b5b9050919050565b60606001805480602002602001604051908101604052809291908181526020015f905b82821015610437578382905f5260205f200180546103ac90611408565b80601f01602080910402602001604051908101604052809291908181526020018280546103d890611408565b80156104235780601f106103fa57610100808354040283529160200191610423565b820191905f5260205f20905b81548152906001019060200180831161040657829003601f168201915b50505050508152602001906001019061038f565b50505050905090565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61046d61070f565b8060019080519060200190610483929190610caf565b5050565b5f7f96b62db84925e7addc1a7d6189ebbe954ad1b17a9bb8cd65bb2d92eac894d9147bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6104f861070f565b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61054361070f565b61054c5f610796565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60603060015f3663b4a8580160e01b5f366040517f556f18300000000000000000000000000000000000000000000000000000000081526004016105bf97969594939291906115b3565b60405180910390fd5b606061061883838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508686610857565b9050949350505050565b61062a61070f565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361069a575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016106919190610fcf565b60405180910390fd5b6106a381610796565b50565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6107176109d1565b73ffffffffffffffffffffffffffffffffffffffff1661073561054e565b73ffffffffffffffffffffffffffffffffffffffff1614610794576107586109d1565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161078b9190610fcf565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60605f5f5f858581019061086b91906116f8565b925092509250428267ffffffffffffffff1610156108c057816040517fa477f5f30000000000000000000000000000000000000000000000000000000081526004016108b7919061178f565b60405180910390fd5b5f6108ff30846108cf8b6109d8565b6108d8886109d8565b6040516020016108eb949392919061189e565b6040516020818303038152906040526109d8565b90505f61090c82846109e7565b905060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109c2578060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fb2187bcd0000000000000000000000000000000000000000000000000000000081526004016109b99291906118f6565b60405180910390fd5b84955050505050509392505050565b5f33905090565b5f815160208301209050919050565b5f5f5f5f6109f58686610a11565b925092509250610a058282610a66565b82935050505092915050565b5f5f5f6041845103610a51575f5f5f602087015192506040870151915060608701515f1a9050610a4388828585610bc8565b955095509550505050610a5f565b5f600285515f1b9250925092505b9250925092565b5f6003811115610a7957610a7861191d565b5b826003811115610a8c57610a8b61191d565b5b0315610bc45760016003811115610aa657610aa561191d565b5b826003811115610ab957610ab861191d565b5b03610af0576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115610b0457610b0361191d565b5b826003811115610b1757610b1661191d565b5b03610b5b57805f1c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401610b529190611962565b60405180910390fd5b600380811115610b6e57610b6d61191d565b5b826003811115610b8157610b8061191d565b5b03610bc357806040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600401610bba919061198a565b60405180910390fd5b5b5050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115610c04575f600385925092509250610ca5565b5f6001888888886040515f8152602001604052604051610c2794939291906119be565b6020604051602081039080840390855afa158015610c47573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c98575f60015f5f1b93509350935050610ca5565b805f5f5f1b935093509350505b9450945094915050565b828054828255905f5260205f20908101928215610cf5579160200282015b82811115610cf4578251829081610ce49190611b8f565b5091602001919060010190610ccd565b5b509050610d029190610d06565b5090565b5b80821115610d25575f8181610d1c9190610d29565b50600101610d07565b5090565b508054610d3590611408565b5f825580601f10610d465750610d63565b601f0160209004905f5260205f2090810190610d629190610d66565b5b50565b5b80821115610d7d575f815f905550600101610d67565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610dc681610d92565b8114610dd0575f5ffd5b50565b5f81359050610de181610dbd565b92915050565b5f60208284031215610dfc57610dfb610d8a565b5b5f610e0984828501610dd3565b91505092915050565b5f8115159050919050565b610e2681610e12565b82525050565b5f602082019050610e3f5f830184610e1d565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610eb082610e6e565b610eba8185610e78565b9350610eca818560208601610e88565b610ed381610e96565b840191505092915050565b5f610ee98383610ea6565b905092915050565b5f602082019050919050565b5f610f0782610e45565b610f118185610e4f565b935083602082028501610f2385610e5f565b805f5b85811015610f5e5784840389528151610f3f8582610ede565b9450610f4a83610ef1565b925060208a01995050600181019050610f26565b50829750879550505050505092915050565b5f6020820190508181035f830152610f888184610efd565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610fb982610f90565b9050919050565b610fc981610faf565b82525050565b5f602082019050610fe25f830184610fc0565b92915050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61102282610e96565b810181811067ffffffffffffffff8211171561104157611040610fec565b5b80604052505050565b5f611053610d81565b905061105f8282611019565b919050565b5f67ffffffffffffffff82111561107e5761107d610fec565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156110b1576110b0610fec565b5b6110ba82610e96565b9050602081019050919050565b828183375f83830152505050565b5f6110e76110e284611097565b61104a565b90508281526020810184848401111561110357611102611093565b5b61110e8482856110c7565b509392505050565b5f82601f83011261112a57611129610fe8565b5b813561113a8482602086016110d5565b91505092915050565b5f61115561115084611064565b61104a565b905080838252602082019050602084028301858111156111785761117761108f565b5b835b818110156111bf57803567ffffffffffffffff81111561119d5761119c610fe8565b5b8086016111aa8982611116565b8552602085019450505060208101905061117a565b5050509392505050565b5f82601f8301126111dd576111dc610fe8565b5b81356111ed848260208601611143565b91505092915050565b5f6020828403121561120b5761120a610d8a565b5b5f82013567ffffffffffffffff81111561122857611227610d8e565b5b611234848285016111c9565b91505092915050565b61124681610faf565b8114611250575f5ffd5b50565b5f813590506112618161123d565b92915050565b5f6020828403121561127c5761127b610d8a565b5b5f61128984828501611253565b91505092915050565b5f5ffd5b5f5f83601f8401126112ab576112aa610fe8565b5b8235905067ffffffffffffffff8111156112c8576112c7611292565b5b6020830191508360018202830111156112e4576112e361108f565b5b9250929050565b5f5f5f5f6040858703121561130357611302610d8a565b5b5f85013567ffffffffffffffff8111156113205761131f610d8e565b5b61132c87828801611296565b9450945050602085013567ffffffffffffffff81111561134f5761134e610d8e565b5b61135b87828801611296565b925092505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b5f61138d82611369565b6113978185611373565b93506113a7818560208601610e88565b6113b081610e96565b840191505092915050565b5f6020820190508181035f8301526113d38184611383565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061141f57607f821691505b602082108103611432576114316113db565b5b50919050565b5f81549050919050565b5f819050815f5260205f209050919050565b5f819050815f5260205f209050919050565b5f815461147281611408565b61147c8186610e78565b9450600182165f811461149657600181146114ac576114de565b60ff1983168652811515602002860193506114de565b6114b585611454565b5f5b838110156114d6578154818901526001820191506020810190506114b7565b808801955050505b50505092915050565b5f6114f28383611466565b905092915050565b5f600182019050919050565b5f61151082611438565b61151a8185610e4f565b93508360208202850161152c85611442565b805f5b858110156115665784840389528161154785826114e7565b9450611552836114fa565b925060208a0199505060018101905061152f565b50829750879550505050505092915050565b5f6115838385611373565b93506115908385846110c7565b61159983610e96565b840190509392505050565b6115ad81610d92565b82525050565b5f60a0820190506115c65f83018a610fc0565b81810360208301526115d88189611506565b905081810360408301526115ed818789611578565b90506115fc60608301866115a4565b818103608083015261160f818486611578565b905098975050505050505050565b5f67ffffffffffffffff82111561163757611636610fec565b5b61164082610e96565b9050602081019050919050565b5f61165f61165a8461161d565b61104a565b90508281526020810184848401111561167b5761167a611093565b5b6116868482856110c7565b509392505050565b5f82601f8301126116a2576116a1610fe8565b5b81356116b284826020860161164d565b91505092915050565b5f67ffffffffffffffff82169050919050565b6116d7816116bb565b81146116e1575f5ffd5b50565b5f813590506116f2816116ce565b92915050565b5f5f5f6060848603121561170f5761170e610d8a565b5b5f84013567ffffffffffffffff81111561172c5761172b610d8e565b5b6117388682870161168e565b9350506020611749868287016116e4565b925050604084013567ffffffffffffffff81111561176a57611769610d8e565b5b6117768682870161168e565b9150509250925092565b611789816116bb565b82525050565b5f6020820190506117a25f830184611780565b92915050565b5f81905092915050565b7f19000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6117e66002836117a8565b91506117f1826117b2565b600282019050919050565b5f8160601b9050919050565b5f611812826117fc565b9050919050565b5f61182382611808565b9050919050565b61183b61183682610faf565b611819565b82525050565b5f8160c01b9050919050565b5f61185782611841565b9050919050565b61186f61186a826116bb565b61184d565b82525050565b5f819050919050565b5f819050919050565b61189861189382611875565b61187e565b82525050565b5f6118a8826117da565b91506118b4828761182a565b6014820191506118c4828661185e565b6008820191506118d48285611887565b6020820191506118e48284611887565b60208201915081905095945050505050565b5f6040820190506119095f830185610fc0565b6119166020830184610fc0565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050919050565b61195c8161194a565b82525050565b5f6020820190506119755f830184611953565b92915050565b61198481611875565b82525050565b5f60208201905061199d5f83018461197b565b92915050565b5f60ff82169050919050565b6119b8816119a3565b82525050565b5f6080820190506119d15f83018761197b565b6119de60208301866119af565b6119eb604083018561197b565b6119f8606083018461197b565b95945050505050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302611a4b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611a10565b611a558683611a10565b95508019841693508086168417925050509392505050565b5f819050919050565b5f611a90611a8b611a868461194a565b611a6d565b61194a565b9050919050565b5f819050919050565b611aa983611a76565b611abd611ab582611a97565b848454611a1c565b825550505050565b5f5f905090565b611ad4611ac5565b611adf818484611aa0565b505050565b5b81811015611b0257611af75f82611acc565b600181019050611ae5565b5050565b601f821115611b4757611b1881611454565b611b2184611a01565b81016020851015611b30578190505b611b44611b3c85611a01565b830182611ae4565b50505b505050565b5f82821c905092915050565b5f611b675f1984600802611b4c565b1980831691505092915050565b5f611b7f8383611b58565b9150826002028217905092915050565b611b9882610e6e565b67ffffffffffffffff811115611bb157611bb0610fec565b5b611bbb8254611408565b611bc6828285611b06565b5f60209050601f831160018114611bf7575f8415611be5578287015190505b611bef8582611b74565b865550611c56565b601f198416611c0586611454565b5f5b82811015611c2c57848901518255600182019150602085019450602081019050611c07565b86831015611c495784890151611c45601f891682611b58565b8355505b6001600288020188555050505b50505050505056fea26469706673582212208e949cfdb26a2620484e64238127fb119268358a92cab6fa128aceed74302a5964736f6c634300081e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000dfc622f06efdd0e830d82f30679a3c9302bc7940000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003a68747470733a2f2f6170692e73746179636c6f616b65642e78797a2f656e732f676174657761792f7b68617264636f6465642d73656e6465727d000000000000
-----Decoded View---------------
Arg [0] : signer_ (address): 0xDFc622F06EfDD0E830d82f30679A3C9302BC7940
Arg [1] : gateways_ (string[]): https://api.staycloaked.xyz/ens/gateway/{hardcoded-sender}
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000dfc622f06efdd0e830d82f30679a3c9302bc7940
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [4] : 000000000000000000000000000000000000000000000000000000000000003a
Arg [5] : 68747470733a2f2f6170692e73746179636c6f616b65642e78797a2f656e732f
Arg [6] : 676174657761792f7b68617264636f6465642d73656e6465727d000000000000
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.