Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
FunditRemote
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2025-02-20 */ // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ 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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); } // File: @openzeppelin/contracts/interfaces/IERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/interfaces/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; // File: @openzeppelin/contracts/interfaces/IERC1363.sol // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; /** * @title SafeERC20 * @dev Wrappers around ERC-20 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 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol pragma solidity >=0.8.0; struct SetConfigParam { uint32 eid; uint32 configType; bytes config; } interface IMessageLibManager { struct Timeout { address lib; uint256 expiry; } event LibraryRegistered(address newLib); event DefaultSendLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry); event SendLibrarySet(address sender, uint32 eid, address newLib); event ReceiveLibrarySet(address receiver, uint32 eid, address newLib); event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout); function registerLibrary(address _lib) external; function isRegisteredLibrary(address _lib) external view returns (bool); function getRegisteredLibraries() external view returns (address[] memory); function setDefaultSendLibrary(uint32 _eid, address _newLib) external; function defaultSendLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external; function defaultReceiveLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external; function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry); function isSupportedEid(uint32 _eid) external view returns (bool); function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool); /// ------------------- OApp interfaces ------------------- function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external; function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib); function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool); function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external; function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault); function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external; function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry); function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external; function getConfig( address _oapp, address _lib, uint32 _eid, uint32 _configType ) external view returns (bytes memory config); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingComposer.sol pragma solidity >=0.8.0; interface IMessagingComposer { event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message); event ComposeDelivered(address from, address to, bytes32 guid, uint16 index); event LzComposeAlert( address indexed from, address indexed to, address indexed executor, bytes32 guid, uint16 index, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); function composeQueue( address _from, address _to, bytes32 _guid, uint16 _index ) external view returns (bytes32 messageHash); function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external; function lzCompose( address _from, address _to, bytes32 _guid, uint16 _index, bytes calldata _message, bytes calldata _extraData ) external payable; } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingChannel.sol pragma solidity >=0.8.0; interface IMessagingChannel { event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce); event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); function eid() external view returns (uint32); // this is an emergency function if a message cannot be verified for some reasons // required to provide _nextNonce to avoid race condition function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external; function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32); function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64); function inboundPayloadHash( address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce ) external view returns (bytes32); function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingContext.sol pragma solidity >=0.8.0; interface IMessagingContext { function isSendingMessage() external view returns (bool); function getSendContext() external view returns (uint32 dstEid, address sender); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol pragma solidity >=0.8.0; struct MessagingParams { uint32 dstEid; bytes32 receiver; bytes message; bytes options; bool payInLzToken; } struct MessagingReceipt { bytes32 guid; uint64 nonce; MessagingFee fee; } struct MessagingFee { uint256 nativeFee; uint256 lzTokenFee; } struct Origin { uint32 srcEid; bytes32 sender; uint64 nonce; } interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext { event PacketSent(bytes encodedPayload, bytes options, address sendLibrary); event PacketVerified(Origin origin, address receiver, bytes32 payloadHash); event PacketDelivered(Origin origin, address receiver); event LzReceiveAlert( address indexed receiver, address indexed executor, Origin origin, bytes32 guid, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); event LzTokenSet(address token); event DelegateSet(address sender, address delegate); function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory); function send( MessagingParams calldata _params, address _refundAddress ) external payable returns (MessagingReceipt memory); function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external; function verifiable(Origin calldata _origin, address _receiver) external view returns (bool); function initializable(Origin calldata _origin, address _receiver) external view returns (bool); function lzReceive( Origin calldata _origin, address _receiver, bytes32 _guid, bytes calldata _message, bytes calldata _extraData ) external payable; // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external; function setLzToken(address _lzToken) external; function lzToken() external view returns (address); function nativeToken() external view returns (address); function setDelegate(address _delegate) external; } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppCore.sol pragma solidity ^0.8.20; /** * @title IOAppCore */ interface IOAppCore { // Custom error messages error OnlyPeer(uint32 eid, bytes32 sender); error NoPeer(uint32 eid); error InvalidEndpointCall(); error InvalidDelegate(); // Event emitted when a peer (OApp) is set for a corresponding endpoint event PeerSet(uint32 eid, bytes32 peer); /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. */ function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion); /** * @notice Retrieves the LayerZero endpoint associated with the OApp. * @return iEndpoint The LayerZero endpoint as an interface. */ function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint); /** * @notice Retrieves the peer (OApp) associated with a corresponding endpoint. * @param _eid The endpoint ID. * @return peer The peer address (OApp instance) associated with the corresponding endpoint. */ function peers(uint32 _eid) external view returns (bytes32 peer); /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. */ function setPeer(uint32 _eid, bytes32 _peer) external; /** * @notice Sets the delegate address for the OApp Core. * @param _delegate The address of the delegate to be set. */ function setDelegate(address _delegate) external; } // File: @layerzerolabs/oapp-evm/contracts/oapp/OAppCore.sol pragma solidity ^0.8.20; /** * @title OAppCore * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations. */ abstract contract OAppCore is IOAppCore, Ownable { // The LayerZero endpoint associated with the given OApp ILayerZeroEndpointV2 public immutable endpoint; // Mapping to store peers associated with corresponding endpoints mapping(uint32 eid => bytes32 peer) public peers; /** * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate. * @param _endpoint The address of the LOCAL Layer Zero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. * * @dev The delegate typically should be set as the owner of the contract. */ constructor(address _endpoint, address _delegate) { endpoint = ILayerZeroEndpointV2(_endpoint); if (_delegate == address(0)) revert InvalidDelegate(); endpoint.setDelegate(_delegate); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Only the owner/admin of the OApp can call this function. * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner { _setPeer(_eid, _peer); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function _setPeer(uint32 _eid, bytes32 _peer) internal virtual { peers[_eid] = _peer; emit PeerSet(_eid, _peer); } /** * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set. * ie. the peer is set to bytes32(0). * @param _eid The endpoint ID. * @return peer The address of the peer associated with the specified endpoint. */ function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) { bytes32 peer = peers[_eid]; if (peer == bytes32(0)) revert NoPeer(_eid); return peer; } /** * @notice Sets the delegate address for the OApp. * @param _delegate The address of the delegate to be set. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract. */ function setDelegate(address _delegate) public onlyOwner { endpoint.setDelegate(_delegate); } } // File: @layerzerolabs/oapp-evm/contracts/oapp/OAppSender.sol pragma solidity ^0.8.20; /** * @title OAppSender * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint. */ abstract contract OAppSender is OAppCore { using SafeERC20 for IERC20; // Custom error messages error NotEnoughNative(uint256 msgValue); error LzTokenUnavailable(); // @dev The version of the OAppSender implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant SENDER_VERSION = 1; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented. * ie. this is a SEND only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, 0); } /** * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens. * @return fee The calculated MessagingFee for the message. * - nativeFee: The native fee for the message. * - lzTokenFee: The LZ token fee for the message. */ function _quote( uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken ) internal view virtual returns (MessagingFee memory fee) { return endpoint.quote( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this) ); } /** * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _fee The calculated LayerZero fee for the message. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess fee values sent to the endpoint. * @return receipt The receipt for the sent message. * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function _lzSend( uint32 _dstEid, bytes memory _message, bytes memory _options, MessagingFee memory _fee, address _refundAddress ) internal virtual returns (MessagingReceipt memory receipt) { // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint. uint256 messageValue = _payNative(_fee.nativeFee); if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee); return // solhint-disable-next-line check-send-result endpoint.send{ value: messageValue }( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0), _refundAddress ); } /** * @dev Internal function to pay the native fee associated with the message. * @param _nativeFee The native fee to be paid. * @return nativeFee The amount of native currency paid. * * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction, * this will need to be overridden because msg.value would contain multiple lzFees. * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency. * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees. * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time. */ function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) { if (msg.value != _nativeFee) revert NotEnoughNative(msg.value); return _nativeFee; } /** * @dev Internal function to pay the LZ token fee associated with the message. * @param _lzTokenFee The LZ token fee to be paid. * * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint. * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend(). */ function _payLzToken(uint256 _lzTokenFee) internal virtual { // @dev Cannot cache the token because it is not immutable in the endpoint. address lzToken = endpoint.lzToken(); if (lzToken == address(0)) revert LzTokenUnavailable(); // Pay LZ token fee by sending tokens to the endpoint. IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee); } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol pragma solidity >=0.8.0; interface ILayerZeroReceiver { function allowInitializePath(Origin calldata _origin) external view returns (bool); function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64); function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable; } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppReceiver.sol pragma solidity ^0.8.20; interface IOAppReceiver is ILayerZeroReceiver { /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata _origin, bytes calldata _message, address _sender ) external view returns (bool isSender); } // File: @layerzerolabs/oapp-evm/contracts/oapp/OAppReceiver.sol pragma solidity ^0.8.20; /** * @title OAppReceiver * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers. */ abstract contract OAppReceiver is IOAppReceiver, OAppCore { // Custom error message for when the caller is not the registered endpoint/ error OnlyEndpoint(address addr); // @dev The version of the OAppReceiver implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant RECEIVER_VERSION = 2; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented. * ie. this is a RECEIVE only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions. */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (0, RECEIVER_VERSION); } /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @dev _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @dev _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement separate composeMsg senders that are NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata /*_origin*/, bytes calldata /*_message*/, address _sender ) public view virtual returns (bool) { return _sender == address(this); } /** * @notice Checks if the path initialization is allowed based on the provided origin. * @param origin The origin information containing the source endpoint and sender address. * @return Whether the path has been initialized. * * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received. * @dev This defaults to assuming if a peer has been set, its initialized. * Can be overridden by the OApp if there is other logic to determine this. */ function allowInitializePath(Origin calldata origin) public view virtual returns (bool) { return peers[origin.srcEid] == origin.sender; } /** * @notice Retrieves the next nonce for a given source endpoint and sender address. * @dev _srcEid The source endpoint ID. * @dev _sender The sender address. * @return nonce The next nonce. * * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement. * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered. * @dev This is also enforced by the OApp. * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0. */ function nextNonce(uint32 /*_srcEid*/, bytes32 /*_sender*/) public view virtual returns (uint64 nonce) { return 0; } /** * @dev Entry point for receiving messages or packets from the endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The payload of the received message. * @param _executor The address of the executor for the received message. * @param _extraData Additional arbitrary data provided by the corresponding executor. * * @dev Entry point for receiving msg/packet from the LayerZero endpoint. */ function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) public payable virtual { // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp. if (address(endpoint) != msg.sender) revert OnlyEndpoint(msg.sender); // Ensure that the sender matches the expected peer for the source endpoint. if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) revert OnlyPeer(_origin.srcEid, _origin.sender); // Call the internal OApp implementation of lzReceive. _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; } // File: @layerzerolabs/oapp-evm/contracts/oapp/OApp.sol pragma solidity ^0.8.20; // @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import // @dev Import the 'Origin' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import /** * @title OApp * @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver functionality. */ abstract contract OApp is OAppSender, OAppReceiver { /** * @dev Constructor to initialize the OApp with the provided endpoint and owner. * @param _endpoint The address of the LOCAL LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(address _endpoint, address _delegate) OAppCore(_endpoint, _delegate) {} /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol implementation. * @return receiverVersion The version of the OAppReceiver.sol implementation. */ function oAppVersion() public pure virtual override(OAppSender, OAppReceiver) returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, RECEIVER_VERSION); } } // File: solidity-bytes-utils/contracts/BytesLib.sol /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function concat( bytes memory _preBytes, bytes memory _postBytes ) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } } // File: @openzeppelin/contracts/utils/math/SafeCast.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/libs/CalldataBytesLib.sol pragma solidity ^0.8.20; library CalldataBytesLib { function toU8(bytes calldata _bytes, uint256 _start) internal pure returns (uint8) { return uint8(_bytes[_start]); } function toU16(bytes calldata _bytes, uint256 _start) internal pure returns (uint16) { unchecked { uint256 end = _start + 2; return uint16(bytes2(_bytes[_start:end])); } } function toU32(bytes calldata _bytes, uint256 _start) internal pure returns (uint32) { unchecked { uint256 end = _start + 4; return uint32(bytes4(_bytes[_start:end])); } } function toU64(bytes calldata _bytes, uint256 _start) internal pure returns (uint64) { unchecked { uint256 end = _start + 8; return uint64(bytes8(_bytes[_start:end])); } } function toU128(bytes calldata _bytes, uint256 _start) internal pure returns (uint128) { unchecked { uint256 end = _start + 16; return uint128(bytes16(_bytes[_start:end])); } } function toU256(bytes calldata _bytes, uint256 _start) internal pure returns (uint256) { unchecked { uint256 end = _start + 32; return uint256(bytes32(_bytes[_start:end])); } } function toAddr(bytes calldata _bytes, uint256 _start) internal pure returns (address) { unchecked { uint256 end = _start + 20; return address(bytes20(_bytes[_start:end])); } } function toB32(bytes calldata _bytes, uint256 _start) internal pure returns (bytes32) { unchecked { uint256 end = _start + 32; return bytes32(_bytes[_start:end]); } } } // File: @layerzerolabs/lz-evm-messagelib-v2/contracts/libs/ExecutorOptions.sol pragma solidity ^0.8.20; library ExecutorOptions { using CalldataBytesLib for bytes; uint8 internal constant WORKER_ID = 1; uint8 internal constant OPTION_TYPE_LZRECEIVE = 1; uint8 internal constant OPTION_TYPE_NATIVE_DROP = 2; uint8 internal constant OPTION_TYPE_LZCOMPOSE = 3; uint8 internal constant OPTION_TYPE_ORDERED_EXECUTION = 4; uint8 internal constant OPTION_TYPE_LZREAD = 5; error Executor_InvalidLzReceiveOption(); error Executor_InvalidNativeDropOption(); error Executor_InvalidLzComposeOption(); error Executor_InvalidLzReadOption(); /// @dev decode the next executor option from the options starting from the specified cursor /// @param _options [executor_id][executor_option][executor_id][executor_option]... /// executor_option = [option_size][option_type][option] /// option_size = len(option_type) + len(option) /// executor_id: uint8, option_size: uint16, option_type: uint8, option: bytes /// @param _cursor the cursor to start decoding from /// @return optionType the type of the option /// @return option the option of the executor /// @return cursor the cursor to start decoding the next executor option function nextExecutorOption( bytes calldata _options, uint256 _cursor ) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) { unchecked { // skip worker id cursor = _cursor + 1; // read option size uint16 size = _options.toU16(cursor); cursor += 2; // read option type optionType = _options.toU8(cursor); // startCursor and endCursor are used to slice the option from _options uint256 startCursor = cursor + 1; // skip option type uint256 endCursor = cursor + size; option = _options[startCursor:endCursor]; cursor += size; } } function decodeLzReceiveOption(bytes calldata _option) internal pure returns (uint128 gas, uint128 value) { if (_option.length != 16 && _option.length != 32) revert Executor_InvalidLzReceiveOption(); gas = _option.toU128(0); value = _option.length == 32 ? _option.toU128(16) : 0; } function decodeNativeDropOption(bytes calldata _option) internal pure returns (uint128 amount, bytes32 receiver) { if (_option.length != 48) revert Executor_InvalidNativeDropOption(); amount = _option.toU128(0); receiver = _option.toB32(16); } function decodeLzComposeOption( bytes calldata _option ) internal pure returns (uint16 index, uint128 gas, uint128 value) { if (_option.length != 18 && _option.length != 34) revert Executor_InvalidLzComposeOption(); index = _option.toU16(0); gas = _option.toU128(2); value = _option.length == 34 ? _option.toU128(18) : 0; } function decodeLzReadOption( bytes calldata _option ) internal pure returns (uint128 gas, uint32 calldataSize, uint128 value) { if (_option.length != 20 && _option.length != 36) revert Executor_InvalidLzReadOption(); gas = _option.toU128(0); calldataSize = _option.toU32(16); value = _option.length == 36 ? _option.toU128(20) : 0; } function encodeLzReceiveOption(uint128 _gas, uint128 _value) internal pure returns (bytes memory) { return _value == 0 ? abi.encodePacked(_gas) : abi.encodePacked(_gas, _value); } function encodeNativeDropOption(uint128 _amount, bytes32 _receiver) internal pure returns (bytes memory) { return abi.encodePacked(_amount, _receiver); } function encodeLzComposeOption(uint16 _index, uint128 _gas, uint128 _value) internal pure returns (bytes memory) { return _value == 0 ? abi.encodePacked(_index, _gas) : abi.encodePacked(_index, _gas, _value); } function encodeLzReadOption( uint128 _gas, uint32 _calldataSize, uint128 _value ) internal pure returns (bytes memory) { return _value == 0 ? abi.encodePacked(_gas, _calldataSize) : abi.encodePacked(_gas, _calldataSize, _value); } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/BitMaps.sol // modified from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/BitMaps.sol pragma solidity ^0.8.20; type BitMap256 is uint256; using BitMaps for BitMap256 global; library BitMaps { /** * @dev Returns whether the bit at `index` is set. */ function get(BitMap256 bitmap, uint8 index) internal pure returns (bool) { uint256 mask = 1 << index; return BitMap256.unwrap(bitmap) & mask != 0; } /** * @dev Sets the bit at `index`. */ function set(BitMap256 bitmap, uint8 index) internal pure returns (BitMap256) { uint256 mask = 1 << index; return BitMap256.wrap(BitMap256.unwrap(bitmap) | mask); } } // File: @layerzerolabs/lz-evm-messagelib-v2/contracts/uln/libs/DVNOptions.sol pragma solidity ^0.8.20; library DVNOptions { using CalldataBytesLib for bytes; using BytesLib for bytes; uint8 internal constant WORKER_ID = 2; uint8 internal constant OPTION_TYPE_PRECRIME = 1; error DVN_InvalidDVNIdx(); error DVN_InvalidDVNOptions(uint256 cursor); /// @dev group dvn options by its idx /// @param _options [dvn_id][dvn_option][dvn_id][dvn_option]... /// dvn_option = [option_size][dvn_idx][option_type][option] /// option_size = len(dvn_idx) + len(option_type) + len(option) /// dvn_id: uint8, dvn_idx: uint8, option_size: uint16, option_type: uint8, option: bytes /// @return dvnOptions the grouped options, still share the same format of _options /// @return dvnIndices the dvn indices function groupDVNOptionsByIdx( bytes memory _options ) internal pure returns (bytes[] memory dvnOptions, uint8[] memory dvnIndices) { if (_options.length == 0) return (dvnOptions, dvnIndices); uint8 numDVNs = getNumDVNs(_options); // if there is only 1 dvn, we can just return the whole options if (numDVNs == 1) { dvnOptions = new bytes[](1); dvnOptions[0] = _options; dvnIndices = new uint8[](1); dvnIndices[0] = _options.toUint8(3); // dvn idx return (dvnOptions, dvnIndices); } // otherwise, we need to group the options by dvn_idx dvnIndices = new uint8[](numDVNs); dvnOptions = new bytes[](numDVNs); unchecked { uint256 cursor = 0; uint256 start = 0; uint8 lastDVNIdx = 255; // 255 is an invalid dvn_idx while (cursor < _options.length) { ++cursor; // skip worker_id // optionLength asserted in getNumDVNs (skip check) uint16 optionLength = _options.toUint16(cursor); cursor += 2; // dvnIdx asserted in getNumDVNs (skip check) uint8 dvnIdx = _options.toUint8(cursor); // dvnIdx must equal to the lastDVNIdx for the first option // so it is always skipped in the first option // this operation slices out options whenever the scan finds a different lastDVNIdx if (lastDVNIdx == 255) { lastDVNIdx = dvnIdx; } else if (dvnIdx != lastDVNIdx) { uint256 len = cursor - start - 3; // 3 is for worker_id and option_length bytes memory opt = _options.slice(start, len); _insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, opt); // reset the start and lastDVNIdx start += len; lastDVNIdx = dvnIdx; } cursor += optionLength; } // skip check the cursor here because the cursor is asserted in getNumDVNs // if we have reached the end of the options, we need to process the last dvn uint256 size = cursor - start; bytes memory op = _options.slice(start, size); _insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, op); // revert dvnIndices to start from 0 for (uint8 i = 0; i < numDVNs; ++i) { --dvnIndices[i]; } } } function _insertDVNOptions( bytes[] memory _dvnOptions, uint8[] memory _dvnIndices, uint8 _dvnIdx, bytes memory _newOptions ) internal pure { // dvnIdx starts from 0 but default value of dvnIndices is 0, // so we tell if the slot is empty by adding 1 to dvnIdx if (_dvnIdx == 255) revert DVN_InvalidDVNIdx(); uint8 dvnIdxAdj = _dvnIdx + 1; for (uint256 j = 0; j < _dvnIndices.length; ++j) { uint8 index = _dvnIndices[j]; if (dvnIdxAdj == index) { _dvnOptions[j] = abi.encodePacked(_dvnOptions[j], _newOptions); break; } else if (index == 0) { // empty slot, that means it is the first time we see this dvn _dvnIndices[j] = dvnIdxAdj; _dvnOptions[j] = _newOptions; break; } } } /// @dev get the number of unique dvns /// @param _options the format is the same as groupDVNOptionsByIdx function getNumDVNs(bytes memory _options) internal pure returns (uint8 numDVNs) { uint256 cursor = 0; BitMap256 bitmap; // find number of unique dvn_idx unchecked { while (cursor < _options.length) { ++cursor; // skip worker_id uint16 optionLength = _options.toUint16(cursor); cursor += 2; if (optionLength < 2) revert DVN_InvalidDVNOptions(cursor); // at least 1 byte for dvn_idx and 1 byte for option_type uint8 dvnIdx = _options.toUint8(cursor); // if dvnIdx is not set, increment numDVNs // max num of dvns is 255, 255 is an invalid dvn_idx // The order of the dvnIdx is not required to be sequential, as enforcing the order may weaken // the composability of the options. e.g. if we refrain from enforcing the order, an OApp that has // already enforced certain options can append additional options to the end of the enforced // ones without restrictions. if (dvnIdx == 255) revert DVN_InvalidDVNIdx(); if (!bitmap.get(dvnIdx)) { ++numDVNs; bitmap = bitmap.set(dvnIdx); } cursor += optionLength; } } if (cursor != _options.length) revert DVN_InvalidDVNOptions(cursor); } /// @dev decode the next dvn option from _options starting from the specified cursor /// @param _options the format is the same as groupDVNOptionsByIdx /// @param _cursor the cursor to start decoding /// @return optionType the type of the option /// @return option the option /// @return cursor the cursor to start decoding the next option function nextDVNOption( bytes calldata _options, uint256 _cursor ) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) { unchecked { // skip worker id cursor = _cursor + 1; // read option size uint16 size = _options.toU16(cursor); cursor += 2; // read option type optionType = _options.toU8(cursor + 1); // skip dvn_idx // startCursor and endCursor are used to slice the option from _options uint256 startCursor = cursor + 2; // skip option type and dvn_idx uint256 endCursor = cursor + size; option = _options[startCursor:endCursor]; cursor += size; } } } // File: @layerzerolabs/oapp-evm/contracts/oapp/libs/OptionsBuilder.sol pragma solidity ^0.8.20; /** * @title OptionsBuilder * @dev Library for building and encoding various message options. */ library OptionsBuilder { using SafeCast for uint256; using BytesLib for bytes; // Constants for options types uint16 internal constant TYPE_1 = 1; // legacy options type 1 uint16 internal constant TYPE_2 = 2; // legacy options type 2 uint16 internal constant TYPE_3 = 3; // Custom error message error InvalidSize(uint256 max, uint256 actual); error InvalidOptionType(uint16 optionType); // Modifier to ensure only options of type 3 are used modifier onlyType3(bytes memory _options) { if (_options.toUint16(0) != TYPE_3) revert InvalidOptionType(_options.toUint16(0)); _; } /** * @dev Creates a new options container with type 3. * @return options The newly created options container. */ function newOptions() internal pure returns (bytes memory) { return abi.encodePacked(TYPE_3); } /** * @dev Adds an executor LZ receive option to the existing options. * @param _options The existing options container. * @param _gas The gasLimit used on the lzReceive() function in the OApp. * @param _value The msg.value passed to the lzReceive() function in the OApp. * @return options The updated options container. * * @dev When multiples of this option are added, they are summed by the executor * eg. if (_gas: 200k, and _value: 1 ether) AND (_gas: 100k, _value: 0.5 ether) are sent in an option to the LayerZeroEndpoint, * that becomes (300k, 1.5 ether) when the message is executed on the remote lzReceive() function. */ function addExecutorLzReceiveOption( bytes memory _options, uint128 _gas, uint128 _value ) internal pure onlyType3(_options) returns (bytes memory) { bytes memory option = ExecutorOptions.encodeLzReceiveOption(_gas, _value); return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZRECEIVE, option); } /** * @dev Adds an executor native drop option to the existing options. * @param _options The existing options container. * @param _amount The amount for the native value that is airdropped to the 'receiver'. * @param _receiver The receiver address for the native drop option. * @return options The updated options container. * * @dev When multiples of this option are added, they are summed by the executor on the remote chain. */ function addExecutorNativeDropOption( bytes memory _options, uint128 _amount, bytes32 _receiver ) internal pure onlyType3(_options) returns (bytes memory) { bytes memory option = ExecutorOptions.encodeNativeDropOption(_amount, _receiver); return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_NATIVE_DROP, option); } // /** // * @dev Adds an executor native drop option to the existing options. // * @param _options The existing options container. // * @param _amount The amount for the native value that is airdropped to the 'receiver'. // * @param _receiver The receiver address for the native drop option. // * @return options The updated options container. // * // * @dev When multiples of this option are added, they are summed by the executor on the remote chain. // */ function addExecutorLzReadOption( bytes memory _options, uint128 _gas, uint32 _size, uint128 _value ) internal pure onlyType3(_options) returns (bytes memory) { bytes memory option = ExecutorOptions.encodeLzReadOption(_gas, _size, _value); return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZREAD, option); } /** * @dev Adds an executor LZ compose option to the existing options. * @param _options The existing options container. * @param _index The index for the lzCompose() function call. * @param _gas The gasLimit for the lzCompose() function call. * @param _value The msg.value for the lzCompose() function call. * @return options The updated options container. * * @dev When multiples of this option are added, they are summed PER index by the executor on the remote chain. * @dev If the OApp sends N lzCompose calls on the remote, you must provide N incremented indexes starting with 0. * ie. When your remote OApp composes (N = 3) messages, you must set this option for index 0,1,2 */ function addExecutorLzComposeOption( bytes memory _options, uint16 _index, uint128 _gas, uint128 _value ) internal pure onlyType3(_options) returns (bytes memory) { bytes memory option = ExecutorOptions.encodeLzComposeOption(_index, _gas, _value); return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZCOMPOSE, option); } /** * @dev Adds an executor ordered execution option to the existing options. * @param _options The existing options container. * @return options The updated options container. */ function addExecutorOrderedExecutionOption( bytes memory _options ) internal pure onlyType3(_options) returns (bytes memory) { return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_ORDERED_EXECUTION, bytes("")); } /** * @dev Adds a DVN pre-crime option to the existing options. * @param _options The existing options container. * @param _dvnIdx The DVN index for the pre-crime option. * @return options The updated options container. */ function addDVNPreCrimeOption( bytes memory _options, uint8 _dvnIdx ) internal pure onlyType3(_options) returns (bytes memory) { return addDVNOption(_options, _dvnIdx, DVNOptions.OPTION_TYPE_PRECRIME, bytes("")); } /** * @dev Adds an executor option to the existing options. * @param _options The existing options container. * @param _optionType The type of the executor option. * @param _option The encoded data for the executor option. * @return options The updated options container. */ function addExecutorOption( bytes memory _options, uint8 _optionType, bytes memory _option ) internal pure onlyType3(_options) returns (bytes memory) { return abi.encodePacked( _options, ExecutorOptions.WORKER_ID, _option.length.toUint16() + 1, // +1 for optionType _optionType, _option ); } /** * @dev Adds a DVN option to the existing options. * @param _options The existing options container. * @param _dvnIdx The DVN index for the DVN option. * @param _optionType The type of the DVN option. * @param _option The encoded data for the DVN option. * @return options The updated options container. */ function addDVNOption( bytes memory _options, uint8 _dvnIdx, uint8 _optionType, bytes memory _option ) internal pure onlyType3(_options) returns (bytes memory) { return abi.encodePacked( _options, DVNOptions.WORKER_ID, _option.length.toUint16() + 2, // +2 for optionType and dvnIdx _dvnIdx, _optionType, _option ); } /** * @dev Encodes legacy options of type 1. * @param _executionGas The gasLimit value passed to lzReceive(). * @return legacyOptions The encoded legacy options. */ function encodeLegacyOptionsType1(uint256 _executionGas) internal pure returns (bytes memory) { if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas); return abi.encodePacked(TYPE_1, _executionGas); } /** * @dev Encodes legacy options of type 2. * @param _executionGas The gasLimit value passed to lzReceive(). * @param _nativeForDst The amount of native air dropped to the receiver. * @param _receiver The _nativeForDst receiver address. * @return legacyOptions The encoded legacy options of type 2. */ function encodeLegacyOptionsType2( uint256 _executionGas, uint256 _nativeForDst, bytes memory _receiver // @dev Use bytes instead of bytes32 in legacy type 2 for _receiver. ) internal pure returns (bytes memory) { if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas); if (_nativeForDst > type(uint128).max) revert InvalidSize(type(uint128).max, _nativeForDst); if (_receiver.length > 32) revert InvalidSize(32, _receiver.length); return abi.encodePacked(TYPE_2, _executionGas, _nativeForDst, _receiver); } } // File: @openzeppelin/contracts/security/Pausable.sol // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); function getRoundData( uint80 _roundId ) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); } // File: Contracts/FunditRemote.sol pragma solidity ^0.8.28; contract FunditRemote is OApp, Pausable, ReentrancyGuard { using SafeERC20 for IERC20; using OptionsBuilder for bytes; // --- CONSTRUCTOR --- constructor(address _endpoint, address _feeWallet, address _vaultWallet, uint256 _feeBasisPoints) OApp(_endpoint, msg.sender) Ownable(msg.sender) { require(_feeWallet != address(0), "Invalid fee wallet"); require(_vaultWallet != address(0), "Invalid vault wallet"); require(_feeBasisPoints < BASIS_POINTS_DIVISOR, "Fee too high"); feeWallet = _feeWallet; vaultWallet = _vaultWallet; feeBasisPoints = _feeBasisPoints; } // --- State Variables --- uint256 public donationCount; struct Donation { uint256 campaignId; uint256 netUsd; bool relayed; address donor; } mapping(uint256 => Donation) public donations; // USD decimals constant for reference (e.g., 8 decimals). uint8 public constant USD_DECIMALS = 8; // --- ADDRESSES --- address public feeWallet; address public vaultWallet; // --- FEE CONFIGURATION --- uint256 public feeBasisPoints; // e.g., 14 means 1.4%. uint256 public constant BASIS_POINTS_DIVISOR = 1000; // --- TOKEN PRICE FEED --- mapping(address => address) public tokenToPriceFeed; // --- EVENTS --- event FeeWalletUpdated(address indexed newFeeWallet); event VaultWalletUpdated(address indexed newVaultWallet); event FeeBasisPointsUpdated(uint256 newFeeBasisPoints); event DonationMade(uint256 indexed donationId, uint256 campaignId, address indexed donor, uint256 netUSDValue); event DonationRelayed(uint256 indexed donationId, uint32 dstEid); event PriceFeedSet(address indexed token, address priceFeed); /// @notice Update the fee wallet address. Only the owner can call this. function updateFeeWallet(address newFeeWallet) external onlyOwner { require(newFeeWallet != address(0), "Invalid fee wallet"); feeWallet = newFeeWallet; emit FeeWalletUpdated(newFeeWallet); } /// @notice Update the vault wallet address. Only the owner can call this. function updateVaultWallet(address newVaultWallet) external onlyOwner { require(newVaultWallet != address(0), "Invalid vault wallet"); vaultWallet = newVaultWallet; emit VaultWalletUpdated(newVaultWallet); } /// @notice Update the fee percentage in basis points. Only the owner can call this. function updateFeeBasisPoints(uint256 newFeeBasisPoints) external onlyOwner { require(newFeeBasisPoints < BASIS_POINTS_DIVISOR, "Fee too high"); feeBasisPoints = newFeeBasisPoints; emit FeeBasisPointsUpdated(newFeeBasisPoints); } // Modify the setPriceFeed function: function setPriceFeed(address token, address priceFeed) external onlyOwner { require(priceFeed != address(0), "Invalid price feed address"); require(tokenToPriceFeed[token] == address(0), "Price feed already set for this token"); tokenToPriceFeed[token] = priceFeed; emit PriceFeedSet(token, priceFeed); } function setPeer(uint32 _eid, address _peerAddress) external onlyOwner { bytes32 peerBytes = bytes32(uint256(uint160(_peerAddress))); peers[_eid] = peerBytes; emit PeerSet(_eid, peerBytes); } function generateOptions(uint128 gasLimit) public pure returns (bytes memory) { return OptionsBuilder.newOptions().addExecutorLzReceiveOption(gasLimit, 0); } function addressToBytes32(address _addr) public pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } function bytes32ToAddress(bytes32 _b) public pure returns (address) { return address(uint160(uint256(_b))); } /// @notice Pause the contract. Only the owner can call this. function pause() external onlyOwner { _pause(); } /// @notice Unpause the contract. Only the owner can call this. function unpause() external onlyOwner { _unpause(); } // --- FEE QUOTE VIEW FUNCTION --- /// @notice Returns a fee estimate (native fee) based on a demo donation payload. function getQuote(uint32 _dstEid, uint256 campaignId, bytes calldata _options) external view returns (uint256 nativeFee) { bool payInLzToken = false; uint256 dummyDonationUsd = 1000000000; bytes memory payload = abi.encode(campaignId, dummyDonationUsd); MessagingFee memory fee = _quote( _dstEid, payload, _options, payInLzToken); nativeFee = fee.nativeFee + ((fee.nativeFee * 2) / 10); } function donate(uint256 campaignId, address token, uint256 amount) external payable nonReentrant whenNotPaused returns (uint256 donationId){ uint256 usdValue; if (token == address(0)) { // --- Native Coin Donation --- require(msg.value > 0, "No native coin sent"); usdValue = convertNativeToUSD(msg.value); uint256 feeUsd = (usdValue * feeBasisPoints) / BASIS_POINTS_DIVISOR; uint256 netUsd = usdValue - feeUsd; (bool feeSent, ) = feeWallet.call{value: (msg.value * feeBasisPoints) / BASIS_POINTS_DIVISOR}(""); require(feeSent, "Fee transfer failed"); (bool vaultSent, ) = vaultWallet.call{value: msg.value - ((msg.value * feeBasisPoints) / BASIS_POINTS_DIVISOR)}(""); require(vaultSent, "Vault transfer failed"); donationCount++; donationId = donationCount; donations[donationId] = Donation({ campaignId: campaignId, netUsd: netUsd, relayed: false, donor: msg.sender }); emit DonationMade(donationId, campaignId, msg.sender, netUsd); } else { // --- ERC20 Donation --- require(tokenToPriceFeed[token] != address(0), "Token not supported"); require(amount > 0, "Donation must be > 0"); IERC20(token).safeTransferFrom(msg.sender, address(this), amount); usdValue = convertTokenToUSD(token, amount); uint256 tokenFee = (amount * feeBasisPoints) / BASIS_POINTS_DIVISOR; uint256 netToken = amount - tokenFee; IERC20(token).safeTransfer(feeWallet, tokenFee); IERC20(token).safeTransfer(vaultWallet, netToken); uint256 feeUsd = (usdValue * feeBasisPoints) / BASIS_POINTS_DIVISOR; uint256 netUsd = usdValue - feeUsd; donationCount++; donationId = donationCount; donations[donationId] = Donation({ campaignId: campaignId, netUsd: netUsd, relayed: false, donor: msg.sender }); emit DonationMade(donationId, campaignId, msg.sender, netUsd); } return donationId; } /// @dev Sends the cross-chain message with the net donation USD amount. function _sendCrossChainMessage( uint256 donationId, uint32 _dstEid, bytes calldata _options ) external payable nonReentrant { Donation storage donation = donations[donationId]; require(!donation.relayed, "Donation already relayed"); bytes memory payload = abi.encode(donation.campaignId, donation.netUsd); _lzSend( _dstEid, payload, _options, MessagingFee(msg.value, 0), payable(msg.sender) ); donation.relayed = true; emit DonationRelayed(donationId, _dstEid); } // --- PRICE FEED CONVERSION HELPERS --- function convertTokenToUSD(address token, uint256 tokenAmount) public view returns (uint256 usdValue) { address priceFeedAddress = tokenToPriceFeed[token]; require(priceFeedAddress != address(0), "Price feed not set for token"); AggregatorV3Interface priceFeed = AggregatorV3Interface(priceFeedAddress); (, int256 price, , , ) = priceFeed.latestRoundData(); require(price > 0, "Invalid price"); uint8 tokenDecimals = IERC20Metadata(token).decimals(); usdValue = (tokenAmount * uint256(price)) / (10**tokenDecimals); } function convertNativeToUSD(uint256 nativeAmount) public view returns (uint256 usdValue) { address priceFeedAddress = tokenToPriceFeed[address(0)]; require( priceFeedAddress != address(0), "Native coin price feed not set"); AggregatorV3Interface priceFeed = AggregatorV3Interface(priceFeedAddress); (, int256 price, , , ) = priceFeed.latestRoundData(); require(price > 0, "Invalid price"); usdValue = (nativeAmount * uint256(price)) / 1e18; } function _lzReceive( Origin calldata, bytes32, bytes calldata, address, bytes calldata) internal pure override { revert("Not implemented"); } // --- EMERGENCY WITHDRAW FUNCTIONS --- function emergencyRescue(address token, uint256 amount) external onlyOwner { if (token == address(0)) { (bool sent, ) = owner().call{value: amount}(""); require(sent, "Failed to send native coin"); } else { IERC20(token).safeTransfer(owner(), amount); } } receive() external payable {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_endpoint","type":"address"},{"internalType":"address","name":"_feeWallet","type":"address"},{"internalType":"address","name":"_vaultWallet","type":"address"},{"internalType":"uint256","name":"_feeBasisPoints","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[{"internalType":"uint16","name":"optionType","type":"uint16"}],"name":"InvalidOptionType","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"OnlyEndpoint","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"donationId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"campaignId","type":"uint256"},{"indexed":true,"internalType":"address","name":"donor","type":"address"},{"indexed":false,"internalType":"uint256","name":"netUSDValue","type":"uint256"}],"name":"DonationMade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"donationId","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"dstEid","type":"uint32"}],"name":"DonationRelayed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFeeBasisPoints","type":"uint256"}],"name":"FeeBasisPointsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newFeeWallet","type":"address"}],"name":"FeeWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"priceFeed","type":"address"}],"name":"PriceFeedSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newVaultWallet","type":"address"}],"name":"VaultWalletUpdated","type":"event"},{"inputs":[],"name":"BASIS_POINTS_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USD_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"donationId","type":"uint256"},{"internalType":"uint32","name":"_dstEid","type":"uint32"},{"internalType":"bytes","name":"_options","type":"bytes"}],"name":"_sendCrossChainMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"addressToBytes32","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_b","type":"bytes32"}],"name":"bytes32ToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"name":"convertNativeToUSD","outputs":[{"internalType":"uint256","name":"usdValue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"convertTokenToUSD","outputs":[{"internalType":"uint256","name":"usdValue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"campaignId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"donate","outputs":[{"internalType":"uint256","name":"donationId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"donationCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"donations","outputs":[{"internalType":"uint256","name":"campaignId","type":"uint256"},{"internalType":"uint256","name":"netUsd","type":"uint256"},{"internalType":"bool","name":"relayed","type":"bool"},{"internalType":"address","name":"donor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyRescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"gasLimit","type":"uint128"}],"name":"generateOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dstEid","type":"uint32"},{"internalType":"uint256","name":"campaignId","type":"uint256"},{"internalType":"bytes","name":"_options","type":"bytes"}],"name":"getQuote","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"_sender","type":"address"}],"name":"isComposeMsgSender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"peer","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"address","name":"_peerAddress","type":"address"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"priceFeed","type":"address"}],"name":"setPriceFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenToPriceFeed","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeeBasisPoints","type":"uint256"}],"name":"updateFeeBasisPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeWallet","type":"address"}],"name":"updateFeeWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newVaultWallet","type":"address"}],"name":"updateVaultWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a060405234801561000f575f5ffd5b50604051614fef380380614fef833981810160405281019061003191906104de565b83338181335f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100a6575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161009d9190610551565b60405180910390fd5b6100b58161038c60201b60201c565b508173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361014f576040517fb586360400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60805173ffffffffffffffffffffffffffffffffffffffff1663ca5eb5e1826040518263ffffffff1660e01b815260040161018a9190610551565b5f604051808303815f87803b1580156101a1575f5ffd5b505af11580156101b3573d5f5f3e3d5ffd5b50505050505050505f60025f6101000a81548160ff02191690831515021790555060016003819055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361024a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610241906105c4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036102b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102af9061062c565b60405180910390fd5b6103e881106102fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102f390610694565b60405180910390fd5b8260065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600881905550505050506106b2565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61047a82610451565b9050919050565b61048a81610470565b8114610494575f5ffd5b50565b5f815190506104a581610481565b92915050565b5f819050919050565b6104bd816104ab565b81146104c7575f5ffd5b50565b5f815190506104d8816104b4565b92915050565b5f5f5f5f608085870312156104f6576104f561044d565b5b5f61050387828801610497565b945050602061051487828801610497565b935050604061052587828801610497565b9250506060610536878288016104ca565b91505092959194509250565b61054b81610470565b82525050565b5f6020820190506105645f830184610542565b92915050565b5f82825260208201905092915050565b7f496e76616c6964206665652077616c6c657400000000000000000000000000005f82015250565b5f6105ae60128361056a565b91506105b98261057a565b602082019050919050565b5f6020820190508181035f8301526105db816105a2565b9050919050565b7f496e76616c6964207661756c742077616c6c65740000000000000000000000005f82015250565b5f61061660148361056a565b9150610621826105e2565b602082019050919050565b5f6020820190508181035f8301526106438161060a565b9050919050565b7f46656520746f6f206869676800000000000000000000000000000000000000005f82015250565b5f61067e600c8361056a565b91506106898261064a565b602082019050919050565b5f6020820190508181035f8301526106ab81610672565b9050919050565b6080516148fb6106f45f395f81816108d10152818161129501528181611e2f0152818161257b015281816126680152818161299c0152612a9401526148fb5ff3fe60806040526004361061021d575f3560e01c80637d25a05e11610122578063b72952ee116100aa578063efd71eb01161006e578063efd71eb0146107bd578063f25f4b56146107e5578063f2fde38b1461080f578063f8626af814610837578063ff7bd03d1461087657610224565b8063b72952ee146106cb578063b8606eef146106f3578063bb0b6a531461071d578063c599668414610759578063ca5eb5e11461079557610224565b806381f6af9e116100f157806381f6af9e146105d757806382413eac1461061357806382c947b71461064f5780638456cb591461068b5780638da5cb5b146106a157610224565b80637d25a05e146105075780637f89d739146105435780638078f22c1461055f57806380f568ad1461059b57610224565b806357802c7d116101a55780635e96da62116101745780635e96da621461043b57806361f1c5ba1461047757806366718524146104a1578063715018a6146104c957806376e11286146104df57610224565b806357802c7d146103835780635c975abb146103ab5780635ced058e146103d55780635e280f111461041157610224565b806325fb2680116101ec57806325fb2680146102c15780632abfab4d146102f15780632f6ee6951461031b5780633400288b146103455780633f4ba83a1461036d57610224565b8063126082cf1461022857806313137d651461025257806317442b701461026e578063177ffe9a1461029957610224565b3661022457005b5f5ffd5b348015610233575f5ffd5b5061023c6108b2565b6040516102499190612d1e565b60405180910390f35b61026c60048036038101906102679190612e58565b6108b8565b005b348015610279575f5ffd5b506102826109d8565b604051610290929190612f31565b60405180910390f35b3480156102a4575f5ffd5b506102bf60048036038101906102ba9190612f91565b6109e6565b005b6102db60048036038101906102d69190612ff9565b610a6a565b6040516102e89190612d1e565b60405180910390f35b3480156102fc575f5ffd5b506103056111b3565b6040516103129190612d1e565b60405180910390f35b348015610326575f5ffd5b5061032f6111b9565b60405161033c9190613064565b60405180910390f35b348015610350575f5ffd5b5061036b6004803603810190610366919061307d565b6111be565b005b348015610378575f5ffd5b506103816111d4565b005b34801561038e575f5ffd5b506103a960048036038101906103a491906130bb565b6111e6565b005b3480156103b6575f5ffd5b506103bf611273565b6040516103cc9190613100565b60405180910390f35b3480156103e0575f5ffd5b506103fb60048036038101906103f69190613119565b611288565b6040516104089190613153565b60405180910390f35b34801561041c575f5ffd5b50610425611293565b60405161043291906131c7565b60405180910390f35b348015610446575f5ffd5b50610461600480360381019061045c91906131e0565b6112b7565b60405161046e9190612d1e565b60405180910390f35b348015610482575f5ffd5b5061048b6114df565b6040516104989190613153565b60405180910390f35b3480156104ac575f5ffd5b506104c760048036038101906104c2919061321e565b611504565b005b3480156104d4575f5ffd5b506104dd611600565b005b3480156104ea575f5ffd5b5061050560048036038101906105009190613249565b611613565b005b348015610512575f5ffd5b5061052d6004803603810190610528919061307d565b611820565b60405161053a9190613287565b60405180910390f35b61055d600480360381019061055891906132a0565b61182a565b005b34801561056a575f5ffd5b506105856004803603810190610580919061321e565b61198c565b6040516105929190613153565b60405180910390f35b3480156105a6575f5ffd5b506105c160048036038101906105bc91906130bb565b6119bc565b6040516105ce9190612d1e565b60405180910390f35b3480156105e2575f5ffd5b506105fd60048036038101906105f89190613311565b611b6e565b60405161060a9190612d1e565b60405180910390f35b34801561061e575f5ffd5b5061063960048036038101906106349190613382565b611c2a565b6040516106469190613100565b60405180910390f35b34801561065a575f5ffd5b506106756004803603810190610670919061321e565b611c64565b6040516106829190613402565b60405180910390f35b348015610696575f5ffd5b5061069f611c85565b005b3480156106ac575f5ffd5b506106b5611c97565b6040516106c29190613153565b60405180910390f35b3480156106d6575f5ffd5b506106f160048036038101906106ec91906131e0565b611cbe565b005b3480156106fe575f5ffd5b50610707611de5565b6040516107149190612d1e565b60405180910390f35b348015610728575f5ffd5b50610743600480360381019061073e919061341b565b611deb565b6040516107509190613402565b60405180910390f35b348015610764575f5ffd5b5061077f600480360381019061077a919061348b565b611e00565b60405161078c9190613526565b60405180910390f35b3480156107a0575f5ffd5b506107bb60048036038101906107b6919061321e565b611e25565b005b3480156107c8575f5ffd5b506107e360048036038101906107de919061321e565b611eb6565b005b3480156107f0575f5ffd5b506107f9611fb2565b6040516108069190613153565b60405180910390f35b34801561081a575f5ffd5b506108356004803603810190610830919061321e565b611fd7565b005b348015610842575f5ffd5b5061085d600480360381019061085891906130bb565b61205b565b60405161086d9493929190613546565b60405180910390f35b348015610881575f5ffd5b5061089c60048036038101906108979190613589565b6120b3565b6040516108a99190613100565b60405180910390f35b6103e881565b3373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161461094857336040517f91ac5e4f00000000000000000000000000000000000000000000000000000000815260040161093f9190613153565b60405180910390fd5b8660200135610967885f016020810190610962919061341b565b6120f0565b146109c057865f01602081019061097e919061341b565b87602001356040517fc26bebcc0000000000000000000000000000000000000000000000000000000081526004016109b79291906135c3565b60405180910390fd5b6109cf87878787878787612161565b50505050505050565b5f5f60016002915091509091565b6109ee61219c565b5f8173ffffffffffffffffffffffffffffffffffffffff165f1b90508060015f8563ffffffff1663ffffffff1681526020019081526020015f20819055507f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b8382604051610a5d9291906135c3565b60405180910390a1505050565b5f610a73612223565b610a7b612272565b5f5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e35575f3411610af1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae890613644565b60405180910390fd5b610afa346119bc565b90505f6103e860085483610b0e919061368f565b610b1891906136fd565b90505f8183610b27919061372d565b90505f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166103e860085434610b73919061368f565b610b7d91906136fd565b604051610b899061378d565b5f6040518083038185875af1925050503d805f8114610bc3576040519150601f19603f3d011682016040523d82523d5f602084013e610bc8565b606091505b5050905080610c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c03906137eb565b60405180910390fd5b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166103e860085434610c56919061368f565b610c6091906136fd565b34610c6b919061372d565b604051610c779061378d565b5f6040518083038185875af1925050503d805f8114610cb1576040519150601f19603f3d011682016040523d82523d5f602084013e610cb6565b606091505b5050905080610cfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf190613853565b60405180910390fd5b60045f815480929190610d0c90613871565b9190505550600454955060405180608001604052808a81526020018481526020015f151581526020013373ffffffffffffffffffffffffffffffffffffffff1681525060055f8881526020019081526020015f205f820151815f0155602082015181600101556040820151816002015f6101000a81548160ff02191690831515021790555060608201518160020160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff16867fb9c87592ed73f7a26fff471ef513f8065a243208d84daa291fb0e770635014e28b86604051610e249291906138b8565b60405180910390a3505050506111a3565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610eff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef690613929565b60405180910390fd5b5f8311610f41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3890613991565b60405180910390fd5b610f6e3330858773ffffffffffffffffffffffffffffffffffffffff166122bc909392919063ffffffff16565b610f7884846112b7565b90505f6103e860085485610f8c919061368f565b610f9691906136fd565b90505f8185610fa5919061372d565b9050610ff360065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838873ffffffffffffffffffffffffffffffffffffffff1661233e9092919063ffffffff16565b61103f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828873ffffffffffffffffffffffffffffffffffffffff1661233e9092919063ffffffff16565b5f6103e860085485611051919061368f565b61105b91906136fd565b90505f818561106a919061372d565b905060045f81548092919061107e90613871565b9190505550600454955060405180608001604052808a81526020018281526020015f151581526020013373ffffffffffffffffffffffffffffffffffffffff1681525060055f8881526020019081526020015f205f820151815f0155602082015181600101556040820151816002015f6101000a81548160ff02191690831515021790555060608201518160020160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff16867fb9c87592ed73f7a26fff471ef513f8065a243208d84daa291fb0e770635014e28b846040516111969291906138b8565b60405180910390a3505050505b506111ac6123bd565b9392505050565b60045481565b600881565b6111c661219c565b6111d082826123c7565b5050565b6111dc61219c565b6111e4612426565b565b6111ee61219c565b6103e88110611232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611229906139f9565b60405180910390fd5b806008819055507f3a81812ce3d900b6196b2d0a225da9df123054670067cf761d52294251a96740816040516112689190612d1e565b60405180910390a150565b5f60025f9054906101000a900460ff16905090565b5f815f1c9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f5f60095f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137d90613a61565b60405180910390fd5b5f8190505f8173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156113d4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113f89190613b05565b5050509150505f8113611440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143790613bc6565b60405180910390fd5b5f8673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561148a573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114ae9190613c0e565b905080600a6114bd9190613d68565b82876114c9919061368f565b6114d391906136fd565b94505050505092915050565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61150c61219c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361157a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157190613dfc565b60405180910390fd5b8060065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f29acee77dafcfa0143d74a7ea236018f3a6e1fa71e27fc59bbfbc6b8ca8edccd60405160405180910390a250565b61160861219c565b6116115f612487565b565b61161b61219c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611689576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168090613e64565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff1660095f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174a90613ef2565b60405180910390fd5b8060095f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff167fd2d8394cf7549a5ddbc2ba3dd7b2de8d53c891472d1f2907008ed6a10045fdae826040516118149190613153565b60405180910390a25050565b5f5f905092915050565b611832612223565b5f60055f8681526020019081526020015f209050806002015f9054906101000a900460ff1615611897576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188e90613f5a565b60405180910390fd5b5f815f015482600101546040516020016118b29291906138b8565b6040516020818303038152906040529050611927858286868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505060405180604001604052803481526020015f81525033612548565b506001826002015f6101000a81548160ff021916908315150217905550857f52e524a2036dcdef7cb6e5fe44cd1aa8975a6c2103710da06505daa54c21f3ed866040516119749190613f78565b60405180910390a250506119866123bd565b50505050565b6009602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f60095f5f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8290613fdb565b60405180910390fd5b5f8190505f8173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611ad9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611afd9190613b05565b5050509150505f8113611b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3c90613bc6565b60405180910390fd5b670de0b6b3a76400008186611b5a919061368f565b611b6491906136fd565b9350505050919050565b5f5f5f90505f633b9aca0090505f8682604051602001611b8f9291906138b8565b60405160208183030381529060405290505f611bf0898389898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508761265e565b9050600a6002825f0151611c04919061368f565b611c0e91906136fd565b815f0151611c1c9190613ff9565b945050505050949350505050565b5f3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050949350505050565b5f8173ffffffffffffffffffffffffffffffffffffffff165f1b9050919050565b611c8d61219c565b611c9561273f565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611cc661219c565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611dae575f611d02611c97565b73ffffffffffffffffffffffffffffffffffffffff1682604051611d259061378d565b5f6040518083038185875af1925050503d805f8114611d5f576040519150601f19603f3d011682016040523d82523d5f602084013e611d64565b606091505b5050905080611da8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9f90614076565b60405180910390fd5b50611de1565b611de0611db9611c97565b828473ffffffffffffffffffffffffffffffffffffffff1661233e9092919063ffffffff16565b5b5050565b60085481565b6001602052805f5260405f205f915090505481565b6060611e1e825f611e0f6127a1565b6127c99092919063ffffffff16565b9050919050565b611e2d61219c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ca5eb5e1826040518263ffffffff1660e01b8152600401611e869190613153565b5f604051808303815f87803b158015611e9d575f5ffd5b505af1158015611eaf573d5f5f3e3d5ffd5b5050505050565b611ebe61219c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f23906140de565b60405180910390fd5b8060075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f5e1c00e9ff18e7e450a492928f1eed7cde32fff1be56c68201eea3d503241a2660405160405180910390a250565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611fdf61219c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361204f575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016120469190613153565b60405180910390fd5b61205881612487565b50565b6005602052805f5260405f205f91509050805f015490806001015490806002015f9054906101000a900460ff16908060020160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905084565b5f816020013560015f845f0160208101906120ce919061341b565b63ffffffff1663ffffffff1681526020019081526020015f2054149050919050565b5f5f60015f8463ffffffff1663ffffffff1681526020019081526020015f205490505f5f1b810361215857826040517ff6ff4fb700000000000000000000000000000000000000000000000000000000815260040161214f9190613f78565b60405180910390fd5b80915050919050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219390614146565b60405180910390fd5b6121a4612861565b73ffffffffffffffffffffffffffffffffffffffff166121c2611c97565b73ffffffffffffffffffffffffffffffffffffffff1614612221576121e5612861565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016122189190613153565b60405180910390fd5b565b600260035403612268576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225f906141ae565b60405180910390fd5b6002600381905550565b61227a611273565b156122ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b190614216565b60405180910390fd5b565b612338848573ffffffffffffffffffffffffffffffffffffffff166323b872dd8686866040516024016122f193929190614234565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612868565b50505050565b6123b8838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401612371929190614269565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612868565b505050565b6001600381905550565b8060015f8463ffffffff1663ffffffff1681526020019081526020015f20819055507f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b828260405161241a9291906135c3565b60405180910390a15050565b61242e612903565b5f60025f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa612470612861565b60405161247d9190613153565b60405180910390a1565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612550612cbf565b5f61255d845f015161294c565b90505f84602001511115612579576125788460200151612999565b5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632637a450826040518060a001604052808b63ffffffff1681526020016125d68c6120f0565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b815260040161261192919061437f565b60806040518083038185885af115801561262d573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906126529190614515565b91505095945050505050565b612666612cee565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ddc28c586040518060a001604052808863ffffffff1681526020016126c2896120f0565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016126f792919061437f565b6040805180830381865afa158015612711573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127359190614540565b9050949350505050565b612747612272565b600160025f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861278a612861565b6040516127979190613153565b60405180910390a1565b606060036040516020016127b591906145ac565b604051602081830303815290604052905090565b606083600361ffff166127e55f83612adf90919063ffffffff16565b61ffff161461283d576128015f82612adf90919063ffffffff16565b6040517f3a51740d00000000000000000000000000000000000000000000000000000000815260040161283491906145d5565b60405180910390fd5b5f6128488585612b44565b905061285686600183612baf565b925050509392505050565b5f33905090565b5f5f60205f8451602086015f885af180612887576040513d5f823e3d81fd5b3d92505f519150505f82146128a05760018114156128bb565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b156128fd57836040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016128f49190613153565b60405180910390fd5b50505050565b61290b611273565b61294a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161294190614638565b60405180910390fd5b565b5f81341461299157346040517f9f7041200000000000000000000000000000000000000000000000000000000081526004016129889190612d1e565b60405180910390fd5b819050919050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a03573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a27919061466a565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612a8e576040517f5373352a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612adb337f0000000000000000000000000000000000000000000000000000000000000000848473ffffffffffffffffffffffffffffffffffffffff166122bc909392919063ffffffff16565b5050565b5f600282612aed9190613ff9565b83511015612b30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b27906146df565b60405180910390fd5b5f8260028501015190508091505092915050565b60605f826fffffffffffffffffffffffffffffffff1614612b86578282604051602001612b72929190614731565b604051602081830303815290604052612ba7565b82604051602001612b97919061475c565b6040516020818303038152906040525b905092915050565b606083600361ffff16612bcb5f83612adf90919063ffffffff16565b61ffff1614612c2357612be75f82612adf90919063ffffffff16565b6040517f3a51740d000000000000000000000000000000000000000000000000000000008152600401612c1a91906145d5565b60405180910390fd5b84600180612c318651612c6a565b612c3b9190614776565b8686604051602001612c5195949392919061480f565b6040516020818303038152906040529150509392505050565b5f61ffff8016821115612cb7576010826040517f6dfcc650000000000000000000000000000000000000000000000000000000008152600401612cae92919061489e565b60405180910390fd5b819050919050565b60405180606001604052805f81526020015f67ffffffffffffffff168152602001612ce8612cee565b81525090565b60405180604001604052805f81526020015f81525090565b5f819050919050565b612d1881612d06565b82525050565b5f602082019050612d315f830184612d0f565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f60608284031215612d6157612d60612d48565b5b81905092915050565b5f819050919050565b612d7c81612d6a565b8114612d86575f5ffd5b50565b5f81359050612d9781612d73565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112612dbe57612dbd612d9d565b5b8235905067ffffffffffffffff811115612ddb57612dda612da1565b5b602083019150836001820283011115612df757612df6612da5565b5b9250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612e2782612dfe565b9050919050565b612e3781612e1d565b8114612e41575f5ffd5b50565b5f81359050612e5281612e2e565b92915050565b5f5f5f5f5f5f5f60e0888a031215612e7357612e72612d40565b5b5f612e808a828b01612d4c565b9750506060612e918a828b01612d89565b965050608088013567ffffffffffffffff811115612eb257612eb1612d44565b5b612ebe8a828b01612da9565b955095505060a0612ed18a828b01612e44565b93505060c088013567ffffffffffffffff811115612ef257612ef1612d44565b5b612efe8a828b01612da9565b925092505092959891949750929550565b5f67ffffffffffffffff82169050919050565b612f2b81612f0f565b82525050565b5f604082019050612f445f830185612f22565b612f516020830184612f22565b9392505050565b5f63ffffffff82169050919050565b612f7081612f58565b8114612f7a575f5ffd5b50565b5f81359050612f8b81612f67565b92915050565b5f5f60408385031215612fa757612fa6612d40565b5b5f612fb485828601612f7d565b9250506020612fc585828601612e44565b9150509250929050565b612fd881612d06565b8114612fe2575f5ffd5b50565b5f81359050612ff381612fcf565b92915050565b5f5f5f606084860312156130105761300f612d40565b5b5f61301d86828701612fe5565b935050602061302e86828701612e44565b925050604061303f86828701612fe5565b9150509250925092565b5f60ff82169050919050565b61305e81613049565b82525050565b5f6020820190506130775f830184613055565b92915050565b5f5f6040838503121561309357613092612d40565b5b5f6130a085828601612f7d565b92505060206130b185828601612d89565b9150509250929050565b5f602082840312156130d0576130cf612d40565b5b5f6130dd84828501612fe5565b91505092915050565b5f8115159050919050565b6130fa816130e6565b82525050565b5f6020820190506131135f8301846130f1565b92915050565b5f6020828403121561312e5761312d612d40565b5b5f61313b84828501612d89565b91505092915050565b61314d81612e1d565b82525050565b5f6020820190506131665f830184613144565b92915050565b5f819050919050565b5f61318f61318a61318584612dfe565b61316c565b612dfe565b9050919050565b5f6131a082613175565b9050919050565b5f6131b182613196565b9050919050565b6131c1816131a7565b82525050565b5f6020820190506131da5f8301846131b8565b92915050565b5f5f604083850312156131f6576131f5612d40565b5b5f61320385828601612e44565b925050602061321485828601612fe5565b9150509250929050565b5f6020828403121561323357613232612d40565b5b5f61324084828501612e44565b91505092915050565b5f5f6040838503121561325f5761325e612d40565b5b5f61326c85828601612e44565b925050602061327d85828601612e44565b9150509250929050565b5f60208201905061329a5f830184612f22565b92915050565b5f5f5f5f606085870312156132b8576132b7612d40565b5b5f6132c587828801612fe5565b94505060206132d687828801612f7d565b935050604085013567ffffffffffffffff8111156132f7576132f6612d44565b5b61330387828801612da9565b925092505092959194509250565b5f5f5f5f6060858703121561332957613328612d40565b5b5f61333687828801612f7d565b945050602061334787828801612fe5565b935050604085013567ffffffffffffffff81111561336857613367612d44565b5b61337487828801612da9565b925092505092959194509250565b5f5f5f5f60a0858703121561339a57613399612d40565b5b5f6133a787828801612d4c565b945050606085013567ffffffffffffffff8111156133c8576133c7612d44565b5b6133d487828801612da9565b935093505060806133e787828801612e44565b91505092959194509250565b6133fc81612d6a565b82525050565b5f6020820190506134155f8301846133f3565b92915050565b5f602082840312156134305761342f612d40565b5b5f61343d84828501612f7d565b91505092915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b61346a81613446565b8114613474575f5ffd5b50565b5f8135905061348581613461565b92915050565b5f602082840312156134a05761349f612d40565b5b5f6134ad84828501613477565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6134f8826134b6565b61350281856134c0565b93506135128185602086016134d0565b61351b816134de565b840191505092915050565b5f6020820190508181035f83015261353e81846134ee565b905092915050565b5f6080820190506135595f830187612d0f565b6135666020830186612d0f565b61357360408301856130f1565b6135806060830184613144565b95945050505050565b5f6060828403121561359e5761359d612d40565b5b5f6135ab84828501612d4c565b91505092915050565b6135bd81612f58565b82525050565b5f6040820190506135d65f8301856135b4565b6135e360208301846133f3565b9392505050565b5f82825260208201905092915050565b7f4e6f206e617469766520636f696e2073656e74000000000000000000000000005f82015250565b5f61362e6013836135ea565b9150613639826135fa565b602082019050919050565b5f6020820190508181035f83015261365b81613622565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61369982612d06565b91506136a483612d06565b92508282026136b281612d06565b915082820484148315176136c9576136c8613662565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61370782612d06565b915061371283612d06565b925082613722576137216136d0565b5b828204905092915050565b5f61373782612d06565b915061374283612d06565b925082820390508181111561375a57613759613662565b5b92915050565b5f81905092915050565b50565b5f6137785f83613760565b91506137838261376a565b5f82019050919050565b5f6137978261376d565b9150819050919050565b7f466565207472616e73666572206661696c6564000000000000000000000000005f82015250565b5f6137d56013836135ea565b91506137e0826137a1565b602082019050919050565b5f6020820190508181035f830152613802816137c9565b9050919050565b7f5661756c74207472616e73666572206661696c656400000000000000000000005f82015250565b5f61383d6015836135ea565b915061384882613809565b602082019050919050565b5f6020820190508181035f83015261386a81613831565b9050919050565b5f61387b82612d06565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036138ad576138ac613662565b5b600182019050919050565b5f6040820190506138cb5f830185612d0f565b6138d86020830184612d0f565b9392505050565b7f546f6b656e206e6f7420737570706f72746564000000000000000000000000005f82015250565b5f6139136013836135ea565b915061391e826138df565b602082019050919050565b5f6020820190508181035f83015261394081613907565b9050919050565b7f446f6e6174696f6e206d757374206265203e20300000000000000000000000005f82015250565b5f61397b6014836135ea565b915061398682613947565b602082019050919050565b5f6020820190508181035f8301526139a88161396f565b9050919050565b7f46656520746f6f206869676800000000000000000000000000000000000000005f82015250565b5f6139e3600c836135ea565b91506139ee826139af565b602082019050919050565b5f6020820190508181035f830152613a10816139d7565b9050919050565b7f50726963652066656564206e6f742073657420666f7220746f6b656e000000005f82015250565b5f613a4b601c836135ea565b9150613a5682613a17565b602082019050919050565b5f6020820190508181035f830152613a7881613a3f565b9050919050565b5f69ffffffffffffffffffff82169050919050565b613a9d81613a7f565b8114613aa7575f5ffd5b50565b5f81519050613ab881613a94565b92915050565b5f819050919050565b613ad081613abe565b8114613ada575f5ffd5b50565b5f81519050613aeb81613ac7565b92915050565b5f81519050613aff81612fcf565b92915050565b5f5f5f5f5f60a08688031215613b1e57613b1d612d40565b5b5f613b2b88828901613aaa565b9550506020613b3c88828901613add565b9450506040613b4d88828901613af1565b9350506060613b5e88828901613af1565b9250506080613b6f88828901613aaa565b9150509295509295909350565b7f496e76616c6964207072696365000000000000000000000000000000000000005f82015250565b5f613bb0600d836135ea565b9150613bbb82613b7c565b602082019050919050565b5f6020820190508181035f830152613bdd81613ba4565b9050919050565b613bed81613049565b8114613bf7575f5ffd5b50565b5f81519050613c0881613be4565b92915050565b5f60208284031215613c2357613c22612d40565b5b5f613c3084828501613bfa565b91505092915050565b5f8160011c9050919050565b5f5f8291508390505b6001851115613c8e57808604811115613c6a57613c69613662565b5b6001851615613c795780820291505b8081029050613c8785613c39565b9450613c4e565b94509492505050565b5f82613ca65760019050613d61565b81613cb3575f9050613d61565b8160018114613cc95760028114613cd357613d02565b6001915050613d61565b60ff841115613ce557613ce4613662565b5b8360020a915084821115613cfc57613cfb613662565b5b50613d61565b5060208310610133831016604e8410600b8410161715613d375782820a905083811115613d3257613d31613662565b5b613d61565b613d448484846001613c45565b92509050818404811115613d5b57613d5a613662565b5b81810290505b9392505050565b5f613d7282612d06565b9150613d7d83613049565b9250613daa7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484613c97565b905092915050565b7f496e76616c6964206665652077616c6c657400000000000000000000000000005f82015250565b5f613de66012836135ea565b9150613df182613db2565b602082019050919050565b5f6020820190508181035f830152613e1381613dda565b9050919050565b7f496e76616c6964207072696365206665656420616464726573730000000000005f82015250565b5f613e4e601a836135ea565b9150613e5982613e1a565b602082019050919050565b5f6020820190508181035f830152613e7b81613e42565b9050919050565b7f5072696365206665656420616c72656164792073657420666f722074686973205f8201527f746f6b656e000000000000000000000000000000000000000000000000000000602082015250565b5f613edc6025836135ea565b9150613ee782613e82565b604082019050919050565b5f6020820190508181035f830152613f0981613ed0565b9050919050565b7f446f6e6174696f6e20616c72656164792072656c6179656400000000000000005f82015250565b5f613f446018836135ea565b9150613f4f82613f10565b602082019050919050565b5f6020820190508181035f830152613f7181613f38565b9050919050565b5f602082019050613f8b5f8301846135b4565b92915050565b7f4e617469766520636f696e2070726963652066656564206e6f742073657400005f82015250565b5f613fc5601e836135ea565b9150613fd082613f91565b602082019050919050565b5f6020820190508181035f830152613ff281613fb9565b9050919050565b5f61400382612d06565b915061400e83612d06565b925082820190508082111561402657614025613662565b5b92915050565b7f4661696c656420746f2073656e64206e617469766520636f696e0000000000005f82015250565b5f614060601a836135ea565b915061406b8261402c565b602082019050919050565b5f6020820190508181035f83015261408d81614054565b9050919050565b7f496e76616c6964207661756c742077616c6c65740000000000000000000000005f82015250565b5f6140c86014836135ea565b91506140d382614094565b602082019050919050565b5f6020820190508181035f8301526140f5816140bc565b9050919050565b7f4e6f7420696d706c656d656e74656400000000000000000000000000000000005f82015250565b5f614130600f836135ea565b915061413b826140fc565b602082019050919050565b5f6020820190508181035f83015261415d81614124565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f614198601f836135ea565b91506141a382614164565b602082019050919050565b5f6020820190508181035f8301526141c58161418c565b9050919050565b7f5061757361626c653a20706175736564000000000000000000000000000000005f82015250565b5f6142006010836135ea565b915061420b826141cc565b602082019050919050565b5f6020820190508181035f83015261422d816141f4565b9050919050565b5f6060820190506142475f830186613144565b6142546020830185613144565b6142616040830184612d0f565b949350505050565b5f60408201905061427c5f830185613144565b6142896020830184612d0f565b9392505050565b61429981612f58565b82525050565b6142a881612d6a565b82525050565b5f82825260208201905092915050565b5f6142c8826134b6565b6142d281856142ae565b93506142e28185602086016134d0565b6142eb816134de565b840191505092915050565b6142ff816130e6565b82525050565b5f60a083015f83015161431a5f860182614290565b50602083015161432d602086018261429f565b506040830151848203604086015261434582826142be565b9150506060830151848203606086015261435f82826142be565b915050608083015161437460808601826142f6565b508091505092915050565b5f6040820190508181035f8301526143978185614305565b90506143a66020830184613144565b9392505050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6143e7826134de565b810181811067ffffffffffffffff82111715614406576144056143b1565b5b80604052505050565b5f614418612d37565b905061442482826143de565b919050565b5f8151905061443781612d73565b92915050565b61444681612f0f565b8114614450575f5ffd5b50565b5f815190506144618161443d565b92915050565b5f6040828403121561447c5761447b6143ad565b5b614486604061440f565b90505f61449584828501613af1565b5f8301525060206144a884828501613af1565b60208301525092915050565b5f608082840312156144c9576144c86143ad565b5b6144d3606061440f565b90505f6144e284828501614429565b5f8301525060206144f584828501614453565b602083015250604061450984828501614467565b60408301525092915050565b5f6080828403121561452a57614529612d40565b5b5f614537848285016144b4565b91505092915050565b5f6040828403121561455557614554612d40565b5b5f61456284828501614467565b91505092915050565b5f61ffff82169050919050565b5f8160f01b9050919050565b5f61458e82614578565b9050919050565b6145a66145a18261456b565b614584565b82525050565b5f6145b78284614595565b60028201915081905092915050565b6145cf8161456b565b82525050565b5f6020820190506145e85f8301846145c6565b92915050565b7f5061757361626c653a206e6f74207061757365640000000000000000000000005f82015250565b5f6146226014836135ea565b915061462d826145ee565b602082019050919050565b5f6020820190508181035f83015261464f81614616565b9050919050565b5f8151905061466481612e2e565b92915050565b5f6020828403121561467f5761467e612d40565b5b5f61468c84828501614656565b91505092915050565b7f746f55696e7431365f6f75744f66426f756e64730000000000000000000000005f82015250565b5f6146c96014836135ea565b91506146d482614695565b602082019050919050565b5f6020820190508181035f8301526146f6816146bd565b9050919050565b5f8160801b9050919050565b5f614713826146fd565b9050919050565b61472b61472682613446565b614709565b82525050565b5f61473c828561471a565b60108201915061474c828461471a565b6010820191508190509392505050565b5f614767828461471a565b60108201915081905092915050565b5f6147808261456b565b915061478b8361456b565b9250828201905061ffff8111156147a5576147a4613662565b5b92915050565b5f6147b5826134b6565b6147bf8185613760565b93506147cf8185602086016134d0565b80840191505092915050565b5f8160f81b9050919050565b5f6147f1826147db565b9050919050565b61480961480482613049565b6147e7565b82525050565b5f61481a82886147ab565b915061482682876147f8565b6001820191506148368286614595565b60028201915061484682856147f8565b60018201915061485682846147ab565b91508190509695505050505050565b5f819050919050565b5f61488861488361487e84614865565b61316c565b613049565b9050919050565b6148988161486e565b82525050565b5f6040820190506148b15f83018561488f565b6148be6020830184612d0f565b939250505056fea264697066735822122059aefbfa9e58854b60580180251b10bd19b5ac21ff130a8b17361592b5c1247c64736f6c634300081c00330000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b00000000000000000000000014ce936fcc154fecc38f9920d937827045f8162800000000000000000000000001cc205772d08cfe45a870df1366b4c6ac408f44000000000000000000000000000000000000000000000000000000000000000e
Deployed Bytecode
0x60806040526004361061021d575f3560e01c80637d25a05e11610122578063b72952ee116100aa578063efd71eb01161006e578063efd71eb0146107bd578063f25f4b56146107e5578063f2fde38b1461080f578063f8626af814610837578063ff7bd03d1461087657610224565b8063b72952ee146106cb578063b8606eef146106f3578063bb0b6a531461071d578063c599668414610759578063ca5eb5e11461079557610224565b806381f6af9e116100f157806381f6af9e146105d757806382413eac1461061357806382c947b71461064f5780638456cb591461068b5780638da5cb5b146106a157610224565b80637d25a05e146105075780637f89d739146105435780638078f22c1461055f57806380f568ad1461059b57610224565b806357802c7d116101a55780635e96da62116101745780635e96da621461043b57806361f1c5ba1461047757806366718524146104a1578063715018a6146104c957806376e11286146104df57610224565b806357802c7d146103835780635c975abb146103ab5780635ced058e146103d55780635e280f111461041157610224565b806325fb2680116101ec57806325fb2680146102c15780632abfab4d146102f15780632f6ee6951461031b5780633400288b146103455780633f4ba83a1461036d57610224565b8063126082cf1461022857806313137d651461025257806317442b701461026e578063177ffe9a1461029957610224565b3661022457005b5f5ffd5b348015610233575f5ffd5b5061023c6108b2565b6040516102499190612d1e565b60405180910390f35b61026c60048036038101906102679190612e58565b6108b8565b005b348015610279575f5ffd5b506102826109d8565b604051610290929190612f31565b60405180910390f35b3480156102a4575f5ffd5b506102bf60048036038101906102ba9190612f91565b6109e6565b005b6102db60048036038101906102d69190612ff9565b610a6a565b6040516102e89190612d1e565b60405180910390f35b3480156102fc575f5ffd5b506103056111b3565b6040516103129190612d1e565b60405180910390f35b348015610326575f5ffd5b5061032f6111b9565b60405161033c9190613064565b60405180910390f35b348015610350575f5ffd5b5061036b6004803603810190610366919061307d565b6111be565b005b348015610378575f5ffd5b506103816111d4565b005b34801561038e575f5ffd5b506103a960048036038101906103a491906130bb565b6111e6565b005b3480156103b6575f5ffd5b506103bf611273565b6040516103cc9190613100565b60405180910390f35b3480156103e0575f5ffd5b506103fb60048036038101906103f69190613119565b611288565b6040516104089190613153565b60405180910390f35b34801561041c575f5ffd5b50610425611293565b60405161043291906131c7565b60405180910390f35b348015610446575f5ffd5b50610461600480360381019061045c91906131e0565b6112b7565b60405161046e9190612d1e565b60405180910390f35b348015610482575f5ffd5b5061048b6114df565b6040516104989190613153565b60405180910390f35b3480156104ac575f5ffd5b506104c760048036038101906104c2919061321e565b611504565b005b3480156104d4575f5ffd5b506104dd611600565b005b3480156104ea575f5ffd5b5061050560048036038101906105009190613249565b611613565b005b348015610512575f5ffd5b5061052d6004803603810190610528919061307d565b611820565b60405161053a9190613287565b60405180910390f35b61055d600480360381019061055891906132a0565b61182a565b005b34801561056a575f5ffd5b506105856004803603810190610580919061321e565b61198c565b6040516105929190613153565b60405180910390f35b3480156105a6575f5ffd5b506105c160048036038101906105bc91906130bb565b6119bc565b6040516105ce9190612d1e565b60405180910390f35b3480156105e2575f5ffd5b506105fd60048036038101906105f89190613311565b611b6e565b60405161060a9190612d1e565b60405180910390f35b34801561061e575f5ffd5b5061063960048036038101906106349190613382565b611c2a565b6040516106469190613100565b60405180910390f35b34801561065a575f5ffd5b506106756004803603810190610670919061321e565b611c64565b6040516106829190613402565b60405180910390f35b348015610696575f5ffd5b5061069f611c85565b005b3480156106ac575f5ffd5b506106b5611c97565b6040516106c29190613153565b60405180910390f35b3480156106d6575f5ffd5b506106f160048036038101906106ec91906131e0565b611cbe565b005b3480156106fe575f5ffd5b50610707611de5565b6040516107149190612d1e565b60405180910390f35b348015610728575f5ffd5b50610743600480360381019061073e919061341b565b611deb565b6040516107509190613402565b60405180910390f35b348015610764575f5ffd5b5061077f600480360381019061077a919061348b565b611e00565b60405161078c9190613526565b60405180910390f35b3480156107a0575f5ffd5b506107bb60048036038101906107b6919061321e565b611e25565b005b3480156107c8575f5ffd5b506107e360048036038101906107de919061321e565b611eb6565b005b3480156107f0575f5ffd5b506107f9611fb2565b6040516108069190613153565b60405180910390f35b34801561081a575f5ffd5b506108356004803603810190610830919061321e565b611fd7565b005b348015610842575f5ffd5b5061085d600480360381019061085891906130bb565b61205b565b60405161086d9493929190613546565b60405180910390f35b348015610881575f5ffd5b5061089c60048036038101906108979190613589565b6120b3565b6040516108a99190613100565b60405180910390f35b6103e881565b3373ffffffffffffffffffffffffffffffffffffffff167f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff161461094857336040517f91ac5e4f00000000000000000000000000000000000000000000000000000000815260040161093f9190613153565b60405180910390fd5b8660200135610967885f016020810190610962919061341b565b6120f0565b146109c057865f01602081019061097e919061341b565b87602001356040517fc26bebcc0000000000000000000000000000000000000000000000000000000081526004016109b79291906135c3565b60405180910390fd5b6109cf87878787878787612161565b50505050505050565b5f5f60016002915091509091565b6109ee61219c565b5f8173ffffffffffffffffffffffffffffffffffffffff165f1b90508060015f8563ffffffff1663ffffffff1681526020019081526020015f20819055507f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b8382604051610a5d9291906135c3565b60405180910390a1505050565b5f610a73612223565b610a7b612272565b5f5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e35575f3411610af1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ae890613644565b60405180910390fd5b610afa346119bc565b90505f6103e860085483610b0e919061368f565b610b1891906136fd565b90505f8183610b27919061372d565b90505f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166103e860085434610b73919061368f565b610b7d91906136fd565b604051610b899061378d565b5f6040518083038185875af1925050503d805f8114610bc3576040519150601f19603f3d011682016040523d82523d5f602084013e610bc8565b606091505b5050905080610c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c03906137eb565b60405180910390fd5b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166103e860085434610c56919061368f565b610c6091906136fd565b34610c6b919061372d565b604051610c779061378d565b5f6040518083038185875af1925050503d805f8114610cb1576040519150601f19603f3d011682016040523d82523d5f602084013e610cb6565b606091505b5050905080610cfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf190613853565b60405180910390fd5b60045f815480929190610d0c90613871565b9190505550600454955060405180608001604052808a81526020018481526020015f151581526020013373ffffffffffffffffffffffffffffffffffffffff1681525060055f8881526020019081526020015f205f820151815f0155602082015181600101556040820151816002015f6101000a81548160ff02191690831515021790555060608201518160020160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff16867fb9c87592ed73f7a26fff471ef513f8065a243208d84daa291fb0e770635014e28b86604051610e249291906138b8565b60405180910390a3505050506111a3565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610eff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef690613929565b60405180910390fd5b5f8311610f41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3890613991565b60405180910390fd5b610f6e3330858773ffffffffffffffffffffffffffffffffffffffff166122bc909392919063ffffffff16565b610f7884846112b7565b90505f6103e860085485610f8c919061368f565b610f9691906136fd565b90505f8185610fa5919061372d565b9050610ff360065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838873ffffffffffffffffffffffffffffffffffffffff1661233e9092919063ffffffff16565b61103f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828873ffffffffffffffffffffffffffffffffffffffff1661233e9092919063ffffffff16565b5f6103e860085485611051919061368f565b61105b91906136fd565b90505f818561106a919061372d565b905060045f81548092919061107e90613871565b9190505550600454955060405180608001604052808a81526020018281526020015f151581526020013373ffffffffffffffffffffffffffffffffffffffff1681525060055f8881526020019081526020015f205f820151815f0155602082015181600101556040820151816002015f6101000a81548160ff02191690831515021790555060608201518160020160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff16867fb9c87592ed73f7a26fff471ef513f8065a243208d84daa291fb0e770635014e28b846040516111969291906138b8565b60405180910390a3505050505b506111ac6123bd565b9392505050565b60045481565b600881565b6111c661219c565b6111d082826123c7565b5050565b6111dc61219c565b6111e4612426565b565b6111ee61219c565b6103e88110611232576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611229906139f9565b60405180910390fd5b806008819055507f3a81812ce3d900b6196b2d0a225da9df123054670067cf761d52294251a96740816040516112689190612d1e565b60405180910390a150565b5f60025f9054906101000a900460ff16905090565b5f815f1c9050919050565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b81565b5f5f60095f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137d90613a61565b60405180910390fd5b5f8190505f8173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156113d4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113f89190613b05565b5050509150505f8113611440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143790613bc6565b60405180910390fd5b5f8673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561148a573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114ae9190613c0e565b905080600a6114bd9190613d68565b82876114c9919061368f565b6114d391906136fd565b94505050505092915050565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61150c61219c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361157a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157190613dfc565b60405180910390fd5b8060065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f29acee77dafcfa0143d74a7ea236018f3a6e1fa71e27fc59bbfbc6b8ca8edccd60405160405180910390a250565b61160861219c565b6116115f612487565b565b61161b61219c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611689576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168090613e64565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff1660095f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611753576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174a90613ef2565b60405180910390fd5b8060095f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff167fd2d8394cf7549a5ddbc2ba3dd7b2de8d53c891472d1f2907008ed6a10045fdae826040516118149190613153565b60405180910390a25050565b5f5f905092915050565b611832612223565b5f60055f8681526020019081526020015f209050806002015f9054906101000a900460ff1615611897576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188e90613f5a565b60405180910390fd5b5f815f015482600101546040516020016118b29291906138b8565b6040516020818303038152906040529050611927858286868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505060405180604001604052803481526020015f81525033612548565b506001826002015f6101000a81548160ff021916908315150217905550857f52e524a2036dcdef7cb6e5fe44cd1aa8975a6c2103710da06505daa54c21f3ed866040516119749190613f78565b60405180910390a250506119866123bd565b50505050565b6009602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f60095f5f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8290613fdb565b60405180910390fd5b5f8190505f8173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611ad9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611afd9190613b05565b5050509150505f8113611b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3c90613bc6565b60405180910390fd5b670de0b6b3a76400008186611b5a919061368f565b611b6491906136fd565b9350505050919050565b5f5f5f90505f633b9aca0090505f8682604051602001611b8f9291906138b8565b60405160208183030381529060405290505f611bf0898389898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508761265e565b9050600a6002825f0151611c04919061368f565b611c0e91906136fd565b815f0151611c1c9190613ff9565b945050505050949350505050565b5f3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050949350505050565b5f8173ffffffffffffffffffffffffffffffffffffffff165f1b9050919050565b611c8d61219c565b611c9561273f565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611cc661219c565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611dae575f611d02611c97565b73ffffffffffffffffffffffffffffffffffffffff1682604051611d259061378d565b5f6040518083038185875af1925050503d805f8114611d5f576040519150601f19603f3d011682016040523d82523d5f602084013e611d64565b606091505b5050905080611da8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9f90614076565b60405180910390fd5b50611de1565b611de0611db9611c97565b828473ffffffffffffffffffffffffffffffffffffffff1661233e9092919063ffffffff16565b5b5050565b60085481565b6001602052805f5260405f205f915090505481565b6060611e1e825f611e0f6127a1565b6127c99092919063ffffffff16565b9050919050565b611e2d61219c565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff1663ca5eb5e1826040518263ffffffff1660e01b8152600401611e869190613153565b5f604051808303815f87803b158015611e9d575f5ffd5b505af1158015611eaf573d5f5f3e3d5ffd5b5050505050565b611ebe61219c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f23906140de565b60405180910390fd5b8060075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f5e1c00e9ff18e7e450a492928f1eed7cde32fff1be56c68201eea3d503241a2660405160405180910390a250565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611fdf61219c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361204f575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016120469190613153565b60405180910390fd5b61205881612487565b50565b6005602052805f5260405f205f91509050805f015490806001015490806002015f9054906101000a900460ff16908060020160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905084565b5f816020013560015f845f0160208101906120ce919061341b565b63ffffffff1663ffffffff1681526020019081526020015f2054149050919050565b5f5f60015f8463ffffffff1663ffffffff1681526020019081526020015f205490505f5f1b810361215857826040517ff6ff4fb700000000000000000000000000000000000000000000000000000000815260040161214f9190613f78565b60405180910390fd5b80915050919050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219390614146565b60405180910390fd5b6121a4612861565b73ffffffffffffffffffffffffffffffffffffffff166121c2611c97565b73ffffffffffffffffffffffffffffffffffffffff1614612221576121e5612861565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016122189190613153565b60405180910390fd5b565b600260035403612268576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225f906141ae565b60405180910390fd5b6002600381905550565b61227a611273565b156122ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b190614216565b60405180910390fd5b565b612338848573ffffffffffffffffffffffffffffffffffffffff166323b872dd8686866040516024016122f193929190614234565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612868565b50505050565b6123b8838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401612371929190614269565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612868565b505050565b6001600381905550565b8060015f8463ffffffff1663ffffffff1681526020019081526020015f20819055507f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b828260405161241a9291906135c3565b60405180910390a15050565b61242e612903565b5f60025f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa612470612861565b60405161247d9190613153565b60405180910390a1565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612550612cbf565b5f61255d845f015161294c565b90505f84602001511115612579576125788460200151612999565b5b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff16632637a450826040518060a001604052808b63ffffffff1681526020016125d68c6120f0565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b815260040161261192919061437f565b60806040518083038185885af115801561262d573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906126529190614515565b91505095945050505050565b612666612cee565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff1663ddc28c586040518060a001604052808863ffffffff1681526020016126c2896120f0565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016126f792919061437f565b6040805180830381865afa158015612711573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127359190614540565b9050949350505050565b612747612272565b600160025f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861278a612861565b6040516127979190613153565b60405180910390a1565b606060036040516020016127b591906145ac565b604051602081830303815290604052905090565b606083600361ffff166127e55f83612adf90919063ffffffff16565b61ffff161461283d576128015f82612adf90919063ffffffff16565b6040517f3a51740d00000000000000000000000000000000000000000000000000000000815260040161283491906145d5565b60405180910390fd5b5f6128488585612b44565b905061285686600183612baf565b925050509392505050565b5f33905090565b5f5f60205f8451602086015f885af180612887576040513d5f823e3d81fd5b3d92505f519150505f82146128a05760018114156128bb565b5f8473ffffffffffffffffffffffffffffffffffffffff163b145b156128fd57836040517f5274afe70000000000000000000000000000000000000000000000000000000081526004016128f49190613153565b60405180910390fd5b50505050565b61290b611273565b61294a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161294190614638565b60405180910390fd5b565b5f81341461299157346040517f9f7041200000000000000000000000000000000000000000000000000000000081526004016129889190612d1e565b60405180910390fd5b819050919050565b5f7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b73ffffffffffffffffffffffffffffffffffffffff1663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a03573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a27919061466a565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612a8e576040517f5373352a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612adb337f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b848473ffffffffffffffffffffffffffffffffffffffff166122bc909392919063ffffffff16565b5050565b5f600282612aed9190613ff9565b83511015612b30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b27906146df565b60405180910390fd5b5f8260028501015190508091505092915050565b60605f826fffffffffffffffffffffffffffffffff1614612b86578282604051602001612b72929190614731565b604051602081830303815290604052612ba7565b82604051602001612b97919061475c565b6040516020818303038152906040525b905092915050565b606083600361ffff16612bcb5f83612adf90919063ffffffff16565b61ffff1614612c2357612be75f82612adf90919063ffffffff16565b6040517f3a51740d000000000000000000000000000000000000000000000000000000008152600401612c1a91906145d5565b60405180910390fd5b84600180612c318651612c6a565b612c3b9190614776565b8686604051602001612c5195949392919061480f565b6040516020818303038152906040529150509392505050565b5f61ffff8016821115612cb7576010826040517f6dfcc650000000000000000000000000000000000000000000000000000000008152600401612cae92919061489e565b60405180910390fd5b819050919050565b60405180606001604052805f81526020015f67ffffffffffffffff168152602001612ce8612cee565b81525090565b60405180604001604052805f81526020015f81525090565b5f819050919050565b612d1881612d06565b82525050565b5f602082019050612d315f830184612d0f565b92915050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f60608284031215612d6157612d60612d48565b5b81905092915050565b5f819050919050565b612d7c81612d6a565b8114612d86575f5ffd5b50565b5f81359050612d9781612d73565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112612dbe57612dbd612d9d565b5b8235905067ffffffffffffffff811115612ddb57612dda612da1565b5b602083019150836001820283011115612df757612df6612da5565b5b9250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612e2782612dfe565b9050919050565b612e3781612e1d565b8114612e41575f5ffd5b50565b5f81359050612e5281612e2e565b92915050565b5f5f5f5f5f5f5f60e0888a031215612e7357612e72612d40565b5b5f612e808a828b01612d4c565b9750506060612e918a828b01612d89565b965050608088013567ffffffffffffffff811115612eb257612eb1612d44565b5b612ebe8a828b01612da9565b955095505060a0612ed18a828b01612e44565b93505060c088013567ffffffffffffffff811115612ef257612ef1612d44565b5b612efe8a828b01612da9565b925092505092959891949750929550565b5f67ffffffffffffffff82169050919050565b612f2b81612f0f565b82525050565b5f604082019050612f445f830185612f22565b612f516020830184612f22565b9392505050565b5f63ffffffff82169050919050565b612f7081612f58565b8114612f7a575f5ffd5b50565b5f81359050612f8b81612f67565b92915050565b5f5f60408385031215612fa757612fa6612d40565b5b5f612fb485828601612f7d565b9250506020612fc585828601612e44565b9150509250929050565b612fd881612d06565b8114612fe2575f5ffd5b50565b5f81359050612ff381612fcf565b92915050565b5f5f5f606084860312156130105761300f612d40565b5b5f61301d86828701612fe5565b935050602061302e86828701612e44565b925050604061303f86828701612fe5565b9150509250925092565b5f60ff82169050919050565b61305e81613049565b82525050565b5f6020820190506130775f830184613055565b92915050565b5f5f6040838503121561309357613092612d40565b5b5f6130a085828601612f7d565b92505060206130b185828601612d89565b9150509250929050565b5f602082840312156130d0576130cf612d40565b5b5f6130dd84828501612fe5565b91505092915050565b5f8115159050919050565b6130fa816130e6565b82525050565b5f6020820190506131135f8301846130f1565b92915050565b5f6020828403121561312e5761312d612d40565b5b5f61313b84828501612d89565b91505092915050565b61314d81612e1d565b82525050565b5f6020820190506131665f830184613144565b92915050565b5f819050919050565b5f61318f61318a61318584612dfe565b61316c565b612dfe565b9050919050565b5f6131a082613175565b9050919050565b5f6131b182613196565b9050919050565b6131c1816131a7565b82525050565b5f6020820190506131da5f8301846131b8565b92915050565b5f5f604083850312156131f6576131f5612d40565b5b5f61320385828601612e44565b925050602061321485828601612fe5565b9150509250929050565b5f6020828403121561323357613232612d40565b5b5f61324084828501612e44565b91505092915050565b5f5f6040838503121561325f5761325e612d40565b5b5f61326c85828601612e44565b925050602061327d85828601612e44565b9150509250929050565b5f60208201905061329a5f830184612f22565b92915050565b5f5f5f5f606085870312156132b8576132b7612d40565b5b5f6132c587828801612fe5565b94505060206132d687828801612f7d565b935050604085013567ffffffffffffffff8111156132f7576132f6612d44565b5b61330387828801612da9565b925092505092959194509250565b5f5f5f5f6060858703121561332957613328612d40565b5b5f61333687828801612f7d565b945050602061334787828801612fe5565b935050604085013567ffffffffffffffff81111561336857613367612d44565b5b61337487828801612da9565b925092505092959194509250565b5f5f5f5f60a0858703121561339a57613399612d40565b5b5f6133a787828801612d4c565b945050606085013567ffffffffffffffff8111156133c8576133c7612d44565b5b6133d487828801612da9565b935093505060806133e787828801612e44565b91505092959194509250565b6133fc81612d6a565b82525050565b5f6020820190506134155f8301846133f3565b92915050565b5f602082840312156134305761342f612d40565b5b5f61343d84828501612f7d565b91505092915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b61346a81613446565b8114613474575f5ffd5b50565b5f8135905061348581613461565b92915050565b5f602082840312156134a05761349f612d40565b5b5f6134ad84828501613477565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6134f8826134b6565b61350281856134c0565b93506135128185602086016134d0565b61351b816134de565b840191505092915050565b5f6020820190508181035f83015261353e81846134ee565b905092915050565b5f6080820190506135595f830187612d0f565b6135666020830186612d0f565b61357360408301856130f1565b6135806060830184613144565b95945050505050565b5f6060828403121561359e5761359d612d40565b5b5f6135ab84828501612d4c565b91505092915050565b6135bd81612f58565b82525050565b5f6040820190506135d65f8301856135b4565b6135e360208301846133f3565b9392505050565b5f82825260208201905092915050565b7f4e6f206e617469766520636f696e2073656e74000000000000000000000000005f82015250565b5f61362e6013836135ea565b9150613639826135fa565b602082019050919050565b5f6020820190508181035f83015261365b81613622565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61369982612d06565b91506136a483612d06565b92508282026136b281612d06565b915082820484148315176136c9576136c8613662565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61370782612d06565b915061371283612d06565b925082613722576137216136d0565b5b828204905092915050565b5f61373782612d06565b915061374283612d06565b925082820390508181111561375a57613759613662565b5b92915050565b5f81905092915050565b50565b5f6137785f83613760565b91506137838261376a565b5f82019050919050565b5f6137978261376d565b9150819050919050565b7f466565207472616e73666572206661696c6564000000000000000000000000005f82015250565b5f6137d56013836135ea565b91506137e0826137a1565b602082019050919050565b5f6020820190508181035f830152613802816137c9565b9050919050565b7f5661756c74207472616e73666572206661696c656400000000000000000000005f82015250565b5f61383d6015836135ea565b915061384882613809565b602082019050919050565b5f6020820190508181035f83015261386a81613831565b9050919050565b5f61387b82612d06565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036138ad576138ac613662565b5b600182019050919050565b5f6040820190506138cb5f830185612d0f565b6138d86020830184612d0f565b9392505050565b7f546f6b656e206e6f7420737570706f72746564000000000000000000000000005f82015250565b5f6139136013836135ea565b915061391e826138df565b602082019050919050565b5f6020820190508181035f83015261394081613907565b9050919050565b7f446f6e6174696f6e206d757374206265203e20300000000000000000000000005f82015250565b5f61397b6014836135ea565b915061398682613947565b602082019050919050565b5f6020820190508181035f8301526139a88161396f565b9050919050565b7f46656520746f6f206869676800000000000000000000000000000000000000005f82015250565b5f6139e3600c836135ea565b91506139ee826139af565b602082019050919050565b5f6020820190508181035f830152613a10816139d7565b9050919050565b7f50726963652066656564206e6f742073657420666f7220746f6b656e000000005f82015250565b5f613a4b601c836135ea565b9150613a5682613a17565b602082019050919050565b5f6020820190508181035f830152613a7881613a3f565b9050919050565b5f69ffffffffffffffffffff82169050919050565b613a9d81613a7f565b8114613aa7575f5ffd5b50565b5f81519050613ab881613a94565b92915050565b5f819050919050565b613ad081613abe565b8114613ada575f5ffd5b50565b5f81519050613aeb81613ac7565b92915050565b5f81519050613aff81612fcf565b92915050565b5f5f5f5f5f60a08688031215613b1e57613b1d612d40565b5b5f613b2b88828901613aaa565b9550506020613b3c88828901613add565b9450506040613b4d88828901613af1565b9350506060613b5e88828901613af1565b9250506080613b6f88828901613aaa565b9150509295509295909350565b7f496e76616c6964207072696365000000000000000000000000000000000000005f82015250565b5f613bb0600d836135ea565b9150613bbb82613b7c565b602082019050919050565b5f6020820190508181035f830152613bdd81613ba4565b9050919050565b613bed81613049565b8114613bf7575f5ffd5b50565b5f81519050613c0881613be4565b92915050565b5f60208284031215613c2357613c22612d40565b5b5f613c3084828501613bfa565b91505092915050565b5f8160011c9050919050565b5f5f8291508390505b6001851115613c8e57808604811115613c6a57613c69613662565b5b6001851615613c795780820291505b8081029050613c8785613c39565b9450613c4e565b94509492505050565b5f82613ca65760019050613d61565b81613cb3575f9050613d61565b8160018114613cc95760028114613cd357613d02565b6001915050613d61565b60ff841115613ce557613ce4613662565b5b8360020a915084821115613cfc57613cfb613662565b5b50613d61565b5060208310610133831016604e8410600b8410161715613d375782820a905083811115613d3257613d31613662565b5b613d61565b613d448484846001613c45565b92509050818404811115613d5b57613d5a613662565b5b81810290505b9392505050565b5f613d7282612d06565b9150613d7d83613049565b9250613daa7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484613c97565b905092915050565b7f496e76616c6964206665652077616c6c657400000000000000000000000000005f82015250565b5f613de66012836135ea565b9150613df182613db2565b602082019050919050565b5f6020820190508181035f830152613e1381613dda565b9050919050565b7f496e76616c6964207072696365206665656420616464726573730000000000005f82015250565b5f613e4e601a836135ea565b9150613e5982613e1a565b602082019050919050565b5f6020820190508181035f830152613e7b81613e42565b9050919050565b7f5072696365206665656420616c72656164792073657420666f722074686973205f8201527f746f6b656e000000000000000000000000000000000000000000000000000000602082015250565b5f613edc6025836135ea565b9150613ee782613e82565b604082019050919050565b5f6020820190508181035f830152613f0981613ed0565b9050919050565b7f446f6e6174696f6e20616c72656164792072656c6179656400000000000000005f82015250565b5f613f446018836135ea565b9150613f4f82613f10565b602082019050919050565b5f6020820190508181035f830152613f7181613f38565b9050919050565b5f602082019050613f8b5f8301846135b4565b92915050565b7f4e617469766520636f696e2070726963652066656564206e6f742073657400005f82015250565b5f613fc5601e836135ea565b9150613fd082613f91565b602082019050919050565b5f6020820190508181035f830152613ff281613fb9565b9050919050565b5f61400382612d06565b915061400e83612d06565b925082820190508082111561402657614025613662565b5b92915050565b7f4661696c656420746f2073656e64206e617469766520636f696e0000000000005f82015250565b5f614060601a836135ea565b915061406b8261402c565b602082019050919050565b5f6020820190508181035f83015261408d81614054565b9050919050565b7f496e76616c6964207661756c742077616c6c65740000000000000000000000005f82015250565b5f6140c86014836135ea565b91506140d382614094565b602082019050919050565b5f6020820190508181035f8301526140f5816140bc565b9050919050565b7f4e6f7420696d706c656d656e74656400000000000000000000000000000000005f82015250565b5f614130600f836135ea565b915061413b826140fc565b602082019050919050565b5f6020820190508181035f83015261415d81614124565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f614198601f836135ea565b91506141a382614164565b602082019050919050565b5f6020820190508181035f8301526141c58161418c565b9050919050565b7f5061757361626c653a20706175736564000000000000000000000000000000005f82015250565b5f6142006010836135ea565b915061420b826141cc565b602082019050919050565b5f6020820190508181035f83015261422d816141f4565b9050919050565b5f6060820190506142475f830186613144565b6142546020830185613144565b6142616040830184612d0f565b949350505050565b5f60408201905061427c5f830185613144565b6142896020830184612d0f565b9392505050565b61429981612f58565b82525050565b6142a881612d6a565b82525050565b5f82825260208201905092915050565b5f6142c8826134b6565b6142d281856142ae565b93506142e28185602086016134d0565b6142eb816134de565b840191505092915050565b6142ff816130e6565b82525050565b5f60a083015f83015161431a5f860182614290565b50602083015161432d602086018261429f565b506040830151848203604086015261434582826142be565b9150506060830151848203606086015261435f82826142be565b915050608083015161437460808601826142f6565b508091505092915050565b5f6040820190508181035f8301526143978185614305565b90506143a66020830184613144565b9392505050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6143e7826134de565b810181811067ffffffffffffffff82111715614406576144056143b1565b5b80604052505050565b5f614418612d37565b905061442482826143de565b919050565b5f8151905061443781612d73565b92915050565b61444681612f0f565b8114614450575f5ffd5b50565b5f815190506144618161443d565b92915050565b5f6040828403121561447c5761447b6143ad565b5b614486604061440f565b90505f61449584828501613af1565b5f8301525060206144a884828501613af1565b60208301525092915050565b5f608082840312156144c9576144c86143ad565b5b6144d3606061440f565b90505f6144e284828501614429565b5f8301525060206144f584828501614453565b602083015250604061450984828501614467565b60408301525092915050565b5f6080828403121561452a57614529612d40565b5b5f614537848285016144b4565b91505092915050565b5f6040828403121561455557614554612d40565b5b5f61456284828501614467565b91505092915050565b5f61ffff82169050919050565b5f8160f01b9050919050565b5f61458e82614578565b9050919050565b6145a66145a18261456b565b614584565b82525050565b5f6145b78284614595565b60028201915081905092915050565b6145cf8161456b565b82525050565b5f6020820190506145e85f8301846145c6565b92915050565b7f5061757361626c653a206e6f74207061757365640000000000000000000000005f82015250565b5f6146226014836135ea565b915061462d826145ee565b602082019050919050565b5f6020820190508181035f83015261464f81614616565b9050919050565b5f8151905061466481612e2e565b92915050565b5f6020828403121561467f5761467e612d40565b5b5f61468c84828501614656565b91505092915050565b7f746f55696e7431365f6f75744f66426f756e64730000000000000000000000005f82015250565b5f6146c96014836135ea565b91506146d482614695565b602082019050919050565b5f6020820190508181035f8301526146f6816146bd565b9050919050565b5f8160801b9050919050565b5f614713826146fd565b9050919050565b61472b61472682613446565b614709565b82525050565b5f61473c828561471a565b60108201915061474c828461471a565b6010820191508190509392505050565b5f614767828461471a565b60108201915081905092915050565b5f6147808261456b565b915061478b8361456b565b9250828201905061ffff8111156147a5576147a4613662565b5b92915050565b5f6147b5826134b6565b6147bf8185613760565b93506147cf8185602086016134d0565b80840191505092915050565b5f8160f81b9050919050565b5f6147f1826147db565b9050919050565b61480961480482613049565b6147e7565b82525050565b5f61481a82886147ab565b915061482682876147f8565b6001820191506148368286614595565b60028201915061484682856147f8565b60018201915061485682846147ab565b91508190509695505050505050565b5f819050919050565b5f61488861488361487e84614865565b61316c565b613049565b9050919050565b6148988161486e565b82525050565b5f6040820190506148b15f83018561488f565b6148be6020830184612d0f565b939250505056fea264697066735822122059aefbfa9e58854b60580180251b10bd19b5ac21ff130a8b17361592b5c1247c64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b00000000000000000000000014ce936fcc154fecc38f9920d937827045f8162800000000000000000000000001cc205772d08cfe45a870df1366b4c6ac408f44000000000000000000000000000000000000000000000000000000000000000e
-----Decoded View---------------
Arg [0] : _endpoint (address): 0x6F475642a6e85809B1c36Fa62763669b1b48DD5B
Arg [1] : _feeWallet (address): 0x14ce936Fcc154FECC38F9920d937827045F81628
Arg [2] : _vaultWallet (address): 0x01Cc205772D08Cfe45A870dF1366B4c6AC408f44
Arg [3] : _feeBasisPoints (uint256): 14
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b
Arg [1] : 00000000000000000000000014ce936fcc154fecc38f9920d937827045f81628
Arg [2] : 00000000000000000000000001cc205772d08cfe45a870df1366b4c6ac408f44
Arg [3] : 000000000000000000000000000000000000000000000000000000000000000e
Deployed Bytecode Sourcemap
136849:9536:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;138047:51;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47469:723;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49708:243;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;140054:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;141591:2329;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137530:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137814:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34324:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;140941:67;;;;;;;;;;;;;:::i;:::-;;139389:261;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;131159:86;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;140603:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33017:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;144706:585;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137918:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;138741:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;29995:103;;;;;;;;;;;;;:::i;:::-;;139700:346;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46591:130;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;144006:640;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;138140:51;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;145299:501;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;141143:438;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45065:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;140464:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;140801:63;;;;;;;;;;;;;:::i;:::-;;29320:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;146019:326;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137987:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33143:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;140285:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35889:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;139052:239;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137887:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30253:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137696:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;45840:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;138047:51;138094:4;138047:51;:::o;47469:723::-;47803:10;47782:31;;47790:8;47782:31;;;47778:68;;47835:10;47822:24;;;;;;;;;;;:::i;:::-;;;;;;;;47778:68;47985:7;:14;;;47949:32;47966:7;:14;;;;;;;;;;:::i;:::-;47949:16;:32::i;:::-;:50;47945:103;;48017:7;:14;;;;;;;;;;:::i;:::-;48033:7;:14;;;48008:40;;;;;;;;;;;;:::i;:::-;;;;;;;;47945:103;48125:59;48136:7;48145:5;48152:8;;48162:9;48173:10;;48125;:59::i;:::-;47469:723;;;;;;;:::o;49708:243::-;49840:20;49862:22;36620:1;43702;49902:41;;;;49708:243;;:::o;140054:223::-;29206:13;:11;:13::i;:::-;140136:17:::1;140180:12;140164:30;;140156:39;;140136:59;;140220:9;140206:5;:11;140212:4;140206:11;;;;;;;;;;;;;;;:23;;;;140245:24;140253:4;140259:9;140245:24;;;;;;;:::i;:::-;;;;;;;;140125:152;140054:223:::0;;:::o;141591:2329::-;141711:18;134486:21;:19;:21::i;:::-;130764:19:::1;:17;:19::i;:::-;141741:16:::2;141789:1;141772:19;;:5;:19;;::::0;141768:2117:::2;;141873:1;141861:9;:13;141853:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;141924:29;141943:9;141924:18;:29::i;:::-;141913:40;;141968:14;138094:4;141997:14;;141986:8;:25;;;;:::i;:::-;141985:50;;;;:::i;:::-;141968:67;;142050:14;142078:6;142067:8;:17;;;;:::i;:::-;142050:34;;142100:12;142118:9;;;;;;;;;;;:14;;138094:4;142153:14;;142141:9;:26;;;;:::i;:::-;142140:51;;;;:::i;:::-;142118:78;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;142099:97;;;142219:7;142211:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;142266:14;142286:11;;;;;;;;;;;:16;;138094:4;142336:14;;142324:9;:26;;;;:::i;:::-;142323:51;;;;:::i;:::-;142310:9;:65;;;;:::i;:::-;142286:94;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;142265:115;;;142403:9;142395:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;142453:13;;:15;;;;;;;;;:::i;:::-;;;;;;142496:13;;142483:26;;142548:168;;;;;;;;142588:10;142548:168;;;;142625:6;142548:168;;;;142659:5;142548:168;;;;;;142690:10;142548:168;;;;::::0;142524:9:::2;:21;142534:10;142524:21;;;;;;;;;;;:192;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;142773:10;142736:56;;142749:10;142736:56;142761:10;142785:6;142736:56;;;;;;;:::i;:::-;;;;;;;;141793:1011;;;;141768:2117;;;142907:1;142872:37;;:16;:23;142889:5;142872:23;;;;;;;;;;;;;;;;;;;;;;;;;:37;;::::0;142864:69:::2;;;;;;;;;;;;:::i;:::-;;;;;;;;;142965:1;142956:6;:10;142948:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;143006:65;143037:10;143057:4;143064:6;143013:5;143006:30;;;;:65;;;;;;:::i;:::-;143097:32;143115:5;143122:6;143097:17;:32::i;:::-;143086:43;;143144:16;138094:4;143173:14;;143164:6;:23;;;;:::i;:::-;143163:48;;;;:::i;:::-;143144:67;;143226:16;143254:8;143245:6;:17;;;;:::i;:::-;143226:36;;143277:47;143304:9;;;;;;;;;;;143315:8;143284:5;143277:26;;;;:47;;;;;:::i;:::-;143339:49;143366:11;;;;;;;;;;;143379:8;143346:5;143339:26;;;;:49;;;;;:::i;:::-;143403:14;138094:4;143432:14;;143421:8;:25;;;;:::i;:::-;143420:50;;;;:::i;:::-;143403:67;;143485:14;143513:6;143502:8;:17;;;;:::i;:::-;143485:34;;143534:13;;:15;;;;;;;;;:::i;:::-;;;;;;143577:13;;143564:26;;143629:168;;;;;;;;143669:10;143629:168;;;;143706:6;143629:168;;;;143740:5;143629:168;;;;;;143771:10;143629:168;;;;::::0;143605:9:::2;:21;143615:10;143605:21;;;;;;;;;;;:192;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;143854:10;143817:56;;143830:10;143817:56;143842:10;143866:6;143817:56;;;;;;;:::i;:::-;;;;;;;;142810:1075;;;;141768:2117;143895:17;134530:20:::0;:18;:20::i;:::-;141591:2329;;;;;:::o;137530:28::-;;;;:::o;137814:38::-;137851:1;137814:38;:::o;34324:110::-;29206:13;:11;:13::i;:::-;34405:21:::1;34414:4;34420:5;34405:8;:21::i;:::-;34324:110:::0;;:::o;140941:67::-;29206:13;:11;:13::i;:::-;140990:10:::1;:8;:10::i;:::-;140941:67::o:0;139389:261::-;29206:13;:11;:13::i;:::-;138094:4:::1;139484:17;:40;139476:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;139569:17;139552:14;:34;;;;139602:40;139624:17;139602:40;;;;;;:::i;:::-;;;;;;;;139389:261:::0;:::o;131159:86::-;131206:4;131230:7;;;;;;;;;;;131223:14;;131159:86;:::o;140603:123::-;140662:7;140713:2;140705:11;;140682:36;;140603:123;;;:::o;33017:46::-;;;:::o;144706:585::-;144790:16;144819:24;144846:16;:23;144863:5;144846:23;;;;;;;;;;;;;;;;;;;;;;;;;144819:50;;144916:1;144888:30;;:16;:30;;;144880:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;144962:31;145018:16;144962:73;;145049:12;145071:9;:25;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;145046:52;;;;;;145125:1;145117:5;:9;145109:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;145155:19;145192:5;145177:30;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;145155:54;;145269:13;145265:2;:17;;;;:::i;:::-;145254:5;145232:11;:28;;;;:::i;:::-;145231:52;;;;:::i;:::-;145220:63;;144808:483;;;;144706:585;;;;:::o;137918:26::-;;;;;;;;;;;;;:::o;138741:223::-;29206:13;:11;:13::i;:::-;138850:1:::1;138826:26;;:12;:26;;::::0;138818:57:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;138898:12;138886:9;;:24;;;;;;;;;;;;;;;;;;138943:12;138926:30;;;;;;;;;;;;138741:223:::0;:::o;29995:103::-;29206:13;:11;:13::i;:::-;30060:30:::1;30087:1;30060:18;:30::i;:::-;29995:103::o:0;139700:346::-;29206:13;:11;:13::i;:::-;139815:1:::1;139794:23;;:9;:23;;::::0;139786:62:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;139902:1;139867:37;;:16;:23;139884:5;139867:23;;;;;;;;;;;;;;;;;;;;;;;;;:37;;;139859:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;139983:9;139957:16;:23;139974:5;139957:23;;;;;;;;;;;;;;;;:35;;;;;;;;;;;;;;;;;;140021:5;140008:30;;;140028:9;140008:30;;;;;;:::i;:::-;;;;;;;;139700:346:::0;;:::o;46591:130::-;46680:12;46712:1;46705:8;;46591:130;;;;:::o;144006:640::-;134486:21;:19;:21::i;:::-;144175:25:::1;144203:9;:21;144213:10;144203:21;;;;;;;;;;;144175:49;;144244:8;:16;;;;;;;;;;;;144243:17;144235:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;144300:20;144334:8;:19;;;144355:8;:15;;;144323:48;;;;;;;;;:::i;:::-;;;;;;;;;;;;;144300:71;;144392:160;144414:7;144436;144458:8;;144392:160;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;144481:26;;;;;;;;144494:9;144481:26;;;;144505:1;144481:26;;::::0;144530:10:::1;144392:7;:160::i;:::-;;144582:4;144563:8;:16;;;:23;;;;;;;;;;;;;;;;;;144618:10;144602:36;144630:7;144602:36;;;;;;:::i;:::-;;;;;;;;144163:483;;134530:20:::0;:18;:20::i;:::-;144006:640;;;;:::o;138140:51::-;;;;;;;;;;;;;;;;;;;;;;:::o;145299:501::-;145370:16;145399:24;145426:16;:28;145451:1;145426:28;;;;;;;;;;;;;;;;;;;;;;;;;145399:55;;145502:1;145474:30;;:16;:30;;;145465:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;145550:31;145606:16;145550:73;;145637:12;145659:9;:25;;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;145634:52;;;;;;145713:1;145705:5;:9;145697:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;145788:4;145778:5;145755:12;:29;;;;:::i;:::-;145754:38;;;;:::i;:::-;145743:49;;145388:412;;;145299:501;;;:::o;141143:438::-;141245:17;141275;141295:5;141275:25;;141311:24;141338:10;141311:37;;141359:20;141393:10;141405:16;141382:40;;;;;;;;;:::i;:::-;;;;;;;;;;;;;141359:63;;141433:23;141459:49;141467:7;141476;141485:8;;141459:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;141495:12;141459:6;:49::i;:::-;141433:75;;141570:2;141565:1;141549:3;:13;;;:17;;;;:::i;:::-;141548:24;;;;:::i;:::-;141531:3;:13;;;:42;;;;:::i;:::-;141519:54;;141264:317;;;;141143:438;;;;;;:::o;45065:222::-;45231:4;45274;45255:24;;:7;:24;;;45248:31;;45065:222;;;;;;:::o;140464:129::-;140526:7;140577:5;140561:23;;140553:32;;140546:39;;140464:129;;;:::o;140801:63::-;29206:13;:11;:13::i;:::-;140848:8:::1;:6;:8::i;:::-;140801:63::o:0;29320:87::-;29366:7;29393:6;;;;;;;;;;;29386:13;;29320:87;:::o;146019:326::-;29206:13;:11;:13::i;:::-;146126:1:::1;146109:19;;:5;:19;;::::0;146105:233:::1;;146146:9;146161:7;:5;:7::i;:::-;:12;;146181:6;146161:31;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;146145:47;;;146215:4;146207:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;146130:132;146105:233;;;146283:43;146310:7;:5;:7::i;:::-;146319:6;146290:5;146283:26;;;;:43;;;;;:::i;:::-;146105:233;146019:326:::0;;:::o;137987:29::-;;;;:::o;33143:48::-;;;;;;;;;;;;;;;;;:::o;140285:171::-;140349:12;140381:67;140436:8;140446:1;140381:27;:25;:27::i;:::-;:54;;:67;;;;;:::i;:::-;140374:74;;140285:171;;;:::o;35889:107::-;29206:13;:11;:13::i;:::-;35957:8:::1;:20;;;35978:9;35957:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35889:107:::0;:::o;139052:239::-;29206:13;:11;:13::i;:::-;139167:1:::1;139141:28;;:14;:28;;::::0;139133:61:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;139219:14;139205:11;;:28;;;;;;;;;;;;;;;;;;139268:14;139249:34;;;;;;;;;;;;139052:239:::0;:::o;137887:24::-;;;;;;;;;;;;;:::o;30253:220::-;29206:13;:11;:13::i;:::-;30358:1:::1;30338:22;;:8;:22;;::::0;30334:93:::1;;30412:1;30384:31;;;;;;;;;;;:::i;:::-;;;;;;;;30334:93;30437:28;30456:8;30437:18;:28::i;:::-;30253:220:::0;:::o;137696:45::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;45840:151::-;45922:4;45970:6;:13;;;45946:5;:20;45952:6;:13;;;;;;;;;;:::i;:::-;45946:20;;;;;;;;;;;;;;;;:37;45939:44;;45840:151;;;:::o;35342:200::-;35412:7;35432:12;35447:5;:11;35453:4;35447:11;;;;;;;;;;;;;;;;35432:26;;35489:1;35481:10;;35473:4;:18;35469:43;;35507:4;35500:12;;;;;;;;;;;:::i;:::-;;;;;;;;35469:43;35530:4;35523:11;;;35342:200;;;:::o;145808:156::-;145931:25;;;;;;;;;;:::i;:::-;;;;;;;;29485:166;29556:12;:10;:12::i;:::-;29545:23;;:7;:5;:7::i;:::-;:23;;;29541:103;;29619:12;:10;:12::i;:::-;29592:40;;;;;;;;;;;:::i;:::-;;;;;;;;29541:103;29485:166::o;134566:293::-;133968:1;134700:7;;:19;134692:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;133968:1;134833:7;:18;;;;134566:293::o;131318:108::-;131389:8;:6;:8::i;:::-;131388:9;131380:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;131318:108::o;10248:190::-;10349:81;10369:5;10391;:18;;;10412:4;10418:2;10422:5;10376:53;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10349:19;:81::i;:::-;10248:190;;;;:::o;9841:162::-;9924:71;9944:5;9966;:14;;;9983:2;9987:5;9951:43;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9924:19;:71::i;:::-;9841:162;;;:::o;134867:213::-;133924:1;135050:7;:22;;;;134867:213::o;34899:137::-;34987:5;34973;:11;34979:4;34973:11;;;;;;;;;;;;;;;:19;;;;35008:20;35016:4;35022:5;35008:20;;;;;;;:::i;:::-;;;;;;;;34899:137;;:::o;132014:120::-;131023:16;:14;:16::i;:::-;132083:5:::1;132073:7;;:15;;;;;;;;;;;;;;;;;;132104:22;132113:12;:10;:12::i;:::-;132104:22;;;;;;:::i;:::-;;;;;;;;132014:120::o:0;30633:191::-;30707:16;30726:6;;;;;;;;;;;30707:25;;30752:8;30743:6;;:17;;;;;;;;;;;;;;;;;;30807:8;30776:40;;30797:8;30776:40;;;;;;;;;;;;30696:128;30633:191;:::o;39017:783::-;39224:31;;:::i;:::-;39391:20;39414:26;39425:4;:14;;;39414:10;:26::i;:::-;39391:49;;39473:1;39455:4;:15;;;:19;39451:53;;;39476:28;39488:4;:15;;;39476:11;:28::i;:::-;39451:53;39597:8;:13;;;39619:12;39652:92;;;;;;;;39668:7;39652:92;;;;;;39677:25;39694:7;39677:16;:25::i;:::-;39652:92;;;;39704:8;39652:92;;;;39714:8;39652:92;;;;39742:1;39724:4;:15;;;:19;39652:92;;;;;39763:14;39597:195;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39517:275;;;39017:783;;;;;;;:::o;37840:402::-;38012:23;;:::i;:::-;38068:8;:14;;;38101:86;;;;;;;;38117:7;38101:86;;;;;;38126:25;38143:7;38126:16;:25::i;:::-;38101:86;;;;38153:8;38101:86;;;;38163:8;38101:86;;;;38173:13;38101:86;;;;;38214:4;38068:166;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38048:186;;37840:402;;;;;;:::o;131755:118::-;130764:19;:17;:19::i;:::-;131825:4:::1;131815:7;;:14;;;;;;;;;;;;;;;;;;131845:20;131852:12;:10;:12::i;:::-;131845:20;;;;;;:::i;:::-;;;;;;;;131755:118::o:0;121313:109::-;121358:12;120811:1;121390:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;121383:31;;121313:109;:::o;122126:364::-;122292:12;122273:8;120811:1;121070:30;;:20;121088:1;121070:8;:17;;:20;;;;:::i;:::-;:30;;;121066:82;;121127:20;121145:1;121127:8;:17;;:20;;;;:::i;:::-;121109:39;;;;;;;;;;;:::i;:::-;;;;;;;;121066:82;122317:19:::1;122339:51;122377:4;122383:6;122339:37;:51::i;:::-;122317:73;;122408:74;122426:8;108072:1;122475:6;122408:17;:74::i;:::-;122401:81;;;122126:364:::0;;;;;;:::o;27329:98::-;27382:7;27409:10;27402:17;;27329:98;:::o;16434:738::-;16515:18;16544:19;16684:4;16681:1;16674:4;16668:11;16661:4;16655;16651:15;16648:1;16641:5;16634;16629:60;16743:7;16733:180;;16788:4;16782:11;16834:16;16831:1;16826:3;16811:40;16881:16;16876:3;16869:29;16733:180;16941:16;16927:30;;16992:1;16986:8;16971:23;;16599:406;17035:1;17021:10;:15;:68;;17088:1;17073:11;:16;;17021:68;;;17069:1;17047:5;17039:26;;;:31;17021:68;17017:148;;;17146:5;17113:40;;;;;;;;;;;:::i;:::-;;;;;;;;17017:148;16504:668;;16434:738;;:::o;131503:108::-;131570:8;:6;:8::i;:::-;131562:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;131503:108::o;40509:194::-;40575:17;40622:10;40609:9;:23;40605:62;;40657:9;40641:26;;;;;;;;;;;:::i;:::-;;;;;;;;40605:62;40685:10;40678:17;;40509:194;;;:::o;41089:417::-;41244:15;41262:8;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41244:36;;41314:1;41295:21;;:7;:21;;;41291:54;;41325:20;;;;;;;;;;;;;;41291:54;41422:76;41455:10;41475:8;41486:11;41429:7;41422:32;;;;:76;;;;;;:::i;:::-;41148:358;41089:417;:::o;63230:314::-;63308:6;63361:1;63352:6;:10;;;;:::i;:::-;63335:6;:13;:27;;63327:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;63398:15;63490:6;63484:3;63476:6;63472:16;63468:29;63462:36;63450:48;;63528:8;63521:15;;;63230:314;;;;:::o;111299:193::-;111383:12;111425:1;111415:6;:11;;;:69;;111471:4;111477:6;111454:30;;;;;;;;;:::i;:::-;;;;;;;;;;;;;111415:69;;;111446:4;111429:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;111415:69;111408:76;;111299:193;;;;:::o;126735:448::-;126903:12;126884:8;120811:1;121070:30;;:20;121088:1;121070:8;:17;;:20;;;;:::i;:::-;:30;;;121066:82;;121127:20;121145:1;121127:8;:17;;:20;;;;:::i;:::-;121109:39;;;;;;;;;;;:::i;:::-;;;;;;;;121066:82;126983:8:::1;108014:1;127082::::0;127054:25:::1;:7;:14;:23;:25::i;:::-;:29;;;;:::i;:::-;127123:11;127153:7;126948:227;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;126928:247;;126735:448:::0;;;;;;:::o;86631:218::-;86687:6;86718:16;86710:24;;:5;:24;86706:105;;;86789:2;86793:5;86758:41;;;;;;;;;;;;:::i;:::-;;;;;;;;86706:105;86835:5;86821:20;;86631:218;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:75::-;475:6;508:2;502:9;492:19;;442:75;:::o;523:117::-;632:1;629;622:12;646:117;755:1;752;745:12;769:117;878:1;875;868:12;913:230;985:5;1026:2;1017:6;1012:3;1008:16;1004:25;1001:112;;;1032:79;;:::i;:::-;1001:112;1131:6;1122:15;;913:230;;;;:::o;1149:77::-;1186:7;1215:5;1204:16;;1149:77;;;:::o;1232:122::-;1305:24;1323:5;1305:24;:::i;:::-;1298:5;1295:35;1285:63;;1344:1;1341;1334:12;1285:63;1232:122;:::o;1360:139::-;1406:5;1444:6;1431:20;1422:29;;1460:33;1487:5;1460:33;:::i;:::-;1360:139;;;;:::o;1505:117::-;1614:1;1611;1604:12;1628:117;1737:1;1734;1727:12;1751:117;1860:1;1857;1850:12;1887:552;1944:8;1954:6;2004:3;1997:4;1989:6;1985:17;1981:27;1971:122;;2012:79;;:::i;:::-;1971:122;2125:6;2112:20;2102:30;;2155:18;2147:6;2144:30;2141:117;;;2177:79;;:::i;:::-;2141:117;2291:4;2283:6;2279:17;2267:29;;2345:3;2337:4;2329:6;2325:17;2315:8;2311:32;2308:41;2305:128;;;2352:79;;:::i;:::-;2305:128;1887:552;;;;;:::o;2445:126::-;2482:7;2522:42;2515:5;2511:54;2500:65;;2445:126;;;:::o;2577:96::-;2614:7;2643:24;2661:5;2643:24;:::i;:::-;2632:35;;2577:96;;;:::o;2679:122::-;2752:24;2770:5;2752:24;:::i;:::-;2745:5;2742:35;2732:63;;2791:1;2788;2781:12;2732:63;2679:122;:::o;2807:139::-;2853:5;2891:6;2878:20;2869:29;;2907:33;2934:5;2907:33;:::i;:::-;2807:139;;;;:::o;2952:1361::-;3095:6;3103;3111;3119;3127;3135;3143;3192:3;3180:9;3171:7;3167:23;3163:33;3160:120;;;3199:79;;:::i;:::-;3160:120;3319:1;3344:79;3415:7;3406:6;3395:9;3391:22;3344:79;:::i;:::-;3334:89;;3290:143;3472:2;3498:53;3543:7;3534:6;3523:9;3519:22;3498:53;:::i;:::-;3488:63;;3443:118;3628:3;3617:9;3613:19;3600:33;3660:18;3652:6;3649:30;3646:117;;;3682:79;;:::i;:::-;3646:117;3795:64;3851:7;3842:6;3831:9;3827:22;3795:64;:::i;:::-;3777:82;;;;3571:298;3908:3;3935:53;3980:7;3971:6;3960:9;3956:22;3935:53;:::i;:::-;3925:63;;3879:119;4065:3;4054:9;4050:19;4037:33;4097:18;4089:6;4086:30;4083:117;;;4119:79;;:::i;:::-;4083:117;4232:64;4288:7;4279:6;4268:9;4264:22;4232:64;:::i;:::-;4214:82;;;;4008:298;2952:1361;;;;;;;;;;:::o;4319:101::-;4355:7;4395:18;4388:5;4384:30;4373:41;;4319:101;;;:::o;4426:115::-;4511:23;4528:5;4511:23;:::i;:::-;4506:3;4499:36;4426:115;;:::o;4547:324::-;4664:4;4702:2;4691:9;4687:18;4679:26;;4715:69;4781:1;4770:9;4766:17;4757:6;4715:69;:::i;:::-;4794:70;4860:2;4849:9;4845:18;4836:6;4794:70;:::i;:::-;4547:324;;;;;:::o;4877:93::-;4913:7;4953:10;4946:5;4942:22;4931:33;;4877:93;;;:::o;4976:120::-;5048:23;5065:5;5048:23;:::i;:::-;5041:5;5038:34;5028:62;;5086:1;5083;5076:12;5028:62;4976:120;:::o;5102:137::-;5147:5;5185:6;5172:20;5163:29;;5201:32;5227:5;5201:32;:::i;:::-;5102:137;;;;:::o;5245:472::-;5312:6;5320;5369:2;5357:9;5348:7;5344:23;5340:32;5337:119;;;5375:79;;:::i;:::-;5337:119;5495:1;5520:52;5564:7;5555:6;5544:9;5540:22;5520:52;:::i;:::-;5510:62;;5466:116;5621:2;5647:53;5692:7;5683:6;5672:9;5668:22;5647:53;:::i;:::-;5637:63;;5592:118;5245:472;;;;;:::o;5723:122::-;5796:24;5814:5;5796:24;:::i;:::-;5789:5;5786:35;5776:63;;5835:1;5832;5825:12;5776:63;5723:122;:::o;5851:139::-;5897:5;5935:6;5922:20;5913:29;;5951:33;5978:5;5951:33;:::i;:::-;5851:139;;;;:::o;5996:619::-;6073:6;6081;6089;6138:2;6126:9;6117:7;6113:23;6109:32;6106:119;;;6144:79;;:::i;:::-;6106:119;6264:1;6289:53;6334:7;6325:6;6314:9;6310:22;6289:53;:::i;:::-;6279:63;;6235:117;6391:2;6417:53;6462:7;6453:6;6442:9;6438:22;6417:53;:::i;:::-;6407:63;;6362:118;6519:2;6545:53;6590:7;6581:6;6570:9;6566:22;6545:53;:::i;:::-;6535:63;;6490:118;5996:619;;;;;:::o;6621:86::-;6656:7;6696:4;6689:5;6685:16;6674:27;;6621:86;;;:::o;6713:112::-;6796:22;6812:5;6796:22;:::i;:::-;6791:3;6784:35;6713:112;;:::o;6831:214::-;6920:4;6958:2;6947:9;6943:18;6935:26;;6971:67;7035:1;7024:9;7020:17;7011:6;6971:67;:::i;:::-;6831:214;;;;:::o;7051:472::-;7118:6;7126;7175:2;7163:9;7154:7;7150:23;7146:32;7143:119;;;7181:79;;:::i;:::-;7143:119;7301:1;7326:52;7370:7;7361:6;7350:9;7346:22;7326:52;:::i;:::-;7316:62;;7272:116;7427:2;7453:53;7498:7;7489:6;7478:9;7474:22;7453:53;:::i;:::-;7443:63;;7398:118;7051:472;;;;;:::o;7529:329::-;7588:6;7637:2;7625:9;7616:7;7612:23;7608:32;7605:119;;;7643:79;;:::i;:::-;7605:119;7763:1;7788:53;7833:7;7824:6;7813:9;7809:22;7788:53;:::i;:::-;7778:63;;7734:117;7529:329;;;;:::o;7864:90::-;7898:7;7941:5;7934:13;7927:21;7916:32;;7864:90;;;:::o;7960:109::-;8041:21;8056:5;8041:21;:::i;:::-;8036:3;8029:34;7960:109;;:::o;8075:210::-;8162:4;8200:2;8189:9;8185:18;8177:26;;8213:65;8275:1;8264:9;8260:17;8251:6;8213:65;:::i;:::-;8075:210;;;;:::o;8291:329::-;8350:6;8399:2;8387:9;8378:7;8374:23;8370:32;8367:119;;;8405:79;;:::i;:::-;8367:119;8525:1;8550:53;8595:7;8586:6;8575:9;8571:22;8550:53;:::i;:::-;8540:63;;8496:117;8291:329;;;;:::o;8626:118::-;8713:24;8731:5;8713:24;:::i;:::-;8708:3;8701:37;8626:118;;:::o;8750:222::-;8843:4;8881:2;8870:9;8866:18;8858:26;;8894:71;8962:1;8951:9;8947:17;8938:6;8894:71;:::i;:::-;8750:222;;;;:::o;8978:60::-;9006:3;9027:5;9020:12;;8978:60;;;:::o;9044:142::-;9094:9;9127:53;9145:34;9154:24;9172:5;9154:24;:::i;:::-;9145:34;:::i;:::-;9127:53;:::i;:::-;9114:66;;9044:142;;;:::o;9192:126::-;9242:9;9275:37;9306:5;9275:37;:::i;:::-;9262:50;;9192:126;;;:::o;9324:155::-;9403:9;9436:37;9467:5;9436:37;:::i;:::-;9423:50;;9324:155;;;:::o;9485:189::-;9601:66;9661:5;9601:66;:::i;:::-;9596:3;9589:79;9485:189;;:::o;9680:280::-;9802:4;9840:2;9829:9;9825:18;9817:26;;9853:100;9950:1;9939:9;9935:17;9926:6;9853:100;:::i;:::-;9680:280;;;;:::o;9966:474::-;10034:6;10042;10091:2;10079:9;10070:7;10066:23;10062:32;10059:119;;;10097:79;;:::i;:::-;10059:119;10217:1;10242:53;10287:7;10278:6;10267:9;10263:22;10242:53;:::i;:::-;10232:63;;10188:117;10344:2;10370:53;10415:7;10406:6;10395:9;10391:22;10370:53;:::i;:::-;10360:63;;10315:118;9966:474;;;;;:::o;10446:329::-;10505:6;10554:2;10542:9;10533:7;10529:23;10525:32;10522:119;;;10560:79;;:::i;:::-;10522:119;10680:1;10705:53;10750:7;10741:6;10730:9;10726:22;10705:53;:::i;:::-;10695:63;;10651:117;10446:329;;;;:::o;10781:474::-;10849:6;10857;10906:2;10894:9;10885:7;10881:23;10877:32;10874:119;;;10912:79;;:::i;:::-;10874:119;11032:1;11057:53;11102:7;11093:6;11082:9;11078:22;11057:53;:::i;:::-;11047:63;;11003:117;11159:2;11185:53;11230:7;11221:6;11210:9;11206:22;11185:53;:::i;:::-;11175:63;;11130:118;10781:474;;;;;:::o;11261:218::-;11352:4;11390:2;11379:9;11375:18;11367:26;;11403:69;11469:1;11458:9;11454:17;11445:6;11403:69;:::i;:::-;11261:218;;;;:::o;11485:815::-;11572:6;11580;11588;11596;11645:2;11633:9;11624:7;11620:23;11616:32;11613:119;;;11651:79;;:::i;:::-;11613:119;11771:1;11796:53;11841:7;11832:6;11821:9;11817:22;11796:53;:::i;:::-;11786:63;;11742:117;11898:2;11924:52;11968:7;11959:6;11948:9;11944:22;11924:52;:::i;:::-;11914:62;;11869:117;12053:2;12042:9;12038:18;12025:32;12084:18;12076:6;12073:30;12070:117;;;12106:79;;:::i;:::-;12070:117;12219:64;12275:7;12266:6;12255:9;12251:22;12219:64;:::i;:::-;12201:82;;;;11996:297;11485:815;;;;;;;:::o;12306:::-;12393:6;12401;12409;12417;12466:2;12454:9;12445:7;12441:23;12437:32;12434:119;;;12472:79;;:::i;:::-;12434:119;12592:1;12617:52;12661:7;12652:6;12641:9;12637:22;12617:52;:::i;:::-;12607:62;;12563:116;12718:2;12744:53;12789:7;12780:6;12769:9;12765:22;12744:53;:::i;:::-;12734:63;;12689:118;12874:2;12863:9;12859:18;12846:32;12905:18;12897:6;12894:30;12891:117;;;12927:79;;:::i;:::-;12891:117;13040:64;13096:7;13087:6;13076:9;13072:22;13040:64;:::i;:::-;13022:82;;;;12817:297;12306:815;;;;;;;:::o;13127:871::-;13241:6;13249;13257;13265;13314:3;13302:9;13293:7;13289:23;13285:33;13282:120;;;13321:79;;:::i;:::-;13282:120;13441:1;13466:79;13537:7;13528:6;13517:9;13513:22;13466:79;:::i;:::-;13456:89;;13412:143;13622:2;13611:9;13607:18;13594:32;13653:18;13645:6;13642:30;13639:117;;;13675:79;;:::i;:::-;13639:117;13788:64;13844:7;13835:6;13824:9;13820:22;13788:64;:::i;:::-;13770:82;;;;13565:297;13901:3;13928:53;13973:7;13964:6;13953:9;13949:22;13928:53;:::i;:::-;13918:63;;13872:119;13127:871;;;;;;;:::o;14004:118::-;14091:24;14109:5;14091:24;:::i;:::-;14086:3;14079:37;14004:118;;:::o;14128:222::-;14221:4;14259:2;14248:9;14244:18;14236:26;;14272:71;14340:1;14329:9;14325:17;14316:6;14272:71;:::i;:::-;14128:222;;;;:::o;14356:327::-;14414:6;14463:2;14451:9;14442:7;14438:23;14434:32;14431:119;;;14469:79;;:::i;:::-;14431:119;14589:1;14614:52;14658:7;14649:6;14638:9;14634:22;14614:52;:::i;:::-;14604:62;;14560:116;14356:327;;;;:::o;14689:118::-;14726:7;14766:34;14759:5;14755:46;14744:57;;14689:118;;;:::o;14813:122::-;14886:24;14904:5;14886:24;:::i;:::-;14879:5;14876:35;14866:63;;14925:1;14922;14915:12;14866:63;14813:122;:::o;14941:139::-;14987:5;15025:6;15012:20;15003:29;;15041:33;15068:5;15041:33;:::i;:::-;14941:139;;;;:::o;15086:329::-;15145:6;15194:2;15182:9;15173:7;15169:23;15165:32;15162:119;;;15200:79;;:::i;:::-;15162:119;15320:1;15345:53;15390:7;15381:6;15370:9;15366:22;15345:53;:::i;:::-;15335:63;;15291:117;15086:329;;;;:::o;15421:98::-;15472:6;15506:5;15500:12;15490:22;;15421:98;;;:::o;15525:168::-;15608:11;15642:6;15637:3;15630:19;15682:4;15677:3;15673:14;15658:29;;15525:168;;;;:::o;15699:139::-;15788:6;15783:3;15778;15772:23;15829:1;15820:6;15815:3;15811:16;15804:27;15699:139;;;:::o;15844:102::-;15885:6;15936:2;15932:7;15927:2;15920:5;15916:14;15912:28;15902:38;;15844:102;;;:::o;15952:373::-;16038:3;16066:38;16098:5;16066:38;:::i;:::-;16120:70;16183:6;16178:3;16120:70;:::i;:::-;16113:77;;16199:65;16257:6;16252:3;16245:4;16238:5;16234:16;16199:65;:::i;:::-;16289:29;16311:6;16289:29;:::i;:::-;16284:3;16280:39;16273:46;;16042:283;15952:373;;;;:::o;16331:309::-;16442:4;16480:2;16469:9;16465:18;16457:26;;16529:9;16523:4;16519:20;16515:1;16504:9;16500:17;16493:47;16557:76;16628:4;16619:6;16557:76;:::i;:::-;16549:84;;16331:309;;;;:::o;16646:541::-;16817:4;16855:3;16844:9;16840:19;16832:27;;16869:71;16937:1;16926:9;16922:17;16913:6;16869:71;:::i;:::-;16950:72;17018:2;17007:9;17003:18;16994:6;16950:72;:::i;:::-;17032:66;17094:2;17083:9;17079:18;17070:6;17032:66;:::i;:::-;17108:72;17176:2;17165:9;17161:18;17152:6;17108:72;:::i;:::-;16646:541;;;;;;;:::o;17193:381::-;17278:6;17327:2;17315:9;17306:7;17302:23;17298:32;17295:119;;;17333:79;;:::i;:::-;17295:119;17453:1;17478:79;17549:7;17540:6;17529:9;17525:22;17478:79;:::i;:::-;17468:89;;17424:143;17193:381;;;;:::o;17580:115::-;17665:23;17682:5;17665:23;:::i;:::-;17660:3;17653:36;17580:115;;:::o;17701:328::-;17820:4;17858:2;17847:9;17843:18;17835:26;;17871:69;17937:1;17926:9;17922:17;17913:6;17871:69;:::i;:::-;17950:72;18018:2;18007:9;18003:18;17994:6;17950:72;:::i;:::-;17701:328;;;;;:::o;18035:169::-;18119:11;18153:6;18148:3;18141:19;18193:4;18188:3;18184:14;18169:29;;18035:169;;;;:::o;18210:::-;18350:21;18346:1;18338:6;18334:14;18327:45;18210:169;:::o;18385:366::-;18527:3;18548:67;18612:2;18607:3;18548:67;:::i;:::-;18541:74;;18624:93;18713:3;18624:93;:::i;:::-;18742:2;18737:3;18733:12;18726:19;;18385:366;;;:::o;18757:419::-;18923:4;18961:2;18950:9;18946:18;18938:26;;19010:9;19004:4;19000:20;18996:1;18985:9;18981:17;18974:47;19038:131;19164:4;19038:131;:::i;:::-;19030:139;;18757:419;;;:::o;19182:180::-;19230:77;19227:1;19220:88;19327:4;19324:1;19317:15;19351:4;19348:1;19341:15;19368:410;19408:7;19431:20;19449:1;19431:20;:::i;:::-;19426:25;;19465:20;19483:1;19465:20;:::i;:::-;19460:25;;19520:1;19517;19513:9;19542:30;19560:11;19542:30;:::i;:::-;19531:41;;19721:1;19712:7;19708:15;19705:1;19702:22;19682:1;19675:9;19655:83;19632:139;;19751:18;;:::i;:::-;19632:139;19416:362;19368:410;;;;:::o;19784:180::-;19832:77;19829:1;19822:88;19929:4;19926:1;19919:15;19953:4;19950:1;19943:15;19970:185;20010:1;20027:20;20045:1;20027:20;:::i;:::-;20022:25;;20061:20;20079:1;20061:20;:::i;:::-;20056:25;;20100:1;20090:35;;20105:18;;:::i;:::-;20090:35;20147:1;20144;20140:9;20135:14;;19970:185;;;;:::o;20161:194::-;20201:4;20221:20;20239:1;20221:20;:::i;:::-;20216:25;;20255:20;20273:1;20255:20;:::i;:::-;20250:25;;20299:1;20296;20292:9;20284:17;;20323:1;20317:4;20314:11;20311:37;;;20328:18;;:::i;:::-;20311:37;20161:194;;;;:::o;20361:147::-;20462:11;20499:3;20484:18;;20361:147;;;;:::o;20514:114::-;;:::o;20634:398::-;20793:3;20814:83;20895:1;20890:3;20814:83;:::i;:::-;20807:90;;20906:93;20995:3;20906:93;:::i;:::-;21024:1;21019:3;21015:11;21008:18;;20634:398;;;:::o;21038:379::-;21222:3;21244:147;21387:3;21244:147;:::i;:::-;21237:154;;21408:3;21401:10;;21038:379;;;:::o;21423:169::-;21563:21;21559:1;21551:6;21547:14;21540:45;21423:169;:::o;21598:366::-;21740:3;21761:67;21825:2;21820:3;21761:67;:::i;:::-;21754:74;;21837:93;21926:3;21837:93;:::i;:::-;21955:2;21950:3;21946:12;21939:19;;21598:366;;;:::o;21970:419::-;22136:4;22174:2;22163:9;22159:18;22151:26;;22223:9;22217:4;22213:20;22209:1;22198:9;22194:17;22187:47;22251:131;22377:4;22251:131;:::i;:::-;22243:139;;21970:419;;;:::o;22395:171::-;22535:23;22531:1;22523:6;22519:14;22512:47;22395:171;:::o;22572:366::-;22714:3;22735:67;22799:2;22794:3;22735:67;:::i;:::-;22728:74;;22811:93;22900:3;22811:93;:::i;:::-;22929:2;22924:3;22920:12;22913:19;;22572:366;;;:::o;22944:419::-;23110:4;23148:2;23137:9;23133:18;23125:26;;23197:9;23191:4;23187:20;23183:1;23172:9;23168:17;23161:47;23225:131;23351:4;23225:131;:::i;:::-;23217:139;;22944:419;;;:::o;23369:233::-;23408:3;23431:24;23449:5;23431:24;:::i;:::-;23422:33;;23477:66;23470:5;23467:77;23464:103;;23547:18;;:::i;:::-;23464:103;23594:1;23587:5;23583:13;23576:20;;23369:233;;;:::o;23608:332::-;23729:4;23767:2;23756:9;23752:18;23744:26;;23780:71;23848:1;23837:9;23833:17;23824:6;23780:71;:::i;:::-;23861:72;23929:2;23918:9;23914:18;23905:6;23861:72;:::i;:::-;23608:332;;;;;:::o;23946:169::-;24086:21;24082:1;24074:6;24070:14;24063:45;23946:169;:::o;24121:366::-;24263:3;24284:67;24348:2;24343:3;24284:67;:::i;:::-;24277:74;;24360:93;24449:3;24360:93;:::i;:::-;24478:2;24473:3;24469:12;24462:19;;24121:366;;;:::o;24493:419::-;24659:4;24697:2;24686:9;24682:18;24674:26;;24746:9;24740:4;24736:20;24732:1;24721:9;24717:17;24710:47;24774:131;24900:4;24774:131;:::i;:::-;24766:139;;24493:419;;;:::o;24918:170::-;25058:22;25054:1;25046:6;25042:14;25035:46;24918:170;:::o;25094:366::-;25236:3;25257:67;25321:2;25316:3;25257:67;:::i;:::-;25250:74;;25333:93;25422:3;25333:93;:::i;:::-;25451:2;25446:3;25442:12;25435:19;;25094:366;;;:::o;25466:419::-;25632:4;25670:2;25659:9;25655:18;25647:26;;25719:9;25713:4;25709:20;25705:1;25694:9;25690:17;25683:47;25747:131;25873:4;25747:131;:::i;:::-;25739:139;;25466:419;;;:::o;25891:162::-;26031:14;26027:1;26019:6;26015:14;26008:38;25891:162;:::o;26059:366::-;26201:3;26222:67;26286:2;26281:3;26222:67;:::i;:::-;26215:74;;26298:93;26387:3;26298:93;:::i;:::-;26416:2;26411:3;26407:12;26400:19;;26059:366;;;:::o;26431:419::-;26597:4;26635:2;26624:9;26620:18;26612:26;;26684:9;26678:4;26674:20;26670:1;26659:9;26655:17;26648:47;26712:131;26838:4;26712:131;:::i;:::-;26704:139;;26431:419;;;:::o;26856:178::-;26996:30;26992:1;26984:6;26980:14;26973:54;26856:178;:::o;27040:366::-;27182:3;27203:67;27267:2;27262:3;27203:67;:::i;:::-;27196:74;;27279:93;27368:3;27279:93;:::i;:::-;27397:2;27392:3;27388:12;27381:19;;27040:366;;;:::o;27412:419::-;27578:4;27616:2;27605:9;27601:18;27593:26;;27665:9;27659:4;27655:20;27651:1;27640:9;27636:17;27629:47;27693:131;27819:4;27693:131;:::i;:::-;27685:139;;27412:419;;;:::o;27837:105::-;27873:7;27913:22;27906:5;27902:34;27891:45;;27837:105;;;:::o;27948:120::-;28020:23;28037:5;28020:23;:::i;:::-;28013:5;28010:34;28000:62;;28058:1;28055;28048:12;28000:62;27948:120;:::o;28074:141::-;28130:5;28161:6;28155:13;28146:22;;28177:32;28203:5;28177:32;:::i;:::-;28074:141;;;;:::o;28221:76::-;28257:7;28286:5;28275:16;;28221:76;;;:::o;28303:120::-;28375:23;28392:5;28375:23;:::i;:::-;28368:5;28365:34;28355:62;;28413:1;28410;28403:12;28355:62;28303:120;:::o;28429:141::-;28485:5;28516:6;28510:13;28501:22;;28532:32;28558:5;28532:32;:::i;:::-;28429:141;;;;:::o;28576:143::-;28633:5;28664:6;28658:13;28649:22;;28680:33;28707:5;28680:33;:::i;:::-;28576:143;;;;:::o;28725:971::-;28828:6;28836;28844;28852;28860;28909:3;28897:9;28888:7;28884:23;28880:33;28877:120;;;28916:79;;:::i;:::-;28877:120;29036:1;29061:63;29116:7;29107:6;29096:9;29092:22;29061:63;:::i;:::-;29051:73;;29007:127;29173:2;29199:63;29254:7;29245:6;29234:9;29230:22;29199:63;:::i;:::-;29189:73;;29144:128;29311:2;29337:64;29393:7;29384:6;29373:9;29369:22;29337:64;:::i;:::-;29327:74;;29282:129;29450:2;29476:64;29532:7;29523:6;29512:9;29508:22;29476:64;:::i;:::-;29466:74;;29421:129;29589:3;29616:63;29671:7;29662:6;29651:9;29647:22;29616:63;:::i;:::-;29606:73;;29560:129;28725:971;;;;;;;;:::o;29702:163::-;29842:15;29838:1;29830:6;29826:14;29819:39;29702:163;:::o;29871:366::-;30013:3;30034:67;30098:2;30093:3;30034:67;:::i;:::-;30027:74;;30110:93;30199:3;30110:93;:::i;:::-;30228:2;30223:3;30219:12;30212:19;;29871:366;;;:::o;30243:419::-;30409:4;30447:2;30436:9;30432:18;30424:26;;30496:9;30490:4;30486:20;30482:1;30471:9;30467:17;30460:47;30524:131;30650:4;30524:131;:::i;:::-;30516:139;;30243:419;;;:::o;30668:118::-;30739:22;30755:5;30739:22;:::i;:::-;30732:5;30729:33;30719:61;;30776:1;30773;30766:12;30719:61;30668:118;:::o;30792:139::-;30847:5;30878:6;30872:13;30863:22;;30894:31;30919:5;30894:31;:::i;:::-;30792:139;;;;:::o;30937:347::-;31005:6;31054:2;31042:9;31033:7;31029:23;31025:32;31022:119;;;31060:79;;:::i;:::-;31022:119;31180:1;31205:62;31259:7;31250:6;31239:9;31235:22;31205:62;:::i;:::-;31195:72;;31151:126;30937:347;;;;:::o;31290:102::-;31332:8;31379:5;31376:1;31372:13;31351:34;;31290:102;;;:::o;31398:848::-;31459:5;31466:4;31490:6;31481:15;;31514:5;31505:14;;31528:712;31549:1;31539:8;31536:15;31528:712;;;31644:4;31639:3;31635:14;31629:4;31626:24;31623:50;;;31653:18;;:::i;:::-;31623:50;31703:1;31693:8;31689:16;31686:451;;;32118:4;32111:5;32107:16;32098:25;;31686:451;32168:4;32162;32158:15;32150:23;;32198:32;32221:8;32198:32;:::i;:::-;32186:44;;31528:712;;;31398:848;;;;;;;:::o;32252:1073::-;32306:5;32497:8;32487:40;;32518:1;32509:10;;32520:5;;32487:40;32546:4;32536:36;;32563:1;32554:10;;32565:5;;32536:36;32632:4;32680:1;32675:27;;;;32716:1;32711:191;;;;32625:277;;32675:27;32693:1;32684:10;;32695:5;;;32711:191;32756:3;32746:8;32743:17;32740:43;;;32763:18;;:::i;:::-;32740:43;32812:8;32809:1;32805:16;32796:25;;32847:3;32840:5;32837:14;32834:40;;;32854:18;;:::i;:::-;32834:40;32887:5;;;32625:277;;33011:2;33001:8;32998:16;32992:3;32986:4;32983:13;32979:36;32961:2;32951:8;32948:16;32943:2;32937:4;32934:12;32930:35;32914:111;32911:246;;;33067:8;33061:4;33057:19;33048:28;;33102:3;33095:5;33092:14;33089:40;;;33109:18;;:::i;:::-;33089:40;33142:5;;32911:246;33182:42;33220:3;33210:8;33204:4;33201:1;33182:42;:::i;:::-;33167:57;;;;33256:4;33251:3;33247:14;33240:5;33237:25;33234:51;;;33265:18;;:::i;:::-;33234:51;33314:4;33307:5;33303:16;33294:25;;32252:1073;;;;;;:::o;33331:281::-;33389:5;33413:23;33431:4;33413:23;:::i;:::-;33405:31;;33457:25;33473:8;33457:25;:::i;:::-;33445:37;;33501:104;33538:66;33528:8;33522:4;33501:104;:::i;:::-;33492:113;;33331:281;;;;:::o;33618:168::-;33758:20;33754:1;33746:6;33742:14;33735:44;33618:168;:::o;33792:366::-;33934:3;33955:67;34019:2;34014:3;33955:67;:::i;:::-;33948:74;;34031:93;34120:3;34031:93;:::i;:::-;34149:2;34144:3;34140:12;34133:19;;33792:366;;;:::o;34164:419::-;34330:4;34368:2;34357:9;34353:18;34345:26;;34417:9;34411:4;34407:20;34403:1;34392:9;34388:17;34381:47;34445:131;34571:4;34445:131;:::i;:::-;34437:139;;34164:419;;;:::o;34589:176::-;34729:28;34725:1;34717:6;34713:14;34706:52;34589:176;:::o;34771:366::-;34913:3;34934:67;34998:2;34993:3;34934:67;:::i;:::-;34927:74;;35010:93;35099:3;35010:93;:::i;:::-;35128:2;35123:3;35119:12;35112:19;;34771:366;;;:::o;35143:419::-;35309:4;35347:2;35336:9;35332:18;35324:26;;35396:9;35390:4;35386:20;35382:1;35371:9;35367:17;35360:47;35424:131;35550:4;35424:131;:::i;:::-;35416:139;;35143:419;;;:::o;35568:224::-;35708:34;35704:1;35696:6;35692:14;35685:58;35777:7;35772:2;35764:6;35760:15;35753:32;35568:224;:::o;35798:366::-;35940:3;35961:67;36025:2;36020:3;35961:67;:::i;:::-;35954:74;;36037:93;36126:3;36037:93;:::i;:::-;36155:2;36150:3;36146:12;36139:19;;35798:366;;;:::o;36170:419::-;36336:4;36374:2;36363:9;36359:18;36351:26;;36423:9;36417:4;36413:20;36409:1;36398:9;36394:17;36387:47;36451:131;36577:4;36451:131;:::i;:::-;36443:139;;36170:419;;;:::o;36595:174::-;36735:26;36731:1;36723:6;36719:14;36712:50;36595:174;:::o;36775:366::-;36917:3;36938:67;37002:2;36997:3;36938:67;:::i;:::-;36931:74;;37014:93;37103:3;37014:93;:::i;:::-;37132:2;37127:3;37123:12;37116:19;;36775:366;;;:::o;37147:419::-;37313:4;37351:2;37340:9;37336:18;37328:26;;37400:9;37394:4;37390:20;37386:1;37375:9;37371:17;37364:47;37428:131;37554:4;37428:131;:::i;:::-;37420:139;;37147:419;;;:::o;37572:218::-;37663:4;37701:2;37690:9;37686:18;37678:26;;37714:69;37780:1;37769:9;37765:17;37756:6;37714:69;:::i;:::-;37572:218;;;;:::o;37796:180::-;37936:32;37932:1;37924:6;37920:14;37913:56;37796:180;:::o;37982:366::-;38124:3;38145:67;38209:2;38204:3;38145:67;:::i;:::-;38138:74;;38221:93;38310:3;38221:93;:::i;:::-;38339:2;38334:3;38330:12;38323:19;;37982:366;;;:::o;38354:419::-;38520:4;38558:2;38547:9;38543:18;38535:26;;38607:9;38601:4;38597:20;38593:1;38582:9;38578:17;38571:47;38635:131;38761:4;38635:131;:::i;:::-;38627:139;;38354:419;;;:::o;38779:191::-;38819:3;38838:20;38856:1;38838:20;:::i;:::-;38833:25;;38872:20;38890:1;38872:20;:::i;:::-;38867:25;;38915:1;38912;38908:9;38901:16;;38936:3;38933:1;38930:10;38927:36;;;38943:18;;:::i;:::-;38927:36;38779:191;;;;:::o;38976:176::-;39116:28;39112:1;39104:6;39100:14;39093:52;38976:176;:::o;39158:366::-;39300:3;39321:67;39385:2;39380:3;39321:67;:::i;:::-;39314:74;;39397:93;39486:3;39397:93;:::i;:::-;39515:2;39510:3;39506:12;39499:19;;39158:366;;;:::o;39530:419::-;39696:4;39734:2;39723:9;39719:18;39711:26;;39783:9;39777:4;39773:20;39769:1;39758:9;39754:17;39747:47;39811:131;39937:4;39811:131;:::i;:::-;39803:139;;39530:419;;;:::o;39955:170::-;40095:22;40091:1;40083:6;40079:14;40072:46;39955:170;:::o;40131:366::-;40273:3;40294:67;40358:2;40353:3;40294:67;:::i;:::-;40287:74;;40370:93;40459:3;40370:93;:::i;:::-;40488:2;40483:3;40479:12;40472:19;;40131:366;;;:::o;40503:419::-;40669:4;40707:2;40696:9;40692:18;40684:26;;40756:9;40750:4;40746:20;40742:1;40731:9;40727:17;40720:47;40784:131;40910:4;40784:131;:::i;:::-;40776:139;;40503:419;;;:::o;40928:165::-;41068:17;41064:1;41056:6;41052:14;41045:41;40928:165;:::o;41099:366::-;41241:3;41262:67;41326:2;41321:3;41262:67;:::i;:::-;41255:74;;41338:93;41427:3;41338:93;:::i;:::-;41456:2;41451:3;41447:12;41440:19;;41099:366;;;:::o;41471:419::-;41637:4;41675:2;41664:9;41660:18;41652:26;;41724:9;41718:4;41714:20;41710:1;41699:9;41695:17;41688:47;41752:131;41878:4;41752:131;:::i;:::-;41744:139;;41471:419;;;:::o;41896:181::-;42036:33;42032:1;42024:6;42020:14;42013:57;41896:181;:::o;42083:366::-;42225:3;42246:67;42310:2;42305:3;42246:67;:::i;:::-;42239:74;;42322:93;42411:3;42322:93;:::i;:::-;42440:2;42435:3;42431:12;42424:19;;42083:366;;;:::o;42455:419::-;42621:4;42659:2;42648:9;42644:18;42636:26;;42708:9;42702:4;42698:20;42694:1;42683:9;42679:17;42672:47;42736:131;42862:4;42736:131;:::i;:::-;42728:139;;42455:419;;;:::o;42880:166::-;43020:18;43016:1;43008:6;43004:14;42997:42;42880:166;:::o;43052:366::-;43194:3;43215:67;43279:2;43274:3;43215:67;:::i;:::-;43208:74;;43291:93;43380:3;43291:93;:::i;:::-;43409:2;43404:3;43400:12;43393:19;;43052:366;;;:::o;43424:419::-;43590:4;43628:2;43617:9;43613:18;43605:26;;43677:9;43671:4;43667:20;43663:1;43652:9;43648:17;43641:47;43705:131;43831:4;43705:131;:::i;:::-;43697:139;;43424:419;;;:::o;43849:442::-;43998:4;44036:2;44025:9;44021:18;44013:26;;44049:71;44117:1;44106:9;44102:17;44093:6;44049:71;:::i;:::-;44130:72;44198:2;44187:9;44183:18;44174:6;44130:72;:::i;:::-;44212;44280:2;44269:9;44265:18;44256:6;44212:72;:::i;:::-;43849:442;;;;;;:::o;44297:332::-;44418:4;44456:2;44445:9;44441:18;44433:26;;44469:71;44537:1;44526:9;44522:17;44513:6;44469:71;:::i;:::-;44550:72;44618:2;44607:9;44603:18;44594:6;44550:72;:::i;:::-;44297:332;;;;;:::o;44635:105::-;44710:23;44727:5;44710:23;:::i;:::-;44705:3;44698:36;44635:105;;:::o;44746:108::-;44823:24;44841:5;44823:24;:::i;:::-;44818:3;44811:37;44746:108;;:::o;44860:158::-;44933:11;44967:6;44962:3;44955:19;45007:4;45002:3;44998:14;44983:29;;44860:158;;;;:::o;45024:353::-;45100:3;45128:38;45160:5;45128:38;:::i;:::-;45182:60;45235:6;45230:3;45182:60;:::i;:::-;45175:67;;45251:65;45309:6;45304:3;45297:4;45290:5;45286:16;45251:65;:::i;:::-;45341:29;45363:6;45341:29;:::i;:::-;45336:3;45332:39;45325:46;;45104:273;45024:353;;;;:::o;45383:99::-;45454:21;45469:5;45454:21;:::i;:::-;45449:3;45442:34;45383:99;;:::o;45544:1223::-;45679:3;45715:4;45710:3;45706:14;45804:4;45797:5;45793:16;45787:23;45823:61;45878:4;45873:3;45869:14;45855:12;45823:61;:::i;:::-;45730:164;45980:4;45973:5;45969:16;45963:23;45999:63;46056:4;46051:3;46047:14;46033:12;45999:63;:::i;:::-;45904:168;46157:4;46150:5;46146:16;46140:23;46210:3;46204:4;46200:14;46193:4;46188:3;46184:14;46177:38;46236:71;46302:4;46288:12;46236:71;:::i;:::-;46228:79;;46082:236;46403:4;46396:5;46392:16;46386:23;46456:3;46450:4;46446:14;46439:4;46434:3;46430:14;46423:38;46482:71;46548:4;46534:12;46482:71;:::i;:::-;46474:79;;46328:236;46654:4;46647:5;46643:16;46637:23;46673:57;46724:4;46719:3;46715:14;46701:12;46673:57;:::i;:::-;46574:166;46757:4;46750:11;;45684:1083;45544:1223;;;;:::o;46773:515::-;46960:4;46998:2;46987:9;46983:18;46975:26;;47047:9;47041:4;47037:20;47033:1;47022:9;47018:17;47011:47;47075:124;47194:4;47185:6;47075:124;:::i;:::-;47067:132;;47209:72;47277:2;47266:9;47262:18;47253:6;47209:72;:::i;:::-;46773:515;;;;;:::o;47294:117::-;47403:1;47400;47393:12;47417:180;47465:77;47462:1;47455:88;47562:4;47559:1;47552:15;47586:4;47583:1;47576:15;47603:281;47686:27;47708:4;47686:27;:::i;:::-;47678:6;47674:40;47816:6;47804:10;47801:22;47780:18;47768:10;47765:34;47762:62;47759:88;;;47827:18;;:::i;:::-;47759:88;47867:10;47863:2;47856:22;47646:238;47603:281;;:::o;47890:129::-;47924:6;47951:20;;:::i;:::-;47941:30;;47980:33;48008:4;48000:6;47980:33;:::i;:::-;47890:129;;;:::o;48148:143::-;48205:5;48236:6;48230:13;48221:22;;48252:33;48279:5;48252:33;:::i;:::-;48148:143;;;;:::o;48297:120::-;48369:23;48386:5;48369:23;:::i;:::-;48362:5;48359:34;48349:62;;48407:1;48404;48397:12;48349:62;48297:120;:::o;48423:141::-;48479:5;48510:6;48504:13;48495:22;;48526:32;48552:5;48526:32;:::i;:::-;48423:141;;;;:::o;48597:623::-;48687:5;48731:4;48719:9;48714:3;48710:19;48706:30;48703:117;;;48739:79;;:::i;:::-;48703:117;48838:21;48854:4;48838:21;:::i;:::-;48829:30;;48923:1;48963:60;49019:3;49010:6;48999:9;48995:22;48963:60;:::i;:::-;48956:4;48949:5;48945:16;48938:86;48869:166;49100:2;49141:60;49197:3;49188:6;49177:9;49173:22;49141:60;:::i;:::-;49134:4;49127:5;49123:16;49116:86;49045:168;48597:623;;;;:::o;49257:817::-;49351:5;49395:4;49383:9;49378:3;49374:19;49370:30;49367:117;;;49403:79;;:::i;:::-;49367:117;49502:21;49518:4;49502:21;:::i;:::-;49493:30;;49582:1;49622:60;49678:3;49669:6;49658:9;49654:22;49622:60;:::i;:::-;49615:4;49608:5;49604:16;49597:86;49533:161;49754:2;49795:59;49850:3;49841:6;49830:9;49826:22;49795:59;:::i;:::-;49788:4;49781:5;49777:16;49770:85;49704:162;49924:2;49965:90;50051:3;50042:6;50031:9;50027:22;49965:90;:::i;:::-;49958:4;49951:5;49947:16;49940:116;49876:191;49257:817;;;;:::o;50080:420::-;50184:6;50233:3;50221:9;50212:7;50208:23;50204:33;50201:120;;;50240:79;;:::i;:::-;50201:120;50360:1;50385:98;50475:7;50466:6;50455:9;50451:22;50385:98;:::i;:::-;50375:108;;50331:162;50080:420;;;;:::o;50506:411::-;50606:6;50655:2;50643:9;50634:7;50630:23;50626:32;50623:119;;;50661:79;;:::i;:::-;50623:119;50781:1;50806:94;50892:7;50883:6;50872:9;50868:22;50806:94;:::i;:::-;50796:104;;50752:158;50506:411;;;;:::o;50923:89::-;50959:7;50999:6;50992:5;50988:18;50977:29;;50923:89;;;:::o;51018:96::-;51052:8;51101:5;51096:3;51092:15;51071:36;;51018:96;;;:::o;51120:94::-;51158:7;51187:21;51202:5;51187:21;:::i;:::-;51176:32;;51120:94;;;:::o;51220:153::-;51323:43;51342:23;51359:5;51342:23;:::i;:::-;51323:43;:::i;:::-;51318:3;51311:56;51220:153;;:::o;51379:251::-;51489:3;51504:73;51573:3;51564:6;51504:73;:::i;:::-;51602:1;51597:3;51593:11;51586:18;;51621:3;51614:10;;51379:251;;;;:::o;51636:115::-;51721:23;51738:5;51721:23;:::i;:::-;51716:3;51709:36;51636:115;;:::o;51757:218::-;51848:4;51886:2;51875:9;51871:18;51863:26;;51899:69;51965:1;51954:9;51950:17;51941:6;51899:69;:::i;:::-;51757:218;;;;:::o;51981:170::-;52121:22;52117:1;52109:6;52105:14;52098:46;51981:170;:::o;52157:366::-;52299:3;52320:67;52384:2;52379:3;52320:67;:::i;:::-;52313:74;;52396:93;52485:3;52396:93;:::i;:::-;52514:2;52509:3;52505:12;52498:19;;52157:366;;;:::o;52529:419::-;52695:4;52733:2;52722:9;52718:18;52710:26;;52782:9;52776:4;52772:20;52768:1;52757:9;52753:17;52746:47;52810:131;52936:4;52810:131;:::i;:::-;52802:139;;52529:419;;;:::o;52954:143::-;53011:5;53042:6;53036:13;53027:22;;53058:33;53085:5;53058:33;:::i;:::-;52954:143;;;;:::o;53103:351::-;53173:6;53222:2;53210:9;53201:7;53197:23;53193:32;53190:119;;;53228:79;;:::i;:::-;53190:119;53348:1;53373:64;53429:7;53420:6;53409:9;53405:22;53373:64;:::i;:::-;53363:74;;53319:128;53103:351;;;;:::o;53460:170::-;53600:22;53596:1;53588:6;53584:14;53577:46;53460:170;:::o;53636:366::-;53778:3;53799:67;53863:2;53858:3;53799:67;:::i;:::-;53792:74;;53875:93;53964:3;53875:93;:::i;:::-;53993:2;53988:3;53984:12;53977:19;;53636:366;;;:::o;54008:419::-;54174:4;54212:2;54201:9;54197:18;54189:26;;54261:9;54255:4;54251:20;54247:1;54236:9;54232:17;54225:47;54289:131;54415:4;54289:131;:::i;:::-;54281:139;;54008:419;;;:::o;54433:96::-;54467:8;54516:5;54511:3;54507:15;54486:36;;54433:96;;;:::o;54535:95::-;54574:7;54603:21;54618:5;54603:21;:::i;:::-;54592:32;;54535:95;;;:::o;54636:157::-;54741:45;54761:24;54779:5;54761:24;:::i;:::-;54741:45;:::i;:::-;54736:3;54729:58;54636:157;;:::o;54799:397::-;54939:3;54954:75;55025:3;55016:6;54954:75;:::i;:::-;55054:2;55049:3;55045:12;55038:19;;55067:75;55138:3;55129:6;55067:75;:::i;:::-;55167:2;55162:3;55158:12;55151:19;;55187:3;55180:10;;54799:397;;;;;:::o;55202:256::-;55314:3;55329:75;55400:3;55391:6;55329:75;:::i;:::-;55429:2;55424:3;55420:12;55413:19;;55449:3;55442:10;;55202:256;;;;:::o;55464:193::-;55503:3;55522:19;55539:1;55522:19;:::i;:::-;55517:24;;55555:19;55572:1;55555:19;:::i;:::-;55550:24;;55597:1;55594;55590:9;55583:16;;55620:6;55615:3;55612:15;55609:41;;;55630:18;;:::i;:::-;55609:41;55464:193;;;;:::o;55663:386::-;55767:3;55795:38;55827:5;55795:38;:::i;:::-;55849:88;55930:6;55925:3;55849:88;:::i;:::-;55842:95;;55946:65;56004:6;55999:3;55992:4;55985:5;55981:16;55946:65;:::i;:::-;56036:6;56031:3;56027:16;56020:23;;55771:278;55663:386;;;;:::o;56055:96::-;56089:8;56138:5;56133:3;56129:15;56108:36;;56055:96;;;:::o;56157:93::-;56194:7;56223:21;56238:5;56223:21;:::i;:::-;56212:32;;56157:93;;;:::o;56256:149::-;56357:41;56375:22;56391:5;56375:22;:::i;:::-;56357:41;:::i;:::-;56352:3;56345:54;56256:149;;:::o;56411:827::-;56661:3;56683:93;56772:3;56763:6;56683:93;:::i;:::-;56676:100;;56786:71;56853:3;56844:6;56786:71;:::i;:::-;56882:1;56877:3;56873:11;56866:18;;56894:73;56963:3;56954:6;56894:73;:::i;:::-;56992:1;56987:3;56983:11;56976:18;;57004:71;57071:3;57062:6;57004:71;:::i;:::-;57100:1;57095:3;57091:11;57084:18;;57119:93;57208:3;57199:6;57119:93;:::i;:::-;57112:100;;57229:3;57222:10;;56411:827;;;;;;;;:::o;57244:86::-;57290:7;57319:5;57308:16;;57244:86;;;:::o;57336:156::-;57393:9;57426:60;57442:43;57451:33;57478:5;57451:33;:::i;:::-;57442:43;:::i;:::-;57426:60;:::i;:::-;57413:73;;57336:156;;;:::o;57498:145::-;57592:44;57630:5;57592:44;:::i;:::-;57587:3;57580:57;57498:145;;:::o;57649:346::-;57777:4;57815:2;57804:9;57800:18;57792:26;;57828:78;57903:1;57892:9;57888:17;57879:6;57828:78;:::i;:::-;57916:72;57984:2;57973:9;57969:18;57960:6;57916:72;:::i;:::-;57649:346;;;;;:::o
Swarm Source
ipfs://59aefbfa9e58854b60580180251b10bd19b5ac21ff130a8b17361592b5c1247c
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.