More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 13,868 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x96f4e9f9 | 67059423 | 3 hrs ago | IN | 1.16420689 WEMIX | 0.0347523 | ||||
0x96f4e9f9 | 67058523 | 3 hrs ago | IN | 17.47431394 WEMIX | 0.0132076 | ||||
0x96f4e9f9 | 67058252 | 3 hrs ago | IN | 0.09115112 WEMIX | 0.0133681 | ||||
0x96f4e9f9 | 67036929 | 9 hrs ago | IN | 0.09577075 WEMIX | 0.0133681 | ||||
0x96f4e9f9 | 67015093 | 15 hrs ago | IN | 0.18412757 WEMIX | 0.0133681 | ||||
0x96f4e9f9 | 67010500 | 17 hrs ago | IN | 1.1092434 WEMIX | 0.0347523 | ||||
0x96f4e9f9 | 67010020 | 17 hrs ago | IN | 1.1092434 WEMIX | 0.0347523 | ||||
0x96f4e9f9 | 67004581 | 18 hrs ago | IN | 1.18645281 WEMIX | 0.034914 | ||||
0x96f4e9f9 | 67003970 | 18 hrs ago | IN | 1.18645281 WEMIX | 0.0349116 | ||||
0x96f4e9f9 | 67003468 | 19 hrs ago | IN | 0.57209105 WEMIX | 0.0352523 | ||||
0x96f4e9f9 | 67003446 | 19 hrs ago | IN | 1.29329043 WEMIX | 0.0352523 | ||||
0x96f4e9f9 | 67003388 | 19 hrs ago | IN | 1.17493302 WEMIX | 0.034914 | ||||
0x96f4e9f9 | 67002756 | 19 hrs ago | IN | 1.29329043 WEMIX | 0.0352523 | ||||
0x96f4e9f9 | 67002694 | 19 hrs ago | IN | 1.40134257 WEMIX | 0.0347523 | ||||
0x96f4e9f9 | 67002479 | 19 hrs ago | IN | 1.0130708 WEMIX | 0.034914 | ||||
0x96f4e9f9 | 67002316 | 19 hrs ago | IN | 0.77910847 WEMIX | 0.0352523 | ||||
0x96f4e9f9 | 67000312 | 20 hrs ago | IN | 2.21469702 WEMIX | 0.0352523 | ||||
0x96f4e9f9 | 66997717 | 20 hrs ago | IN | 1.16563574 WEMIX | 0.0347523 | ||||
0x96f4e9f9 | 66997416 | 20 hrs ago | IN | 1.16563574 WEMIX | 0.0347499 | ||||
0x96f4e9f9 | 66996695 | 21 hrs ago | IN | 1.07226946 WEMIX | 0.0347523 | ||||
0x96f4e9f9 | 66996274 | 21 hrs ago | IN | 1.07226946 WEMIX | 0.0347523 | ||||
0x96f4e9f9 | 66991545 | 22 hrs ago | IN | 0.85002512 WEMIX | 0.0349116 | ||||
0x96f4e9f9 | 66991510 | 22 hrs ago | IN | 0.23274013 WEMIX | 0.0353916 | ||||
0x96f4e9f9 | 66984276 | 24 hrs ago | IN | 0.2701754 WEMIX | 0.0347523 | ||||
0x96f4e9f9 | 66980252 | 25 hrs ago | IN | 0.26000911 WEMIX | 0.0347523 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
67059423 | 3 hrs ago | 1.16420689 WEMIX | ||||
67058523 | 3 hrs ago | 17.47431394 WEMIX | ||||
67058252 | 3 hrs ago | 0.09115112 WEMIX | ||||
67036929 | 9 hrs ago | 0.09577075 WEMIX | ||||
67015093 | 15 hrs ago | 0.18412757 WEMIX | ||||
67010500 | 17 hrs ago | 1.1092434 WEMIX | ||||
67010020 | 17 hrs ago | 1.1092434 WEMIX | ||||
67004581 | 18 hrs ago | 1.18645281 WEMIX | ||||
67003970 | 18 hrs ago | 1.18645281 WEMIX | ||||
67003468 | 19 hrs ago | 0.57209105 WEMIX | ||||
67003446 | 19 hrs ago | 1.29329043 WEMIX | ||||
67003388 | 19 hrs ago | 1.17493302 WEMIX | ||||
67002756 | 19 hrs ago | 1.29329043 WEMIX | ||||
67002694 | 19 hrs ago | 1.40134257 WEMIX | ||||
67002479 | 19 hrs ago | 1.0130708 WEMIX | ||||
67002316 | 19 hrs ago | 0.77910847 WEMIX | ||||
67000312 | 20 hrs ago | 2.21469702 WEMIX | ||||
66997717 | 20 hrs ago | 1.16563574 WEMIX | ||||
66997416 | 20 hrs ago | 1.16563574 WEMIX | ||||
66996695 | 21 hrs ago | 1.07226946 WEMIX | ||||
66996274 | 21 hrs ago | 1.07226946 WEMIX | ||||
66991545 | 22 hrs ago | 0.85002512 WEMIX | ||||
66991510 | 22 hrs ago | 0.23274013 WEMIX | ||||
66984276 | 24 hrs ago | 0.2701754 WEMIX | ||||
66980252 | 25 hrs ago | 0.26000911 WEMIX |
Loading...
Loading
Contract Name:
Router
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.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 {Internal} from "./libraries/Internal.sol"; import {CallWithExactGas} from "../shared/call/CallWithExactGas.sol"; import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/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, ITypeAndVersion, OwnerIsCreator { using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.UintSet; error FailedToSendValue(); error InvalidRecipientAddress(address to); error OffRampMismatch(uint64 chainSelector, address offRamp); 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.2.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; // Stores [sourceChainSelector << 160 + offramp] as a pair to allow for // lookups for specific chain/offramp pairs. EnumerableSet.UintSet private s_chainSelectorAndOffRamps; 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(destinationChainSelector, 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(chainSelector); } /// @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; // We rely on getFee to validate that the feeToken is whitelisted. feeTokenAmount = IEVM2AnyOnRamp(onRamp).getFee(destinationChainSelector, 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(); // We rely on getFee to validate that the feeToken is whitelisted. feeTokenAmount = IEVM2AnyOnRamp(onRamp).getFee(destinationChainSelector, 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); // We rely on getPoolBySourceToken to validate that the token is whitelisted. token.safeTransferFrom( msg.sender, address(IEVM2AnyOnRamp(onRamp).getPoolBySourceToken(destinationChainSelector, token)), message.tokenAmounts[i].amount ); } return IEVM2AnyOnRamp(onRamp).forwardFromRouter(destinationChainSelector, message, feeTokenAmount, msg.sender); } // ================================================================ // │ Message execution │ // ================================================================ /// @inheritdoc IRouter /// @dev _callWithExactGas protects against return data bombs by capping the return data size at MAX_RET_BYTES. function routeMessage( Client.Any2EVMMessage calldata message, uint16 gasForCallExactCheck, uint256 gasLimit, address receiver ) external override whenHealthy returns (bool success, bytes memory retData, uint256 gasUsed) { // We only permit offRamps to call this function. if (!isOffRamp(message.sourceChainSelector, msg.sender)) revert OnlyOffRamp(); // 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); (success, retData, gasUsed) = CallWithExactGas._callWithExactGasSafeReturnData( data, receiver, gasLimit, gasForCallExactCheck, Internal.MAX_RET_BYTES ); emit MessageExecuted(message.messageId, message.sourceChainSelector, msg.sender, keccak256(data)); return (success, retData, gasUsed); } // @notice Merges a chain selector and offRamp address into a single uint256 by shifting the // chain selector 160 bits to the left. function _mergeChainSelectorAndOffRamp( uint64 sourceChainSelector, address offRampAddress ) internal pure returns (uint256) { return (uint256(sourceChainSelector) << 160) + uint160(offRampAddress); } // ================================================================ // │ 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; } /// @inheritdoc IRouter function getOnRamp(uint64 destChainSelector) external view returns (address) { return s_onRamps[destChainSelector]; } function getOffRamps() external view returns (OffRamp[] memory) { uint256[] memory encodedOffRamps = s_chainSelectorAndOffRamps.values(); OffRamp[] memory offRamps = new OffRamp[](encodedOffRamps.length); for (uint256 i = 0; i < encodedOffRamps.length; ++i) { uint256 encodedOffRamp = encodedOffRamps[i]; offRamps[i] = OffRamp({ sourceChainSelector: uint64(encodedOffRamp >> 160), offRamp: address(uint160(encodedOffRamp)) }); } return offRamps; } /// @inheritdoc IRouter function isOffRamp(uint64 sourceChainSelector, address offRamp) public view returns (bool) { // We have to encode the sourceChainSelector and offRamp into a uint256 to use as a key in the set. return s_chainSelectorAndOffRamps.contains(_mergeChainSelectorAndOffRamp(sourceChainSelector, offRamp)); } /// @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. for (uint256 i = 0; i < offRampRemoves.length; ++i) { uint64 sourceChainSelector = offRampRemoves[i].sourceChainSelector; address offRampAddress = offRampRemoves[i].offRamp; // If the selector-offRamp pair does not exist, revert. if (!s_chainSelectorAndOffRamps.remove(_mergeChainSelectorAndOffRamp(sourceChainSelector, offRampAddress))) revert OffRampMismatch(sourceChainSelector, offRampAddress); emit OffRampRemoved(sourceChainSelector, offRampAddress); } for (uint256 i = 0; i < offRampAdds.length; ++i) { uint64 sourceChainSelector = offRampAdds[i].sourceChainSelector; address offRampAddress = offRampAdds[i].offRamp; if (s_chainSelectorAndOffRamps.add(_mergeChainSelectorAndOffRamp(sourceChainSelector, offRampAddress))) { emit OffRampAdded(sourceChainSelector, offRampAddress); } } } /// @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 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; interface ITypeAndVersion { function typeAndVersion() external pure returns (string memory); }
// SPDX-License-Identifier: MIT 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 execution fee for the message /// delivery to destination chain, denominated in the feeToken specified in the message. /// @dev Reverts with appropriate reason upon 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. /// @dev Reverts with appropriate reason upon invalid message. function ccipSend( uint64 destinationChainSelector, Client.EVM2AnyMessage calldata message ) external payable returns (bytes32); }
// SPDX-License-Identifier: MIT 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. /// @return gasUsed the gas used by the external customer call. Does not include any overhead. function routeMessage( Client.Any2EVMMessage calldata message, uint16 gasForCallExactCheck, uint256 gasLimit, address receiver ) external returns (bool success, bytes memory retBytes, uint256 gasUsed); /// @notice Returns the configured onramp for a specific destination chain. /// @param destChainSelector The destination chain Id to get the onRamp for. /// @return onRampAddress The address of the onRamp. function getOnRamp(uint64 destChainSelector) external view returns (address onRampAddress); /// @notice Return true if the given offRamp is a configured offRamp for the given source chain. /// @param sourceChainSelector The source chain selector to check. /// @param offRamp The address of the offRamp to check. function isOffRamp(uint64 sourceChainSelector, address offRamp) external view returns (bool isOffRamp); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IEVM2AnyOnRampClient} from "./IEVM2AnyOnRampClient.sol"; import {Internal} from "../libraries/Internal.sol"; interface IEVM2AnyOnRamp is IEVM2AnyOnRampClient { /// @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; }
// SPDX-License-Identifier: MIT 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: MIT pragma solidity ^0.8.0; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; interface IWrappedNative is IERC20 { function deposit() external payable; function withdraw(uint256 wad) external; }
// SPDX-License-Identifier: MIT 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: MIT pragma solidity ^0.8.0; // End consumer library. library Client { /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. 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. 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) } // bytes4(keccak256("CCIP EVMExtraArgsV1")); bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9; struct EVMExtraArgsV1 { uint256 gasLimit; } 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 {Client} from "./Client.sol"; import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol"; // Library for CCIP internal definitions common to multiple contracts. library Internal { /// @dev The minimum amount of gas to perform the call with exact gas. /// We include this in the offramp so that we can redeploy to adjust it /// should a hardfork change the gas costs of relevant opcodes in callWithExactGas. uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5_000; // @dev 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 internal constant MAX_RET_BYTES = 4 + 4 * 32; /// @notice A collection of token price and gas price updates. /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. struct PriceUpdates { TokenPriceUpdate[] tokenPriceUpdates; GasPriceUpdate[] gasPriceUpdates; } /// @notice Token price in USD. /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. struct TokenPriceUpdate { address sourceToken; // Source token uint224 usdPerToken; // 1e18 USD per 1e18 of the smallest token denomination. } /// @notice Gas price for a given chain in USD, its value may contain tightly packed fields. /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. struct GasPriceUpdate { uint64 destChainSelector; // Destination chain selector uint224 usdPerUnitGas; // 1e18 USD per smallest unit (e.g. wei) of destination chain gas } /// @notice A timestamped uint224 value that can contain several tightly packed fields. struct TimestampedPackedUint224 { uint224 value; // ───────╮ Value in uint224, packed. uint32 timestamp; // ────╯ Timestamp of the most recent price update. } /// @dev Gas price is stored in 112-bit unsigned int. uint224 can pack 2 prices. /// When packing L1 and L2 gas prices, L1 gas price is left-shifted to the higher-order bits. /// Using uint8 type, which cannot be higher than other bit shift operands, to avoid shift operand type warning. uint8 public constant GAS_PRICE_BITS = 112; struct PoolUpdate { address token; // The IERC20 token address address pool; // The token pool address } /// @notice Report that is submitted by the execution DON at the execution phase. /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. 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. /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. struct EVM2EVMMessage { uint64 sourceChainSelector; // ─────────╮ the chain selector of the source chain, note: not chainId address sender; // ─────────────────────╯ sender address on the source chain address receiver; // ───────────────────╮ receiver address on the destination chain uint64 sequenceNumber; // ──────────────╯ sequence number, not unique across lanes uint256 gasLimit; // user supplied maximum gas amount available for dest chain execution bool strict; // ────────────────────────╮ DEPRECATED uint64 nonce; // │ nonce for this lane for this sender, not unique across senders/lanes address feeToken; // ───────────────────╯ fee token uint256 feeTokenAmount; // fee token amount bytes data; // arbitrary data payload supplied by the message sender Client.EVMTokenAmount[] tokenAmounts; // array of tokens and amounts to transfer bytes[] sourceTokenData; // array of token pool return values, one per token bytes32 messageId; // a hash of the message data } /// @dev EVM2EVMMessage struct has 13 fields, including 3 variable arrays. /// Each variable array takes 1 more slot to store its length. /// When abi encoded, excluding array contents, /// EVM2EVMMessage takes up a fixed number of 16 lots, 32 bytes each. /// For structs that contain arrays, 1 more slot is added to the front, reaching a total of 17. uint256 public constant MESSAGE_FIXED_BYTES = 32 * 17; /// @dev Each token transfer adds 1 EVMTokenAmount and 1 bytes. /// When abiEncoded, each EVMTokenAmount takes 2 slots, each bytes takes 2 slots, excl bytes contents uint256 public constant MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 4; 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("EVM2EVMMessageHashV2"); function _hash(EVM2EVMMessage memory original, bytes32 metadataHash) internal pure returns (bytes32) { // Fixed-size message fields are included in nested hash to reduce stack pressure. // This hashing scheme is also used by RMN. If changing it, please notify the RMN maintainers. return keccak256( abi.encode( MerkleMultiProof.LEAF_DOMAIN_SEPARATOR, metadataHash, keccak256( abi.encode( original.sender, original.receiver, original.sequenceNumber, original.gasLimit, original.strict, original.nonce, original.feeToken, original.feeTokenAmount ) ), keccak256(original.data), keccak256(abi.encode(original.tokenAmounts)), keccak256(abi.encode(original.sourceTokenData)) ) ); } /// @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. /// @dev RMN depends on this enum, if changing, please notify the RMN maintainers. enum MessageExecutionState { UNTOUCHED, IN_PROGRESS, SUCCESS, FAILURE } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @notice This library contains various callWithExactGas functions. All of them are /// safe from gas bomb attacks. /// @dev There is code duplication in this library. This is done to not leave the assembly /// the blocks. library CallWithExactGas { error NoContract(); error NoGasForCallExactCheck(); error NotEnoughGasForCall(); bytes4 internal constant NO_CONTRACT_SIG = 0x0c3b563c; bytes4 internal constant NO_GAS_FOR_CALL_EXACT_CHECK_SIG = 0xafa32a2c; bytes4 internal constant NOT_ENOUGH_GAS_FOR_CALL_SIG = 0x37c3be29; /// @notice calls target address with exactly gasAmount gas and payload as calldata. /// Accounts for gasForCallExactCheck gas that will be used by this function. Will revert /// if the target is not a contact. Will revert when there is not enough gas to call the /// target with gasAmount gas. /// @dev Ignores the return data, which makes it immune to gas bomb attacks. /// @return success whether the call succeeded function _callWithExactGas( bytes memory payload, address target, uint256 gasLimit, uint16 gasForCallExactCheck ) internal returns (bool success) { 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(target)) { mstore(0x0, NO_CONTRACT_SIG) revert(0x0, 0x4) } 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) { mstore(0x0, NO_GAS_FOR_CALL_EXACT_CHECK_SIG) revert(0x0, 0x4) } 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)) { mstore(0x0, NOT_ENOUGH_GAS_FOR_CALL_SIG) revert(0x0, 0x4) } // call and return whether we succeeded. ignore return data // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) success := call(gasLimit, target, 0, add(payload, 0x20), mload(payload), 0x0, 0x0) } return success; } /// @notice calls target address with exactly gasAmount gas and payload as calldata. /// Account for gasForCallExactCheck gas that will be used by this function. Will revert /// if the target is not a contact. Will revert when there is not enough gas to call the /// target with gasAmount gas. /// @dev Caps the return data length, which makes it immune to gas bomb attacks. /// @dev Return data cap logic borrowed from /// https://github.com/nomad-xyz/ExcessivelySafeCall/blob/main/src/ExcessivelySafeCall.sol. /// @return success whether the call succeeded /// @return retData the return data from the call, capped at maxReturnBytes bytes /// @return gasUsed the gas used by the external call. Does not include the overhead of this function. function _callWithExactGasSafeReturnData( bytes memory payload, address target, uint256 gasLimit, uint16 gasForCallExactCheck, uint16 maxReturnBytes ) internal returns (bool success, bytes memory retData, uint256 gasUsed) { // allocate retData memory ahead of time retData = new bytes(maxReturnBytes); 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(target)) { mstore(0x0, NO_CONTRACT_SIG) revert(0x0, 0x4) } 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) { mstore(0x0, NO_GAS_FOR_CALL_EXACT_CHECK_SIG) revert(0x0, 0x4) } 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)) { mstore(0x0, NOT_ENOUGH_GAS_FOR_CALL_SIG) revert(0x0, 0x4) } // We save the gas before the call so we can calculate how much gas the call used let gasBeforeCall := gas() // call and return whether we succeeded. ignore return data // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) success := call(gasLimit, target, 0, add(payload, 0x20), mload(payload), 0x0, 0x0) gasUsed := sub(gasBeforeCall, gas()) // limit our copy to maxReturnBytes bytes let toCopy := returndatasize() if gt(toCopy, maxReturnBytes) { toCopy := maxReturnBytes } // Store the length of the copied bytes mstore(retData, toCopy) // copy the bytes from retData[0:_toCopy] returndatacopy(add(retData, 0x20), 0x0, toCopy) } return (success, retData, gasUsed); } /// @notice Calls target address with exactly gasAmount gas and payload as calldata /// or reverts if at least gasLimit gas is not available. /// @dev Does not check if target is a contract. If it is not a contract, the low-level /// call will still be made and it will succeed. /// @dev Ignores the return data, which makes it immune to gas bomb attacks. /// @return success whether the call succeeded /// @return sufficientGas Whether there was enough gas to make the call function _callWithExactGasEvenIfTargetIsNoContract( bytes memory payload, address target, uint256 gasLimit, uint16 gasForCallExactCheck ) internal returns (bool success, bool sufficientGas) { assembly { let g := gas() // Compute g -= CALL_WITH_EXACT_GAS_CUSHION and check for underflow. We // need the cushion since the logic following the above call to gas also // costs gas which we cannot account for exactly. So cushion is a // conservative upper bound for the cost of this logic. if iszero(lt(g, gasForCallExactCheck)) { g := sub(g, gasForCallExactCheck) // If g - g//64 <= gasAmount, we don't have enough gas. We subtract g//64 because of EIP-150. if gt(sub(g, div(g, 64)), gasLimit) { // Call and ignore success/return data. Note that we did not check // whether a contract actually exists at the target address. success := call(gasLimit, target, 0, add(payload, 0x20), mload(payload), 0x0, 0x0) sufficientGas := true } } } return (success, sufficientGas); } }
// 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/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 (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: MIT pragma solidity ^0.8.0; import {IPool} from "./pools/IPool.sol"; import {Client} from "../libraries/Client.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; interface IEVM2AnyOnRampClient { /// @notice Get the fee for a given ccip message /// @param destChainSelector The destination chain selector /// @param message The message to calculate the cost for /// @return fee The calculated fee function getFee(uint64 destChainSelector, Client.EVM2AnyMessage calldata message) external view returns (uint256 fee); /// @notice Get the pool for a specific token /// @param destChainSelector The destination chain selector /// @param sourceToken The source chain token to get the pool for /// @return pool Token pool function getPoolBySourceToken(uint64 destChainSelector, IERC20 sourceToken) external view returns (IPool); /// @notice Gets a list of all supported source chain tokens. /// @param destChainSelector The destination chain selector /// @return tokens The addresses of all tokens that this onRamp supports the given destination chain function getSupportedTokens(uint64 destChainSelector) external view returns (address[] memory tokens); /// @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 destChainSelector The destination chain selector /// @param message Message struct to send /// @param feeTokenAmount Amount of fee tokens for payment /// @param originalSender The original initiator of the CCIP request function forwardFromRouter( uint64 destChainSelector, Client.EVM2AnyMessage memory message, uint256 feeTokenAmount, address originalSender ) external returns (bytes32); }
// 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 {ConfirmedOwnerWithProposal} from "./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 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: MIT pragma solidity ^0.8.0; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/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 remoteChainSelector 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 remoteChainSelector, 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 remoteChainSelector 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 remoteChainSelector, 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: MIT pragma solidity ^0.8.0; import {IOwnable} from "../interfaces/IOwnable.sol"; /// @title The ConfirmedOwner contract /// @notice A contract with helpers for basic contract ownership. contract ConfirmedOwnerWithProposal is IOwnable { 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) { // solhint-disable-next-line custom-errors 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. function transferOwnership(address to) public override onlyOwner { _transferOwnership(to); } /// @notice Allows an ownership transfer to be completed by the recipient. function acceptOwnership() external override { // solhint-disable-next-line custom-errors 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 { // solhint-disable-next-line custom-errors require(to != msg.sender, "Cannot transfer to self"); s_pendingOwner = to; emit OwnershipTransferRequested(s_owner, to); } /// @notice validate access function _validateOwnership() internal view { // solhint-disable-next-line custom-errors 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 IOwnable { function owner() external returns (address); function transferOwnership(address recipient) external; function acceptOwnership() external; }
{ "remappings": [ "ds-test/=foundry-lib/forge-std/lib/ds-test/src/", "forge-std/=foundry-lib/forge-std/src/", "@openzeppelin/=node_modules/@openzeppelin/", "@arbitrum/=node_modules/@arbitrum/", "hardhat/=node_modules/hardhat/", "@eth-optimism/=node_modules/@eth-optimism/", "@scroll-tech/=node_modules/@scroll-tech/" ], "optimizer": { "enabled": true, "runs": 1000000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "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":[{"internalType":"uint64","name":"chainSelector","type":"uint64"},{"internalType":"address","name":"offRamp","type":"address"}],"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":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"offRamp","type":"address"}],"name":"isOffRamp","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"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
60a06040523480156200001157600080fd5b5060405162002d8b38038062002d8b8339810160408190526200003491620001af565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e7565b5050600280546001600160a01b0319166001600160a01b039485161790555016608052620001e7565b336001600160a01b03821603620001415760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001aa57600080fd5b919050565b60008060408385031215620001c357600080fd5b620001ce8362000192565b9150620001de6020840162000192565b90509250929050565b608051612b7a62000211600039600081816101f9015281816105e10152610af20152612b7a6000f3fe6080604052600436106101295760003560e01c80638da5cb5b116100a5578063a8d87a3b11610074578063e861e90711610059578063e861e90714610409578063f2fde38b14610434578063fbca3b741461045457600080fd5b8063a8d87a3b1461039c578063da5fcac8146103e957600080fd5b80638da5cb5b146102ed57806396f4e9f914610318578063a40e69c71461032b578063a48a90581461034d57600080fd5b806352cb60ca116100fc578063787350e3116100e1578063787350e31461028057806379ba5097146102a857806383826b2b146102bd57600080fd5b806352cb60ca1461023e5780635f3e849f1461026057600080fd5b8063181f5a771461012e57806320487ded1461018d5780633cf97983146101bb5780635246492f146101ea575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280600c81526020017f526f7574657220312e322e30000000000000000000000000000000000000000081525081565b6040516101849190611f67565b60405180910390f35b34801561019957600080fd5b506101ad6101a83660046121d8565b610481565b604051908152602001610184565b3480156101c757600080fd5b506101db6101d63660046122d5565b6105d9565b6040516101849392919061234d565b3480156101f657600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561024a57600080fd5b5061025e610259366004612378565b610836565b005b34801561026c57600080fd5b5061025e61027b366004612395565b610885565b34801561028c57600080fd5b50610295608481565b60405161ffff9091168152602001610184565b3480156102b457600080fd5b5061025e6109d3565b3480156102c957600080fd5b506102dd6102d83660046123d6565b610ad0565b6040519015158152602001610184565b3480156102f957600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610219565b6101ad6103263660046121d8565b610aee565b34801561033757600080fd5b5061034061108f565b604051610184919061240d565b34801561035957600080fd5b506102dd61036836600461247c565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b3480156103a857600080fd5b506102196103b736600461247c565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156103f557600080fd5b5061025e6104043660046124e3565b61119c565b34801561041557600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff16610219565b34801561044057600080fd5b5061025e61044f366004612378565b6114bb565b34801561046057600080fd5b5061047461046f36600461247c565b6114cf565b604051610184919061257d565b606081015160009073ffffffffffffffffffffffffffffffffffffffff166104c25760025473ffffffffffffffffffffffffffffffffffffffff1660608301525b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff168061053a576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024015b60405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216906320487ded9061058e90879087906004016126b4565b602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf91906126d7565b9150505b92915050565b6000606060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e91906126f0565b156106a5576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106be6106b86040890160208a0161247c565b33610ad0565b6106f4576040517fd2316ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006385572ffb60e01b8860405160240161070f919061281f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905061079c8186888a60846115ef565b919550935091507f9b877de93ea9895756e337442c657f95a34fc68e7eb988bdfa693d5be83016b688356107d660408b0160208c0161247c565b83516020850120604051610823939291339193845267ffffffffffffffff92909216602084015273ffffffffffffffffffffffffffffffffffffffff166040830152606082015260800190565b60405180910390a1509450945094915050565b61083e611715565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61088d611715565b73ffffffffffffffffffffffffffffffffffffffff82166108f2576040517f26a78f8f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610531565b73ffffffffffffffffffffffffffffffffffffffff83166109ad5760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610967576040519150601f19603f3d011682016040523d82523d6000602084013e61096c565b606091505b50509050806109a7576040517fe417b80b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6109ce73ffffffffffffffffffffffffffffffffffffffff84168383611798565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610531565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000610ae7610adf848461186c565b6004906118b0565b9392505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7f91906126f0565b15610bb6576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610c29576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610531565b606083015160009073ffffffffffffffffffffffffffffffffffffffff16610dbb5760025473ffffffffffffffffffffffffffffffffffffffff90811660608601526040517f20487ded000000000000000000000000000000000000000000000000000000008152908316906320487ded90610cab90889088906004016126b4565b602060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec91906126d7565b905080341015610d28576040517f07da6ee600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b349050836060015173ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d7757600080fd5b505af1158015610d8b573d6000803e3d6000fd5b505050506060850151610db6915073ffffffffffffffffffffffffffffffffffffffff168383611798565b610eb2565b3415610df3576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906320487ded90610e4790889088906004016126b4565b602060405180830381865afa158015610e64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8891906126d7565b6060850151909150610eb29073ffffffffffffffffffffffffffffffffffffffff163384846118c8565b60005b846040015151811015610fea57600085604001518281518110610eda57610eda61292b565b6020908102919091010151516040517f48a98aa400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8916600482015273ffffffffffffffffffffffffffffffffffffffff8083166024830152919250610fd9913391908716906348a98aa490604401602060405180830381865afa158015610f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f90919061295a565b88604001518581518110610fa657610fa661292b565b6020026020010151602001518473ffffffffffffffffffffffffffffffffffffffff166118c8909392919063ffffffff16565b50610fe3816129a6565b9050610eb5565b506040517fdf0aa9e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063df0aa9e9906110439088908890869033906004016129de565b6020604051808303816000875af1158015611062573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108691906126d7565b95945050505050565b6060600061109d6004611926565b90506000815167ffffffffffffffff8111156110bb576110bb611f97565b60405190808252806020026020018201604052801561110057816020015b60408051808201909152600080825260208201528152602001906001900390816110d95790505b50905060005b82518110156111955760008382815181106111235761112361292b565b60200260200101519050604051806040016040528060a083901c67ffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff168152508383815181106111785761117861292b565b6020026020010181905250508061118e906129a6565b9050611106565b5092915050565b6111a4611715565b60005b858110156112885760008787838181106111c3576111c361292b565b9050604002018036038101906111d99190612a2e565b60208181018051835167ffffffffffffffff90811660009081526003855260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055855193519051921682529394509216917f1f7d0ec248b80e5c0dde0ee531c4fc8fdb6ce9a2b3d90f560c74acd6a7202f23910160405180910390a250611281816129a6565b90506111a7565b5060005b838110156113c95760008585838181106112a8576112a861292b565b6112be926020604090920201908101915061247c565b905060008686848181106112d4576112d461292b565b90506040020160200160208101906112ec9190612378565b90506113036112fb838361186c565b600490611933565b611361576040517f4964779000000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8316600482015273ffffffffffffffffffffffffffffffffffffffff82166024820152604401610531565b60405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa823809efda3ba66c873364eec120fa0923d9fabda73bc97dd5663341e2d9bcb9060200160405180910390a25050806113c2906129a6565b905061128c565b5060005b818110156114b25760008383838181106113e9576113e961292b565b6113ff926020604090920201908101915061247c565b905060008484848181106114155761141561292b565b905060400201602001602081019061142d9190612378565b905061144461143c838361186c565b60049061193f565b1561149f5760405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa4bdf64ebdf3316320601a081916a75aa144bcef6c4beeb0e9fb1982cacc6b949060200160405180910390a25b5050806114ab906129a6565b90506113cd565b50505050505050565b6114c3611715565b6114cc8161194b565b50565b60606115098267ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b611523576040805160008082526020820190925290611195565b67ffffffffffffffff8216600081815260036020526040908190205490517ffbca3b74000000000000000000000000000000000000000000000000000000008152600481019290925273ffffffffffffffffffffffffffffffffffffffff169063fbca3b7490602401600060405180830381865afa1580156115a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d39190810190612a6d565b6000606060008361ffff1667ffffffffffffffff81111561161257611612611f97565b6040519080825280601f01601f19166020018201604052801561163c576020820181803683370190505b509150863b61166f577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a858110156116a2577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b85900360408104810387106116db577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156116fe5750835b808352806000602085013e50955095509592505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610531565b565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109ce9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a40565b6000610ae773ffffffffffffffffffffffffffffffffffffffff83167bffffffffffffffff000000000000000000000000000000000000000060a086901b16612afc565b60008181526001830160205260408120541515610ae7565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109a79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016117ea565b60606000610ae783611b4c565b6000610ae78383611ba8565b6000610ae78383611c9b565b3373ffffffffffffffffffffffffffffffffffffffff8216036119ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610531565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611aa2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cea9092919063ffffffff16565b8051909150156109ce5780806020019051810190611ac091906126f0565b6109ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610531565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9c57602002820191906000526020600020905b815481526020019060010190808311611b88575b50505050509050919050565b60008181526001830160205260408120548015611c91576000611bcc600183612b0f565b8554909150600090611be090600190612b0f565b9050818114611c45576000866000018281548110611c0057611c0061292b565b9060005260206000200154905080876000018481548110611c2357611c2361292b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611c5657611c56612b22565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d3565b60009150506105d3565b6000818152600183016020526040812054611ce2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d3565b5060006105d3565b6060611cf98484600085611d01565b949350505050565b606082471015611d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610531565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611dbc9190612b51565b60006040518083038185875af1925050503d8060008114611df9576040519150601f19603f3d011682016040523d82523d6000602084013e611dfe565b606091505b5091509150611e0f87838387611e1a565b979650505050505050565b60608315611eb0578251600003611ea95773ffffffffffffffffffffffffffffffffffffffff85163b611ea9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610531565b5081611cf9565b611cf98383815115611ec55781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105319190611f67565b60005b83811015611f14578181015183820152602001611efc565b50506000910152565b60008151808452611f35816020860160208601611ef9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ae76020830184611f1d565b803567ffffffffffffffff81168114611f9257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611fe957611fe9611f97565b60405290565b60405160a0810167ffffffffffffffff81118282101715611fe957611fe9611f97565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561205957612059611f97565b604052919050565b600082601f83011261207257600080fd5b813567ffffffffffffffff81111561208c5761208c611f97565b6120bd60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612012565b8181528460208386010111156120d257600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff82111561210957612109611f97565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146114cc57600080fd5b8035611f9281612113565b600082601f83011261215157600080fd5b81356020612166612161836120ef565b612012565b82815260069290921b8401810191818101908684111561218557600080fd5b8286015b848110156121cd57604081890312156121a25760008081fd5b6121aa611fc6565b81356121b581612113565b81528185013585820152835291830191604001612189565b509695505050505050565b600080604083850312156121eb57600080fd5b6121f483611f7a565b9150602083013567ffffffffffffffff8082111561221157600080fd5b9084019060a0828703121561222557600080fd5b61222d611fef565b82358281111561223c57600080fd5b61224888828601612061565b82525060208301358281111561225d57600080fd5b61226988828601612061565b60208301525060408301358281111561228157600080fd5b61228d88828601612140565b60408301525061229f60608401612135565b60608201526080830135828111156122b657600080fd5b6122c288828601612061565b6080830152508093505050509250929050565b600080600080608085870312156122eb57600080fd5b843567ffffffffffffffff81111561230257600080fd5b850160a0818803121561231457600080fd5b9350602085013561ffff8116811461232b57600080fd5b925060408501359150606085013561234281612113565b939692955090935050565b83151581526060602082015260006123686060830185611f1d565b9050826040830152949350505050565b60006020828403121561238a57600080fd5b8135610ae781612113565b6000806000606084860312156123aa57600080fd5b83356123b581612113565b925060208401356123c581612113565b929592945050506040919091013590565b600080604083850312156123e957600080fd5b6123f283611f7a565b9150602083013561240281612113565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b8281101561246f578151805167ffffffffffffffff16855286015173ffffffffffffffffffffffffffffffffffffffff1686850152928401929085019060010161242a565b5091979650505050505050565b60006020828403121561248e57600080fd5b610ae782611f7a565b60008083601f8401126124a957600080fd5b50813567ffffffffffffffff8111156124c157600080fd5b6020830191508360208260061b85010111156124dc57600080fd5b9250929050565b600080600080600080606087890312156124fc57600080fd5b863567ffffffffffffffff8082111561251457600080fd5b6125208a838b01612497565b9098509650602089013591508082111561253957600080fd5b6125458a838b01612497565b9096509450604089013591508082111561255e57600080fd5b5061256b89828a01612497565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b818110156125cb57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612599565b50909695505050505050565b6000815160a084526125ec60a0850182611f1d565b9050602080840151858303828701526126058382611f1d565b60408681015188830389830152805180845290850195509092506000918401905b80831015612665578551805173ffffffffffffffffffffffffffffffffffffffff16835285015185830152948401946001929092019190830190612626565b506060870151945061268f606089018673ffffffffffffffffffffffffffffffffffffffff169052565b6080870151945087810360808901526126a88186611f1d565b98975050505050505050565b67ffffffffffffffff83168152604060208201526000611cf960408301846125d7565b6000602082840312156126e957600080fd5b5051919050565b60006020828403121561270257600080fd5b81518015158114610ae757600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261274757600080fd5b830160208101925035905067ffffffffffffffff81111561276757600080fd5b8036038213156124dc57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156128145781356127e281612113565b73ffffffffffffffffffffffffffffffffffffffff1687528183013583880152604096870196909101906001016127cf565b509495945050505050565b6020815281356020820152600061283860208401611f7a565b67ffffffffffffffff80821660408501526128566040860186612712565b925060a0606086015261286d60c086018483612776565b92505061287d6060860186612712565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808786030160808801526128b3858385612776565b9450608088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030183126128ec57600080fd5b6020928801928301923591508382111561290557600080fd5b8160061b360383131561291757600080fd5b8685030160a0870152611e0f8482846127bf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561296c57600080fd5b8151610ae781612113565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036129d7576129d7612977565b5060010190565b67ffffffffffffffff85168152608060208201526000612a0160808301866125d7565b905083604083015273ffffffffffffffffffffffffffffffffffffffff8316606083015295945050505050565b600060408284031215612a4057600080fd5b612a48611fc6565b612a5183611f7a565b81526020830135612a6181612113565b60208201529392505050565b60006020808385031215612a8057600080fd5b825167ffffffffffffffff811115612a9757600080fd5b8301601f81018513612aa857600080fd5b8051612ab6612161826120ef565b81815260059190911b82018301908381019087831115612ad557600080fd5b928401925b82841015611e0f578351612aed81612113565b82529284019290840190612ada565b808201808211156105d3576105d3612977565b818103818111156105d3576105d3612977565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612b63818460208701611ef9565b919091019291505056fea164736f6c6343000813000a0000000000000000000000007d72b22a74a216af4a002a1095c8c707d6ec1c5f0000000000000000000000002375959c6571ac7a83c164c6fccbd09e7782773d
Deployed Bytecode
0x6080604052600436106101295760003560e01c80638da5cb5b116100a5578063a8d87a3b11610074578063e861e90711610059578063e861e90714610409578063f2fde38b14610434578063fbca3b741461045457600080fd5b8063a8d87a3b1461039c578063da5fcac8146103e957600080fd5b80638da5cb5b146102ed57806396f4e9f914610318578063a40e69c71461032b578063a48a90581461034d57600080fd5b806352cb60ca116100fc578063787350e3116100e1578063787350e31461028057806379ba5097146102a857806383826b2b146102bd57600080fd5b806352cb60ca1461023e5780635f3e849f1461026057600080fd5b8063181f5a771461012e57806320487ded1461018d5780633cf97983146101bb5780635246492f146101ea575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280600c81526020017f526f7574657220312e322e30000000000000000000000000000000000000000081525081565b6040516101849190611f67565b60405180910390f35b34801561019957600080fd5b506101ad6101a83660046121d8565b610481565b604051908152602001610184565b3480156101c757600080fd5b506101db6101d63660046122d5565b6105d9565b6040516101849392919061234d565b3480156101f657600080fd5b507f0000000000000000000000002375959c6571ac7a83c164c6fccbd09e7782773d5b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561024a57600080fd5b5061025e610259366004612378565b610836565b005b34801561026c57600080fd5b5061025e61027b366004612395565b610885565b34801561028c57600080fd5b50610295608481565b60405161ffff9091168152602001610184565b3480156102b457600080fd5b5061025e6109d3565b3480156102c957600080fd5b506102dd6102d83660046123d6565b610ad0565b6040519015158152602001610184565b3480156102f957600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610219565b6101ad6103263660046121d8565b610aee565b34801561033757600080fd5b5061034061108f565b604051610184919061240d565b34801561035957600080fd5b506102dd61036836600461247c565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b3480156103a857600080fd5b506102196103b736600461247c565b67ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156103f557600080fd5b5061025e6104043660046124e3565b61119c565b34801561041557600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff16610219565b34801561044057600080fd5b5061025e61044f366004612378565b6114bb565b34801561046057600080fd5b5061047461046f36600461247c565b6114cf565b604051610184919061257d565b606081015160009073ffffffffffffffffffffffffffffffffffffffff166104c25760025473ffffffffffffffffffffffffffffffffffffffff1660608301525b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff168061053a576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526024015b60405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216906320487ded9061058e90879087906004016126b4565b602060405180830381865afa1580156105ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105cf91906126d7565b9150505b92915050565b6000606060007f0000000000000000000000002375959c6571ac7a83c164c6fccbd09e7782773d73ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561064a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066e91906126f0565b156106a5576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106be6106b86040890160208a0161247c565b33610ad0565b6106f4576040517fd2316ede00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006385572ffb60e01b8860405160240161070f919061281f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152905061079c8186888a60846115ef565b919550935091507f9b877de93ea9895756e337442c657f95a34fc68e7eb988bdfa693d5be83016b688356107d660408b0160208c0161247c565b83516020850120604051610823939291339193845267ffffffffffffffff92909216602084015273ffffffffffffffffffffffffffffffffffffffff166040830152606082015260800190565b60405180910390a1509450945094915050565b61083e611715565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61088d611715565b73ffffffffffffffffffffffffffffffffffffffff82166108f2576040517f26a78f8f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610531565b73ffffffffffffffffffffffffffffffffffffffff83166109ad5760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114610967576040519150601f19603f3d011682016040523d82523d6000602084013e61096c565b606091505b50509050806109a7576040517fe417b80b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6109ce73ffffffffffffffffffffffffffffffffffffffff84168383611798565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610531565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000610ae7610adf848461186c565b6004906118b0565b9392505050565b60007f0000000000000000000000002375959c6571ac7a83c164c6fccbd09e7782773d73ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7f91906126f0565b15610bb6576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff831660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610c29576040517fae236d9c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610531565b606083015160009073ffffffffffffffffffffffffffffffffffffffff16610dbb5760025473ffffffffffffffffffffffffffffffffffffffff90811660608601526040517f20487ded000000000000000000000000000000000000000000000000000000008152908316906320487ded90610cab90889088906004016126b4565b602060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec91906126d7565b905080341015610d28576040517f07da6ee600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b349050836060015173ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015610d7757600080fd5b505af1158015610d8b573d6000803e3d6000fd5b505050506060850151610db6915073ffffffffffffffffffffffffffffffffffffffff168383611798565b610eb2565b3415610df3576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f20487ded00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906320487ded90610e4790889088906004016126b4565b602060405180830381865afa158015610e64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8891906126d7565b6060850151909150610eb29073ffffffffffffffffffffffffffffffffffffffff163384846118c8565b60005b846040015151811015610fea57600085604001518281518110610eda57610eda61292b565b6020908102919091010151516040517f48a98aa400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8916600482015273ffffffffffffffffffffffffffffffffffffffff8083166024830152919250610fd9913391908716906348a98aa490604401602060405180830381865afa158015610f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f90919061295a565b88604001518581518110610fa657610fa661292b565b6020026020010151602001518473ffffffffffffffffffffffffffffffffffffffff166118c8909392919063ffffffff16565b50610fe3816129a6565b9050610eb5565b506040517fdf0aa9e900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063df0aa9e9906110439088908890869033906004016129de565b6020604051808303816000875af1158015611062573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108691906126d7565b95945050505050565b6060600061109d6004611926565b90506000815167ffffffffffffffff8111156110bb576110bb611f97565b60405190808252806020026020018201604052801561110057816020015b60408051808201909152600080825260208201528152602001906001900390816110d95790505b50905060005b82518110156111955760008382815181106111235761112361292b565b60200260200101519050604051806040016040528060a083901c67ffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff168152508383815181106111785761117861292b565b6020026020010181905250508061118e906129a6565b9050611106565b5092915050565b6111a4611715565b60005b858110156112885760008787838181106111c3576111c361292b565b9050604002018036038101906111d99190612a2e565b60208181018051835167ffffffffffffffff90811660009081526003855260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff948516179055855193519051921682529394509216917f1f7d0ec248b80e5c0dde0ee531c4fc8fdb6ce9a2b3d90f560c74acd6a7202f23910160405180910390a250611281816129a6565b90506111a7565b5060005b838110156113c95760008585838181106112a8576112a861292b565b6112be926020604090920201908101915061247c565b905060008686848181106112d4576112d461292b565b90506040020160200160208101906112ec9190612378565b90506113036112fb838361186c565b600490611933565b611361576040517f4964779000000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8316600482015273ffffffffffffffffffffffffffffffffffffffff82166024820152604401610531565b60405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa823809efda3ba66c873364eec120fa0923d9fabda73bc97dd5663341e2d9bcb9060200160405180910390a25050806113c2906129a6565b905061128c565b5060005b818110156114b25760008383838181106113e9576113e961292b565b6113ff926020604090920201908101915061247c565b905060008484848181106114155761141561292b565b905060400201602001602081019061142d9190612378565b905061144461143c838361186c565b60049061193f565b1561149f5760405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907fa4bdf64ebdf3316320601a081916a75aa144bcef6c4beeb0e9fb1982cacc6b949060200160405180910390a25b5050806114ab906129a6565b90506113cd565b50505050505050565b6114c3611715565b6114cc8161194b565b50565b60606115098267ffffffffffffffff1660009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b611523576040805160008082526020820190925290611195565b67ffffffffffffffff8216600081815260036020526040908190205490517ffbca3b74000000000000000000000000000000000000000000000000000000008152600481019290925273ffffffffffffffffffffffffffffffffffffffff169063fbca3b7490602401600060405180830381865afa1580156115a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526105d39190810190612a6d565b6000606060008361ffff1667ffffffffffffffff81111561161257611612611f97565b6040519080825280601f01601f19166020018201604052801561163c576020820181803683370190505b509150863b61166f577f0c3b563c0000000000000000000000000000000000000000000000000000000060005260046000fd5b5a858110156116a2577fafa32a2c0000000000000000000000000000000000000000000000000000000060005260046000fd5b85900360408104810387106116db577f37c3be290000000000000000000000000000000000000000000000000000000060005260046000fd5b505a6000808a5160208c0160008c8cf193505a900390503d848111156116fe5750835b808352806000602085013e50955095509592505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610531565b565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526109ce9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a40565b6000610ae773ffffffffffffffffffffffffffffffffffffffff83167bffffffffffffffff000000000000000000000000000000000000000060a086901b16612afc565b60008181526001830160205260408120541515610ae7565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109a79085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016117ea565b60606000610ae783611b4c565b6000610ae78383611ba8565b6000610ae78383611c9b565b3373ffffffffffffffffffffffffffffffffffffffff8216036119ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610531565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611aa2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611cea9092919063ffffffff16565b8051909150156109ce5780806020019051810190611ac091906126f0565b6109ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610531565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9c57602002820191906000526020600020905b815481526020019060010190808311611b88575b50505050509050919050565b60008181526001830160205260408120548015611c91576000611bcc600183612b0f565b8554909150600090611be090600190612b0f565b9050818114611c45576000866000018281548110611c0057611c0061292b565b9060005260206000200154905080876000018481548110611c2357611c2361292b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611c5657611c56612b22565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105d3565b60009150506105d3565b6000818152600183016020526040812054611ce2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105d3565b5060006105d3565b6060611cf98484600085611d01565b949350505050565b606082471015611d93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610531565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611dbc9190612b51565b60006040518083038185875af1925050503d8060008114611df9576040519150601f19603f3d011682016040523d82523d6000602084013e611dfe565b606091505b5091509150611e0f87838387611e1a565b979650505050505050565b60608315611eb0578251600003611ea95773ffffffffffffffffffffffffffffffffffffffff85163b611ea9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610531565b5081611cf9565b611cf98383815115611ec55781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105319190611f67565b60005b83811015611f14578181015183820152602001611efc565b50506000910152565b60008151808452611f35816020860160208601611ef9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610ae76020830184611f1d565b803567ffffffffffffffff81168114611f9257600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611fe957611fe9611f97565b60405290565b60405160a0810167ffffffffffffffff81118282101715611fe957611fe9611f97565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561205957612059611f97565b604052919050565b600082601f83011261207257600080fd5b813567ffffffffffffffff81111561208c5761208c611f97565b6120bd60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612012565b8181528460208386010111156120d257600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff82111561210957612109611f97565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146114cc57600080fd5b8035611f9281612113565b600082601f83011261215157600080fd5b81356020612166612161836120ef565b612012565b82815260069290921b8401810191818101908684111561218557600080fd5b8286015b848110156121cd57604081890312156121a25760008081fd5b6121aa611fc6565b81356121b581612113565b81528185013585820152835291830191604001612189565b509695505050505050565b600080604083850312156121eb57600080fd5b6121f483611f7a565b9150602083013567ffffffffffffffff8082111561221157600080fd5b9084019060a0828703121561222557600080fd5b61222d611fef565b82358281111561223c57600080fd5b61224888828601612061565b82525060208301358281111561225d57600080fd5b61226988828601612061565b60208301525060408301358281111561228157600080fd5b61228d88828601612140565b60408301525061229f60608401612135565b60608201526080830135828111156122b657600080fd5b6122c288828601612061565b6080830152508093505050509250929050565b600080600080608085870312156122eb57600080fd5b843567ffffffffffffffff81111561230257600080fd5b850160a0818803121561231457600080fd5b9350602085013561ffff8116811461232b57600080fd5b925060408501359150606085013561234281612113565b939692955090935050565b83151581526060602082015260006123686060830185611f1d565b9050826040830152949350505050565b60006020828403121561238a57600080fd5b8135610ae781612113565b6000806000606084860312156123aa57600080fd5b83356123b581612113565b925060208401356123c581612113565b929592945050506040919091013590565b600080604083850312156123e957600080fd5b6123f283611f7a565b9150602083013561240281612113565b809150509250929050565b602080825282518282018190526000919060409081850190868401855b8281101561246f578151805167ffffffffffffffff16855286015173ffffffffffffffffffffffffffffffffffffffff1686850152928401929085019060010161242a565b5091979650505050505050565b60006020828403121561248e57600080fd5b610ae782611f7a565b60008083601f8401126124a957600080fd5b50813567ffffffffffffffff8111156124c157600080fd5b6020830191508360208260061b85010111156124dc57600080fd5b9250929050565b600080600080600080606087890312156124fc57600080fd5b863567ffffffffffffffff8082111561251457600080fd5b6125208a838b01612497565b9098509650602089013591508082111561253957600080fd5b6125458a838b01612497565b9096509450604089013591508082111561255e57600080fd5b5061256b89828a01612497565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b818110156125cb57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612599565b50909695505050505050565b6000815160a084526125ec60a0850182611f1d565b9050602080840151858303828701526126058382611f1d565b60408681015188830389830152805180845290850195509092506000918401905b80831015612665578551805173ffffffffffffffffffffffffffffffffffffffff16835285015185830152948401946001929092019190830190612626565b506060870151945061268f606089018673ffffffffffffffffffffffffffffffffffffffff169052565b6080870151945087810360808901526126a88186611f1d565b98975050505050505050565b67ffffffffffffffff83168152604060208201526000611cf960408301846125d7565b6000602082840312156126e957600080fd5b5051919050565b60006020828403121561270257600080fd5b81518015158114610ae757600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261274757600080fd5b830160208101925035905067ffffffffffffffff81111561276757600080fd5b8036038213156124dc57600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8183526000602080850194508260005b858110156128145781356127e281612113565b73ffffffffffffffffffffffffffffffffffffffff1687528183013583880152604096870196909101906001016127cf565b509495945050505050565b6020815281356020820152600061283860208401611f7a565b67ffffffffffffffff80821660408501526128566040860186612712565b925060a0606086015261286d60c086018483612776565b92505061287d6060860186612712565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808786030160808801526128b3858385612776565b9450608088013592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030183126128ec57600080fd5b6020928801928301923591508382111561290557600080fd5b8160061b360383131561291757600080fd5b8685030160a0870152611e0f8482846127bf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561296c57600080fd5b8151610ae781612113565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036129d7576129d7612977565b5060010190565b67ffffffffffffffff85168152608060208201526000612a0160808301866125d7565b905083604083015273ffffffffffffffffffffffffffffffffffffffff8316606083015295945050505050565b600060408284031215612a4057600080fd5b612a48611fc6565b612a5183611f7a565b81526020830135612a6181612113565b60208201529392505050565b60006020808385031215612a8057600080fd5b825167ffffffffffffffff811115612a9757600080fd5b8301601f81018513612aa857600080fd5b8051612ab6612161826120ef565b81815260059190911b82018301908381019087831115612ad557600080fd5b928401925b82841015611e0f578351612aed81612113565b82529284019290840190612ada565b808201808211156105d3576105d3612977565b818103818111156105d3576105d3612977565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612b63818460208701611ef9565b919091019291505056fea164736f6c6343000813000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007d72b22a74a216af4a002a1095c8c707d6ec1c5f0000000000000000000000002375959c6571ac7a83c164c6fccbd09e7782773d
-----Decoded View---------------
Arg [0] : wrappedNative (address): 0x7D72b22a74A216Af4a002a1095C8C707d6eC1C5f
Arg [1] : armProxy (address): 0x2375959c6571AC7a83c164C6FCcbd09E7782773d
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000007d72b22a74a216af4a002a1095c8c707d6ec1c5f
Arg [1] : 0000000000000000000000002375959c6571ac7a83c164c6fccbd09e7782773d
Deployed Bytecode Sourcemap
1239:11421:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2130:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;3441:515;;;;;;;;;;-1:-1:-1;3441:515:0;;;;;:::i;:::-;;:::i;:::-;;;5642:25:23;;;5630:2;5615:18;3441:515:0;5496:177:23;6858:947:0;;;;;;;;;;-1:-1:-1;6858:947:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;8930:83::-;;;;;;;;;;-1:-1:-1;8998:10:0;8930:83;;;7130:42:23;7118:55;;;7100:74;;7088:2;7073:18;8930:83:0;6954:226:23;8728:110:0;;;;;;;;;;-1:-1:-1;8728:110:0;;;;;:::i;:::-;;:::i;:::-;;11866:370;;;;;;;;;;-1:-1:-1;11866:370:0;;;;;:::i;:::-;;:::i;2378:49::-;;;;;;;;;;;;2417:10;2378:49;;;;;8072:6:23;8060:19;;;8042:38;;8030:2;8015:18;2378:49:0;7898:188:23;1022:312:13;;;;;;;;;;;;;:::i;9703:309:0:-;;;;;;;;;;-1:-1:-1;9703:309:0;;;;;:::i;:::-;;:::i;:::-;;;8580:14:23;;8573:22;8555:41;;8543:2;8528:18;9703:309:0;8415:187:23;1374:81:13;;;;;;;;;;-1:-1:-1;1421:7:13;1443;;;1374:81;;4468:2031:0;;;;;;:::i;:::-;;:::i;9170:503::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;4301:131::-;;;;;;;;;;-1:-1:-1;4301:131:0;;;;;:::i;:::-;4389:24;;4370:4;4389:24;;;:9;:24;;;;;;:38;:24;:38;;;4301:131;9043:123;;;;;;;;;;-1:-1:-1;9043:123:0;;;;;:::i;:::-;9133:28;;9111:7;9133:28;;;:9;:28;;;;;;;;;9043:123;10147:1424;;;;;;;;;;-1:-1:-1;10147:1424:0;;;;;:::i;:::-;;:::i;8506:93::-;;;;;;;;;;-1:-1:-1;8579:15:0;;;;8506:93;;843:98:13;;;;;;;;;;-1:-1:-1;843:98:13;;;;;:::i;:::-;;:::i;3992:273:0:-;;;;;;;;;;-1:-1:-1;3992:273:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3441:515::-;3586:16;;;;3563:11;;3586:30;;3582:143;;3702:15;;;;3675:16;;;:43;3582:143;3747:35;;;3730:14;3747:35;;;:9;:35;;;;;;;;;3788:86;;3821:53;;;;;12300:18:23;12288:31;;3821:53:0;;;12270:50:23;12243:18;;3821:53:0;;;;;;;;3788:86;3887:64;;;;;:29;;;;;;:64;;3917:24;;3943:7;;3887:64;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3880:71;;;3441:515;;;;;:::o;6858:947::-;7044:12;7058:20;7080:15;12601:10;12596:25;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12592:54;;;12632:14;;;;;;;;;;;;;;12592:54;7162:50:::1;7172:27;::::0;;;::::1;::::0;::::1;;:::i;:::-;7201:10;7162:9;:50::i;:::-;7157:77;;7221:13;;;;;;;;;;;;;;7157:77;7366:17;7409:44;;;7455:7;7386:77;;;;;;;;:::i;:::-;;::::0;;;;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;;;-1:-1:-1;7500:156:0::1;7386:77:::0;7568:8;7584;7600:20;776:10:10::1;7500:48:0;:156::i;:::-;7470:186:::0;;-1:-1:-1;7470:186:0;-1:-1:-1;7470:186:0;-1:-1:-1;7668:92:0::1;7684:17:::0;::::1;7703:27;::::0;;;::::1;::::0;::::1;;:::i;:::-;7744:15:::0;;::::1;::::0;::::1;::::0;7668:92:::1;::::0;::::1;::::0;;;7732:10:::1;::::0;17936:25:23;;;18009:18;17997:31;;;;17992:2;17977:18;;17970:59;18077:42;18065:55;18060:2;18045:18;;18038:83;18152:2;18137:18;;18130:34;17923:3;17908:19;;17707:463;7668:92:0::1;;;;;;;;7766:34;6858:947:::0;;;;;;;;:::o;8728:110::-;2059:20:13;:18;:20::i;:::-;8802:15:0::1;:31:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;8728:110::o;11866:370::-;2059:20:13;:18;:20::i;:::-;11968:16:0::1;::::0;::::1;11964:56;;11993:27;::::0;::::1;::::0;;7130:42:23;7118:55;;11993:27:0::1;::::0;::::1;7100:74:23::0;7073:18;;11993:27:0::1;6954:226:23::0;11964:56:0::1;12031:26;::::0;::::1;12027:154;;12068:12;12086:2;:7;;12101:6;12086:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12067:45;;;12125:7;12120:40;;12141:19;;;;;;;;;;;;;;12120:40;12168:7;11866:370:::0;;;:::o;12027:154::-:1;12186:45;:33;::::0;::::1;12220:2:::0;12224:6;12186:33:::1;:45::i;:::-;11866:370:::0;;;:::o;1022:312:13:-;1142:14;;;;1128:10;:28;1120:63;;;;;;;18587:2:23;1120:63:13;;;18569:21:23;18626:2;18606:18;;;18599:30;18665:24;18645:18;;;18638:52;18707:18;;1120:63:13;18385:346:23;1120:63:13;1190:16;1209:7;;1232:10;1222:20;;;;;;;;-1:-1:-1;1248:27:13;;;;;;;1287:42;;1209:7;;;;;1232:10;;1209:7;;1287:42;;;1067:267;1022:312::o;9703:309:0:-;9788:4;9911:96;9947:59;9977:19;9998:7;9947:29;:59::i;:::-;9911:26;;:35;:96::i;:::-;9904:103;9703:309;-1:-1:-1;;;9703:309:0:o;4468:2031::-;4607:7;12601:10;12596:25;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12592:54;;;12632:14;;;;;;;;;;;;;;12592:54;4639:35:::1;::::0;::::1;4622:14;4639:35:::0;;;:9:::1;:35;::::0;;;;;::::1;;::::0;4680:86:::1;;4713:53;::::0;::::1;::::0;;12300:18:23;12288:31;;4713:53:0::1;::::0;::::1;12270:50:23::0;12243:18;;4713:53:0::1;12126:200:23::0;4680:86:0::1;4853:16;::::0;::::1;::::0;4772:22:::1;::::0;4853:30:::1;;4849:1074;;5035:15;::::0;::::1;::::0;;::::1;5016:16;::::0;::::1;:34:::0;5148:64:::1;::::0;;;;:29;;::::1;::::0;::::1;::::0;:64:::1;::::0;5178:24;;5016:7;;5148:64:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5131:81;;5271:14;5259:9;:26;5255:67;;;5294:28;;;;;;;;;;;;;;5255:67;5454:9;5437:26;;5486:7;:16;;;5471:40;;;5519:14;5471:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;;;5551:16:0::1;::::0;::::1;::::0;5544:61:::1;::::0;-1:-1:-1;5544:37:0::1;;5582:6:::0;5590:14;5544:37:::1;:61::i;:::-;4849:1074;;;5630:9;:13:::0;5626:43:::1;;5652:17;;;;;;;;;;;;;;5626:43;5767:64;::::0;;;;:29:::1;::::0;::::1;::::0;::::1;::::0;:64:::1;::::0;5797:24;;5823:7;;5767:64:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5846:16;::::0;::::1;::::0;5750:81;;-1:-1:-1;5839:77:0::1;::::0;:41:::1;;5881:10;5893:6:::0;5750:81;5839:41:::1;:77::i;:::-;5981:9;5976:402;6000:7;:20;;;:27;5996:1;:31;5976:402;;;6042:12;6064:7;:20;;;6085:1;6064:23;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;:29;6246:76:::1;::::0;;;;19142:18:23;19130:31;;6246:76:0::1;::::0;::::1;19112:50:23::0;6246:43:0::1;19198:55:23::0;;;19178:18;;;19171:83;6064:29:0;;-1:-1:-1;6186:185:0::1;::::0;6218:10:::1;::::0;6246:43;;::::1;::::0;::::1;::::0;19085:18:23;;6246:76:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6333:7;:20;;;6354:1;6333:23;;;;;;;;:::i;:::-;;;;;;;:30;;;6186:5;:22;;;;:185;;;;;;:::i;:::-;-1:-1:-1::0;6029:3:0::1;::::0;::::1;:::i;:::-;;;5976:402;;;-1:-1:-1::0;6391:103:0::1;::::0;;;;:40:::1;::::0;::::1;::::0;::::1;::::0;:103:::1;::::0;6432:24;;6458:7;;6467:14;;6483:10:::1;::::0;6391:103:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6384:110:::0;4468:2031;-1:-1:-1;;;;;4468:2031:0:o;9170:503::-;9216:16;9240:32;9275:35;:26;:33;:35::i;:::-;9240:70;;9316:25;9358:15;:22;9344:37;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;9344:37:0;;;;;;;;;;;;;;;;9316:65;;9392:9;9387:261;9411:15;:22;9407:1;:26;9387:261;;;9448:22;9473:15;9489:1;9473:18;;;;;;;;:::i;:::-;;;;;;;9448:43;;9513:128;;;;;;;;9577:3;9559:14;:21;;9513:128;;;;;;9616:14;9513:128;;;;;9499:8;9508:1;9499:11;;;;;;;;:::i;:::-;;;;;;:142;;;;9440:208;9435:3;;;;:::i;:::-;;;9387:261;;;-1:-1:-1;9660:8:0;9170:503;-1:-1:-1;;9170:503:0:o;10147:1424::-;2059:20:13;:18;:20::i;:::-;10404:9:0::1;10399:257;10419:24:::0;;::::1;10399:257;;;10458:26;10487:13;;10501:1;10487:16;;;;;;;:::i;:::-;;;;;;10458:45;;;;;;;;;;:::i;:::-;10555:19;::::0;;::::1;::::0;;10521:30;;10511:41:::1;::::0;;::::1;;::::0;;;:9:::1;:41:::0;;;;;;;:63;;;::::1;;::::0;;::::1;;::::0;;10597:30;;10629:19;;10587:62;;7118:55:23;;7100:74;;10555:19:0;;-1:-1:-1;10587:62:0;::::1;::::0;::::1;::::0;7073:18:23;10587:62:0::1;;;;;;;-1:-1:-1::0;10445:3:0::1;::::0;::::1;:::i;:::-;;;10399:257;;;;10697:9;10692:502;10712:25:::0;;::::1;10692:502;;;10752:26;10781:14;;10796:1;10781:17;;;;;;;:::i;:::-;:37;::::0;::::1;:17;::::0;;::::1;;:37:::0;;::::1;::::0;-1:-1:-1;10781:37:0::1;:::i;:::-;10752:66;;10826:22;10851:14;;10866:1;10851:17;;;;;;;:::i;:::-;;;;;;:25;;;;;;;;;;:::i;:::-;10826:50;;10952:101;10986:66;11016:19;11037:14;10986:29;:66::i;:::-;10952:26;::::0;:33:::1;:101::i;:::-;10947:175;;11070:52;::::0;::::1;::::0;;19142:18:23;19130:31;;11070:52:0::1;::::0;::::1;19112:50:23::0;19210:42;19198:55;;19178:18;;;19171:83;19085:18;;11070:52:0::1;18925:335:23::0;10947:175:0::1;11136:51;::::0;7130:42:23;7118:55;;7100:74;;11136:51:0::1;::::0;::::1;::::0;::::1;::::0;7088:2:23;7073:18;11136:51:0::1;;;;;;;10744:450;;10739:3;;;;:::i;:::-;;;10692:502;;;;11205:9;11200:367;11220:22:::0;;::::1;11200:367;;;11257:26;11286:11;;11298:1;11286:14;;;;;;;:::i;:::-;:34;::::0;::::1;:14;::::0;;::::1;;:34:::0;;::::1;::::0;-1:-1:-1;11286:34:0::1;:::i;:::-;11257:63;;11328:22;11353:11;;11365:1;11353:14;;;;;;;:::i;:::-;;;;;;:22;;;;;;;;;;:::i;:::-;11328:47;;11388:98;11419:66;11449:19;11470:14;11419:29;:66::i;:::-;11388:26;::::0;:30:::1;:98::i;:::-;11384:177;;;11503:49;::::0;7130:42:23;7118:55;;7100:74;;11503:49:0::1;::::0;::::1;::::0;::::1;::::0;7088:2:23;7073:18;11503:49:0::1;;;;;;;11384:177;11249:318;;11244:3;;;;:::i;:::-;;;11200:367;;;;10147:1424:::0;;;;;;:::o;843:98:13:-;2059:20;:18;:20::i;:::-;914:22:::1;933:2;914:18;:22::i;:::-;843:98:::0;:::o;3992:273:0:-;4065:16;4094:31;4111:13;4389:24;;4370:4;4389:24;;;:9;:24;;;;;;:38;:24;:38;;;4301:131;4094:31;4089:76;;4142:16;;;4156:1;4142:16;;;;;;;;;;;;4089:76;4202:22;;;4192:33;;;;:9;:33;;;;;;;;4177:83;;;;;;;;12270:50:23;;;;4192:33:0;;;4177:68;;12243:18:23;;4177:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;3442:2338:15:-;3633:12;3647:20;3669:15;3757:14;3747:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3747:25:15;;3737:35;;4053:6;4041:19;4031:102;;4084:15;4079:3;4072:28;4121:3;4116;4109:16;4031:102;4150:5;4631:20;4628:1;4625:27;4622:118;;;4675:31;4670:3;4663:44;4728:3;4723;4716:16;4622:118;4752:28;;;4895:2;4888:10;;4881:18;;4878:32;-1:-1:-1;4868:127:15;;4934:27;4929:3;4922:40;4983:3;4978;4971:16;4868:127;;5112:5;5340:3;5335;5325:7;5319:14;5312:4;5303:7;5299:18;5296:1;5288:6;5278:8;5273:71;5262:82;;5381:5;5362:25;;;-1:-1:-1;5457:16:15;5483:26;;;5480:72;;;-1:-1:-1;5530:14:15;5480:72;5621:6;5612:7;5605:23;5723:6;5718:3;5711:4;5702:7;5698:18;5683:47;;3442:2338;;;;;;;;;:::o;1797:158:13:-;1916:7;;;;1902:10;:21;1894:56;;;;;;;22609:2:23;1894:56:13;;;22591:21:23;22648:2;22628:18;;;22621:30;22687:24;22667:18;;;22660:52;22729:18;;1894:56:13;22407:346:23;1894:56:13;1797:158::o;759:169:20:-;864:58;;22962:42:23;22950:55;;864:58:20;;;22932:74:23;23022:18;;;23015:34;;;837:86:20;;857:5;;887:23;;22905:18:23;;864:58:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;837:19;:86::i;7946:216:0:-;8072:7;8094:63;;;;8095:35;8127:3;8095:35;;;;8094:63;:::i;10584:138:22:-;10661:4;4067:19;;;:12;;;:19;;;;;;:24;;10680:37;3975:121;932:197:20;1055:68;;23402:42:23;23471:15;;;1055:68:20;;;23453:34:23;23523:15;;23503:18;;;23496:43;23555:18;;;23548:34;;;1028:96:20;;1048:5;;1078:27;;23365:18:23;;1055:68:20;23190:398:23;11872:265:22;11932:16;11956:22;11981:19;11989:3;11981:7;:19::i;10382:129::-;10452:4;10471:35;10479:3;10499:5;10471:7;:35::i;10105:123::-;10172:4;10191:32;10196:3;10216:5;10191:4;:32::i;1528:235:13:-;1643:10;1637:16;;;;1629:52;;;;;;;23795:2:23;1629:52:13;;;23777:21:23;23834:2;23814:18;;;23807:30;23873:25;23853:18;;;23846:53;23916:18;;1629:52:13;23593:347:23;1629:52:13;1688:14;:19;;;;;;;;;;;;;;-1:-1:-1;1746:7:13;;1719:39;;1688:19;;1746:7;;1719:39;;-1:-1:-1;1719:39:13;1528:235;:::o;3401:668:20:-;3804:23;3830:69;3858:4;3830:69;;;;;;;;;;;;;;;;;3838:5;3830:27;;;;:69;;;;;:::i;:::-;3909:17;;3804:95;;-1:-1:-1;3909:21:20;3905:160;;3992:10;3981:30;;;;;;;;;;;;:::i;:::-;3973:85;;;;;;;24147:2:23;3973:85:20;;;24129:21:23;24186:2;24166:18;;;24159:30;24225:34;24205:18;;;24198:62;24296:12;24276:18;;;24269:40;24326:19;;3973:85:20;23945:406:23;5224:103:22;5280:16;5311:3;:11;;5304:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5224:103;;;:::o;2660:1242::-;2726:4;2855:19;;;:12;;;:19;;;;;;2885:15;;2881:1017;;3224:21;3248:14;3261:1;3248:10;:14;:::i;:::-;3290:18;;3224:38;;-1:-1:-1;3270:17:22;;3290:22;;3311:1;;3290:22;:::i;:::-;3270:42;;3338:13;3325:9;:26;3321:352;;3363:17;3383:3;:11;;3395:9;3383:22;;;;;;;;:::i;:::-;;;;;;;;;3363:42;;3518:9;3489:3;:11;;3501:13;3489:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3585:23;;;:12;;;:23;;;;;:36;;;3321:352;3739:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3819:3;:12;;:19;3832:5;3819:19;;;;;;;;;;;3812:26;;;3854:4;3847:11;;;;;;;2881:1017;3886:5;3879:12;;;;;2152:354;2215:4;4067:19;;;:12;;;:19;;;;;;2227:275;;-1:-1:-1;2263:23:22;;;;;;;;:11;:23;;;;;;;;;;;;;2425:18;;2403:19;;;:12;;;:19;;;;;;:40;;;;2451:11;;2227:275;-1:-1:-1;2490:5:22;2483:12;;3695:187:21;3798:12;3825:52;3847:6;3855:4;3861:1;3864:12;3825:21;:52::i;:::-;3818:59;3695:187;-1:-1:-1;;;;3695:187:21:o;4672:414::-;4819:12;4872:5;4847:21;:30;;4839:81;;;;;;;24880:2:23;4839:81:21;;;24862:21:23;24919:2;24899:18;;;24892:30;24958:34;24938:18;;;24931:62;25029:8;25009:18;;;25002:36;25055:19;;4839:81:21;24678:402:23;4839:81:21;4927:12;4941:23;4968:6;:11;;4987:5;4994:4;4968:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4926:73;;;;5012:69;5039:6;5047:7;5056:10;5068:12;5012:26;:69::i;:::-;5005:76;4672:414;-1:-1:-1;;;;;;;4672:414:21:o;7016:548::-;7178:12;7202:7;7198:362;;;7223:10;:17;7244:1;7223:22;7219:256;;1395:19;;;;7406:60;;;;;;;25579:2:23;7406:60:21;;;25561:21:23;25618:2;25598:18;;;25591:30;25657:31;25637:18;;;25630:59;25706:18;;7406:60:21;25377:353:23;7406:60:21;-1:-1:-1;7489:10:21;7482:17;;7198:362;7520:33;7528:10;7540:12;8181:17;;:21;8177:325;;8383:10;8377:17;8431:15;8418:10;8414:2;8410:19;8403:44;8177:325;8482:12;8475:20;;;;;;;;;;;:::i;14:250:23:-;99:1;109:113;123:6;120:1;117:13;109:113;;;199:11;;;193:18;180:11;;;173:39;145:2;138:10;109:113;;;-1:-1:-1;;256:1:23;238:16;;231:27;14:250::o;269:330::-;311:3;349:5;343:12;376:6;371:3;364:19;392:76;461:6;454:4;449:3;445:14;438:4;431:5;427:16;392:76;:::i;:::-;513:2;501:15;518:66;497:88;488:98;;;;588:4;484:109;;269:330;-1:-1:-1;;269:330:23:o;604:220::-;753:2;742:9;735:21;716:4;773:45;814:2;803:9;799:18;791:6;773:45;:::i;829:171::-;896:20;;956:18;945:30;;935:41;;925:69;;990:1;987;980:12;925:69;829:171;;;:::o;1005:184::-;1057:77;1054:1;1047:88;1154:4;1151:1;1144:15;1178:4;1175:1;1168:15;1194:257;1266:4;1260:11;;;1298:17;;1345:18;1330:34;;1366:22;;;1327:62;1324:88;;;1392:18;;:::i;:::-;1428:4;1421:24;1194:257;:::o;1456:253::-;1528:2;1522:9;1570:4;1558:17;;1605:18;1590:34;;1626:22;;;1587:62;1584:88;;;1652:18;;:::i;1714:334::-;1785:2;1779:9;1841:2;1831:13;;1846:66;1827:86;1815:99;;1944:18;1929:34;;1965:22;;;1926:62;1923:88;;;1991:18;;:::i;:::-;2027:2;2020:22;1714:334;;-1:-1:-1;1714:334:23:o;2053:589::-;2095:5;2148:3;2141:4;2133:6;2129:17;2125:27;2115:55;;2166:1;2163;2156:12;2115:55;2202:6;2189:20;2228:18;2224:2;2221:26;2218:52;;;2250:18;;:::i;:::-;2294:114;2402:4;2333:66;2326:4;2322:2;2318:13;2314:86;2310:97;2294:114;:::i;:::-;2433:2;2424:7;2417:19;2479:3;2472:4;2467:2;2459:6;2455:15;2451:26;2448:35;2445:55;;;2496:1;2493;2486:12;2445:55;2561:2;2554:4;2546:6;2542:17;2535:4;2526:7;2522:18;2509:55;2609:1;2584:16;;;2602:4;2580:27;2573:38;;;;2588:7;2053:589;-1:-1:-1;;;2053:589:23:o;2647:197::-;2721:4;2754:18;2746:6;2743:30;2740:56;;;2776:18;;:::i;:::-;-1:-1:-1;2821:1:23;2817:14;2833:4;2813:25;;2647:197::o;2849:154::-;2935:42;2928:5;2924:54;2917:5;2914:65;2904:93;;2993:1;2990;2983:12;3008:134;3076:20;;3105:31;3076:20;3105:31;:::i;3147:1044::-;3215:5;3268:3;3261:4;3253:6;3249:17;3245:27;3235:55;;3286:1;3283;3276:12;3235:55;3322:6;3309:20;3348:4;3372:74;3388:57;3442:2;3388:57;:::i;:::-;3372:74;:::i;:::-;3480:15;;;3566:1;3562:10;;;;3550:23;;3546:32;;;3511:12;;;;3590:15;;;3587:35;;;3618:1;3615;3608:12;3587:35;3654:2;3646:6;3642:15;3666:496;3682:6;3677:3;3674:15;3666:496;;;3760:4;3754:3;3749;3745:13;3741:24;3738:114;;;3806:1;3835:2;3831;3824:14;3738:114;3878:22;;:::i;:::-;3941:3;3928:17;3958:33;3983:7;3958:33;:::i;:::-;4004:22;;4075:12;;;4062:26;4046:14;;;4039:50;4102:18;;4140:12;;;;3708:4;3699:14;3666:496;;;-1:-1:-1;4180:5:23;3147:1044;-1:-1:-1;;;;;;3147:1044:23:o;4196:1295::-;4295:6;4303;4356:2;4344:9;4335:7;4331:23;4327:32;4324:52;;;4372:1;4369;4362:12;4324:52;4395:28;4413:9;4395:28;:::i;:::-;4385:38;;4474:2;4463:9;4459:18;4446:32;4497:18;4538:2;4530:6;4527:14;4524:34;;;4554:1;4551;4544:12;4524:34;4577:22;;;;4633:4;4615:16;;;4611:27;4608:47;;;4651:1;4648;4641:12;4608:47;4677:22;;:::i;:::-;4737:2;4724:16;4765:2;4755:8;4752:16;4749:36;;;4781:1;4778;4771:12;4749:36;4808:44;4844:7;4833:8;4829:2;4825:17;4808:44;:::i;:::-;4801:5;4794:59;;4899:2;4895;4891:11;4878:25;4928:2;4918:8;4915:16;4912:36;;;4944:1;4941;4934:12;4912:36;4980:44;5016:7;5005:8;5001:2;4997:17;4980:44;:::i;:::-;4975:2;4968:5;4964:14;4957:68;;5071:2;5067;5063:11;5050:25;5100:2;5090:8;5087:16;5084:36;;;5116:1;5113;5106:12;5084:36;5152:70;5214:7;5203:8;5199:2;5195:17;5152:70;:::i;:::-;5147:2;5140:5;5136:14;5129:94;;5255:31;5282:2;5278;5274:11;5255:31;:::i;:::-;5250:2;5243:5;5239:14;5232:55;5333:3;5329:2;5325:12;5312:26;5363:2;5353:8;5350:16;5347:36;;;5379:1;5376;5369:12;5347:36;5416:44;5452:7;5441:8;5437:2;5433:17;5416:44;:::i;:::-;5410:3;5403:5;5399:15;5392:69;;5480:5;5470:15;;;;;4196:1295;;;;;:::o;5678:764::-;5797:6;5805;5813;5821;5874:3;5862:9;5853:7;5849:23;5845:33;5842:53;;;5891:1;5888;5881:12;5842:53;5931:9;5918:23;5964:18;5956:6;5953:30;5950:50;;;5996:1;5993;5986:12;5950:50;6019:22;;6075:3;6057:16;;;6053:26;6050:46;;;6092:1;6089;6082:12;6050:46;6115:2;-1:-1:-1;6167:2:23;6152:18;;6139:32;6211:6;6200:18;;6190:29;;6180:57;;6233:1;6230;6223:12;6180:57;6256:5;-1:-1:-1;6308:2:23;6293:18;;6280:32;;-1:-1:-1;6364:2:23;6349:18;;6336:32;6377:33;6336:32;6377:33;:::i;:::-;5678:764;;;;-1:-1:-1;5678:764:23;;-1:-1:-1;;5678:764:23:o;6447:370::-;6658:6;6651:14;6644:22;6633:9;6626:41;6703:2;6698;6687:9;6683:18;6676:30;6607:4;6723:45;6764:2;6753:9;6749:18;6741:6;6723:45;:::i;:::-;6715:53;;6804:6;6799:2;6788:9;6784:18;6777:34;6447:370;;;;;;:::o;7185:247::-;7244:6;7297:2;7285:9;7276:7;7272:23;7268:32;7265:52;;;7313:1;7310;7303:12;7265:52;7352:9;7339:23;7371:31;7396:5;7371:31;:::i;7437:456::-;7514:6;7522;7530;7583:2;7571:9;7562:7;7558:23;7554:32;7551:52;;;7599:1;7596;7589:12;7551:52;7638:9;7625:23;7657:31;7682:5;7657:31;:::i;:::-;7707:5;-1:-1:-1;7764:2:23;7749:18;;7736:32;7777:33;7736:32;7777:33;:::i;:::-;7437:456;;7829:7;;-1:-1:-1;;;7883:2:23;7868:18;;;;7855:32;;7437:456::o;8091:319::-;8158:6;8166;8219:2;8207:9;8198:7;8194:23;8190:32;8187:52;;;8235:1;8232;8225:12;8187:52;8258:28;8276:9;8258:28;:::i;:::-;8248:38;;8336:2;8325:9;8321:18;8308:32;8349:31;8374:5;8349:31;:::i;:::-;8399:5;8389:15;;;8091:319;;;;;:::o;8789:858::-;9006:2;9058:21;;;9128:13;;9031:18;;;9150:22;;;8977:4;;9006:2;9191;;9209:18;;;;9250:15;;;8977:4;9293:328;9307:6;9304:1;9301:13;9293:328;;;9366:13;;9408:9;;9419:18;9404:34;9392:47;;9483:11;;9477:18;9497:42;9473:67;9459:12;;;9452:89;9561:12;;;;9596:15;;;;9329:1;9322:9;9293:328;;;-1:-1:-1;9638:3:23;;8789:858;-1:-1:-1;;;;;;;8789:858:23:o;9652:184::-;9710:6;9763:2;9751:9;9742:7;9738:23;9734:32;9731:52;;;9779:1;9776;9769:12;9731:52;9802:28;9820:9;9802:28;:::i;9841:382::-;9919:8;9929:6;9983:3;9976:4;9968:6;9964:17;9960:27;9950:55;;10001:1;9998;9991:12;9950:55;-1:-1:-1;10024:20:23;;10067:18;10056:30;;10053:50;;;10099:1;10096;10089:12;10053:50;10136:4;10128:6;10124:17;10112:29;;10196:3;10189:4;10179:6;10176:1;10172:14;10164:6;10160:27;10156:38;10153:47;10150:67;;;10213:1;10210;10203:12;10150:67;9841:382;;;;;:::o;10228:1207::-;10460:6;10468;10476;10484;10492;10500;10553:2;10541:9;10532:7;10528:23;10524:32;10521:52;;;10569:1;10566;10559:12;10521:52;10609:9;10596:23;10638:18;10679:2;10671:6;10668:14;10665:34;;;10695:1;10692;10685:12;10665:34;10734:85;10811:7;10802:6;10791:9;10787:22;10734:85;:::i;:::-;10838:8;;-1:-1:-1;10708:111:23;-1:-1:-1;10926:2:23;10911:18;;10898:32;;-1:-1:-1;10942:16:23;;;10939:36;;;10971:1;10968;10961:12;10939:36;11010:87;11089:7;11078:8;11067:9;11063:24;11010:87;:::i;:::-;11116:8;;-1:-1:-1;10984:113:23;-1:-1:-1;11204:2:23;11189:18;;11176:32;;-1:-1:-1;11220:16:23;;;11217:36;;;11249:1;11246;11239:12;11217:36;;11288:87;11367:7;11356:8;11345:9;11341:24;11288:87;:::i;:::-;10228:1207;;;;-1:-1:-1;10228:1207:23;;-1:-1:-1;10228:1207:23;;11394:8;;10228:1207;-1:-1:-1;;;10228:1207:23:o;11440:681::-;11611:2;11663:21;;;11733:13;;11636:18;;;11755:22;;;11582:4;;11611:2;11834:15;;;;11808:2;11793:18;;;11582:4;11877:218;11891:6;11888:1;11885:13;11877:218;;;11956:13;;11971:42;11952:62;11940:75;;12070:15;;;;12035:12;;;;11913:1;11906:9;11877:218;;;-1:-1:-1;12112:3:23;;11440:681;-1:-1:-1;;;;;;11440:681:23:o;12331:1303::-;12388:3;12432:5;12426:12;12459:4;12454:3;12447:17;12485:47;12526:4;12521:3;12517:14;12503:12;12485:47;:::i;:::-;12473:59;;12551:4;12603:2;12596:5;12592:14;12586:21;12647:3;12641:4;12637:14;12632:2;12627:3;12623:12;12616:36;12675:39;12709:4;12693:14;12675:39;:::i;:::-;12733:4;12774:14;;;12768:21;12819:16;;;12805:12;;;12798:38;12887:21;;12917:22;;;12995:23;;;;-1:-1:-1;12733:4:23;;-1:-1:-1;;;12957:15:23;;;13046:311;13060:6;13057:1;13054:13;13046:311;;;13119:13;;13163:9;;13174:42;13159:58;13145:73;;13260:11;;13254:18;13238:14;;;13231:42;13332:15;;;;13082:1;13075:9;;;;;13295:14;;;;13046:311;;;13050:3;13405:4;13398:5;13394:16;13388:23;13366:45;;13420:50;13464:4;13459:3;13455:14;13439;6899:42;6888:54;6876:67;;6822:127;13420:50;13518:4;13511:5;13507:16;13501:23;13479:45;;13567:3;13560:5;13556:15;13549:4;13544:3;13540:14;13533:39;13588:40;13622:5;13606:14;13588:40;:::i;:::-;13581:47;12331:1303;-1:-1:-1;;;;;;;;12331:1303:23:o;13639:373::-;13870:18;13862:6;13858:31;13847:9;13840:50;13926:2;13921;13910:9;13906:18;13899:30;13821:4;13946:60;14002:2;13991:9;13987:18;13979:6;13946:60;:::i;14017:184::-;14087:6;14140:2;14128:9;14119:7;14115:23;14111:32;14108:52;;;14156:1;14153;14146:12;14108:52;-1:-1:-1;14179:16:23;;14017:184;-1:-1:-1;14017:184:23:o;14206:277::-;14273:6;14326:2;14314:9;14305:7;14301:23;14297:32;14294:52;;;14342:1;14339;14332:12;14294:52;14374:9;14368:16;14427:5;14420:13;14413:21;14406:5;14403:32;14393:60;;14449:1;14446;14439:12;14488:559;14546:5;14553:6;14613:3;14600:17;14695:66;14684:8;14668:14;14664:29;14660:102;14640:18;14636:127;14626:155;;14777:1;14774;14767:12;14626:155;14805:33;;14909:4;14896:18;;;-1:-1:-1;14857:21:23;;-1:-1:-1;14937:18:23;14926:30;;14923:50;;;14969:1;14966;14959:12;14923:50;15016:6;15000:14;14996:27;14989:5;14985:39;14982:59;;;15037:1;15034;15027:12;15052:325;15140:6;15135:3;15128:19;15192:6;15185:5;15178:4;15173:3;15169:14;15156:43;;15244:1;15237:4;15228:6;15223:3;15219:16;15215:27;15208:38;15110:3;15366:4;15296:66;15291:2;15283:6;15279:15;15275:88;15270:3;15266:98;15262:109;15255:116;;15052:325;;;;:::o;15382:659::-;15505:6;15500:3;15493:19;15475:3;15531:4;15560:2;15555:3;15551:12;15544:19;;15586:5;15609:1;15619:397;15633:6;15630:1;15627:13;15619:397;;;15710:6;15697:20;15730:33;15755:7;15730:33;:::i;:::-;15801:42;15788:56;15776:69;;15892:15;;;15879:29;15865:12;;;15858:51;15932:4;15956:12;;;;15991:15;;;;15655:1;15648:9;15619:397;;;-1:-1:-1;16032:3:23;;15382:659;-1:-1:-1;;;;;15382:659:23:o;16046:1656::-;16241:2;16230:9;16223:21;16293:6;16280:20;16275:2;16264:9;16260:18;16253:48;16204:4;16330:34;16360:2;16352:6;16348:15;16330:34;:::i;:::-;16383:18;16455:2;16441:12;16437:21;16432:2;16421:9;16417:18;16410:49;16504:55;16555:2;16547:6;16543:15;16535:6;16504:55;:::i;:::-;16468:91;;16595:4;16590:2;16579:9;16575:18;16568:32;16623:76;16694:3;16683:9;16679:19;16665:12;16649:14;16623:76;:::i;:::-;16609:90;;;16746:55;16797:2;16789:6;16785:15;16777:6;16746:55;:::i;:::-;16820:66;16951:2;16939:9;16931:6;16927:22;16923:31;16917:3;16906:9;16902:19;16895:60;16978:65;17036:6;17020:14;17004;16978:65;:::i;:::-;16964:79;;17103:3;17095:6;17091:16;17078:30;17052:56;;17184:66;17175:6;17159:14;17155:27;17151:100;17131:18;17127:125;17117:153;;17266:1;17263;17256:12;17117:153;17400:2;17292:31;;;17389:14;;;;17346:19;;-1:-1:-1;17415:14:23;;;17412:34;;;17442:1;17439;17432:12;17412:34;17498:6;17495:1;17491:14;17475;17471:35;17462:7;17458:49;17455:69;;;17520:1;17517;17510:12;17455:69;17566:22;;;17562:31;17555:4;17540:20;;17533:61;17611:85;17570:6;17681;17672:7;17611:85;:::i;18736:184::-;18788:77;18785:1;18778:88;18885:4;18882:1;18875:15;18909:4;18906:1;18899:15;19265:265;19349:6;19402:2;19390:9;19381:7;19377:23;19373:32;19370:52;;;19418:1;19415;19408:12;19370:52;19450:9;19444:16;19469:31;19494:5;19469:31;:::i;19535:184::-;19587:77;19584:1;19577:88;19684:4;19681:1;19674:15;19708:4;19705:1;19698:15;19724:195;19763:3;19794:66;19787:5;19784:77;19781:103;;19864:18;;:::i;:::-;-1:-1:-1;19911:1:23;19900:13;;19724:195::o;19924:566::-;20211:18;20203:6;20199:31;20188:9;20181:50;20267:3;20262:2;20251:9;20247:18;20240:31;20162:4;20288:61;20344:3;20333:9;20329:19;20321:6;20288:61;:::i;:::-;20280:69;;20385:6;20380:2;20369:9;20365:18;20358:34;20440:42;20432:6;20428:55;20423:2;20412:9;20408:18;20401:83;19924:566;;;;;;;:::o;20684:418::-;20765:6;20818:2;20806:9;20797:7;20793:23;20789:32;20786:52;;;20834:1;20831;20824:12;20786:52;20860:22;;:::i;:::-;20905:28;20923:9;20905:28;:::i;:::-;20898:5;20891:43;20986:2;20975:9;20971:18;20958:32;20999:33;21024:7;20999:33;:::i;:::-;21059:2;21048:14;;21041:31;21052:5;20684:418;-1:-1:-1;;;20684:418:23:o;21432:970::-;21527:6;21558:2;21601;21589:9;21580:7;21576:23;21572:32;21569:52;;;21617:1;21614;21607:12;21569:52;21650:9;21644:16;21683:18;21675:6;21672:30;21669:50;;;21715:1;21712;21705:12;21669:50;21738:22;;21791:4;21783:13;;21779:27;-1:-1:-1;21769:55:23;;21820:1;21817;21810:12;21769:55;21849:2;21843:9;21872:74;21888:57;21942:2;21888:57;:::i;21872:74::-;21980:15;;;22062:1;22058:10;;;;22050:19;;22046:28;;;22011:12;;;;22086:19;;;22083:39;;;22118:1;22115;22108:12;22083:39;22142:11;;;;22162:210;22178:6;22173:3;22170:15;22162:210;;;22251:3;22245:10;22268:31;22293:5;22268:31;:::i;:::-;22312:18;;22195:12;;;;22350;;;;22162:210;;23060:125;23125:9;;;23146:10;;;23143:36;;;23159:18;;:::i;24356:128::-;24423:9;;;24444:11;;;24441:37;;;24458:18;;:::i;24489:184::-;24541:77;24538:1;24531:88;24638:4;24635:1;24628:15;24662:4;24659:1;24652:15;25085:287;25214:3;25252:6;25246:13;25268:66;25327:6;25322:3;25315:4;25307:6;25303:17;25268:66;:::i;:::-;25350:16;;;;;25085:287;-1:-1:-1;;25085:287:23:o
Swarm Source
none
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 29 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.