Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 8,547 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Ccip Send | 19398420 | 259 days ago | IN | 0.00000047 ETH | 0.00426892 | ||||
Ccip Send | 19398419 | 259 days ago | IN | 0.00007085 ETH | 0.00423104 | ||||
Ccip Send | 19398419 | 259 days ago | IN | 0.00017257 ETH | 0.00423104 | ||||
Ccip Send | 19380659 | 261 days ago | IN | 0.00014823 ETH | 0.00869017 | ||||
Ccip Send | 19380650 | 261 days ago | IN | 0.0000284 ETH | 0.00799512 | ||||
Ccip Send | 19380362 | 261 days ago | IN | 0.00014678 ETH | 0.00661004 | ||||
Ccip Send | 19380357 | 261 days ago | IN | 0.0000174 ETH | 0.00737206 | ||||
Ccip Send | 19380061 | 261 days ago | IN | 0.00014396 ETH | 0.00834885 | ||||
Ccip Send | 19380060 | 261 days ago | IN | 0.00001211 ETH | 0.00776362 | ||||
Ccip Send | 19380055 | 261 days ago | IN | 0.00000874 ETH | 0.00372381 | ||||
Ccip Send | 19380054 | 261 days ago | IN | 0.00003975 ETH | 0.00735739 | ||||
Ccip Send | 19380053 | 261 days ago | IN | 0.00015826 ETH | 0.00757436 | ||||
Ccip Send | 19326071 | 269 days ago | IN | 0.00017151 ETH | 0.00792733 | ||||
Ccip Send | 19325776 | 269 days ago | IN | 0.00017151 ETH | 0.00549307 | ||||
Ccip Send | 19325485 | 269 days ago | IN | 0.00015957 ETH | 0.00630995 | ||||
Ccip Send | 19325185 | 269 days ago | IN | 0.00015957 ETH | 0.00586785 | ||||
Ccip Send | 19324888 | 269 days ago | IN | 0.00017117 ETH | 0.00586148 | ||||
Ccip Send | 19324591 | 269 days ago | IN | 0.00017117 ETH | 0.00492214 | ||||
Ccip Send | 19324306 | 269 days ago | IN | 0.00001322 ETH | 0.00406252 | ||||
Ccip Send | 19324291 | 269 days ago | IN | 0.00015959 ETH | 0.00442148 | ||||
Ccip Send | 19324008 | 269 days ago | IN | 0.00001322 ETH | 0.00418713 | ||||
Ccip Send | 19323993 | 269 days ago | IN | 0.00015959 ETH | 0.00441653 | ||||
Ccip Send | 19323712 | 269 days ago | IN | 0.00001196 ETH | 0.00475076 | ||||
Ccip Send | 19323699 | 269 days ago | IN | 0.00015995 ETH | 0.00464841 | ||||
Ccip Send | 19323415 | 269 days ago | IN | 0.00001196 ETH | 0.00401703 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19838714 | 197 days ago | 0.00012511 ETH | ||||
19838714 | 197 days ago | 0.00012511 ETH | ||||
19695832 | 217 days ago | 0.00111602 ETH | ||||
19695832 | 217 days ago | 0.00111602 ETH | ||||
19558064 | 236 days ago | 0.00014871 ETH | ||||
19558064 | 236 days ago | 0.00014871 ETH | ||||
19458745 | 250 days ago | 0.00174261 ETH | ||||
19458745 | 250 days ago | 0.00174261 ETH | ||||
19407525 | 257 days ago | 0.00023727 ETH | ||||
19407525 | 257 days ago | 0.00023727 ETH | ||||
19385267 | 260 days ago | 0.0024086 ETH | ||||
19385267 | 260 days ago | 0.0024086 ETH | ||||
19381731 | 261 days ago | 0.0036762 ETH | ||||
19381731 | 261 days ago | 0.0036762 ETH | ||||
19381526 | 261 days ago | 0.0012525 ETH | ||||
19381526 | 261 days ago | 0.0012525 ETH | ||||
19380659 | 261 days ago | 0.00014823 ETH | ||||
19380650 | 261 days ago | 0.0000284 ETH | ||||
19380362 | 261 days ago | 0.00014678 ETH | ||||
19380357 | 261 days ago | 0.0000174 ETH | ||||
19380061 | 261 days ago | 0.00014396 ETH | ||||
19380060 | 261 days ago | 0.00001211 ETH | ||||
19380054 | 261 days ago | 0.00003975 ETH | ||||
19380053 | 261 days ago | 0.00015826 ETH | ||||
19337018 | 267 days ago | 0.00027652 ETH |
Loading...
Loading
Contract Name:
Router
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 26000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; import {IRouterClient} from "./interfaces/IRouterClient.sol"; import {IRouter} from "./interfaces/IRouter.sol"; import {IEVM2AnyOnRamp} from "./interfaces/IEVM2AnyOnRamp.sol"; import {IARM} from "./interfaces/IARM.sol"; import {IWrappedNative} from "./interfaces/IWrappedNative.sol"; import {IAny2EVMMessageReceiver} from "./interfaces/IAny2EVMMessageReceiver.sol"; import {Client} from "./libraries/Client.sol"; import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; import {EnumerableMap} from "../vendor/openzeppelin-solidity/v4.8.0/utils/structs/EnumerableMap.sol"; import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.0/token/ERC20/utils/SafeERC20.sol"; import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.0/token/ERC20/IERC20.sol"; /// @title Router /// @notice This is the entry point for the end user wishing to send data across chains. /// @dev This contract is used as a router for both on-ramps and off-ramps contract Router is IRouter, IRouterClient, TypeAndVersionInterface, OwnerIsCreator { using SafeERC20 for IERC20; using EnumerableMap for EnumerableMap.AddressToUintMap; error FailedToSendValue(); error InvalidRecipientAddress(address to); error OffRampMismatch(); error BadARMSignal(); event OnRampSet(uint64 indexed destChainSelector, address onRamp); event OffRampAdded(uint64 indexed sourceChainSelector, address offRamp); event OffRampRemoved(uint64 indexed sourceChainSelector, address offRamp); event MessageExecuted(bytes32 messageId, uint64 sourceChainSelector, address offRamp, bytes32 calldataHash); struct OnRamp { uint64 destChainSelector; address onRamp; } struct OffRamp { uint64 sourceChainSelector; address offRamp; } // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables string public constant override typeAndVersion = "Router 1.0.0"; // We limit return data to a selector plus 4 words. This is to avoid // malicious contracts from returning large amounts of data and causing // repeated out-of-gas scenarios. uint16 public constant MAX_RET_BYTES = 4 + 4 * 32; // STATIC CONFIG // Address of arm proxy contract. address private immutable i_armProxy; // DYNAMIC CONFIG address private s_wrappedNative; // destChainSelector => onRamp address // Only ever one onRamp enabled at a time for a given destChainSelector. mapping(uint256 destChainSelector => address onRamp) private s_onRamps; // Mapping of offRamps to source chain ids // Can be multiple offRamps enabled at a time for a given sourceChainSelector, // for example during an no downtime upgrade while v1 messages are being flushed. EnumerableMap.AddressToUintMap private s_offRamps; constructor(address wrappedNative, address armProxy) { // Zero address indicates unsupported auto-wrapping, therefore, unsupported // native fee token payments. s_wrappedNative = wrappedNative; i_armProxy = armProxy; } // ================================================================ // | Message sending | // ================================================================ /// @inheritdoc IRouterClient function getFee( uint64 destinationChainSelector, Client.EVM2AnyMessage memory message ) external view returns (uint256 fee) { if (message.feeToken == address(0)) { // For empty feeToken return native quote. message.feeToken = address(s_wrappedNative); } address onRamp = s_onRamps[destinationChainSelector]; if (onRamp == address(0)) revert UnsupportedDestinationChain(destinationChainSelector); return IEVM2AnyOnRamp(onRamp).getFee(message); } /// @inheritdoc IRouterClient function getSupportedTokens(uint64 chainSelector) external view returns (address[] memory) { if (!isChainSupported(chainSelector)) { return new address[](0); } return IEVM2AnyOnRamp(s_onRamps[uint256(chainSelector)]).getSupportedTokens(); } /// @inheritdoc IRouterClient function isChainSupported(uint64 chainSelector) public view returns (bool) { return s_onRamps[chainSelector] != address(0); } /// @inheritdoc IRouterClient function ccipSend( uint64 destinationChainSelector, Client.EVM2AnyMessage memory message ) external payable whenHealthy returns (bytes32) { address onRamp = s_onRamps[destinationChainSelector]; if (onRamp == address(0)) revert UnsupportedDestinationChain(destinationChainSelector); uint256 feeTokenAmount; // address(0) signals payment in true native if (message.feeToken == address(0)) { // for fee calculation we check the wrapped native price as we wrap // as part of the native fee coin payment. message.feeToken = s_wrappedNative; feeTokenAmount = IEVM2AnyOnRamp(onRamp).getFee(message); // Ensure sufficient native. if (msg.value < feeTokenAmount) revert InsufficientFeeTokenAmount(); // Wrap and send native payment. // Note we take the whole msg.value regardless if its larger. feeTokenAmount = msg.value; IWrappedNative(message.feeToken).deposit{value: feeTokenAmount}(); IERC20(message.feeToken).safeTransfer(onRamp, feeTokenAmount); } else { if (msg.value > 0) revert InvalidMsgValue(); feeTokenAmount = IEVM2AnyOnRamp(onRamp).getFee(message); IERC20(message.feeToken).safeTransferFrom(msg.sender, onRamp, feeTokenAmount); } // Transfer the tokens to the token pools. for (uint256 i = 0; i < message.tokenAmounts.length; ++i) { IERC20 token = IERC20(message.tokenAmounts[i].token); token.safeTransferFrom( msg.sender, address(IEVM2AnyOnRamp(onRamp).getPoolBySourceToken(token)), message.tokenAmounts[i].amount ); } return IEVM2AnyOnRamp(onRamp).forwardFromRouter(message, feeTokenAmount, msg.sender); } // ================================================================ // | Message execution | // ================================================================ /// @inheritdoc IRouter /// @dev Handles the edge case where we want to pass a specific amount of gas, /// @dev but EIP-150 sends all but 1/64 of the remaining gas instead so the user gets /// @dev less gas than they paid for. The other 2 parts of EIP-150 do not apply since /// @dev a) we hard code value=0 and b) we ensure code already exists. /// @dev If we revert instead, then that will never happen. /// @dev Separately we capture the return data up to a maximum size to avoid return bombs, /// @dev borrowed from https://github.com/nomad-xyz/ExcessivelySafeCall/blob/main/src/ExcessivelySafeCall.sol. function routeMessage( Client.Any2EVMMessage calldata message, uint16 gasForCallExactCheck, uint256 gasLimit, address receiver ) external override onlyOffRamp(message.sourceChainSelector) whenHealthy returns (bool success, bytes memory retData) { // We encode here instead of the offRamps to constrain specifically what functions // can be called from the router. bytes memory data = abi.encodeWithSelector(IAny2EVMMessageReceiver.ccipReceive.selector, message); // allocate retData memory ahead of time retData = new bytes(MAX_RET_BYTES); // solhint-disable-next-line no-inline-assembly assembly { // solidity calls check that a contract actually exists at the destination, so we do the same // Note we do this check prior to measuring gas so gasForCallExactCheck (our "cushion") // doesn't need to account for it. if iszero(extcodesize(receiver)) { revert(0, 0) } let g := gas() // Compute g -= gasForCallExactCheck and check for underflow // The gas actually passed to the callee is _min(gasAmount, 63//64*gas available). // We want to ensure that we revert if gasAmount > 63//64*gas available // as we do not want to provide them with less, however that check itself costs // gas. gasForCallExactCheck ensures we have at least enough gas to be able // to revert if gasAmount > 63//64*gas available. if lt(g, gasForCallExactCheck) { revert(0, 0) } g := sub(g, gasForCallExactCheck) // if g - g//64 <= gasAmount, revert // (we subtract g//64 because of EIP-150) if iszero(gt(sub(g, div(g, 64)), gasLimit)) { revert(0, 0) } // call and return whether we succeeded. ignore return data // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) success := call(gasLimit, receiver, 0, add(data, 0x20), mload(data), 0, 0) // limit our copy to MAX_RET_BYTES bytes let toCopy := returndatasize() if gt(toCopy, MAX_RET_BYTES) { toCopy := MAX_RET_BYTES } // Store the length of the copied bytes mstore(retData, toCopy) // copy the bytes from retData[0:_toCopy] returndatacopy(add(retData, 0x20), 0, toCopy) } emit MessageExecuted(message.messageId, message.sourceChainSelector, msg.sender, keccak256(data)); return (success, retData); } // ================================================================ // | Config | // ================================================================ /// @notice Gets the wrapped representation of the native fee coin. /// @return The address of the ERC20 wrapped native. function getWrappedNative() external view returns (address) { return s_wrappedNative; } /// @notice Sets a new wrapped native token. /// @param wrappedNative The address of the new wrapped native ERC20 token. function setWrappedNative(address wrappedNative) external onlyOwner { s_wrappedNative = wrappedNative; } /// @notice Gets the arm address /// @return The address of the ARM proxy contract. function getArmProxy() external view returns (address) { return i_armProxy; } /// @notice Return the configured onramp for specific a destination chain. /// @param destChainSelector The destination chain Id to get the onRamp for. /// @return The address of the onRamp. function getOnRamp(uint64 destChainSelector) external view returns (address) { return s_onRamps[destChainSelector]; } /// @notice Return a full list of configured offRamps. function getOffRamps() external view returns (OffRamp[] memory) { OffRamp[] memory offRamps = new OffRamp[](s_offRamps.length()); for (uint256 i = 0; i < offRamps.length; ++i) { (address offRamp, uint256 sourceChainSelector) = s_offRamps.at(i); offRamps[i] = OffRamp({sourceChainSelector: uint64(sourceChainSelector), offRamp: offRamp}); } return offRamps; } /// @notice Returns true if the given address is a permissioned offRamp /// and sourceChainSelector if so. function isOffRamp(address offRamp) external view returns (bool, uint64) { (bool exists, uint256 sourceChainSelector) = s_offRamps.tryGet(offRamp); return (exists, uint64(sourceChainSelector)); } /// @notice applyRampUpdates applies a set of ramp changes which provides /// the ability to add new chains and upgrade ramps. function applyRampUpdates( OnRamp[] calldata onRampUpdates, OffRamp[] calldata offRampRemoves, OffRamp[] calldata offRampAdds ) external onlyOwner { // Apply egress updates. // We permit zero address as way to disable egress. for (uint256 i = 0; i < onRampUpdates.length; ++i) { OnRamp memory onRampUpdate = onRampUpdates[i]; s_onRamps[onRampUpdate.destChainSelector] = onRampUpdate.onRamp; emit OnRampSet(onRampUpdate.destChainSelector, onRampUpdate.onRamp); } // Apply ingress updates. // We permit an empty list as a way to disable ingress. for (uint256 i = 0; i < offRampRemoves.length; ++i) { uint64 rampSelector = offRampRemoves[i].sourceChainSelector; address rampAddress = offRampRemoves[i].offRamp; if (s_offRamps.get(rampAddress) != uint256(rampSelector)) revert OffRampMismatch(); if (s_offRamps.remove(rampAddress)) { emit OffRampRemoved(rampSelector, rampAddress); } } for (uint256 i = 0; i < offRampAdds.length; ++i) { uint64 rampSelector = offRampAdds[i].sourceChainSelector; address rampAddress = offRampAdds[i].offRamp; if (s_offRamps.set(rampAddress, rampSelector)) { emit OffRampAdded(rampSelector, rampAddress); } } } /// @notice Provides the ability for the owner to recover any tokens accidentally /// sent to this contract. /// @dev Must be onlyOwner to avoid malicious token contract calls. /// @param tokenAddress ERC20-token to recover /// @param to Destination address to send the tokens to. function recoverTokens(address tokenAddress, address to, uint256 amount) external onlyOwner { if (to == address(0)) revert InvalidRecipientAddress(to); if (tokenAddress == address(0)) { (bool success, ) = to.call{value: amount}(""); if (!success) revert FailedToSendValue(); return; } IERC20(tokenAddress).safeTransfer(to, amount); } // ================================================================ // | Access | // ================================================================ /// @notice only lets permissioned offRamps execute /// @dev We additionally restrict offRamps to specific source chains for defense in depth. modifier onlyOffRamp(uint64 expectedSourceChainSelector) { (bool exists, uint256 sourceChainSelector) = s_offRamps.tryGet(msg.sender); if (!exists || expectedSourceChainSelector != uint64(sourceChainSelector)) revert OnlyOffRamp(); _; } /// @notice Ensure that the ARM has not emitted a bad signal, and that the latest heartbeat is not stale. modifier whenHealthy() { if (IARM(i_armProxy).isCursed()) revert BadARMSignal(); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; abstract contract TypeAndVersionInterface { function typeAndVersion() external pure virtual returns (string memory); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {Client} from "../libraries/Client.sol"; interface IRouterClient { error UnsupportedDestinationChain(uint64 destChainSelector); error InsufficientFeeTokenAmount(); error InvalidMsgValue(); /// @notice Checks if the given chain ID is supported for sending/receiving. /// @param chainSelector The chain to check. /// @return supported is true if it is supported, false if not. function isChainSupported(uint64 chainSelector) external view returns (bool supported); /// @notice Gets a list of all supported tokens which can be sent or received /// to/from a given chain id. /// @param chainSelector The chainSelector. /// @return tokens The addresses of all tokens that are supported. function getSupportedTokens(uint64 chainSelector) external view returns (address[] memory tokens); /// @param destinationChainSelector The destination chainSelector /// @param message The cross-chain CCIP message including data and/or tokens /// @return fee returns guaranteed execution fee for the specified message /// delivery to destination chain /// @dev returns 0 fee on invalid message. function getFee( uint64 destinationChainSelector, Client.EVM2AnyMessage memory message ) external view returns (uint256 fee); /// @notice Request a message to be sent to the destination chain /// @param destinationChainSelector The destination chain ID /// @param message The cross-chain CCIP message including data and/or tokens /// @return messageId The message ID /// @dev Note if msg.value is larger than the required fee (from getFee) we accept /// the overpayment with no refund. function ccipSend( uint64 destinationChainSelector, Client.EVM2AnyMessage calldata message ) external payable returns (bytes32); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {Client} from "../libraries/Client.sol"; interface IRouter { error OnlyOffRamp(); /// @notice Route the message to its intended receiver contract. /// @param message Client.Any2EVMMessage struct. /// @param gasForCallExactCheck of params for exec /// @param gasLimit set of params for exec /// @param receiver set of params for exec /// @dev if the receiver is a contracts that signals support for CCIP execution through EIP-165. /// the contract is called. If not, only tokens are transferred. /// @return success A boolean value indicating whether the ccip message was received without errors. /// @return retBytes A bytes array containing return data form CCIP receiver. function routeMessage( Client.Any2EVMMessage calldata message, uint16 gasForCallExactCheck, uint256 gasLimit, address receiver ) external returns (bool success, bytes memory retBytes); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IPool} from "./pools/IPool.sol"; import {Client} from "../libraries/Client.sol"; import {Internal} from "../libraries/Internal.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/token/ERC20/IERC20.sol"; interface IEVM2AnyOnRamp { /// @notice Get the fee for a given ccip message /// @param message The message to calculate the cost for /// @return fee The calculated fee function getFee(Client.EVM2AnyMessage calldata message) external view returns (uint256 fee); /// @notice Get the pool for a specific token /// @param sourceToken The source chain token to get the pool for /// @return pool Token pool function getPoolBySourceToken(IERC20 sourceToken) external view returns (IPool); /// @notice Gets a list of all supported source chain tokens. /// @return tokens The addresses of all tokens that this onRamp supports for sending. function getSupportedTokens() external view returns (address[] memory tokens); /// @notice Gets the next sequence number to be used in the onRamp /// @return the next sequence number to be used function getExpectedNextSequenceNumber() external view returns (uint64); /// @notice Get the next nonce for a given sender /// @param sender The sender to get the nonce for /// @return nonce The next nonce for the sender function getSenderNonce(address sender) external view returns (uint64 nonce); /// @notice Adds and removed token pools. /// @param removes The tokens and pools to be removed /// @param adds The tokens and pools to be added. function applyPoolUpdates(Internal.PoolUpdate[] memory removes, Internal.PoolUpdate[] memory adds) external; /// @notice Send a message to the remote chain /// @dev only callable by the Router /// @dev approve() must have already been called on the token using the this ramp address as the spender. /// @dev if the contract is paused, this function will revert. /// @param message Message struct to send /// @param originalSender The original initiator of the CCIP request function forwardFromRouter( Client.EVM2AnyMessage memory message, uint256 feeTokenAmount, address originalSender ) external returns (bytes32); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; /// @notice This interface contains the only ARM-related functions that might be used on-chain by other CCIP contracts. interface IARM { /// @notice A Merkle root tagged with the address of the commit store contract it is destined for. struct TaggedRoot { address commitStore; bytes32 root; } /// @notice Callers MUST NOT cache the return value as a blessed tagged root could become unblessed. function isBlessed(TaggedRoot calldata taggedRoot) external view returns (bool); /// @notice When the ARM is "cursed", CCIP pauses until the curse is lifted. function isCursed() external view returns (bool); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/token/ERC20/IERC20.sol"; interface IWrappedNative is IERC20 { function deposit() external payable; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {Client} from "../libraries/Client.sol"; /// @notice Application contracts that intend to receive messages from /// the router should implement this interface. interface IAny2EVMMessageReceiver { /// @notice Called by the Router to deliver a message. /// If this reverts, any token transfers also revert. The message /// will move to a FAILED state and become available for manual execution. /// @param message CCIP Message /// @dev Note ensure you check the msg.sender is the OffRampRouter function ccipReceive(Client.Any2EVMMessage calldata message) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; // End consumer library. library Client { struct EVMTokenAmount { address token; // token address on the local chain. uint256 amount; // Amount of tokens. } struct Any2EVMMessage { bytes32 messageId; // MessageId corresponding to ccipSend on source. uint64 sourceChainSelector; // Source chain selector. bytes sender; // abi.decode(sender) if coming from an EVM chain. bytes data; // payload sent in original message. EVMTokenAmount[] destTokenAmounts; // Tokens and their amounts in their destination chain representation. } // If extraArgs is empty bytes, the default is 200k gas limit and strict = false. struct EVM2AnyMessage { bytes receiver; // abi.encode(receiver address) for dest EVM chains bytes data; // Data payload EVMTokenAmount[] tokenAmounts; // Token transfers address feeToken; // Address of feeToken. address(0) means you will send msg.value. bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV1) } // extraArgs will evolve to support new features // bytes4(keccak256("CCIP EVMExtraArgsV1")); bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9; struct EVMExtraArgsV1 { uint256 gasLimit; // ATTENTION!!! MAX GAS LIMIT 4M FOR BETA TESTING bool strict; // See strict sequencing details below. } function _argsToBytes(EVMExtraArgsV1 memory extraArgs) internal pure returns (bytes memory bts) { return abi.encodeWithSelector(EVM_EXTRA_ARGS_V1_TAG, extraArgs); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {ConfirmedOwner} from "../../ConfirmedOwner.sol"; /// @title The OwnerIsCreator contract /// @notice A contract with helpers for basic contract ownership. contract OwnerIsCreator is ConfirmedOwner { constructor() ConfirmedOwner(msg.sender) {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableMap.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableMap.js. pragma solidity ^0.8.0; import "./EnumerableSet.sol"; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * The following map types are supported: * * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0 * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableMap. * ==== */ library EnumerableMap { using EnumerableSet for EnumerableSet.Bytes32Set; // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct Bytes32ToBytes32Map { // Storage of keys EnumerableSet.Bytes32Set _keys; mapping(bytes32 => bytes32) _values; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value ) internal returns (bool) { map._values[key] = value; return map._keys.add(key); } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { delete map._values[key]; return map._keys.remove(key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { return map._keys.contains(key); } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { return map._keys.length(); } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { bytes32 key = map._keys.at(index); return (key, map._values[key]); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { bytes32 value = map._values[key]; if (value == bytes32(0)) { return (contains(map, key), bytes32(0)); } else { return (true, value); } } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key"); return value; } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( Bytes32ToBytes32Map storage map, bytes32 key, string memory errorMessage ) internal view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || contains(map, key), errorMessage); return value; } // UintToUintMap struct UintToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( UintToUintMap storage map, uint256 key, uint256 value ) internal returns (bool) { return set(map._inner, bytes32(key), bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { return remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { return contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) { (bytes32 key, bytes32 value) = at(map._inner, index); return (uint256(key), uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) { (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { return uint256(get(map._inner, bytes32(key))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( UintToUintMap storage map, uint256 key, string memory errorMessage ) internal view returns (uint256) { return uint256(get(map._inner, bytes32(key), errorMessage)); } // UintToAddressMap struct UintToAddressMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( UintToAddressMap storage map, uint256 key, address value ) internal returns (bool) { return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( UintToAddressMap storage map, uint256 key, string memory errorMessage ) internal view returns (address) { return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage)))); } // AddressToUintMap struct AddressToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( AddressToUintMap storage map, address key, uint256 value ) internal returns (bool) { return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToUintMap storage map, address key) internal returns (bool) { return remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToUintMap storage map, address key) internal view returns (bool) { return contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { (bytes32 key, bytes32 value) = at(map._inner, index); return (address(uint160(uint256(key))), uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToUintMap storage map, address key) internal view returns (uint256) { return uint256(get(map._inner, bytes32(uint256(uint160(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( AddressToUintMap storage map, address key, string memory errorMessage ) internal view returns (uint256) { return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage)); } // Bytes32ToUintMap struct Bytes32ToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( Bytes32ToUintMap storage map, bytes32 key, uint256 value ) internal returns (bool) { return set(map._inner, key, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { return remove(map._inner, key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { return contains(map._inner, key); } /** * @dev Returns the number of elements in the map. O(1). */ function length(Bytes32ToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) { (bytes32 key, bytes32 value) = at(map._inner, index); return (key, uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) { (bool success, bytes32 value) = tryGet(map._inner, key); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { return uint256(get(map._inner, key)); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( Bytes32ToUintMap storage map, bytes32 key, string memory errorMessage ) internal view returns (uint256) { return uint256(get(map._inner, key, errorMessage)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/token/ERC20/IERC20.sol"; // Shared public interface for multiple pool types. // Each pool type handles a different child token model (lock/unlock, mint/burn.) interface IPool { /// @notice Lock tokens into the pool or burn the tokens. /// @param originalSender Original sender of the tokens. /// @param receiver Receiver of the tokens on destination chain. /// @param amount Amount to lock or burn. /// @param destChainSelector Destination chain Id. /// @param extraArgs Additional data passed in by sender for lockOrBurn processing /// in custom pools on source chain. /// @return retData Optional field that contains bytes. Unused for now but already /// implemented to allow future upgrades while preserving the interface. function lockOrBurn( address originalSender, bytes calldata receiver, uint256 amount, uint64 destChainSelector, bytes calldata extraArgs ) external returns (bytes memory); /// @notice Releases or mints tokens to the receiver address. /// @param originalSender Original sender of the tokens. /// @param receiver Receiver of the tokens. /// @param amount Amount to release or mint. /// @param sourceChainSelector Source chain Id. /// @param extraData Additional data supplied offchain for releaseOrMint processing in /// custom pools on dest chain. This could be an attestation that was retrieved through a /// third party API. /// @dev offchainData can come from any untrusted source. function releaseOrMint( bytes memory originalSender, address receiver, uint256 amount, uint64 sourceChainSelector, bytes memory extraData ) external; /// @notice Gets the IERC20 token that this pool can lock or burn. /// @return token The IERC20 token representation. function getToken() external view returns (IERC20 token); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {Client} from "./Client.sol"; import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol"; // Library for CCIP internal definitions common to multiple contracts. library Internal { struct PriceUpdates { TokenPriceUpdate[] tokenPriceUpdates; uint64 destChainSelector; // --┐ Destination chain selector uint192 usdPerUnitGas; // -----┘ 1e18 USD per smallest unit (e.g. wei) of destination chain gas } struct TokenPriceUpdate { address sourceToken; // Source token uint192 usdPerToken; // 1e18 USD per smallest unit of token } struct TimestampedUint192Value { uint192 value; // -------┐ The price, in 1e18 USD. uint64 timestamp; // ----┘ Timestamp of the most recent price update. } struct PoolUpdate { address token; // The IERC20 token address address pool; // The token pool address } struct ExecutionReport { EVM2EVMMessage[] messages; // Contains a bytes array for each message // each inner bytes array contains bytes per transferred token bytes[][] offchainTokenData; bytes32[] proofs; uint256 proofFlagBits; } // @notice The cross chain message that gets committed to EVM chains struct EVM2EVMMessage { uint64 sourceChainSelector; uint64 sequenceNumber; uint256 feeTokenAmount; address sender; uint64 nonce; uint256 gasLimit; bool strict; // User fields address receiver; bytes data; Client.EVMTokenAmount[] tokenAmounts; address feeToken; bytes32 messageId; } function _toAny2EVMMessage( EVM2EVMMessage memory original, Client.EVMTokenAmount[] memory destTokenAmounts ) internal pure returns (Client.Any2EVMMessage memory message) { message = Client.Any2EVMMessage({ messageId: original.messageId, sourceChainSelector: original.sourceChainSelector, sender: abi.encode(original.sender), data: original.data, destTokenAmounts: destTokenAmounts }); } bytes32 internal constant EVM_2_EVM_MESSAGE_HASH = keccak256("EVM2EVMMessageEvent"); function _hash(EVM2EVMMessage memory original, bytes32 metadataHash) internal pure returns (bytes32) { return keccak256( abi.encode( MerkleMultiProof.LEAF_DOMAIN_SEPARATOR, metadataHash, original.sequenceNumber, original.nonce, original.sender, original.receiver, keccak256(original.data), keccak256(abi.encode(original.tokenAmounts)), original.gasLimit, original.strict, original.feeToken, original.feeTokenAmount ) ); } /// @notice Enum listing the possible message execution states within /// the offRamp contract. /// UNTOUCHED never executed /// IN_PROGRESS currently being executed, used a replay protection /// SUCCESS successfully executed. End state /// FAILURE unsuccessfully executed, manual execution is now enabled. enum MessageExecutionState { UNTOUCHED, IN_PROGRESS, SUCCESS, FAILURE } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ConfirmedOwnerWithProposal.sol"; /** * @title The ConfirmedOwner contract * @notice A contract with helpers for basic contract ownership. */ contract ConfirmedOwner is ConfirmedOwnerWithProposal { constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library MerkleMultiProof { /// @notice Leaf domain separator, should be used as the first 32 bytes of a leaf's preimage. bytes32 internal constant LEAF_DOMAIN_SEPARATOR = 0x0000000000000000000000000000000000000000000000000000000000000000; /// @notice Internal domain separator, should be used as the first 32 bytes of an internal node's preiimage. bytes32 internal constant INTERNAL_DOMAIN_SEPARATOR = 0x0000000000000000000000000000000000000000000000000000000000000001; uint256 internal constant MAX_NUM_HASHES = 256; error InvalidProof(); error LeavesCannotBeEmpty(); /// @notice Computes the root based on provided pre-hashed leaf nodes in /// leaves, internal nodes in proofs, and using proofFlagBits' i-th bit to /// determine if an element of proofs or one of the previously computed leafs /// or internal nodes will be used for the i-th hash. /// @param leaves Should be pre-hashed and the first 32 bytes of a leaf's /// preimage should match LEAF_DOMAIN_SEPARATOR. /// @param proofs The hashes to be used instead of a leaf hash when the proofFlagBits /// indicates a proof should be used. /// @param proofFlagBits A single uint256 of which each bit indicates whether a leaf or /// a proof needs to be used in a hash operation. /// @dev the maximum number of hash operations it set to 256. Any input that would require /// more than 256 hashes to get to a root will revert. /// @dev For given input `leaves` = [a,b,c] `proofs` = [D] and `proofFlagBits` = 5 /// totalHashes = 3 + 1 - 1 = 3 /// ** round 1 ** /// proofFlagBits = (5 >> 0) & 1 = true /// hashes[0] = hashPair(a, b) /// (leafPos, hashPos, proofPos) = (2, 0, 0); /// /// ** round 2 ** /// proofFlagBits = (5 >> 1) & 1 = false /// hashes[1] = hashPair(D, c) /// (leafPos, hashPos, proofPos) = (3, 0, 1); /// /// ** round 3 ** /// proofFlagBits = (5 >> 2) & 1 = true /// hashes[2] = hashPair(hashes[0], hashes[1]) /// (leafPos, hashPos, proofPos) = (3, 2, 1); /// /// i = 3 and no longer < totalHashes. The algorithm is done /// return hashes[totalHashes - 1] = hashes[2]; the last hash we computed. // We mark this function as internal to force it to be inlined in contracts // that use it, but semantically it is public. // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function merkleRoot( bytes32[] memory leaves, bytes32[] memory proofs, uint256 proofFlagBits ) internal pure returns (bytes32) { unchecked { uint256 leavesLen = leaves.length; uint256 proofsLen = proofs.length; if (leavesLen == 0) revert LeavesCannotBeEmpty(); if (!(leavesLen <= MAX_NUM_HASHES + 1 && proofsLen <= MAX_NUM_HASHES + 1)) revert InvalidProof(); uint256 totalHashes = leavesLen + proofsLen - 1; if (!(totalHashes <= MAX_NUM_HASHES)) revert InvalidProof(); if (totalHashes == 0) { return leaves[0]; } bytes32[] memory hashes = new bytes32[](totalHashes); (uint256 leafPos, uint256 hashPos, uint256 proofPos) = (0, 0, 0); for (uint256 i = 0; i < totalHashes; ++i) { // Checks if the bit flag signals the use of a supplied proof or a leaf/previous hash. bytes32 a; if (proofFlagBits & (1 << i) == (1 << i)) { // Use a leaf or a previously computed hash. if (leafPos < leavesLen) { a = leaves[leafPos++]; } else { a = hashes[hashPos++]; } } else { // Use a supplied proof. a = proofs[proofPos++]; } // The second part of the hashed pair is never a proof as hashing two proofs would result in a // hash that can already be computed offchain. bytes32 b; if (leafPos < leavesLen) { b = leaves[leafPos++]; } else { b = hashes[hashPos++]; } if (!(hashPos <= i)) revert InvalidProof(); hashes[i] = _hashPair(a, b); } if (!(hashPos == totalHashes - 1 && leafPos == leavesLen && proofPos == proofsLen)) revert InvalidProof(); // Return the last hash. return hashes[totalHashes - 1]; } } /// @notice Hashes two bytes32 objects in their given order, prepended by the /// INTERNAL_DOMAIN_SEPARATOR. function _hashInternalNode(bytes32 left, bytes32 right) private pure returns (bytes32 hash) { return keccak256(abi.encode(INTERNAL_DOMAIN_SEPARATOR, left, right)); } /// @notice Hashes two bytes32 objects. The order is taken into account, /// using the lower value first. function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _hashInternalNode(a, b) : _hashInternalNode(b, a); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interfaces/OwnableInterface.sol"; /** * @title The ConfirmedOwner contract * @notice A contract with helpers for basic contract ownership. */ contract ConfirmedOwnerWithProposal is OwnableInterface { address private s_owner; address private s_pendingOwner; event OwnershipTransferRequested(address indexed from, address indexed to); event OwnershipTransferred(address indexed from, address indexed to); constructor(address newOwner, address pendingOwner) { require(newOwner != address(0), "Cannot set owner to zero"); s_owner = newOwner; if (pendingOwner != address(0)) { _transferOwnership(pendingOwner); } } /** * @notice Allows an owner to begin transferring ownership to a new address, * pending. */ function transferOwnership(address to) public override onlyOwner { _transferOwnership(to); } /** * @notice Allows an ownership transfer to be completed by the recipient. */ function acceptOwnership() external override { require(msg.sender == s_pendingOwner, "Must be proposed owner"); address oldOwner = s_owner; s_owner = msg.sender; s_pendingOwner = address(0); emit OwnershipTransferred(oldOwner, msg.sender); } /** * @notice Get the current owner */ function owner() public view override returns (address) { return s_owner; } /** * @notice validate, transfer ownership, and emit relevant events */ function _transferOwnership(address to) private { require(to != msg.sender, "Cannot transfer to self"); s_pendingOwner = to; emit OwnershipTransferRequested(s_owner, to); } /** * @notice validate access */ function _validateOwnership() internal view { require(msg.sender == s_owner, "Only callable by owner"); } /** * @notice Reverts if called by anyone other than the contract owner. */ modifier onlyOwner() { _validateOwnership(); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface OwnableInterface { function owner() external returns (address); function transferOwnership(address recipient) external; function acceptOwnership() external; }
{ "remappings": [ "@eth-optimism/=node_modules/@eth-optimism/", "@openzeppelin/=node_modules/@openzeppelin/", "ds-test/=foundry-lib/forge-std/lib/ds-test/src/", "erc4626-tests/=foundry-lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=foundry-lib/forge-std/src/", "hardhat/=node_modules/hardhat/", "openzeppelin-contracts/=foundry-lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 26000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"wrappedNative","type":"address"},{"internalType":"address","name":"armProxy","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BadARMSignal","type":"error"},{"inputs":[],"name":"FailedToSendValue","type":"error"},{"inputs":[],"name":"InsufficientFeeTokenAmount","type":"error"},{"inputs":[],"name":"InvalidMsgValue","type":"error"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"InvalidRecipientAddress","type":"error"},{"inputs":[],"name":"OffRampMismatch","type":"error"},{"inputs":[],"name":"OnlyOffRamp","type":"error"},{"inputs":[{"internalType":"uint64","name":"destChainSelector","type":"uint64"}],"name":"UnsupportedDestinationChain","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"messageId","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"indexed":false,"internalType":"address","name":"offRamp","type":"address"},{"indexed":false,"internalType":"bytes32","name":"calldataHash","type":"bytes32"}],"name":"MessageExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"indexed":false,"internalType":"address","name":"offRamp","type":"address"}],"name":"OffRampAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"indexed":false,"internalType":"address","name":"offRamp","type":"address"}],"name":"OffRampRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"destChainSelector","type":"uint64"},{"indexed":false,"internalType":"address","name":"onRamp","type":"address"}],"name":"OnRampSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"MAX_RET_BYTES","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"destChainSelector","type":"uint64"},{"internalType":"address","name":"onRamp","type":"address"}],"internalType":"struct Router.OnRamp[]","name":"onRampUpdates","type":"tuple[]"},{"components":[{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"offRamp","type":"address"}],"internalType":"struct Router.OffRamp[]","name":"offRampRemoves","type":"tuple[]"},{"components":[{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"offRamp","type":"address"}],"internalType":"struct Router.OffRamp[]","name":"offRampAdds","type":"tuple[]"}],"name":"applyRampUpdates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"destinationChainSelector","type":"uint64"},{"components":[{"internalType":"bytes","name":"receiver","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Client.EVMTokenAmount[]","name":"tokenAmounts","type":"tuple[]"},{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"bytes","name":"extraArgs","type":"bytes"}],"internalType":"struct Client.EVM2AnyMessage","name":"message","type":"tuple"}],"name":"ccipSend","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getArmProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"destinationChainSelector","type":"uint64"},{"components":[{"internalType":"bytes","name":"receiver","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Client.EVMTokenAmount[]","name":"tokenAmounts","type":"tuple[]"},{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"bytes","name":"extraArgs","type":"bytes"}],"internalType":"struct Client.EVM2AnyMessage","name":"message","type":"tuple"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOffRamps","outputs":[{"components":[{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"offRamp","type":"address"}],"internalType":"struct Router.OffRamp[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"destChainSelector","type":"uint64"}],"name":"getOnRamp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainSelector","type":"uint64"}],"name":"getSupportedTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWrappedNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainSelector","type":"uint64"}],"name":"isChainSupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"offRamp","type":"address"}],"name":"isOffRamp","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"messageId","type":"bytes32"},{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"bytes","name":"sender","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Client.EVMTokenAmount[]","name":"destTokenAmounts","type":"tuple[]"}],"internalType":"struct Client.Any2EVMMessage","name":"message","type":"tuple"},{"internalType":"uint16","name":"gasForCallExactCheck","type":"uint16"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"routeMessage","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"retData","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wrappedNative","type":"address"}],"name":"setWrappedNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162002dd438038062002dd48339810160408190526200003491620001af565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e7565b5050600280546001600160a01b0319166001600160a01b039485161790555016608052620001e7565b336001600160a01b03821603620001415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001aa57600080fd5b919050565b60008060408385031215620001c357600080fd5b620001ce8362000192565b9150620001de6020840162000192565b90509250929050565b608051612bc36200021160003960008181610238015281816106920152610b9b0152612bc36000f3fe6080604052600436106101295760003560e01c80638da5cb5b116100a5578063a8d87a3b11610074578063e861e90711610059578063e861e90714610428578063f2fde38b14610453578063fbca3b741461047357600080fd5b8063a8d87a3b146103bb578063da5fcac81461040857600080fd5b80638da5cb5b146102fc57806396f4e9f914610327578063a40e69c71461033a578063a48a90581461035c57600080fd5b80635246492f116100fc5780635f3e849f116100e15780635f3e849f1461029f578063787350e3146102bf57806379ba5097146102e757600080fd5b80635246492f1461022957806352cb60ca1461027d57600080fd5b8063181f5a771461012e5780631d7a74a01461018d57806320487ded146101cd5780633cf97983146101fb575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280600c81526020017f526f7574657220312e302e30000000000000000000000000000000000000000081525081565b6040516101849190612032565b60405180910390f35b34801561019957600080fd5b506101ad6101a8366004612077565b6104a0565b60408051921515835267ffffffffffffffff909116602083015201610184565b3480156101d957600080fd5b506101ed6101e83660046122c0565b6104bc565b604051908152602001610184565b34801561020757600080fd5b5061021b6102163660046123bd565b610612565b604051610184929190612435565b34801561023557600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561028957600080fd5b5061029d610298366004612077565b6108fd565b005b3480156102ab57600080fd5b5061029d6102ba366004612450565b61094c565b3480156102cb57600080fd5b506102d4608481565b60405161ffff9091168152602001610184565b3480156102f357600080fd5b5061029d610a9a565b34801561030857600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610258565b6101ed6103353660046122c0565b610b97565b34801561034657600080fd5b5061034f611122565b6040516101849190612491565b34801561036857600080fd5b506103ab610377366004612500565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b6040519015158152602001610184565b3480156103c757600080fd5b506102586103d6366004612500565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b34801561041457600080fd5b5061029d610423366004612560565b611219565b34801561043457600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff16610258565b34801561045f57600080fd5b5061029d61046e366004612077565b611524565b34801561047f57600080fd5b5061049361048e366004612500565b611538565b60405161018491906125fa565b60008080806104b0600486611651565b90969095509350505050565b606081015160009073ffffffffffffffffffffffffffffffffffffffff166104fd5760025473ffffffffffffffffffffffffffffffffffffffff1660608301525b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610575576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024015b60405180910390fd5b6040517f38724a9500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216906338724a95906105c7908690600401612731565b602060405180830381865afa1580156105e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106089190612744565b9150505b92915050565b600060606106266040870160208801612500565b600080610634600433611651565b9150915081158061065957508067ffffffffffffffff168367ffffffffffffffff1614155b15610690576040517fd2316ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071f919061275d565b15610756576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006385572ffb60e01b8a604051602401610771919061288c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000095909516949094179093528051608480825260c08201909252919350909182018180368337019050509450863b61081b57600080fd5b5a8981101561082957600080fd5b899003604081048103891061083d57600080fd5b5060008082516020840160008b8df195503d608481111561085c575060845b808652806000602088013e507f9b877de93ea9895756e337442c657f95a34fc68e7eb988bdfa693d5be83016b68a3561089b60408d0160208e01612500565b835160208501206040516108e8939291339193845267ffffffffffffffff92909216602084015273ffffffffffffffffffffffffffffffffffffffff166040830152606082015260800190565b60405180910390a15050505094509492505050565b610905611685565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610954611685565b73ffffffffffffffffffffffffffffffffffffffff82166109b9576040517f26a78f8f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161056c565b73ffffffffffffffffffffffffffffffffffffffff8316610a745760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610a2e576040519150601f19603f3d011682016040523d82523d6000602084013e610a33565b606091505b5050905080610a6e576040517fe417b80b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b610a9573ffffffffffffffffffffffffffffffffffffffff84168383611708565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c28919061275d565b15610c5f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610cd2576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8516600482015260240161056c565b606083015160009073ffffffffffffffffffffffffffffffffffffffff16610e625760025473ffffffffffffffffffffffffffffffffffffffff90811660608601526040517f38724a95000000000000000000000000000000000000000000000000000000008152908316906338724a9590610d52908790600401612731565b602060405180830381865afa158015610d6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d939190612744565b905080341015610dcf576040517f07da6ee600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b349050836060015173ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610e1e57600080fd5b505af1158015610e32573d6000803e3d6000fd5b505050506060850151610e5d915073ffffffffffffffffffffffffffffffffffffffff168383611708565b610f57565b3415610e9a576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f38724a9500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906338724a9590610eec908790600401612731565b602060405180830381865afa158015610f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2d9190612744565b6060850151909150610f579073ffffffffffffffffffffffffffffffffffffffff163384846117dc565b60005b84604001515181101561107f57600085604001518281518110610f7f57610f7f612998565b6020908102919091010151516040517f5d86f14100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808316600483015291925061106e91339190871690635d86f14190602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102591906129c7565b8860400151858151811061103b5761103b612998565b6020026020010151602001518473ffffffffffffffffffffffffffffffffffffffff166117dc909392919063ffffffff16565b5061107881612a13565b9050610f5a565b506040517fa7d3e02f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063a7d3e02f906110d690879085903390600401612a4b565b6020604051808303816000875af11580156110f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111199190612744565b95945050505050565b60606000611130600461183a565b67ffffffffffffffff811115611148576111486120ac565b60405190808252806020026020018201604052801561118d57816020015b60408051808201909152600080825260208201528152602001906001900390816111665790505b50905060005b8151811015611213576000806111aa600484611845565b9150915060405180604001604052808267ffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff168152508484815181106111f5576111f5612998565b602002602001018190525050508061120c90612a13565b9050611193565b50919050565b611221611685565b60005b8581101561130557600087878381811061124057611240612998565b9050604002018036038101906112569190612a8a565b60208181018051835167ffffffffffffffff90811660009081526003855260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055855193519051921682529394509216917f1f7d0ec248b80e5c0dde0ee531c4fc8fdb6ce9a2b3d90f560c74acd6a7202f23910160405180910390a2506112fe81612a13565b9050611224565b5060005b8381101561143157600085858381811061132557611325612998565b61133b9260206040909202019081019150612500565b9050600086868481811061135157611351612998565b90506040020160200160208101906113699190612077565b905067ffffffffffffffff8216611381600483611854565b146113b8576040517f5737980600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113c360048261187d565b1561141e5760405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa823809efda3ba66c873364eec120fa0923d9fabda73bc97dd5663341e2d9bcb9060200160405180910390a25b50508061142a90612a13565b9050611309565b5060005b8181101561151b57600083838381811061145157611451612998565b6114679260206040909202019081019150612500565b9050600084848481811061147d5761147d612998565b90506040020160200160208101906114959190612077565b90506114ad60048267ffffffffffffffff851661189f565b156115085760405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa4bdf64ebdf3316320601a081916a75aa144bcef6c4beeb0e9fb1982cacc6b949060200160405180910390a25b50508061151490612a13565b9050611435565b50505050505050565b61152c611685565b611535816118ca565b50565b60606115728267ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b61158a57505060408051600081526020810190915290565b67ffffffffffffffff82166000908152600360205260408082205481517fd3c7c2c7000000000000000000000000000000000000000000000000000000008152915173ffffffffffffffffffffffffffffffffffffffff9091169263d3c7c2c792600480820193918290030181865afa15801561160b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261060c9190810190612ac9565b60008080806116768673ffffffffffffffffffffffffffffffffffffffff87166119bf565b909450925050505b9250929050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611706576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056c565b565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a959084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526119f9565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a6e9085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161175a565b600061060c82611b05565b60008080806116768686611b10565b60006118768373ffffffffffffffffffffffffffffffffffffffff8416611b3b565b9392505050565b60006118768373ffffffffffffffffffffffffffffffffffffffff8416611bc5565b60006118c28473ffffffffffffffffffffffffffffffffffffffff851684611be2565b949350505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526002830160205260408120548190806119ee576119e18585611bff565b92506000915061167e9050565b60019250905061167e565b6000611a5b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611c0b9092919063ffffffff16565b805190915015610a955780806020019051810190611a79919061275d565b610a95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056c565b600061060c82611c1a565b60008080611b1e8585611c24565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081205480151580611b5f5750611b5f8484611bff565b611876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640161056c565b600081815260028301602052604081208190556118768383611c30565b600082815260028401602052604081208290556118c28484611c3c565b60006118768383611c48565b60606118c28484600085611c60565b600061060c825490565b60006118768383611d79565b60006118768383611da3565b60006118768383611e96565b60008181526001830160205260408120541515611876565b606082471015611cf2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056c565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611d1b9190612b58565b60006040518083038185875af1925050503d8060008114611d58576040519150601f19603f3d011682016040523d82523d6000602084013e611d5d565b606091505b5091509150611d6e87838387611ee5565b979650505050505050565b6000826000018281548110611d9057611d90612998565b9060005260206000200154905092915050565b60008181526001830160205260408120548015611e8c576000611dc7600183612b74565b8554909150600090611ddb90600190612b74565b9050818114611e40576000866000018281548110611dfb57611dfb612998565b9060005260206000200154905080876000018481548110611e1e57611e1e612998565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611e5157611e51612b87565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061060c565b600091505061060c565b6000818152600183016020526040812054611edd5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561060c565b50600061060c565b60608315611f7b578251600003611f745773ffffffffffffffffffffffffffffffffffffffff85163b611f74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056c565b50816118c2565b6118c28383815115611f905781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056c9190612032565b60005b83811015611fdf578181015183820152602001611fc7565b50506000910152565b60008151808452612000816020860160208601611fc4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006118766020830184611fe8565b73ffffffffffffffffffffffffffffffffffffffff8116811461153557600080fd5b803561207281612045565b919050565b60006020828403121561208957600080fd5b813561187681612045565b803567ffffffffffffffff8116811461207257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156120fe576120fe6120ac565b60405290565b60405160a0810167ffffffffffffffff811182821017156120fe576120fe6120ac565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561216e5761216e6120ac565b604052919050565b600082601f83011261218757600080fd5b813567ffffffffffffffff8111156121a1576121a16120ac565b6121d260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612127565b8181528460208386010111156121e757600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff82111561221e5761221e6120ac565b5060051b60200190565b600082601f83011261223957600080fd5b8135602061224e61224983612204565b612127565b82815260069290921b8401810191818101908684111561226d57600080fd5b8286015b848110156122b5576040818903121561228a5760008081fd5b6122926120db565b813561229d81612045565b81528185013585820152835291830191604001612271565b509695505050505050565b600080604083850312156122d357600080fd5b6122dc83612094565b9150602083013567ffffffffffffffff808211156122f957600080fd5b9084019060a0828703121561230d57600080fd5b612315612104565b82358281111561232457600080fd5b61233088828601612176565b82525060208301358281111561234557600080fd5b61235188828601612176565b60208301525060408301358281111561236957600080fd5b61237588828601612228565b60408301525061238760608401612067565b606082015260808301358281111561239e57600080fd5b6123aa88828601612176565b6080830152508093505050509250929050565b600080600080608085870312156123d357600080fd5b843567ffffffffffffffff8111156123ea57600080fd5b850160a081880312156123fc57600080fd5b9350602085013561ffff8116811461241357600080fd5b925060408501359150606085013561242a81612045565b939692955090935050565b82151581526040602082015260006118c26040830184611fe8565b60008060006060848603121561246557600080fd5b833561247081612045565b9250602084013561248081612045565b929592945050506040919091013590565b602080825282518282018190526000919060409081850190868401855b828110156124f3578151805167ffffffffffffffff16855286015173ffffffffffffffffffffffffffffffffffffffff168685015292840192908501906001016124ae565b5091979650505050505050565b60006020828403121561251257600080fd5b61187682612094565b60008083601f84011261252d57600080fd5b50813567ffffffffffffffff81111561254557600080fd5b6020830191508360208260061b850101111561167e57600080fd5b6000806000806000806060878903121561257957600080fd5b863567ffffffffffffffff8082111561259157600080fd5b61259d8a838b0161251b565b909850965060208901359150808211156125b657600080fd5b6125c28a838b0161251b565b909650945060408901359150808211156125db57600080fd5b506125e889828a0161251b565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b8181101561264857835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612616565b50909695505050505050565b6000815160a0845261266960a0850182611fe8565b9050602080840151858303828701526126828382611fe8565b60408681015188830389830152805180845290850195509092506000918401905b808310156126e2578551805173ffffffffffffffffffffffffffffffffffffffff168352850151858301529484019460019290920191908301906126a3565b506060870151945061270c606089018673ffffffffffffffffffffffffffffffffffffffff169052565b6080870151945087810360808901526127258186611fe8565b98975050505050505050565b6020815260006118766020830184612654565b60006020828403121561275657600080fd5b5051919050565b60006020828403121561276f57600080fd5b8151801515811461187657600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126127b457600080fd5b830160208101925035905067ffffffffffffffff8111156127d457600080fd5b80360382131561167e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b8581101561288157813561284f81612045565b73ffffffffffffffffffffffffffffffffffffffff16875281830135838801526040968701969091019060010161283c565b509495945050505050565b602081528135602082015260006128a560208401612094565b67ffffffffffffffff80821660408501526128c3604086018661277f565b925060a060608601526128da60c0860184836127e3565b9250506128ea606086018661277f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808786030160808801526129208583856127e3565b9450608088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301831261295957600080fd5b6020928801928301923591508382111561297257600080fd5b8160061b360383131561298457600080fd5b8685030160a0870152611d6e84828461282c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156129d957600080fd5b815161187681612045565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612a4457612a446129e4565b5060010190565b606081526000612a5e6060830186612654565b905083602083015273ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b600060408284031215612a9c57600080fd5b612aa46120db565b612aad83612094565b81526020830135612abd81612045565b60208201529392505050565b60006020808385031215612adc57600080fd5b825167ffffffffffffffff811115612af357600080fd5b8301601f81018513612b0457600080fd5b8051612b1261224982612204565b81815260059190911b82018301908381019087831115612b3157600080fd5b928401925b82841015611d6e578351612b4981612045565b82529284019290840190612b36565b60008251612b6a818460208701611fc4565b9190910192915050565b8181038181111561060c5761060c6129e4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000411de17f12d1a34ecc7f45f49844626267c75e81
Deployed Bytecode
0x6080604052600436106101295760003560e01c80638da5cb5b116100a5578063a8d87a3b11610074578063e861e90711610059578063e861e90714610428578063f2fde38b14610453578063fbca3b741461047357600080fd5b8063a8d87a3b146103bb578063da5fcac81461040857600080fd5b80638da5cb5b146102fc57806396f4e9f914610327578063a40e69c71461033a578063a48a90581461035c57600080fd5b80635246492f116100fc5780635f3e849f116100e15780635f3e849f1461029f578063787350e3146102bf57806379ba5097146102e757600080fd5b80635246492f1461022957806352cb60ca1461027d57600080fd5b8063181f5a771461012e5780631d7a74a01461018d57806320487ded146101cd5780633cf97983146101fb575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280600c81526020017f526f7574657220312e302e30000000000000000000000000000000000000000081525081565b6040516101849190612032565b60405180910390f35b34801561019957600080fd5b506101ad6101a8366004612077565b6104a0565b60408051921515835267ffffffffffffffff909116602083015201610184565b3480156101d957600080fd5b506101ed6101e83660046122c0565b6104bc565b604051908152602001610184565b34801561020757600080fd5b5061021b6102163660046123bd565b610612565b604051610184929190612435565b34801561023557600080fd5b507f000000000000000000000000411de17f12d1a34ecc7f45f49844626267c75e815b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561028957600080fd5b5061029d610298366004612077565b6108fd565b005b3480156102ab57600080fd5b5061029d6102ba366004612450565b61094c565b3480156102cb57600080fd5b506102d4608481565b60405161ffff9091168152602001610184565b3480156102f357600080fd5b5061029d610a9a565b34801561030857600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610258565b6101ed6103353660046122c0565b610b97565b34801561034657600080fd5b5061034f611122565b6040516101849190612491565b34801561036857600080fd5b506103ab610377366004612500565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b6040519015158152602001610184565b3480156103c757600080fd5b506102586103d6366004612500565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b34801561041457600080fd5b5061029d610423366004612560565b611219565b34801561043457600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff16610258565b34801561045f57600080fd5b5061029d61046e366004612077565b611524565b34801561047f57600080fd5b5061049361048e366004612500565b611538565b60405161018491906125fa565b60008080806104b0600486611651565b90969095509350505050565b606081015160009073ffffffffffffffffffffffffffffffffffffffff166104fd5760025473ffffffffffffffffffffffffffffffffffffffff1660608301525b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610575576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024015b60405180910390fd5b6040517f38724a9500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216906338724a95906105c7908690600401612731565b602060405180830381865afa1580156105e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106089190612744565b9150505b92915050565b600060606106266040870160208801612500565b600080610634600433611651565b9150915081158061065957508067ffffffffffffffff168367ffffffffffffffff1614155b15610690576040517fd2316ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000411de17f12d1a34ecc7f45f49844626267c75e8173ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071f919061275d565b15610756576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006385572ffb60e01b8a604051602401610771919061288c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000095909516949094179093528051608480825260c08201909252919350909182018180368337019050509450863b61081b57600080fd5b5a8981101561082957600080fd5b899003604081048103891061083d57600080fd5b5060008082516020840160008b8df195503d608481111561085c575060845b808652806000602088013e507f9b877de93ea9895756e337442c657f95a34fc68e7eb988bdfa693d5be83016b68a3561089b60408d0160208e01612500565b835160208501206040516108e8939291339193845267ffffffffffffffff92909216602084015273ffffffffffffffffffffffffffffffffffffffff166040830152606082015260800190565b60405180910390a15050505094509492505050565b610905611685565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610954611685565b73ffffffffffffffffffffffffffffffffffffffff82166109b9576040517f26a78f8f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161056c565b73ffffffffffffffffffffffffffffffffffffffff8316610a745760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610a2e576040519150601f19603f3d011682016040523d82523d6000602084013e610a33565b606091505b5050905080610a6e576040517fe417b80b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b610a9573ffffffffffffffffffffffffffffffffffffffff84168383611708565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161056c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60007f000000000000000000000000411de17f12d1a34ecc7f45f49844626267c75e8173ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c28919061275d565b15610c5f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610cd2576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8516600482015260240161056c565b606083015160009073ffffffffffffffffffffffffffffffffffffffff16610e625760025473ffffffffffffffffffffffffffffffffffffffff90811660608601526040517f38724a95000000000000000000000000000000000000000000000000000000008152908316906338724a9590610d52908790600401612731565b602060405180830381865afa158015610d6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d939190612744565b905080341015610dcf576040517f07da6ee600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b349050836060015173ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610e1e57600080fd5b505af1158015610e32573d6000803e3d6000fd5b505050506060850151610e5d915073ffffffffffffffffffffffffffffffffffffffff168383611708565b610f57565b3415610e9a576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f38724a9500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906338724a9590610eec908790600401612731565b602060405180830381865afa158015610f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2d9190612744565b6060850151909150610f579073ffffffffffffffffffffffffffffffffffffffff163384846117dc565b60005b84604001515181101561107f57600085604001518281518110610f7f57610f7f612998565b6020908102919091010151516040517f5d86f14100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808316600483015291925061106e91339190871690635d86f14190602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102591906129c7565b8860400151858151811061103b5761103b612998565b6020026020010151602001518473ffffffffffffffffffffffffffffffffffffffff166117dc909392919063ffffffff16565b5061107881612a13565b9050610f5a565b506040517fa7d3e02f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063a7d3e02f906110d690879085903390600401612a4b565b6020604051808303816000875af11580156110f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111199190612744565b95945050505050565b60606000611130600461183a565b67ffffffffffffffff811115611148576111486120ac565b60405190808252806020026020018201604052801561118d57816020015b60408051808201909152600080825260208201528152602001906001900390816111665790505b50905060005b8151811015611213576000806111aa600484611845565b9150915060405180604001604052808267ffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff168152508484815181106111f5576111f5612998565b602002602001018190525050508061120c90612a13565b9050611193565b50919050565b611221611685565b60005b8581101561130557600087878381811061124057611240612998565b9050604002018036038101906112569190612a8a565b60208181018051835167ffffffffffffffff90811660009081526003855260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055855193519051921682529394509216917f1f7d0ec248b80e5c0dde0ee531c4fc8fdb6ce9a2b3d90f560c74acd6a7202f23910160405180910390a2506112fe81612a13565b9050611224565b5060005b8381101561143157600085858381811061132557611325612998565b61133b9260206040909202019081019150612500565b9050600086868481811061135157611351612998565b90506040020160200160208101906113699190612077565b905067ffffffffffffffff8216611381600483611854565b146113b8576040517f5737980600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113c360048261187d565b1561141e5760405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa823809efda3ba66c873364eec120fa0923d9fabda73bc97dd5663341e2d9bcb9060200160405180910390a25b50508061142a90612a13565b9050611309565b5060005b8181101561151b57600083838381811061145157611451612998565b6114679260206040909202019081019150612500565b9050600084848481811061147d5761147d612998565b90506040020160200160208101906114959190612077565b90506114ad60048267ffffffffffffffff851661189f565b156115085760405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa4bdf64ebdf3316320601a081916a75aa144bcef6c4beeb0e9fb1982cacc6b949060200160405180910390a25b50508061151490612a13565b9050611435565b50505050505050565b61152c611685565b611535816118ca565b50565b60606115728267ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b61158a57505060408051600081526020810190915290565b67ffffffffffffffff82166000908152600360205260408082205481517fd3c7c2c7000000000000000000000000000000000000000000000000000000008152915173ffffffffffffffffffffffffffffffffffffffff9091169263d3c7c2c792600480820193918290030181865afa15801561160b573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261060c9190810190612ac9565b60008080806116768673ffffffffffffffffffffffffffffffffffffffff87166119bf565b909450925050505b9250929050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611706576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161056c565b565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a959084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526119f9565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a6e9085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161175a565b600061060c82611b05565b60008080806116768686611b10565b60006118768373ffffffffffffffffffffffffffffffffffffffff8416611b3b565b9392505050565b60006118768373ffffffffffffffffffffffffffffffffffffffff8416611bc5565b60006118c28473ffffffffffffffffffffffffffffffffffffffff851684611be2565b949350505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161056c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526002830160205260408120548190806119ee576119e18585611bff565b92506000915061167e9050565b60019250905061167e565b6000611a5b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611c0b9092919063ffffffff16565b805190915015610a955780806020019051810190611a79919061275d565b610a95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161056c565b600061060c82611c1a565b60008080611b1e8585611c24565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081205480151580611b5f5750611b5f8484611bff565b611876576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640161056c565b600081815260028301602052604081208190556118768383611c30565b600082815260028401602052604081208290556118c28484611c3c565b60006118768383611c48565b60606118c28484600085611c60565b600061060c825490565b60006118768383611d79565b60006118768383611da3565b60006118768383611e96565b60008181526001830160205260408120541515611876565b606082471015611cf2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161056c565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611d1b9190612b58565b60006040518083038185875af1925050503d8060008114611d58576040519150601f19603f3d011682016040523d82523d6000602084013e611d5d565b606091505b5091509150611d6e87838387611ee5565b979650505050505050565b6000826000018281548110611d9057611d90612998565b9060005260206000200154905092915050565b60008181526001830160205260408120548015611e8c576000611dc7600183612b74565b8554909150600090611ddb90600190612b74565b9050818114611e40576000866000018281548110611dfb57611dfb612998565b9060005260206000200154905080876000018481548110611e1e57611e1e612998565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611e5157611e51612b87565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061060c565b600091505061060c565b6000818152600183016020526040812054611edd5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561060c565b50600061060c565b60608315611f7b578251600003611f745773ffffffffffffffffffffffffffffffffffffffff85163b611f74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161056c565b50816118c2565b6118c28383815115611f905781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056c9190612032565b60005b83811015611fdf578181015183820152602001611fc7565b50506000910152565b60008151808452612000816020860160208601611fc4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006118766020830184611fe8565b73ffffffffffffffffffffffffffffffffffffffff8116811461153557600080fd5b803561207281612045565b919050565b60006020828403121561208957600080fd5b813561187681612045565b803567ffffffffffffffff8116811461207257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156120fe576120fe6120ac565b60405290565b60405160a0810167ffffffffffffffff811182821017156120fe576120fe6120ac565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561216e5761216e6120ac565b604052919050565b600082601f83011261218757600080fd5b813567ffffffffffffffff8111156121a1576121a16120ac565b6121d260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612127565b8181528460208386010111156121e757600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff82111561221e5761221e6120ac565b5060051b60200190565b600082601f83011261223957600080fd5b8135602061224e61224983612204565b612127565b82815260069290921b8401810191818101908684111561226d57600080fd5b8286015b848110156122b5576040818903121561228a5760008081fd5b6122926120db565b813561229d81612045565b81528185013585820152835291830191604001612271565b509695505050505050565b600080604083850312156122d357600080fd5b6122dc83612094565b9150602083013567ffffffffffffffff808211156122f957600080fd5b9084019060a0828703121561230d57600080fd5b612315612104565b82358281111561232457600080fd5b61233088828601612176565b82525060208301358281111561234557600080fd5b61235188828601612176565b60208301525060408301358281111561236957600080fd5b61237588828601612228565b60408301525061238760608401612067565b606082015260808301358281111561239e57600080fd5b6123aa88828601612176565b6080830152508093505050509250929050565b600080600080608085870312156123d357600080fd5b843567ffffffffffffffff8111156123ea57600080fd5b850160a081880312156123fc57600080fd5b9350602085013561ffff8116811461241357600080fd5b925060408501359150606085013561242a81612045565b939692955090935050565b82151581526040602082015260006118c26040830184611fe8565b60008060006060848603121561246557600080fd5b833561247081612045565b9250602084013561248081612045565b929592945050506040919091013590565b602080825282518282018190526000919060409081850190868401855b828110156124f3578151805167ffffffffffffffff16855286015173ffffffffffffffffffffffffffffffffffffffff168685015292840192908501906001016124ae565b5091979650505050505050565b60006020828403121561251257600080fd5b61187682612094565b60008083601f84011261252d57600080fd5b50813567ffffffffffffffff81111561254557600080fd5b6020830191508360208260061b850101111561167e57600080fd5b6000806000806000806060878903121561257957600080fd5b863567ffffffffffffffff8082111561259157600080fd5b61259d8a838b0161251b565b909850965060208901359150808211156125b657600080fd5b6125c28a838b0161251b565b909650945060408901359150808211156125db57600080fd5b506125e889828a0161251b565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b8181101561264857835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612616565b50909695505050505050565b6000815160a0845261266960a0850182611fe8565b9050602080840151858303828701526126828382611fe8565b60408681015188830389830152805180845290850195509092506000918401905b808310156126e2578551805173ffffffffffffffffffffffffffffffffffffffff168352850151858301529484019460019290920191908301906126a3565b506060870151945061270c606089018673ffffffffffffffffffffffffffffffffffffffff169052565b6080870151945087810360808901526127258186611fe8565b98975050505050505050565b6020815260006118766020830184612654565b60006020828403121561275657600080fd5b5051919050565b60006020828403121561276f57600080fd5b8151801515811461187657600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126127b457600080fd5b830160208101925035905067ffffffffffffffff8111156127d457600080fd5b80360382131561167e57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b8581101561288157813561284f81612045565b73ffffffffffffffffffffffffffffffffffffffff16875281830135838801526040968701969091019060010161283c565b509495945050505050565b602081528135602082015260006128a560208401612094565b67ffffffffffffffff80821660408501526128c3604086018661277f565b925060a060608601526128da60c0860184836127e3565b9250506128ea606086018661277f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808786030160808801526129208583856127e3565b9450608088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301831261295957600080fd5b6020928801928301923591508382111561297257600080fd5b8160061b360383131561298457600080fd5b8685030160a0870152611d6e84828461282c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156129d957600080fd5b815161187681612045565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612a4457612a446129e4565b5060010190565b606081526000612a5e6060830186612654565b905083602083015273ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b600060408284031215612a9c57600080fd5b612aa46120db565b612aad83612094565b81526020830135612abd81612045565b60208201529392505050565b60006020808385031215612adc57600080fd5b825167ffffffffffffffff811115612af357600080fd5b8301601f81018513612b0457600080fd5b8051612b1261224982612204565b81815260059190911b82018301908381019087831115612b3157600080fd5b928401925b82841015611d6e578351612b4981612045565b82529284019290840190612b36565b60008251612b6a818460208701611fc4565b9190910192915050565b8181038181111561060c5761060c6129e4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000411de17f12d1a34ecc7f45f49844626267c75e81
-----Decoded View---------------
Arg [0] : wrappedNative (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [1] : armProxy (address): 0x411dE17f12D1A34ecC7F45f49844626267c75e81
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [1] : 000000000000000000000000411de17f12d1a34ecc7f45f49844626267c75e81
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.