More Info
Private Name Tags
ContractCreator
Sponsored
Latest 25 from a total of 36 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Execute Batch Ca... | 8309798 | 9 days ago | IN | 0 ETH | 0.00001765 | ||||
Execute Batch Ca... | 7792009 | 21 days ago | IN | 0.1 ETH | 0.00000403 | ||||
Execute Batch Ca... | 7530608 | 27 days ago | IN | 0.09 ETH | 0.0000012 | ||||
Execute Batch Ca... | 7382785 | 31 days ago | IN | 0.0184 ETH | 0.00000058 | ||||
Execute Batch Ca... | 7368214 | 31 days ago | IN | 0.04 ETH | 0.00000043 | ||||
Execute Batch Ca... | 6725959 | 46 days ago | IN | 13 ETH | 0.00000009 | ||||
Execute Batch Ca... | 6725372 | 46 days ago | IN | 0.2 ETH | 0.00000011 | ||||
Execute Batch Ca... | 6690921 | 47 days ago | IN | 0.005 ETH | 0.00000147 | ||||
Execute Batch Ca... | 6482021 | 52 days ago | IN | 0.003 ETH | 0.0000001 | ||||
Execute Batch Ca... | 6481997 | 52 days ago | IN | 0.003 ETH | 0.00000011 | ||||
Execute Batch Ca... | 6275911 | 57 days ago | IN | 0.007 ETH | 0 | ||||
Execute Batch Ca... | 6227304 | 58 days ago | IN | 5 ETH | 0.00000008 | ||||
Execute Batch Ca... | 6214027 | 58 days ago | IN | 0.015 ETH | 0.00000005 | ||||
Execute Batch Ca... | 6211017 | 58 days ago | IN | 0.112 ETH | 0.0000001 | ||||
Execute Batch Ca... | 6135118 | 60 days ago | IN | 0.1475 ETH | 0 | ||||
Execute Batch Ca... | 6059512 | 62 days ago | IN | 0.01 ETH | 0.00000001 | ||||
Execute Batch Ca... | 5974181 | 63 days ago | IN | 9 ETH | 0.00000093 | ||||
Execute Batch Ca... | 5940487 | 64 days ago | IN | 0.02 ETH | 0.00000042 | ||||
Execute Batch Ca... | 5940208 | 64 days ago | IN | 0.016 ETH | 0.00000042 | ||||
Execute Batch Ca... | 5914684 | 65 days ago | IN | 0.24 ETH | 0.00000192 | ||||
Execute Batch Ca... | 5904756 | 65 days ago | IN | 0.005 ETH | 0.00000001 | ||||
Execute Batch Ca... | 5903932 | 65 days ago | IN | 0 ETH | 0.00000008 | ||||
Execute Batch Ca... | 5903880 | 65 days ago | IN | 0.004 ETH | 0.00000006 | ||||
Execute Batch Ca... | 5872516 | 66 days ago | IN | 0.016 ETH | 0.00000031 | ||||
Execute Batch Ca... | 5863555 | 66 days ago | IN | 0.02 ETH | 0.00000146 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
8453356 | 6 days ago | 0.02228444 ETH | ||||
8453356 | 6 days ago | 0.02228444 ETH | ||||
8452844 | 6 days ago | 0.00295229 ETH | ||||
8452844 | 6 days ago | 0.00295229 ETH | ||||
8309798 | 9 days ago | 0.00231154 ETH | ||||
8309798 | 9 days ago | 0.00231154 ETH | ||||
8229468 | 11 days ago | 0.00201803 ETH | ||||
8229468 | 11 days ago | 0.00201803 ETH | ||||
7792009 | 21 days ago | 0.09995 ETH | ||||
7792009 | 21 days ago | 0.00005 ETH | ||||
7530608 | 27 days ago | 0.089955 ETH | ||||
7530608 | 27 days ago | 0.000045 ETH | ||||
7382785 | 31 days ago | 0.0183908 ETH | ||||
7382785 | 31 days ago | 0.0000092 ETH | ||||
7368214 | 31 days ago | 0.03998 ETH | ||||
7368214 | 31 days ago | 0.00002 ETH | ||||
6725959 | 46 days ago | 12.9935 ETH | ||||
6725959 | 46 days ago | 0.0065 ETH | ||||
6725372 | 46 days ago | 0.1999 ETH | ||||
6725372 | 46 days ago | 0.0001 ETH | ||||
6690921 | 47 days ago | 0.0049975 ETH | ||||
6690921 | 47 days ago | 0.0000025 ETH | ||||
6482021 | 52 days ago | 0.0029985 ETH | ||||
6482021 | 52 days ago | 0.0000015 ETH | ||||
6481997 | 52 days ago | 0.0029985 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
BatchTransaction
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {ReentrancyGuard} from "@routerprotocol/intents-core/contracts/utils/ReentrancyGuard.sol"; import {Basic} from "@routerprotocol/intents-core/contracts/common/Basic.sol"; import {CallLib} from "@routerprotocol/intents-core/contracts/utils/CallLib.sol"; import {IERC20, SafeERC20} from "@routerprotocol/intents-core/contracts/utils/SafeERC20.sol"; import {Errors} from "@routerprotocol/intents-core/contracts/utils/Errors.sol"; import {Errors as IntentErrors} from "./Errors.sol"; import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; import {EoaExecutorWithDataProvider, EoaExecutorWithoutDataProvider} from "@routerprotocol/intents-core/contracts/RouterIntentEoaAdapter.sol"; import {BaseAdapter} from "@routerprotocol/intents-core/contracts/BaseAdapter.sol"; import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; /** * @title BatchTransaction * @author Shivam Agrawal * @notice Batch Transaction Contract for EOAs. */ contract BatchTransaction is Basic, AccessControl, ReentrancyGuard, IERC721Receiver { using SafeERC20 for IERC20; struct RefundData { address[] tokens; } struct FeeInfo { uint96 fee; address recipient; } bytes32 public constant SETTER_ROLE = keccak256("SETTER_ROLE"); address private immutable _native; address private immutable _wnative; address private _assetForwarder; address private _dexspan; address private _assetBridge; // user -> token array mapping(address => RefundData) private tokensToRefund; mapping(address => bool) private adapterWhitelist; event OperationFailedRefundEvent( address token, address recipient, uint256 amount ); event OperationSuccessful(); event Executed(uint256 appId); constructor( address __native, address __wnative, address __assetForwarder, address __dexspan, address __assetBridge ) { _native = __native; _wnative = __wnative; _assetForwarder = __assetForwarder; _dexspan = __dexspan; _assetBridge = __assetBridge; _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(SETTER_ROLE, msg.sender); } /** * @notice function to return the address of WNative token. */ function wnative() public view virtual override returns (address) { return _wnative; } /** * @notice function to return the address of Native token. */ function native() public view virtual override returns (address) { return _native; } /** * @notice function to return the address of Dexspan. */ function dexspan() public view virtual returns (address) { return _dexspan; } /** * @notice function to return the address of AssetForwarder. */ function assetForwarder() public view virtual returns (address) { return _assetForwarder; } /** * @notice function to return the address of AssetBridge. */ function assetBridge() public view virtual returns (address) { return _assetBridge; } /** * @notice function to check whether an adapter is whitelisted. * @param adapter Address of the adapter. */ function isAdapterWhitelisted(address adapter) public view returns (bool) { return adapterWhitelist[adapter]; } /** * @notice function to set dexspan address. * @param __dexspan Address of the dexspan. */ function setDexspan(address __dexspan) external onlyRole(SETTER_ROLE) { _dexspan = __dexspan; } /** * @notice function to set assetForwarder address. * @param __assetForwarder Address of the assetForwarder. */ function setAssetForwarder( address __assetForwarder ) external onlyRole(SETTER_ROLE) { _assetForwarder = __assetForwarder; } /** * @notice function to set assetForwarder address. * @param __assetBridge Address of the assetBridge. */ function setAssetBridge( address __assetBridge ) external onlyRole(SETTER_ROLE) { _assetBridge = __assetBridge; } /** * @notice function to set adapter whitelist. * @param adapters Addresses of the adapters. * @param shouldWhitelist Boolean array suggesting whether to whitelist the adapters. */ function setAdapterWhitelist( address[] memory adapters, bool[] memory shouldWhitelist ) external onlyRole(SETTER_ROLE) { uint256 len = adapters.length; require( len != 0 && len == shouldWhitelist.length, Errors.ARRAY_LENGTH_MISMATCH ); for (uint i = 0; i < len; ) { adapterWhitelist[adapters[i]] = shouldWhitelist[i]; unchecked { ++i; } } } /** * @dev function to execute batch calls on the same chain * @param appId Application Id * @param tokens Addresses of the tokens to fetch from the user * @param amounts amounts of the tokens to fetch from the user * @param feeInfos feeInfo for the tokens * @param target Addresses of the contracts to call * @param value Amounts of native tokens to send along with the transactions * @param callType Type of call. 1: call, 2: delegatecall * @param data Data of the transactions */ function executeBatchCallsSameChain( uint256 appId, address[] calldata tokens, uint256[] calldata amounts, FeeInfo[] calldata feeInfos, address[] calldata target, uint256[] calldata value, uint256[] calldata callType, bytes[] calldata data ) external payable nonReentrant { uint256 tokensLength = tokens.length; require( tokensLength == amounts.length && tokensLength == feeInfos.length, Errors.ARRAY_LENGTH_MISMATCH ); uint256 totalValue = 0; for (uint256 i = 0; i < tokensLength; ) { totalValue += _pullTokens(tokens[i], amounts[i]); tokensToRefund[msg.sender].tokens.push(tokens[i]); if (feeInfos[i].fee != 0) { if (feeInfos[i].fee > (amounts[i] * 500) / 10000) revert(IntentErrors.FEE_EXCEEDS_MAX_BIPS); if (feeInfos[i].recipient == address(0)) revert(IntentErrors.FEE_RECIPIENT_CANNOT_BE_ZERO_ADDRESS); withdrawTokens( tokens[i], feeInfos[i].recipient, uint256(feeInfos[i].fee) ); } unchecked { ++i; } } require( msg.value >= totalValue, Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED ); for (uint256 i = 0; i < callType.length; ) { // callType can be either 1 or 2 require(callType[i] < 3, Errors.INVALID_CALL_TYPE); unchecked { ++i; } } _executeBatchCalls(appId, msg.sender, target, value, callType, data); } /** * @dev function to execute batch calls * @param appId Application Id * @param refundRecipient Address of recipient of refunds of dust at the end * @param target Addresses of the contracts to call * @param value Amounts of native tokens to send along with the transactions * @param data Data of the transactions * @param callType Type of call. 1: call, 2: delegatecall */ function executeBatchCallsDestChain( uint256 appId, address refundRecipient, address[] calldata target, uint256[] calldata value, uint256[] calldata callType, bytes[] calldata data ) external payable { require(msg.sender == address(this), Errors.ONLY_SELF); _executeBatchCalls( appId, refundRecipient, target, value, callType, data ); } /** * @dev function to execute batch calls * @param appId Application Id * @param target Addresses of the contracts to call * @param value Amounts of native tokens to send along with the transactions * @param data Data of the transactions * @param callType Type of call. 1: call, 2: delegatecall */ function _executeBatchCalls( uint256 appId, address refundRecipient, address[] calldata target, uint256[] calldata value, uint256[] calldata callType, bytes[] calldata data ) internal { uint256 targetLength = target.length; require( targetLength != 0 && targetLength == value.length && value.length == data.length && data.length == callType.length, Errors.WRONG_BATCH_PROVIDED ); if (target.length == 1) { _execute( refundRecipient, target[0], address(0), address(0), value[0], callType[0], data[0] ); } else { _execute( refundRecipient, target[0], address(0), target[1], value[0], callType[0], data[0] ); for (uint256 i = 1; i < targetLength; ) { if (i != targetLength - 1) { _execute( refundRecipient, target[i], target[i - 1], target[i + 1], value[i], callType[i], data[i] ); } else { _execute( refundRecipient, target[i], target[i - 1], address(0), value[i], callType[i], data[i] ); } unchecked { ++i; } } } processRefunds(refundRecipient); emit Executed(appId); } function _pullTokens( address token, uint256 amount ) internal returns (uint256) { uint256 totalValue = 0; if (token == native()) { totalValue += amount; } else { IERC20(token).safeTransferFrom(msg.sender, address(this), amount); } return totalValue; } function _execute( address refundRecipient, address target, address precedingAdapter, address succeedingAdapter, uint256 value, uint256 callType, bytes memory data ) internal { require(adapterWhitelist[target], Errors.ADAPTER_NOT_WHITELISTED); bytes memory _calldata; if (address(BaseAdapter(target).adapterDataProvider()) == address(0)) { _calldata = abi.encodeWithSelector( EoaExecutorWithoutDataProvider.execute.selector, data ); } else { _calldata = abi.encodeWithSelector( EoaExecutorWithDataProvider.execute.selector, precedingAdapter, succeedingAdapter, data ); } bytes memory result; if (callType == 1) result = CallLib._call(target, value, _calldata); else if (callType == 2) result = CallLib._delegateCall(target, _calldata); if (result.length != 0) processResult(refundRecipient, result); } function processResult(address user, bytes memory data) internal { address[] memory tokens = abi.decode(data, (address[])); for (uint256 i = 0; i < tokens.length; ) { tokensToRefund[user].tokens.push(tokens[i]); unchecked { ++i; } } } function processRefunds(address user) internal { uint256 len = tokensToRefund[user].tokens.length; for (uint256 i = 0; i < len; ) { withdrawTokens( tokensToRefund[user].tokens[i], user, type(uint256).max ); unchecked { ++i; } } delete tokensToRefund[user]; } function handleMessage( address tokenSent, uint256 amount, bytes memory instruction ) external onlyNitro nonReentrant { ( uint256 appId, address refundAddress, address[] memory target, uint256[] memory value, uint256[] memory callType, bytes[] memory data ) = abi.decode( instruction, (uint256, address, address[], uint256[], uint256[], bytes[]) ); for (uint256 i = 0; i < callType.length; ) { if (callType[i] > 2) { withdrawTokens(tokenSent, refundAddress, amount); emit OperationFailedRefundEvent( tokenSent, refundAddress, amount ); return; } unchecked { ++i; } } // solhint-disable-next-line avoid-low-level-calls (bool success, ) = address(this).call( abi.encodeWithSelector( this.executeBatchCallsDestChain.selector, appId, refundAddress, target, value, callType, data ) ); if (success) { emit OperationSuccessful(); } else { withdrawTokens(tokenSent, refundAddress, amount); emit OperationFailedRefundEvent(tokenSent, refundAddress, amount); } } // solhint-disable-next-line no-empty-blocks receive() external payable {} function adminWithdrawFunds( address _token, address _recipient, uint256 _amount ) external onlyRole(DEFAULT_ADMIN_ROLE) { if (_token == native()) { if (_amount == type(uint256).max) _amount = address(this).balance; (bool success, ) = _recipient.call{value: _amount}(""); if (!success) revert("Transfer failed"); } else { if (_amount == type(uint256).max) _amount = IERC20(_token).balanceOf(address(this)); IERC20(_token).transfer(_recipient, _amount); } } /** * @notice modifier to ensure that only Nitro bridge can call handleMessage function */ modifier onlyNitro() { _onlyNitro(); _; } function _onlyNitro() private view { require( msg.sender == _assetForwarder || msg.sender == _dexspan || msg.sender == _assetBridge, Errors.ONLY_NITRO ); } function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * 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[EIP 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {IAdapterDataProvider} from "./interfaces/IAdapterDataProvider.sol"; /** * @title AdapterDataProvider * @author Router Protocol * @notice This contract serves as the data provider for an intent adapter based on Router * Cross-Chain Intent Framework. */ contract AdapterDataProvider is IAdapterDataProvider { address private _owner; mapping(address => bool) private _headRegistry; mapping(address => bool) private _tailRegistry; mapping(address => bool) private _inboundAssetRegistry; mapping(address => bool) private _outboundAssetRegistry; constructor(address __owner) { _owner = __owner; } /** * @inheritdoc IAdapterDataProvider */ function owner() external view returns (address) { return _owner; } /** * @inheritdoc IAdapterDataProvider */ function setOwner(address __owner) external onlyOwner { _owner = __owner; } /** * @inheritdoc IAdapterDataProvider */ function isAuthorizedPrecedingContract( address precedingContract ) external view returns (bool) { if (precedingContract == address(0)) return true; return _headRegistry[precedingContract]; } /** * @inheritdoc IAdapterDataProvider */ function isAuthorizedSucceedingContract( address succeedingContract ) external view returns (bool) { if (succeedingContract == address(0)) return true; return _tailRegistry[succeedingContract]; } /** * @inheritdoc IAdapterDataProvider */ function isValidInboundAsset(address asset) external view returns (bool) { return _inboundAssetRegistry[asset]; } /** * @inheritdoc IAdapterDataProvider */ function isValidOutboundAsset(address asset) external view returns (bool) { return _outboundAssetRegistry[asset]; } /** * @inheritdoc IAdapterDataProvider */ function setPrecedingContract( address precedingContract, bool isValid ) external onlyOwner { _headRegistry[precedingContract] = isValid; } /** * @inheritdoc IAdapterDataProvider */ function setSucceedingContract( address succeedingContract, bool isValid ) external onlyOwner { _tailRegistry[succeedingContract] = isValid; } /** * @inheritdoc IAdapterDataProvider */ function setInboundAsset(address asset, bool isValid) external onlyOwner { _inboundAssetRegistry[asset] = isValid; } /** * @inheritdoc IAdapterDataProvider */ function setOutboundAsset(address asset, bool isValid) external onlyOwner { _outboundAssetRegistry[asset] = isValid; } /** * @notice modifier to ensure that only owner can call this function */ modifier onlyOwner() { _onlyOwner(); _; } function _onlyOwner() private view { require(msg.sender == _owner, "Only owner"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {Basic} from "./common/Basic.sol"; import {Errors} from "./utils/Errors.sol"; import {ReentrancyGuard} from "./utils/ReentrancyGuard.sol"; import {AdapterDataProvider} from "./AdapterDataProvider.sol"; /** * @title BaseAdapter * @author Router Protocol * @notice This contract is the base implementation of an intent adapter based on Router * Cross-Chain Intent Framework. */ abstract contract BaseAdapter is Basic, ReentrancyGuard { address private immutable _self; address private immutable _native; address private immutable _wnative; AdapterDataProvider private immutable _adapterDataProvider; event ExecutionEvent(string indexed adapterName, bytes data); event OperationFailedRefundEvent( address token, address recipient, uint256 amount ); event UnsupportedOperation( address token, address refundAddress, uint256 amount ); constructor( address __native, address __wnative, bool __deployDataProvider, address __owner ) { _self = address(this); _native = __native; _wnative = __wnative; AdapterDataProvider dataProvider; if (__deployDataProvider) dataProvider = new AdapterDataProvider(__owner); else dataProvider = AdapterDataProvider(address(0)); _adapterDataProvider = dataProvider; } /** * @dev function to get the address of weth */ function wnative() public view override returns (address) { return _wnative; } /** * @dev function to get the address of native token */ function native() public view override returns (address) { return _native; } /** * @dev function to get the AdapterDataProvider instance for this contract */ function adapterDataProvider() public view returns (AdapterDataProvider) { return _adapterDataProvider; } /** * @dev Function to check whether the contract is a valid preceding contract registered in * the head registry. * @dev This registry governs the initiation of the adapter, exclusively listing authorized * preceding adapters. * @notice Only the adapters documented in this registry can invoke the current adapter, * thereby guaranteeing regulated and secure execution sequences. * @param precedingContract Address of preceding contract. * @return true if valid, false if invalid. */ function isAuthorizedPrecedingContract( address precedingContract ) public view returns (bool) { return _adapterDataProvider.isAuthorizedPrecedingContract( precedingContract ); } /** * @dev Function to check whether the contract is a valid succeeding contract registered in * the tail registry. * @dev This registry dictates the potential succeeding actions by listing adapters that * may be invoked following the current one. * @notice Only the adapters documented in this registry can be invoked by the current adapter, * thereby guaranteeing regulated and secure execution sequences. * @param succeedingContract Address of succeeding contract. * @return true if valid, false if invalid. */ function isAuthorizedSucceedingContract( address succeedingContract ) public view returns (bool) { return _adapterDataProvider.isAuthorizedSucceedingContract( succeedingContract ); } /** * @dev Function to check whether the asset is a valid inbound asset registered in the inbound * asset registry. * @dev This registry keeps track of all the acceptable incoming assets, ensuring that the * adapter only processes predefined asset types. * @param asset Address of the asset. * @return true if valid, false if invalid. */ function isValidInboundAsset(address asset) public view returns (bool) { return _adapterDataProvider.isValidInboundAsset(asset); } /** * @dev Function to check whether the asset is a valid outbound asset registered in the outbound * asset registry. * @dev It manages the types of assets that the adapter is allowed to output, thus controlling * the flow’s output and maintaining consistency. * @param asset Address of the asset. * @return true if valid, false if invalid. */ function isValidOutboundAsset(address asset) public view returns (bool) { return _adapterDataProvider.isValidOutboundAsset(asset); } /** * @dev function to get the name of the adapter */ function name() public view virtual returns (string memory); /** * @dev function to get the address of the contract */ function self() public view returns (address) { return _self; } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {TokenInterface} from "./Interfaces.sol"; import {TokenUtilsBase} from "./TokenUtilsBase.sol"; abstract contract Basic is TokenUtilsBase { function getTokenBal(address token) internal view returns (uint _amt) { _amt = address(token) == native() ? address(this).balance : TokenInterface(token).balanceOf(address(this)); } function approve(address token, address spender, uint256 amount) internal { // solhint-disable-next-line no-empty-blocks try TokenInterface(token).approve(spender, amount) {} catch { TokenInterface(token).approve(spender, 0); TokenInterface(token).approve(spender, amount); } } function convertNativeToWnative(uint amount) internal { TokenInterface(wnative()).deposit{value: amount}(); } function convertWnativeToNative(uint amount) internal { TokenInterface(wnative()).withdraw(amount); } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.18; interface TokenInterface { function approve(address, uint256) external; function transfer(address, uint) external; function transferFrom(address, address, uint) external; function deposit() external payable; function withdraw(uint) external; function balanceOf(address) external view returns (uint); function decimals() external view returns (uint); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {IWETH} from "../interfaces/IWETH.sol"; import {SafeERC20, IERC20} from "../utils/SafeERC20.sol"; abstract contract TokenUtilsBase { using SafeERC20 for IERC20; function wnative() public view virtual returns (address); function native() public view virtual returns (address); function approveToken( address _tokenAddr, address _to, uint256 _amount ) internal { if (_tokenAddr == native()) return; if (IERC20(_tokenAddr).allowance(address(this), _to) < _amount) { IERC20(_tokenAddr).safeApprove(_to, _amount); } } function pullTokensIfNeeded( address _token, address _from, uint256 _amount ) internal returns (uint256) { // handle max uint amount if (_amount == type(uint256).max) { _amount = getBalance(_token, _from); } if ( _from != address(0) && _from != address(this) && _token != native() && _amount != 0 ) { IERC20(_token).safeTransferFrom(_from, address(this), _amount); } return _amount; } function withdrawTokens( address _token, address _to, uint256 _amount ) internal returns (uint256) { if (_amount == type(uint256).max) { _amount = getBalance(_token, address(this)); } if (_to != address(0) && _to != address(this) && _amount != 0) { if (_token != native()) { IERC20(_token).safeTransfer(_to, _amount); } else { (bool success, ) = _to.call{value: _amount}(""); require(success, "native send fail"); } } return _amount; } function depositWnative(uint256 _amount) internal { IWETH(wnative()).deposit{value: _amount}(); } function withdrawWnative(uint256 _amount) internal { IWETH(wnative()).withdraw(_amount); } function getBalance( address _tokenAddr, address _acc ) internal view returns (uint256) { if (_tokenAddr == native()) { return _acc.balance; } else { return IERC20(_tokenAddr).balanceOf(_acc); } } function getTokenDecimals(address _token) internal view returns (uint256) { if (_token == native()) return 18; return IERC20(_token).decimals(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; /** * @title Interface for Adapter Data Provider contract for intent adapter. * @author Router Protocol. */ interface IAdapterDataProvider { /** * @dev Function to get the address of owner. */ function owner() external view returns (address); /** * @dev Function to set the address of owner. * @dev This function can only be called by the owner of this contract. * @param __owner Address of the new owner */ function setOwner(address __owner) external; /** * @dev Function to check whether the contract is a valid preceding contract registered in * the head registry. * @dev This registry governs the initiation of the adapter, exclusively listing authorized * preceding adapters. * @notice Only the adapters documented in this registry can invoke the current adapter, * thereby guaranteeing regulated and secure execution sequences. * @param precedingContract Address of preceding contract. * @return true if valid, false if invalid. */ function isAuthorizedPrecedingContract( address precedingContract ) external view returns (bool); /** * @dev Function to check whether the contract is a valid succeeding contract registered in * the tail registry. * @dev This registry dictates the potential succeeding actions by listing adapters that * may be invoked following the current one. * @notice Only the adapters documented in this registry can be invoked by the current adapter, * thereby guaranteeing regulated and secure execution sequences. * @param succeedingContract Address of succeeding contract. * @return true if valid, false if invalid. */ function isAuthorizedSucceedingContract( address succeedingContract ) external view returns (bool); /** * @dev Function to check whether the asset is a valid inbound asset registered in the inbound * asset registry. * @dev This registry keeps track of all the acceptable incoming assets, ensuring that the * adapter only processes predefined asset types. * @param asset Address of the asset. * @return true if valid, false if invalid. */ function isValidInboundAsset(address asset) external view returns (bool); /** * @dev Function to check whether the asset is a valid outbound asset registered in the outbound * asset registry. * @dev It manages the types of assets that the adapter is allowed to output, thus controlling * the flow’s output and maintaining consistency. * @param asset Address of the asset. * @return true if valid, false if invalid. */ function isValidOutboundAsset(address asset) external view returns (bool); /** * @dev Function to set preceding contract (head registry) for the adapter. * @dev This registry governs the initiation of the adapter, exclusively listing authorized * preceding adapters. * @notice Only the adapters documented in this registry can invoke the current adapter, * thereby guaranteeing regulated and secure execution sequences. * @param precedingContract Address of preceding contract. * @param isValid Boolean value suggesting if this is a valid preceding contract. */ function setPrecedingContract( address precedingContract, bool isValid ) external; /** * @dev Function to set succeeding contract (tail registry) for the adapter. * @dev This registry dictates the potential succeeding actions by listing adapters that * may be invoked following the current one. * @notice Only the adapters documented in this registry can be invoked by the current adapter, * thereby guaranteeing regulated and secure execution sequences. * @param succeedingContract Address of succeeding contract. * @param isValid Boolean value suggesting if this is a valid succeeding contract. */ function setSucceedingContract( address succeedingContract, bool isValid ) external; /** * @dev Function to set inbound asset registry for the adapter. * @dev This registry keeps track of all the acceptable incoming assets, ensuring that the * adapter only processes predefined asset types. * @param asset Address of the asset. * @param isValid Boolean value suggesting if this is a valid inbound asset. */ function setInboundAsset(address asset, bool isValid) external; /** * @dev Function to set outbound asset registry for the adapter. * @dev It manages the types of assets that the adapter is allowed to output, thus controlling * the flow’s output and maintaining consistency. * @param asset Address of the asset. * @param isValid Boolean value suggesting if this is a valid inbound asset. */ function setOutboundAsset(address asset, bool isValid) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; interface IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256 supply); function balanceOf(address _owner) external view returns (uint256 balance); function transfer( address _to, uint256 _value ) external returns (bool success); function transferFrom( address _from, address _to, uint256 _value ) external returns (bool success); function approve( address _spender, uint256 _value ) external returns (bool success); function allowance( address _owner, address _spender ) external view returns (uint256 remaining); event Approval( address indexed _owner, address indexed _spender, uint256 _value ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {IERC20} from "../utils/SafeERC20.sol"; abstract contract IWETH { function allowance(address, address) public view virtual returns (uint256); function balanceOf(address) public view virtual returns (uint256); function approve(address, uint256) public virtual; function transfer(address, uint256) public virtual returns (bool); function transferFrom( address, address, uint256 ) public virtual returns (bool); function deposit() public payable virtual; function withdraw(uint256) public virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {BaseAdapter} from "./BaseAdapter.sol"; import {EoaExecutorWithDataProvider, EoaExecutorWithoutDataProvider} from "./utils/EoaExecutor.sol"; abstract contract RouterIntentEoaAdapterWithDataProvider is BaseAdapter, EoaExecutorWithDataProvider { constructor( address __native, address __wnative, address __owner ) BaseAdapter(__native, __wnative, true, __owner) // solhint-disable-next-line no-empty-blocks { } } abstract contract RouterIntentEoaAdapterWithoutDataProvider is BaseAdapter, EoaExecutorWithoutDataProvider { constructor( address __native, address __wnative ) BaseAdapter(__native, __wnative, false, address(0)) // solhint-disable-next-line no-empty-blocks { } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; library Address { //insufficient balance error InsufficientBalance(uint256 available, uint256 required); //unable to send value, recipient may have reverted error SendingValueFail(); //insufficient balance for call error InsufficientBalanceForCall(uint256 available, uint256 required); //call to non-contract error NonContractCall(); function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } function sendValue(address payable recipient, uint256 amount) internal { uint256 balance = address(this).balance; if (balance < amount) { revert InsufficientBalance(balance, amount); } // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{value: amount}(""); if (!(success)) { revert SendingValueFail(); } } function functionCall( address target, bytes memory data ) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, "Address: low-level call with value failed" ); } function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { uint256 balance = address(this).balance; if (balance < value) { revert InsufficientBalanceForCall(balance, value); } return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue( address target, bytes memory data, uint256 weiValue, string memory errorMessage ) private returns (bytes memory) { if (!(isContract(target))) { revert NonContractCall(); } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{value: weiValue}( data ); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; library CallLib { /** * @dev internal method that fecilitates the extenral calls from SmartAccount * @dev similar to execute() of Executor.sol * @param target destination address contract/non-contract * @param value amount of native tokens * @param data function singature of destination */ function _call( address target, uint256 value, bytes memory data ) internal returns (bytes memory result) { // solhint-disable-next-line no-inline-assembly assembly { let success := call( gas(), target, value, add(data, 0x20), mload(data), 0, 0 ) // Get the size of the returned data let size := returndatasize() // Allocate memory for the return data result := mload(0x40) // Set the length of the return data mstore(result, size) // Copy the return data to the allocated memory returndatacopy(add(result, 0x20), 0, size) // Update the free memory pointer mstore(0x40, add(result, add(0x20, size))) if iszero(success) { revert(result, returndatasize()) } } } /** * @dev internal method that fecilitates the extenral calls from SmartAccount * @dev similar to execute() of Executor.sol * @param target destination address contract/non-contract * @param data function singature of destination */ function _delegateCall( address target, bytes memory data ) internal returns (bytes memory result) { require(target != address(this), "delegatecall to self"); // solhint-disable-next-line no-inline-assembly assembly { // Perform delegatecall to the target contract let success := delegatecall( gas(), target, add(data, 0x20), mload(data), 0, 0 ) // Get the size of the returned data let size := returndatasize() // Allocate memory for the return data result := mload(0x40) // Set the length of the return data mstore(result, size) // Copy the return data to the allocated memory returndatacopy(add(result, 0x20), 0, size) // Update the free memory pointer mstore(0x40, add(result, add(0x20, size))) if iszero(success) { revert(result, returndatasize()) } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; abstract contract EoaExecutorWithDataProvider { /** * @dev function to execute an action on an adapter used in an EOA. * @param precedingAdapter Address of the preceding adapter. * @param succeedingAdapter Address of the succeeding adapter. * @param data inputs data. * @return tokens to be refunded to user at the end of tx. */ function execute( address precedingAdapter, address succeedingAdapter, bytes calldata data ) external payable virtual returns (address[] memory tokens); } abstract contract EoaExecutorWithoutDataProvider { /** * @dev function to execute an action on an adapter used in an EOA. * @param data inputs data. * @return tokens to be refunded to user at the end of tx. */ function execute( bytes calldata data ) external payable virtual returns (address[] memory tokens); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; /** * @title Errors library * @author Router Intents Error * @notice Defines the error messages emitted by the contracts on Router Intents */ library Errors { string public constant ARRAY_LENGTH_MISMATCH = "1"; // 'Array lengths mismatch' string public constant INSUFFICIENT_NATIVE_FUNDS_PASSED = "2"; // 'Insufficient native tokens passed' string public constant WRONG_BATCH_PROVIDED = "3"; // 'The targetLength, valueLength, callTypeLength, funcLength do not match in executeBatch transaction functions in batch transaction contract' string public constant INVALID_CALL_TYPE = "4"; // 'The callType value can only be 1 (call)' and 2(delegatecall)' string public constant ONLY_NITRO = "5"; // 'Only nitro can call this function' string public constant ONLY_SELF = "6"; // 'Only the current contract can call this function' string public constant ADAPTER_NOT_WHITELISTED = "7"; // 'Adapter not whitelisted' }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; 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; error ReentrantCall(); 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 make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true if (_status == _ENTERED) { revert ReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {IERC20} from "../interfaces/IERC20.sol"; import {Address} from "./Address.sol"; import {SafeMath} from "./SafeMath.sol"; library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /// @dev Edited so it always first approves 0 and then the value, because of non standard tokens function safeApprove( IERC20 token, address spender, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, 0) ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).add( value ); _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).sub( value, "SafeERC20: decreased allowance below zero" ); _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function _callOptionalReturn(IERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall( data, "SafeERC20: low-level call failed" ); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require( abi.decode(returndata, (bool)), "SafeERC20: operation failed" ); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: mul overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; /** * @title Errors library * @author Router Intents Error * @notice Defines the error messages emitted by the contracts on Router Intents */ library Errors { string public constant ARRAY_LENGTH_MISMATCH = "1"; // 'Array lengths mismatch' string public constant INSUFFICIENT_NATIVE_FUNDS_PASSED = "2"; // 'Insufficient native tokens passed' string public constant WRONG_BATCH_PROVIDED = "3"; // 'The targetLength, valueLength, callTypeLength, funcLength do not match in executeBatch transaction functions in batch transaction contract' string public constant INVALID_CALL_TYPE = "4"; // 'The callType value can only be 1 (call)' and 2(delegatecall)' string public constant ONLY_NITRO = "5"; // 'Only nitro can call this function' string public constant ONLY_SELF = "6"; // 'Only the current contract can call this function' string public constant ADAPTER_NOT_WHITELISTED = "7"; // 'Adapter not whitelisted' string public constant INVALID_BRIDGE_ADDRESS = "8"; // 'Bridge address neither asset forwarder nor dexspan' string public constant BRIDGE_CALL_FAILED = "9"; // 'Bridge call failed' string public constant INVALID_BRDIGE_TX_TYPE = "10"; // 'Bridge tx type cannot be greater than 3' string public constant INVALID_AMOUNT = "11"; // 'Amount is invalid' string public constant INVALID_BRIDGE_CHAIN_ID = "12"; // 'Bridging chainId is invalid' string public constant ZERO_AMOUNT_RECEIVED = "13"; // 'Zero amount received' string public constant INVALID_TX_TYPE = "14"; // 'Invalid txType value' string public constant INVALID_REQUEST = "15"; // 'Invalid Request' string public constant INVALID_ASSET_BRDIGE_TX_TYPE = "16"; // 'Asset Bridge tx type cannot be greater than 1' string public constant FEE_EXCEEDS_MAX_BIPS = "17"; // 'Fee passed exceeds max bips fee' string public constant FEE_RECIPIENT_CANNOT_BE_ZERO_ADDRESS = "18"; // 'Fee recipient cannot be address(0)' }
{ "optimizer": { "enabled": true, "runs": 1000000 }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"__native","type":"address"},{"internalType":"address","name":"__wnative","type":"address"},{"internalType":"address","name":"__assetForwarder","type":"address"},{"internalType":"address","name":"__dexspan","type":"address"},{"internalType":"address","name":"__assetBridge","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NonContractCall","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"appId","type":"uint256"}],"name":"Executed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OperationFailedRefundEvent","type":"event"},{"anonymous":false,"inputs":[],"name":"OperationSuccessful","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SETTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"adminWithdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"assetBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dexspan","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"appId","type":"uint256"},{"internalType":"address","name":"refundRecipient","type":"address"},{"internalType":"address[]","name":"target","type":"address[]"},{"internalType":"uint256[]","name":"value","type":"uint256[]"},{"internalType":"uint256[]","name":"callType","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"executeBatchCallsDestChain","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"appId","type":"uint256"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"components":[{"internalType":"uint96","name":"fee","type":"uint96"},{"internalType":"address","name":"recipient","type":"address"}],"internalType":"struct BatchTransaction.FeeInfo[]","name":"feeInfos","type":"tuple[]"},{"internalType":"address[]","name":"target","type":"address[]"},{"internalType":"uint256[]","name":"value","type":"uint256[]"},{"internalType":"uint256[]","name":"callType","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"executeBatchCallsSameChain","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenSent","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"instruction","type":"bytes"}],"name":"handleMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"}],"name":"isAdapterWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"native","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"adapters","type":"address[]"},{"internalType":"bool[]","name":"shouldWhitelist","type":"bool[]"}],"name":"setAdapterWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__assetBridge","type":"address"}],"name":"setAssetBridge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__assetForwarder","type":"address"}],"name":"setAssetForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__dexspan","type":"address"}],"name":"setDexspan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wnative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c034620001db57601f6200384438819003918201601f191683019291906001600160401b03841183851017620001e0578160a09284926040968752833981010312620001db576200005181620001f6565b60209162000061838201620001f6565b916200006f858301620001f6565b926200008c60806200008460608601620001f6565b9401620001f6565b916001805560805260a05260018060a01b0380928160018060a01b0319951685600254161760025516836003541617600355169060045416176004556000808052808252828120338252825260ff838220541615620001a3575b7f61c92169ef077349011ff0b1383c894d86c5f0b41d986366b58a6cf31e93beda91828252818152838220338352815260ff84832054161562000168575b835161361890816200020c823960805181818161029a0152818161080701528181612005015281816120ba015281816127750152613101015260a051816105010152f35b8282528181528382209033835252828120600160ff19825416179055339160008051602062003824833981519152339280a438808062000124565b8080528082528281203382528252828120600160ff19825416179055333382600080516020620038248339815191528180a4620000e6565b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620001db5756fe6080604052600436101561001b575b361561001957600080fd5b005b60003560e01c806301ffc9a71461018b57806311b0b42d14610186578063150b7a021461018157806318137a411461017c578063248a9ca314610177578063285f94a0146101725780632cebdeb21461016d5780632f2ff15d1461016857806336568abe146101635780636cec044b1461015e57806375ea1c92146101595780637fe689171461015457806391d148541461014f578063963276f31461014a5780639e28cc3c146101455780639e99ec3914610140578063a2011b3f1461013b578063a217fddf14610136578063c5962f2614610131578063d00a2d5f1461012c578063d547741f14610127578063dfd7cb06146101225763f6f38e7c0361000e57611294565b6111ca565b6110e0565b610fa0565b610e17565b610ddd565b610d84565b610cfd565b610c0a565b610b26565b610a73565b610a21565b610798565b610746565b61065e565b610525565b6104b6565b610464565b610417565b610390565b6102eb565b61024f565b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361024a57807f7965db0b0000000000000000000000000000000000000000000000000000000060209214908115610220575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501438610215565b600080fd5b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b73ffffffffffffffffffffffffffffffffffffffff81160361024a57565b602435906102e9826102be565b565b3461024a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a576103256004356102be565b6103306024356102be565b60643567ffffffffffffffff80821161024a573660238301121561024a57816004013590811161024a573691016024011161024a576040517f150b7a02000000000000000000000000000000000000000000000000000000008152602090f35b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5773ffffffffffffffffffffffffffffffffffffffff6004356103e0816102be565b6103e8611302565b167fffffffffffffffffffffffff00000000000000000000000000000000000000006002541617600255600080f35b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5760043560005260006020526020600160406000200154604051908152f35b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602073ffffffffffffffffffffffffffffffffffffffff60045416604051908152f35b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57600435602435610563816102be565b6000918083528260205261057d6001604085200154611596565b8083528260205260ff6105b383604086209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b5416156105be578280f35b808352826020526105f282604085209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905573ffffffffffffffffffffffffffffffffffffffff339216907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8480a438808280f35b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602435610699816102be565b3373ffffffffffffffffffffffffffffffffffffffff8216036106c257610019906004356116fa565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152fd5b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b3461024a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a576004356107d3816102be565b6024356107df816102be565b604435906107eb6114ca565b8173ffffffffffffffffffffffffffffffffffffffff809416937f00000000000000000000000000000000000000000000000000000000000000001684146000146108e057506000809350828193927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8394146108d8575b5af161086d611f0b565b501561087557005b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5472616e73666572206661696c656400000000000000000000000000000000006044820152606490fd5b0390fd5b479150610863565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461099d575b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481019190915290602090829081600081604481015b03925af180156109985761097157005b6100199060203d8111610991575b6109898183610eee565b8101906121d6565b503d61097f565b612093565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529150602082602481865afa92831561099857610961936020936000916109f4575b5092509250610907565b610a149150843d8111610a1a575b610a0c8183610eee565b810190612084565b386109ea565b503d610a02565b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602073ffffffffffffffffffffffffffffffffffffffff60025416604051908152f35b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602060ff610ae9602435610ab5816102be565b6004356000526000845260406000209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54166040519015158152f35b9181601f8401121561024a5782359167ffffffffffffffff831161024a576020808501948460051b01011161024a57565b60c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57610b586102dc565b67ffffffffffffffff9060443582811161024a57610b7a903690600401610af5565b60649291923584811161024a57610b95903690600401610af5565b60849291923586811161024a57610bb0903690600401610af5565b93909260a43597881161024a57610bce610019983690600401610af5565b979096600435612393565b9181601f8401121561024a5782359167ffffffffffffffff831161024a576020808501948460061b01011161024a57565b6101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5767ffffffffffffffff60243581811161024a57610c5760049136908301610af5565b60449291923584811161024a57610c719036908401610af5565b60649291923586811161024a57610c8b9036908601610bd9565b60849291923588811161024a57610ca59036908801610af5565b9160a4358a811161024a57610cbd9036908a01610af5565b95909460c4358c811161024a57610cd79036908c01610af5565b99909860e4359d8e1161024a57610cf48c6100199f369101610af5565b9d909c35611b36565b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5773ffffffffffffffffffffffffffffffffffffffff600435610d4d816102be565b610d55611302565b167fffffffffffffffffffffffff00000000000000000000000000000000000000006004541617600455600080f35b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5760206040517f61c92169ef077349011ff0b1383c894d86c5f0b41d986366b58a6cf31e93beda8152f35b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602060405160008152f35b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5773ffffffffffffffffffffffffffffffffffffffff600435610e67816102be565b610e6f611302565b167fffffffffffffffffffffffff00000000000000000000000000000000000000006003541617600355600080f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff821117610ee957604052565b610e9e565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610ee957604052565b67ffffffffffffffff8111610ee957601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192610f7582610f2f565b91610f836040519384610eee565b82948184528183011161024a578281602093846000960137010152565b3461024a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57600435610fdb816102be565b60443567ffffffffffffffff811161024a573660238201121561024a5761100c903690602481600401359101610f69565b61107773ffffffffffffffffffffffffffffffffffffffff806002541633149081156110d1575b81156110c3575b506040519061104882610ecd565b600182527f35000000000000000000000000000000000000000000000000000000000000006020830152611adc565b6002600154146110995761109391600260015560243590613468565b60018055005b60046040517f37ed32e8000000000000000000000000000000000000000000000000000000008152fd5b90506004541633143861103a565b80915060035416331490611033565b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57610019602435600435611121826102be565b80600052600060205261113b600160406000200154611596565b6116fa565b67ffffffffffffffff8111610ee95760051b60200190565b8015150361024a57565b81601f8201121561024a5780359161117983611140565b926111876040519485610eee565b808452602092838086019260051b82010192831161024a578301905b8282106111b1575050505090565b83809183356111bf81611158565b8152019101906111a3565b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5767ffffffffffffffff60043581811161024a573660238201121561024a57806004013561122581611140565b916112336040519384610eee565b81835260209160248385019160051b8301019136831161024a57602401905b82821061127b576024358587821161024a57611275610019923690600401611162565b906119f2565b8380918335611289816102be565b815201910190611252565b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5773ffffffffffffffffffffffffffffffffffffffff6004356112e4816102be565b166000526006602052602060ff604060002054166040519015158152f35b3360009081527f637999432676374d4ea036a5e1ac845bfb5900b653d4393f12108092e01503ce60205260409020547f61c92169ef077349011ff0b1383c894d86c5f0b41d986366b58a6cf31e93beda9060ff161561135e5750565b61136733611955565b61136f61183c565b91603061137b84611897565b536078611387846118a4565b5360415b60018111611477576108d4604861144585611419886113aa88156118f0565b6040519485937f416363657373436f6e74726f6c3a206163636f756e742000000000000000000060208601526113ea815180926020603789019101611669565b84017f206973206d697373696e6720726f6c65200000000000000000000000000000006037820152019061168c565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610eee565b6040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352600483016116e6565b90600f81169060108210156114c5577f30313233343536373839616263646566000000000000000000000000000000006114c0921a6114b684876118b4565b5360041c916118c5565b61138b565b611868565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff161561150357565b61150c33611955565b60009061151761183c565b91603061152384611897565b53607861152f846118a4565b5360415b60018111611552576108d4604861144585611419886113aa88156118f0565b90600f81169060108210156114c5577f3031323334353637383961626364656600000000000000000000000000000000611591921a6114b684876118b4565b611533565b80600052600060205260ff6115cf3360406000209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b5416156115d95750565b6115e233611955565b6115ea61183c565b9160306115f684611897565b536078611602846118a4565b5360415b60018111611625576108d4604861144585611419886113aa88156118f0565b90600f81169060108210156114c5577f3031323334353637383961626364656600000000000000000000000000000000611664921a6114b684876118b4565b611606565b60005b83811061167c5750506000910152565b818101518382015260200161166c565b9061169f60209282815194859201611669565b0190565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936116df81518092818752878088019101611669565b0116010190565b9060206116f79281815201906116a3565b90565b6000908082528160205260ff61173384604085209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b541661173e57505050565b8082528160205261177283604084209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b73ffffffffffffffffffffffffffffffffffffffff3394169280a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b906101f49182810292818404149015171561181c57565b6117d6565b906001820180921161181c57565b9190820180921161181c57565b604051906080820182811067ffffffffffffffff821117610ee957604052604282526060366020840137565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8051156114c55760200190565b8051600110156114c55760210190565b9081518110156114c5570160200190565b801561181c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b156118f757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b604051906060820182811067ffffffffffffffff821117610ee957604052602a82526040366020840137603061198a83611897565b536078611996836118a4565b536029905b600182116119ae576116f79150156118f0565b600f81169060108210156114c5577f30313233343536373839616263646566000000000000000000000000000000006119ec921a6114b684866118b4565b9061199b565b6119fa611302565b80519182151580611a99575b611a1890611a12611aa3565b90611adc565b600090815b848110611a2b575050505050565b80611a3860019284611b22565b51151573ffffffffffffffffffffffffffffffffffffffff611a5a8388611b22565b511685526006602052604085209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00835416911617905501611a1d565b5080518314611a06565b60405190611ab082610ecd565b600182527f31000000000000000000000000000000000000000000000000000000000000006020830152565b15611ae45750565b6108d4906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301906116a3565b80518210156114c55760209160051b010190565b9e9d9c9b9a999897969593929460026001541461109957600260015583831480611d5d575b611b6d90611a12969594939296611aa3565b60009485965b838810611bd957505050505050611b969150611b8d611e99565b90341015611adc565b60005b868110611bb65750611bad98993390612505565b6102e960018055565b80611bd36003611bc96001948b8b611d7e565b3510611a12611ed2565b01611b99565b909192939495611c1190611c0b611bf9611bf48b8989611d7e565b611d8e565b611c048b8a87611d7e565b3590612757565b9061182f565b96611c53611c3f3373ffffffffffffffffffffffffffffffffffffffff166000526005602052604060002090565b611c4d611bf4848989611d7e565b90611db0565b611c7a611c69611c64838a87611dfe565b611e0e565b6bffffffffffffffffffffffff1690565b611c8e575b60010196959493929190611b73565b611c9c611c64828986611dfe565b6bffffffffffffffffffffffff611cc8611cc0611cba858b88611d7e565b35611805565b612710900490565b911611611d525760209073ffffffffffffffffffffffffffffffffffffffff611cfc83611cf6848c89611dfe565b01611d8e565b1615611d4757611d3f8489611d39611c69611c6486611d32600199611cf68f8f611d2c611bf48780948d94611d7e565b9a611dfe565b948b611dfe565b91611fa0565b509050611c7f565b6108d4611445611e60565b6108d4611445611e27565b50828514611b5b565b90156114c55790565b90600110156114c55760200190565b91908110156114c55760051b0190565b356116f7816102be565b80548210156114c55760005260206000200190600090565b805468010000000000000000811015610ee957611dd291600182018155611d98565b819291549060031b9173ffffffffffffffffffffffffffffffffffffffff809116831b921b1916179055565b91908110156114c55760061b0190565b356bffffffffffffffffffffffff8116810361024a5790565b60405190611e3482610ecd565b600282527f31370000000000000000000000000000000000000000000000000000000000006020830152565b60405190611e6d82610ecd565b600282527f31380000000000000000000000000000000000000000000000000000000000006020830152565b60405190611ea682610ecd565b600182527f32000000000000000000000000000000000000000000000000000000000000006020830152565b60405190611edf82610ecd565b600182527f34000000000000000000000000000000000000000000000000000000000000006020830152565b3d15611f36573d90611f1c82610f2f565b91611f2a6040519384610eee565b82523d6000602084013e565b606090565b15611f4257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6e61746976652073656e64206661696c000000000000000000000000000000006044820152fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8314612072575b829073ffffffffffffffffffffffffffffffffffffffff908184168015159081612067575b508061205e575b612000575b5050505090565b8116907f000000000000000000000000000000000000000000000000000000000000000016811461203e57916120359261214a565b38818180611ff9565b50600080808093612059955af1612053611f0b565b50611f3b565b612035565b50821515611ff4565b905030141538611fed565b915061207e308361209f565b91611fc8565b9081602091031261024a575190565b6040513d6000823e3d90fd5b73ffffffffffffffffffffffffffffffffffffffff908116907f0000000000000000000000000000000000000000000000000000000000000000811682036120e75750503190565b60246020929360405194859384927f70a082310000000000000000000000000000000000000000000000000000000084521660048301525afa90811561099857600091612132575090565b6116f7915060203d8111610a1a57610a0c8183610eee565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff909216602483015260448201929092526102e9916121d182606481015b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283610eee565b6121eb565b9081602091031261024a57516116f781611158565b6122419173ffffffffffffffffffffffffffffffffffffffff6040519261221184610ecd565b602084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646020850152166122c3565b8051908161224d575050565b60208061225e9383010191016121d6565b1561226557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5361666545524332303a206f7065726174696f6e206661696c656400000000006044820152fd5b803f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708114159081612389575b501561235f5781600092918360208194519301915af19061230f611f0b565b9115612319575090565b8151156123295750805190602001fd5b6108d4906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352600483016116e6565b60046040517f304619b5000000000000000000000000000000000000000000000000000000008152fd5b90501515386122f0565b906102e99998979695949392916123e16040516123af81610ecd565b600181527f36000000000000000000000000000000000000000000000000000000000000006020820152303314611adc565b612505565b604051906123f382610ecd565b600182527f33000000000000000000000000000000000000000000000000000000000000006020830152565b90156114c5578035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561024a57019081359167ffffffffffffffff831161024a57602001823603811361024a579190565b91908110156114c55760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561024a57019081359167ffffffffffffffff831161024a57602001823603811361024a579190565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820191821161181c57565b9893969290979594918115158061274e575b80612745575b8061273c575b61252f90611a126123e6565b60018281036125c157506125996125a7956125927fbcf6a68a2f901be4a23a41b53acd7697893a7e34def4e28acba584da75283b679c9a9661258b6125ac9b976125856125bc9f9c98611bf4906125a099611d66565b99611d66565b3595611d66565b359461241f565b3691610f69565b9285612bbd565b61301a565b6040519081529081906020820190565b0390a1565b97926126168a89898786612610612599829f9d8d9f9d612609906126028c8f859f816125f6611bf46125fc94611bf494611d66565b9a611d6f565b98611d66565b3597611d66565b359661241f565b946128fa565b885b83811061265757505050505050505050507fbcf6a68a2f901be4a23a41b53acd7697893a7e34def4e28acba584da75283b67916125ac6125bc9261301a565b80888c8989898f968f908a8a8d9361266e856124d8565b84146126e857926126dc926126d5826126e29c6126ce82612599976126c8611bf48c6126b88f9e8f611bf4886126a792611bf494611d7e565b9f6126b1886124d8565b9084611d7e565b9e6126c286611821565b91611d7e565b9c611d7e565b359a611d7e565b3598612478565b95612ce4565b01612618565b9161272a846127379b61272382809661271d611bf48a612713611bf48f9e6127319f6125999f611d7e565b9d6126c2866124d8565b9b611d7e565b3599611d7e565b3597612478565b94612a95565b6126e2565b50848414612523565b5084831461251d565b50828214612517565b60009073ffffffffffffffffffffffffffffffffffffffff908116907f00000000000000000000000000000000000000000000000000000000000000001681036127a057505090565b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820152336024820152306044820152606481019390935290916116f7916121d182608481016121a5565b604051906127fd82610ecd565b600182527f37000000000000000000000000000000000000000000000000000000000000006020830152565b9081602091031261024a57516116f7816102be565b60609073ffffffffffffffffffffffffffffffffffffffff6116f794936000835216602082015281604082015201906116a3565b60609073ffffffffffffffffffffffffffffffffffffffff6116f794931681526000602082015281604082015201906116a3565b9060606116f792600081526000602082015281604082015201906116a3565b6060916116f7949373ffffffffffffffffffffffffffffffffffffffff809216835216602082015281604082015201906116a3565b9490929161293d61293561292e8673ffffffffffffffffffffffffffffffffffffffff166000526006602052604060002090565b5460ff1690565b611a126127f0565b6000604051907f6af563e900000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff91602081600481868b165afa9182156109985791612a67575b5016612a2557506129d7611419916040519283917f09c5eabe000000000000000000000000000000000000000000000000000000006020840152602483016116e6565b915b60609360018103612a0257506129ef9350612e10565b80516129f9575050565b6102e991612f56565b600291925014612a14575b50506129ef565b612a1e9250612e44565b3880612a0d565b612a61906114196040519384927ff5542f2d0000000000000000000000000000000000000000000000000000000060208501526024840161283e565b916129d9565b612a88915060203d8111612a8e575b612a808183610eee565b810190612829565b38612994565b503d612a76565b94909291612ac961293561292e8673ffffffffffffffffffffffffffffffffffffffff166000526006602052604060002090565b6000604051907f6af563e900000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff91602081600481868b165afa9182156109985791612b9f575b5016612b6357506129d7611419916040519283917f09c5eabe000000000000000000000000000000000000000000000000000000006020840152602483016116e6565b612a61906114196040519384927ff5542f2d00000000000000000000000000000000000000000000000000000000602085015260248401612872565b612bb7915060203d8111612a8e57612a808183610eee565b38612b20565b93919091612bf161293561292e8573ffffffffffffffffffffffffffffffffffffffff166000526006602052604060002090565b6000604051907f6af563e900000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff91602081600481868a165afa9182156109985791612cc6575b5016612c8a576129d7611419916040519283917f09c5eabe000000000000000000000000000000000000000000000000000000006020840152602483016116e6565b612a61611419916040519283917ff5542f2d000000000000000000000000000000000000000000000000000000006020840152602483016128a6565b612cde915060203d8111612a8e57612a808183610eee565b38612c48565b959193929093612d1a61293561292e8773ffffffffffffffffffffffffffffffffffffffff166000526006602052604060002090565b6000604051907f6af563e900000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff91602081600481868c165afa9182156109985791612df2575b5016612db55750506129d7611419916040519283917f09c5eabe000000000000000000000000000000000000000000000000000000006020840152602483016116e6565b611419612a6192936040519485937ff5542f2d000000000000000000000000000000000000000000000000000000006020860152602485016128c5565b612e0a915060203d8111612a8e57612a808183610eee565b38612d71565b916000928392602083519301915af1903d916020604051938085528060008387013e84010160405215612e3f57565b503d90fd5b3073ffffffffffffffffffffffffffffffffffffffff821614612e9057816000929160208493519201905af4903d916020604051938085528060008387013e84010160405215612e3f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64656c656761746563616c6c20746f2073656c660000000000000000000000006044820152fd5b81601f8201121561024a57805191612f0583611140565b92612f136040519485610eee565b808452602092838086019260051b82010192831161024a578301905b828210612f3d575050505090565b8380918351612f4b816102be565b815201910190612f2f565b91909182518301602093848183031261024a57848101519167ffffffffffffffff831161024a57612f8d9286809201920101612eee565b92600090815b8551811015612fdd57600190612fd773ffffffffffffffffffffffffffffffffffffffff8087168652600585526040862090612fcf848b611b22565b511690611db0565b01612f93565b505050509050565b80549060009081815582612ff857505050565b815260208120918201915b82811061300f57505050565b818155600101613003565b73ffffffffffffffffffffffffffffffffffffffff811660005260059060209082825260406000205460005b81811061307657505073ffffffffffffffffffffffffffffffffffffffff16600052526102e96040600020612fe5565b60019073ffffffffffffffffffffffffffffffffffffffff841660005285855273ffffffffffffffffffffffffffffffffffffffff6130b9826040600020611d98565b90549060031b1c166130cb308261209f565b73ffffffffffffffffffffffffffffffffffffffff861680151590613170575b80613167575b6130fe575b505001613046565b857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16831461314c576131459261214a565b38806130f6565b6131629250600080809381935af1612053611f0b565b613145565b508015156130f1565b503073ffffffffffffffffffffffffffffffffffffffff871614156130eb565b51906102e9826102be565b81601f8201121561024a578051916131b283611140565b926131c06040519485610eee565b808452602092838086019260051b82010192831161024a578301905b8282106131ea575050505090565b815181529083019083016131dc565b9080601f8301121561024a5781519161321183611140565b9260409061322182519586610eee565b808552602093848087019260051b8501019381851161024a57858101925b858410613250575050505050505090565b835167ffffffffffffffff811161024a5782019083603f8301121561024a57878201519061327d82610f2f565b61328988519182610eee565b8281528588848601011161024a576132aa8a949385948a8685019101611669565b81520193019261323f565b91909160c08184031261024a578051926132d160208301613190565b9260408301519067ffffffffffffffff9182811161024a57836132f5918601612eee565b93606081015183811161024a578461330e91830161319b565b93608082015184811161024a578161332791840161319b565b9360a083015190811161024a576116f792016131f9565b90815180825260208080930193019160005b82811061335e575050505090565b835185529381019392810192600101613350565b90815180825260208092019182818360051b85019501936000915b84831061339d5750505050505090565b90919293949584806133b783856001950387528a516116a3565b980193019301919493929061338d565b949291909695939660c0860190865273ffffffffffffffffffffffffffffffffffffffff9182602091168188015260c0604088015283518092528060e088019401926000905b83821061344f57505050505090613433826116f79697866134419503606088015261333e565b90848203608086015261333e565b9160a0818403910152613372565b845181168652948201949382019360019091019061340d565b61349173ffffffffffffffffffffffffffffffffffffffff9293602080825183010191016132b5565b979492969093169560005b845181101561352e5760026134b18287611b22565b51116134bf5760010161349c565b50505050507fb69677b2a82170abd46dbc9853e73529a3ac021a6e65e7c02f89cdf3b3d063c79350806134f66125bc928585611fa0565b506040519384938460409194939294606082019573ffffffffffffffffffffffffffffffffffffffff80921683521660208201520152565b50613574906114196000969987966040519586948c60208701997f963276f3000000000000000000000000000000000000000000000000000000008b52602488016133c7565b519082305af1613582611f0b565b50156135b2575050507fc2623b31705c3a17d595c59e4c160723c6c140a0a0cbea051392e781b741575d600080a1565b6125bc836134f67fb69677b2a82170abd46dbc9853e73529a3ac021a6e65e7c02f89cdf3b3d063c7958585611fa056fea264697066735822122035a4edeaa8687779d4e52b7dc3961f6dd34f45cbb9e86661ca536d2075048de464736f6c634300081200332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000430000000000000000000000000000000000000400000000000000000000000097eec1c29f745dc7c267f90292aa663d997a601d00000000000000000000000001b4ce0d48ce91eb6bcaf5db33870c65d641b89400000000000000000000000097eec1c29f745dc7c267f90292aa663d997a601d
Deployed Bytecode
0x6080604052600436101561001b575b361561001957600080fd5b005b60003560e01c806301ffc9a71461018b57806311b0b42d14610186578063150b7a021461018157806318137a411461017c578063248a9ca314610177578063285f94a0146101725780632cebdeb21461016d5780632f2ff15d1461016857806336568abe146101635780636cec044b1461015e57806375ea1c92146101595780637fe689171461015457806391d148541461014f578063963276f31461014a5780639e28cc3c146101455780639e99ec3914610140578063a2011b3f1461013b578063a217fddf14610136578063c5962f2614610131578063d00a2d5f1461012c578063d547741f14610127578063dfd7cb06146101225763f6f38e7c0361000e57611294565b6111ca565b6110e0565b610fa0565b610e17565b610ddd565b610d84565b610cfd565b610c0a565b610b26565b610a73565b610a21565b610798565b610746565b61065e565b610525565b6104b6565b610464565b610417565b610390565b6102eb565b61024f565b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361024a57807f7965db0b0000000000000000000000000000000000000000000000000000000060209214908115610220575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501438610215565b600080fd5b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee168152f35b73ffffffffffffffffffffffffffffffffffffffff81160361024a57565b602435906102e9826102be565b565b3461024a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a576103256004356102be565b6103306024356102be565b60643567ffffffffffffffff80821161024a573660238301121561024a57816004013590811161024a573691016024011161024a576040517f150b7a02000000000000000000000000000000000000000000000000000000008152602090f35b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5773ffffffffffffffffffffffffffffffffffffffff6004356103e0816102be565b6103e8611302565b167fffffffffffffffffffffffff00000000000000000000000000000000000000006002541617600255600080f35b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5760043560005260006020526020600160406000200154604051908152f35b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602073ffffffffffffffffffffffffffffffffffffffff60045416604051908152f35b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004300000000000000000000000000000000000004168152f35b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57600435602435610563816102be565b6000918083528260205261057d6001604085200154611596565b8083528260205260ff6105b383604086209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b5416156105be578280f35b808352826020526105f282604085209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905573ffffffffffffffffffffffffffffffffffffffff339216907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8480a438808280f35b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602435610699816102be565b3373ffffffffffffffffffffffffffffffffffffffff8216036106c257610019906004356116fa565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152fd5b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b3461024a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a576004356107d3816102be565b6024356107df816102be565b604435906107eb6114ca565b8173ffffffffffffffffffffffffffffffffffffffff809416937f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1684146000146108e057506000809350828193927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8394146108d8575b5af161086d611f0b565b501561087557005b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5472616e73666572206661696c656400000000000000000000000000000000006044820152606490fd5b0390fd5b479150610863565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461099d575b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481019190915290602090829081600081604481015b03925af180156109985761097157005b6100199060203d8111610991575b6109898183610eee565b8101906121d6565b503d61097f565b612093565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529150602082602481865afa92831561099857610961936020936000916109f4575b5092509250610907565b610a149150843d8111610a1a575b610a0c8183610eee565b810190612084565b386109ea565b503d610a02565b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602073ffffffffffffffffffffffffffffffffffffffff60025416604051908152f35b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602060ff610ae9602435610ab5816102be565b6004356000526000845260406000209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54166040519015158152f35b9181601f8401121561024a5782359167ffffffffffffffff831161024a576020808501948460051b01011161024a57565b60c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57610b586102dc565b67ffffffffffffffff9060443582811161024a57610b7a903690600401610af5565b60649291923584811161024a57610b95903690600401610af5565b60849291923586811161024a57610bb0903690600401610af5565b93909260a43597881161024a57610bce610019983690600401610af5565b979096600435612393565b9181601f8401121561024a5782359167ffffffffffffffff831161024a576020808501948460061b01011161024a57565b6101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5767ffffffffffffffff60243581811161024a57610c5760049136908301610af5565b60449291923584811161024a57610c719036908401610af5565b60649291923586811161024a57610c8b9036908601610bd9565b60849291923588811161024a57610ca59036908801610af5565b9160a4358a811161024a57610cbd9036908a01610af5565b95909460c4358c811161024a57610cd79036908c01610af5565b99909860e4359d8e1161024a57610cf48c6100199f369101610af5565b9d909c35611b36565b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5773ffffffffffffffffffffffffffffffffffffffff600435610d4d816102be565b610d55611302565b167fffffffffffffffffffffffff00000000000000000000000000000000000000006004541617600455600080f35b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5760206040517f61c92169ef077349011ff0b1383c894d86c5f0b41d986366b58a6cf31e93beda8152f35b3461024a5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57602060405160008152f35b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5773ffffffffffffffffffffffffffffffffffffffff600435610e67816102be565b610e6f611302565b167fffffffffffffffffffffffff00000000000000000000000000000000000000006003541617600355600080f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff821117610ee957604052565b610e9e565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610ee957604052565b67ffffffffffffffff8111610ee957601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192610f7582610f2f565b91610f836040519384610eee565b82948184528183011161024a578281602093846000960137010152565b3461024a5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57600435610fdb816102be565b60443567ffffffffffffffff811161024a573660238201121561024a5761100c903690602481600401359101610f69565b61107773ffffffffffffffffffffffffffffffffffffffff806002541633149081156110d1575b81156110c3575b506040519061104882610ecd565b600182527f35000000000000000000000000000000000000000000000000000000000000006020830152611adc565b6002600154146110995761109391600260015560243590613468565b60018055005b60046040517f37ed32e8000000000000000000000000000000000000000000000000000000008152fd5b90506004541633143861103a565b80915060035416331490611033565b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a57610019602435600435611121826102be565b80600052600060205261113b600160406000200154611596565b6116fa565b67ffffffffffffffff8111610ee95760051b60200190565b8015150361024a57565b81601f8201121561024a5780359161117983611140565b926111876040519485610eee565b808452602092838086019260051b82010192831161024a578301905b8282106111b1575050505090565b83809183356111bf81611158565b8152019101906111a3565b3461024a5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5767ffffffffffffffff60043581811161024a573660238201121561024a57806004013561122581611140565b916112336040519384610eee565b81835260209160248385019160051b8301019136831161024a57602401905b82821061127b576024358587821161024a57611275610019923690600401611162565b906119f2565b8380918335611289816102be565b815201910190611252565b3461024a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261024a5773ffffffffffffffffffffffffffffffffffffffff6004356112e4816102be565b166000526006602052602060ff604060002054166040519015158152f35b3360009081527f637999432676374d4ea036a5e1ac845bfb5900b653d4393f12108092e01503ce60205260409020547f61c92169ef077349011ff0b1383c894d86c5f0b41d986366b58a6cf31e93beda9060ff161561135e5750565b61136733611955565b61136f61183c565b91603061137b84611897565b536078611387846118a4565b5360415b60018111611477576108d4604861144585611419886113aa88156118f0565b6040519485937f416363657373436f6e74726f6c3a206163636f756e742000000000000000000060208601526113ea815180926020603789019101611669565b84017f206973206d697373696e6720726f6c65200000000000000000000000000000006037820152019061168c565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610eee565b6040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352600483016116e6565b90600f81169060108210156114c5577f30313233343536373839616263646566000000000000000000000000000000006114c0921a6114b684876118b4565b5360041c916118c5565b61138b565b611868565b3360009081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff161561150357565b61150c33611955565b60009061151761183c565b91603061152384611897565b53607861152f846118a4565b5360415b60018111611552576108d4604861144585611419886113aa88156118f0565b90600f81169060108210156114c5577f3031323334353637383961626364656600000000000000000000000000000000611591921a6114b684876118b4565b611533565b80600052600060205260ff6115cf3360406000209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b5416156115d95750565b6115e233611955565b6115ea61183c565b9160306115f684611897565b536078611602846118a4565b5360415b60018111611625576108d4604861144585611419886113aa88156118f0565b90600f81169060108210156114c5577f3031323334353637383961626364656600000000000000000000000000000000611664921a6114b684876118b4565b611606565b60005b83811061167c5750506000910152565b818101518382015260200161166c565b9061169f60209282815194859201611669565b0190565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936116df81518092818752878088019101611669565b0116010190565b9060206116f79281815201906116a3565b90565b6000908082528160205260ff61173384604085209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b541661173e57505050565b8082528160205261177283604084209073ffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b73ffffffffffffffffffffffffffffffffffffffff3394169280a4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b906101f49182810292818404149015171561181c57565b6117d6565b906001820180921161181c57565b9190820180921161181c57565b604051906080820182811067ffffffffffffffff821117610ee957604052604282526060366020840137565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8051156114c55760200190565b8051600110156114c55760210190565b9081518110156114c5570160200190565b801561181c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b156118f757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b604051906060820182811067ffffffffffffffff821117610ee957604052602a82526040366020840137603061198a83611897565b536078611996836118a4565b536029905b600182116119ae576116f79150156118f0565b600f81169060108210156114c5577f30313233343536373839616263646566000000000000000000000000000000006119ec921a6114b684866118b4565b9061199b565b6119fa611302565b80519182151580611a99575b611a1890611a12611aa3565b90611adc565b600090815b848110611a2b575050505050565b80611a3860019284611b22565b51151573ffffffffffffffffffffffffffffffffffffffff611a5a8388611b22565b511685526006602052604085209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00835416911617905501611a1d565b5080518314611a06565b60405190611ab082610ecd565b600182527f31000000000000000000000000000000000000000000000000000000000000006020830152565b15611ae45750565b6108d4906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301906116a3565b80518210156114c55760209160051b010190565b9e9d9c9b9a999897969593929460026001541461109957600260015583831480611d5d575b611b6d90611a12969594939296611aa3565b60009485965b838810611bd957505050505050611b969150611b8d611e99565b90341015611adc565b60005b868110611bb65750611bad98993390612505565b6102e960018055565b80611bd36003611bc96001948b8b611d7e565b3510611a12611ed2565b01611b99565b909192939495611c1190611c0b611bf9611bf48b8989611d7e565b611d8e565b611c048b8a87611d7e565b3590612757565b9061182f565b96611c53611c3f3373ffffffffffffffffffffffffffffffffffffffff166000526005602052604060002090565b611c4d611bf4848989611d7e565b90611db0565b611c7a611c69611c64838a87611dfe565b611e0e565b6bffffffffffffffffffffffff1690565b611c8e575b60010196959493929190611b73565b611c9c611c64828986611dfe565b6bffffffffffffffffffffffff611cc8611cc0611cba858b88611d7e565b35611805565b612710900490565b911611611d525760209073ffffffffffffffffffffffffffffffffffffffff611cfc83611cf6848c89611dfe565b01611d8e565b1615611d4757611d3f8489611d39611c69611c6486611d32600199611cf68f8f611d2c611bf48780948d94611d7e565b9a611dfe565b948b611dfe565b91611fa0565b509050611c7f565b6108d4611445611e60565b6108d4611445611e27565b50828514611b5b565b90156114c55790565b90600110156114c55760200190565b91908110156114c55760051b0190565b356116f7816102be565b80548210156114c55760005260206000200190600090565b805468010000000000000000811015610ee957611dd291600182018155611d98565b819291549060031b9173ffffffffffffffffffffffffffffffffffffffff809116831b921b1916179055565b91908110156114c55760061b0190565b356bffffffffffffffffffffffff8116810361024a5790565b60405190611e3482610ecd565b600282527f31370000000000000000000000000000000000000000000000000000000000006020830152565b60405190611e6d82610ecd565b600282527f31380000000000000000000000000000000000000000000000000000000000006020830152565b60405190611ea682610ecd565b600182527f32000000000000000000000000000000000000000000000000000000000000006020830152565b60405190611edf82610ecd565b600182527f34000000000000000000000000000000000000000000000000000000000000006020830152565b3d15611f36573d90611f1c82610f2f565b91611f2a6040519384610eee565b82523d6000602084013e565b606090565b15611f4257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6e61746976652073656e64206661696c000000000000000000000000000000006044820152fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8314612072575b829073ffffffffffffffffffffffffffffffffffffffff908184168015159081612067575b508061205e575b612000575b5050505090565b8116907f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee16811461203e57916120359261214a565b38818180611ff9565b50600080808093612059955af1612053611f0b565b50611f3b565b612035565b50821515611ff4565b905030141538611fed565b915061207e308361209f565b91611fc8565b9081602091031261024a575190565b6040513d6000823e3d90fd5b73ffffffffffffffffffffffffffffffffffffffff908116907f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee811682036120e75750503190565b60246020929360405194859384927f70a082310000000000000000000000000000000000000000000000000000000084521660048301525afa90811561099857600091612132575090565b6116f7915060203d8111610a1a57610a0c8183610eee565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff909216602483015260448201929092526102e9916121d182606481015b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283610eee565b6121eb565b9081602091031261024a57516116f781611158565b6122419173ffffffffffffffffffffffffffffffffffffffff6040519261221184610ecd565b602084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646020850152166122c3565b8051908161224d575050565b60208061225e9383010191016121d6565b1561226557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5361666545524332303a206f7065726174696f6e206661696c656400000000006044820152fd5b803f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708114159081612389575b501561235f5781600092918360208194519301915af19061230f611f0b565b9115612319575090565b8151156123295750805190602001fd5b6108d4906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352600483016116e6565b60046040517f304619b5000000000000000000000000000000000000000000000000000000008152fd5b90501515386122f0565b906102e99998979695949392916123e16040516123af81610ecd565b600181527f36000000000000000000000000000000000000000000000000000000000000006020820152303314611adc565b612505565b604051906123f382610ecd565b600182527f33000000000000000000000000000000000000000000000000000000000000006020830152565b90156114c5578035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561024a57019081359167ffffffffffffffff831161024a57602001823603811361024a579190565b91908110156114c55760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561024a57019081359167ffffffffffffffff831161024a57602001823603811361024a579190565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820191821161181c57565b9893969290979594918115158061274e575b80612745575b8061273c575b61252f90611a126123e6565b60018281036125c157506125996125a7956125927fbcf6a68a2f901be4a23a41b53acd7697893a7e34def4e28acba584da75283b679c9a9661258b6125ac9b976125856125bc9f9c98611bf4906125a099611d66565b99611d66565b3595611d66565b359461241f565b3691610f69565b9285612bbd565b61301a565b6040519081529081906020820190565b0390a1565b97926126168a89898786612610612599829f9d8d9f9d612609906126028c8f859f816125f6611bf46125fc94611bf494611d66565b9a611d6f565b98611d66565b3597611d66565b359661241f565b946128fa565b885b83811061265757505050505050505050507fbcf6a68a2f901be4a23a41b53acd7697893a7e34def4e28acba584da75283b67916125ac6125bc9261301a565b80888c8989898f968f908a8a8d9361266e856124d8565b84146126e857926126dc926126d5826126e29c6126ce82612599976126c8611bf48c6126b88f9e8f611bf4886126a792611bf494611d7e565b9f6126b1886124d8565b9084611d7e565b9e6126c286611821565b91611d7e565b9c611d7e565b359a611d7e565b3598612478565b95612ce4565b01612618565b9161272a846127379b61272382809661271d611bf48a612713611bf48f9e6127319f6125999f611d7e565b9d6126c2866124d8565b9b611d7e565b3599611d7e565b3597612478565b94612a95565b6126e2565b50848414612523565b5084831461251d565b50828214612517565b60009073ffffffffffffffffffffffffffffffffffffffff908116907f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1681036127a057505090565b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820152336024820152306044820152606481019390935290916116f7916121d182608481016121a5565b604051906127fd82610ecd565b600182527f37000000000000000000000000000000000000000000000000000000000000006020830152565b9081602091031261024a57516116f7816102be565b60609073ffffffffffffffffffffffffffffffffffffffff6116f794936000835216602082015281604082015201906116a3565b60609073ffffffffffffffffffffffffffffffffffffffff6116f794931681526000602082015281604082015201906116a3565b9060606116f792600081526000602082015281604082015201906116a3565b6060916116f7949373ffffffffffffffffffffffffffffffffffffffff809216835216602082015281604082015201906116a3565b9490929161293d61293561292e8673ffffffffffffffffffffffffffffffffffffffff166000526006602052604060002090565b5460ff1690565b611a126127f0565b6000604051907f6af563e900000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff91602081600481868b165afa9182156109985791612a67575b5016612a2557506129d7611419916040519283917f09c5eabe000000000000000000000000000000000000000000000000000000006020840152602483016116e6565b915b60609360018103612a0257506129ef9350612e10565b80516129f9575050565b6102e991612f56565b600291925014612a14575b50506129ef565b612a1e9250612e44565b3880612a0d565b612a61906114196040519384927ff5542f2d0000000000000000000000000000000000000000000000000000000060208501526024840161283e565b916129d9565b612a88915060203d8111612a8e575b612a808183610eee565b810190612829565b38612994565b503d612a76565b94909291612ac961293561292e8673ffffffffffffffffffffffffffffffffffffffff166000526006602052604060002090565b6000604051907f6af563e900000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff91602081600481868b165afa9182156109985791612b9f575b5016612b6357506129d7611419916040519283917f09c5eabe000000000000000000000000000000000000000000000000000000006020840152602483016116e6565b612a61906114196040519384927ff5542f2d00000000000000000000000000000000000000000000000000000000602085015260248401612872565b612bb7915060203d8111612a8e57612a808183610eee565b38612b20565b93919091612bf161293561292e8573ffffffffffffffffffffffffffffffffffffffff166000526006602052604060002090565b6000604051907f6af563e900000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff91602081600481868a165afa9182156109985791612cc6575b5016612c8a576129d7611419916040519283917f09c5eabe000000000000000000000000000000000000000000000000000000006020840152602483016116e6565b612a61611419916040519283917ff5542f2d000000000000000000000000000000000000000000000000000000006020840152602483016128a6565b612cde915060203d8111612a8e57612a808183610eee565b38612c48565b959193929093612d1a61293561292e8773ffffffffffffffffffffffffffffffffffffffff166000526006602052604060002090565b6000604051907f6af563e900000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff91602081600481868c165afa9182156109985791612df2575b5016612db55750506129d7611419916040519283917f09c5eabe000000000000000000000000000000000000000000000000000000006020840152602483016116e6565b611419612a6192936040519485937ff5542f2d000000000000000000000000000000000000000000000000000000006020860152602485016128c5565b612e0a915060203d8111612a8e57612a808183610eee565b38612d71565b916000928392602083519301915af1903d916020604051938085528060008387013e84010160405215612e3f57565b503d90fd5b3073ffffffffffffffffffffffffffffffffffffffff821614612e9057816000929160208493519201905af4903d916020604051938085528060008387013e84010160405215612e3f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f64656c656761746563616c6c20746f2073656c660000000000000000000000006044820152fd5b81601f8201121561024a57805191612f0583611140565b92612f136040519485610eee565b808452602092838086019260051b82010192831161024a578301905b828210612f3d575050505090565b8380918351612f4b816102be565b815201910190612f2f565b91909182518301602093848183031261024a57848101519167ffffffffffffffff831161024a57612f8d9286809201920101612eee565b92600090815b8551811015612fdd57600190612fd773ffffffffffffffffffffffffffffffffffffffff8087168652600585526040862090612fcf848b611b22565b511690611db0565b01612f93565b505050509050565b80549060009081815582612ff857505050565b815260208120918201915b82811061300f57505050565b818155600101613003565b73ffffffffffffffffffffffffffffffffffffffff811660005260059060209082825260406000205460005b81811061307657505073ffffffffffffffffffffffffffffffffffffffff16600052526102e96040600020612fe5565b60019073ffffffffffffffffffffffffffffffffffffffff841660005285855273ffffffffffffffffffffffffffffffffffffffff6130b9826040600020611d98565b90549060031b1c166130cb308261209f565b73ffffffffffffffffffffffffffffffffffffffff861680151590613170575b80613167575b6130fe575b505001613046565b857f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff16831461314c576131459261214a565b38806130f6565b6131629250600080809381935af1612053611f0b565b613145565b508015156130f1565b503073ffffffffffffffffffffffffffffffffffffffff871614156130eb565b51906102e9826102be565b81601f8201121561024a578051916131b283611140565b926131c06040519485610eee565b808452602092838086019260051b82010192831161024a578301905b8282106131ea575050505090565b815181529083019083016131dc565b9080601f8301121561024a5781519161321183611140565b9260409061322182519586610eee565b808552602093848087019260051b8501019381851161024a57858101925b858410613250575050505050505090565b835167ffffffffffffffff811161024a5782019083603f8301121561024a57878201519061327d82610f2f565b61328988519182610eee565b8281528588848601011161024a576132aa8a949385948a8685019101611669565b81520193019261323f565b91909160c08184031261024a578051926132d160208301613190565b9260408301519067ffffffffffffffff9182811161024a57836132f5918601612eee565b93606081015183811161024a578461330e91830161319b565b93608082015184811161024a578161332791840161319b565b9360a083015190811161024a576116f792016131f9565b90815180825260208080930193019160005b82811061335e575050505090565b835185529381019392810192600101613350565b90815180825260208092019182818360051b85019501936000915b84831061339d5750505050505090565b90919293949584806133b783856001950387528a516116a3565b980193019301919493929061338d565b949291909695939660c0860190865273ffffffffffffffffffffffffffffffffffffffff9182602091168188015260c0604088015283518092528060e088019401926000905b83821061344f57505050505090613433826116f79697866134419503606088015261333e565b90848203608086015261333e565b9160a0818403910152613372565b845181168652948201949382019360019091019061340d565b61349173ffffffffffffffffffffffffffffffffffffffff9293602080825183010191016132b5565b979492969093169560005b845181101561352e5760026134b18287611b22565b51116134bf5760010161349c565b50505050507fb69677b2a82170abd46dbc9853e73529a3ac021a6e65e7c02f89cdf3b3d063c79350806134f66125bc928585611fa0565b506040519384938460409194939294606082019573ffffffffffffffffffffffffffffffffffffffff80921683521660208201520152565b50613574906114196000969987966040519586948c60208701997f963276f3000000000000000000000000000000000000000000000000000000008b52602488016133c7565b519082305af1613582611f0b565b50156135b2575050507fc2623b31705c3a17d595c59e4c160723c6c140a0a0cbea051392e781b741575d600080a1565b6125bc836134f67fb69677b2a82170abd46dbc9853e73529a3ac021a6e65e7c02f89cdf3b3d063c7958585611fa056fea264697066735822122035a4edeaa8687779d4e52b7dc3961f6dd34f45cbb9e86661ca536d2075048de464736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000430000000000000000000000000000000000000400000000000000000000000097eec1c29f745dc7c267f90292aa663d997a601d00000000000000000000000001b4ce0d48ce91eb6bcaf5db33870c65d641b89400000000000000000000000097eec1c29f745dc7c267f90292aa663d997a601d
-----Decoded View---------------
Arg [0] : __native (address): 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
Arg [1] : __wnative (address): 0x4300000000000000000000000000000000000004
Arg [2] : __assetForwarder (address): 0x97eec1c29f745dC7c267F90292AA663d997a601D
Arg [3] : __dexspan (address): 0x01B4CE0d48Ce91eB6bcaf5dB33870C65d641b894
Arg [4] : __assetBridge (address): 0x97eec1c29f745dC7c267F90292AA663d997a601D
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
Arg [1] : 0000000000000000000000004300000000000000000000000000000000000004
Arg [2] : 00000000000000000000000097eec1c29f745dc7c267f90292aa663d997a601d
Arg [3] : 00000000000000000000000001b4ce0d48ce91eb6bcaf5db33870c65d641b894
Arg [4] : 00000000000000000000000097eec1c29f745dc7c267f90292aa663d997a601d
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.