Overview
AVAX Balance
AVAX Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 76,661 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap Exact In | 57191217 | 15 secs ago | IN | 0 AVAX | 0.00136705 | ||||
Swap Exact In | 57191208 | 29 secs ago | IN | 0 AVAX | 0.00014217 | ||||
Swap Exact In | 57191144 | 2 mins ago | IN | 0 AVAX | 0.00051623 | ||||
Swap Exact In | 57191142 | 2 mins ago | IN | 0 AVAX | 0.00014217 | ||||
Swap Exact In | 57191086 | 4 mins ago | IN | 0 AVAX | 0.00045156 | ||||
Swap Exact In | 57191075 | 4 mins ago | IN | 1 AVAX | 0.00045027 | ||||
Swap Exact In | 57191038 | 5 mins ago | IN | 0 AVAX | 0.00014257 | ||||
Swap Exact In | 57191034 | 6 mins ago | IN | 0 AVAX | 0.00145997 | ||||
Swap Exact In | 57191008 | 6 mins ago | IN | 0 AVAX | 0.00014257 | ||||
Swap Exact In | 57190974 | 7 mins ago | IN | 0 AVAX | 0.00062955 | ||||
Swap Exact In | 57190815 | 12 mins ago | IN | 0 AVAX | 0.00014353 | ||||
Swap Exact In | 57190784 | 13 mins ago | IN | 0 AVAX | 0.00014217 | ||||
Swap Exact In | 57190754 | 14 mins ago | IN | 0 AVAX | 0.00014217 | ||||
Swap Exact In | 57190733 | 15 mins ago | IN | 0 AVAX | 0.00014217 | ||||
Swap Exact In | 57190720 | 15 mins ago | IN | 0 AVAX | 0.00160056 | ||||
Swap Exact In | 57190719 | 15 mins ago | IN | 0 AVAX | 0.00025003 | ||||
Swap Exact In | 57190702 | 16 mins ago | IN | 0 AVAX | 0.00076632 | ||||
Swap Exact In | 57190592 | 19 mins ago | IN | 0 AVAX | 0.00042905 | ||||
Swap Exact In | 57190526 | 21 mins ago | IN | 0.0001044 AVAX | 0.00086524 | ||||
Swap Exact In | 57190521 | 21 mins ago | IN | 0 AVAX | 0.00014217 | ||||
Swap Exact In | 57190511 | 21 mins ago | IN | 0 AVAX | 0.00044543 | ||||
Swap Exact In | 57190474 | 23 mins ago | IN | 0 AVAX | 0.00014257 | ||||
Swap Exact In | 57190455 | 23 mins ago | IN | 0 AVAX | 0.00058301 | ||||
Swap Exact In | 57190437 | 24 mins ago | IN | 0 AVAX | 0.00041446 | ||||
Swap Exact In | 57190422 | 24 mins ago | IN | 0 AVAX | 0.00043142 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
57191144 | 2 mins ago | 0.22412329 AVAX | ||||
57191144 | 2 mins ago | 0.22412329 AVAX | ||||
57191086 | 4 mins ago | 2.87122111 AVAX | ||||
57191086 | 4 mins ago | 2.87122111 AVAX | ||||
57191075 | 4 mins ago | 1 AVAX | ||||
57191034 | 6 mins ago | 0.91479321 AVAX | ||||
57191034 | 6 mins ago | 0.91479321 AVAX | ||||
57190974 | 7 mins ago | 157.85524039 AVAX | ||||
57190974 | 7 mins ago | 157.85524039 AVAX | ||||
57190720 | 15 mins ago | 39.57654921 AVAX | ||||
57190720 | 15 mins ago | 39.57654921 AVAX | ||||
57190702 | 16 mins ago | 118.86942077 AVAX | ||||
57190702 | 16 mins ago | 118.86942077 AVAX | ||||
57190526 | 21 mins ago | 0.0001044 AVAX | ||||
57190511 | 21 mins ago | 0.53537004 AVAX | ||||
57190511 | 21 mins ago | 0.53537004 AVAX | ||||
57190335 | 27 mins ago | 0.00013648 AVAX | ||||
57190276 | 29 mins ago | 0.01683195 AVAX | ||||
57190276 | 29 mins ago | 0.01683195 AVAX | ||||
57190188 | 30 mins ago | 0.1 AVAX | ||||
57189923 | 39 mins ago | 1.5 AVAX | ||||
57189702 | 45 mins ago | 0.08954002 AVAX | ||||
57189702 | 45 mins ago | 0.08954002 AVAX | ||||
57189693 | 45 mins ago | 1.02885736 AVAX | ||||
57189693 | 45 mins ago | 1.02885736 AVAX |
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:
Router
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {Ownable2Step, Ownable} from "@openzeppelin/contracts/access/Ownable2Step.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {TokenLib} from "./libraries/TokenLib.sol"; import {RouterLib} from "./libraries/RouterLib.sol"; import {IRouter} from "./interfaces/IRouter.sol"; /** * @title Router * @dev Router contract for swapping tokens using a predefined route. * The route must follow the PackedRoute format. */ contract Router is Ownable2Step, ReentrancyGuard, IRouter { using EnumerableSet for EnumerableSet.AddressSet; address public immutable WNATIVE; EnumerableSet.AddressSet private _trustedLogics; /** * @dev The allowances represent the maximum amount of tokens that the logic contract can spend on behalf of the sender. * It is always reseted at the end of the swap. * The key is calculated as keccak256(abi.encodePacked(token, sender, user)). */ mapping(bytes32 key => uint256 allowance) private _allowances; /** * @dev Constructor for the Router contract. * * Requirements: * - The wnative address must be a contract with code. */ constructor(address wnative, address initialOwner) Ownable(initialOwner) { if (address(wnative).code.length == 0) revert Router__InvalidWnative(); WNATIVE = wnative; } /** * @dev Only allows native token to be received from unwrapping wnative. */ receive() external payable { if (msg.sender != WNATIVE) revert Router__OnlyWnative(); } /** * @dev Fallback function to validate and transfer tokens. */ fallback() external { RouterLib.validateAndTransfer(_allowances); } /** * @dev Returns the logic contract address at the specified index. */ function getTrustedLogicAt( uint256 index ) external view override returns (address) { return _trustedLogics.at(index); } /** * @dev Returns the number of trusted logic contracts. */ function getTrustedLogicLength() external view override returns (uint256) { return _trustedLogics.length(); } /** * @dev Swaps tokens from the sender to the recipient using the exact input amount. It will use the specified logic contract. * * Emits a {SwapExactIn} event. * * Requirements: * - The logic contract must be a trusted logic contract. * - The recipient address must not be zero or the router address. * - The deadline must not have passed. * - The input token and output token must not be the same. * - If the amountIn is zero, the entire balance of the input token will be used and it must not be zero. * - The entire amountIn of the input token must be spent. * - The actual amount of tokenOut received must be greater than or equal to the amountOutMin. */ function swapExactIn( address logic, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin, address to, uint256 deadline, bytes calldata route ) external payable override nonReentrant returns (uint256 totalIn, uint256 totalOut) { if (amountIn == 0) amountIn = tokenIn == address(0) ? msg.value : TokenLib.balanceOf(tokenIn, msg.sender); _verifyParameters(amountIn, amountOutMin, to, deadline); (totalIn, totalOut) = _swap( logic, tokenIn, tokenOut, amountIn, amountOutMin, msg.sender, to, route, true ); emit SwapExactIn(msg.sender, to, tokenIn, tokenOut, totalIn, totalOut); } /** * @dev Swaps tokens from the sender to the recipient using the exact output amount. It will use the specified logic contract. * * Emits a {SwapExactOut} event. * * Requirements: * - The logic contract must be a trusted logic contract. * - The recipient address must not be zero or the router address. * - The deadline must not have passed. * - The input token and output token must not be the same. * - If the amountInMax is zero, the entire balance of the input token will be used and it must not be zero. * - The actual amount of tokenIn spent must be less than or equal to the amountInMax. * - The actual amount of tokenOut received must be greater than or equal to the amountOut. */ function swapExactOut( address logic, address tokenIn, address tokenOut, uint256 amountOut, uint256 amountInMax, address to, uint256 deadline, bytes calldata route ) external payable override nonReentrant returns (uint256 totalIn, uint256 totalOut) { _verifyParameters(amountInMax, amountOut, to, deadline); (totalIn, totalOut) = _swap( logic, tokenIn, tokenOut, amountInMax, amountOut, msg.sender, to, route, false ); emit SwapExactOut(msg.sender, to, tokenIn, tokenOut, totalIn, totalOut); } /** * @dev Simulates the swap of tokens using multiple routes and the specified logic contract. * The simulation will revert with an array of amounts if the swap is valid. */ function simulate( address logic, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut, address to, bool exactIn, bytes[] calldata multiRoutes ) external payable override { uint256 length = multiRoutes.length; uint256[] memory amounts = new uint256[](length); for (uint256 i; i < length; ) { (, bytes memory data) = address(this).delegatecall( abi.encodeWithSelector( IRouter.simulateSingle.selector, logic, tokenIn, tokenOut, amountIn, amountOut, to, exactIn, multiRoutes[i++] ) ); if (bytes4(data) == IRouter.Router__SimulateSingle.selector) { assembly ("memory-safe") { mstore(add(amounts, mul(i, 32)), mload(add(data, 36))) } } else { amounts[i - 1] = exactIn ? 0 : type(uint256).max; } } revert Router__Simulations(amounts); } /** * @dev Simulates the swap of tokens using a single route and the specified logic contract. * The simulation will revert with the total amount of tokenIn or tokenOut if the swap is valid. */ function simulateSingle( address logic, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut, address to, bool exactIn, bytes calldata route ) external payable override { _verifyParameters(amountIn, amountOut, to, block.timestamp); (uint256 totalIn, uint256 totalOut) = _swap( logic, tokenIn, tokenOut, amountIn, amountOut, msg.sender, to, route, exactIn ); revert Router__SimulateSingle(exactIn ? totalOut : totalIn); } /** * @dev Updates the logic contract address. * * Emits a {RouterLogicUpdated} event. * * Requirements: * - The caller must be the owner. */ function updateRouterLogic( address logic, bool add ) external override onlyOwner { if (add) { if (!_trustedLogics.add(logic)) revert Router__LogicAlreadyAdded(logic); } else { if (!_trustedLogics.remove(logic)) revert Router__LogicNotFound(logic); } emit RouterLogicUpdated(logic, add); } /** * @dev Helper function to verify the input parameters of a swap. * * Requirements: * - The recipient address must not be zero or the router address. * - The deadline must not have passed. * - The amounts must not be zero. */ function _verifyParameters( uint256 amountIn, uint256 amountOut, address to, uint256 deadline ) internal view { if (to == address(0) || to == address(this)) revert Router__InvalidTo(); if (block.timestamp > deadline) revert Router__DeadlineExceeded(); if (amountIn == 0 || amountOut == 0) revert Router__ZeroAmount(); } /** * @dev Helper function to verify the output of a swap. * * Requirements: * - The actual amount of tokenOut returned by the logic contract must be greater than the amountOutMin. * - The actual balance increase of the recipient must be greater than the amountOutMin. */ function _verifySwap( address tokenOut, address to, uint256 balance, uint256 amountOutMin, uint256 amountOut ) internal view returns (uint256) { if (amountOut < amountOutMin) revert Router__InsufficientOutputAmount(amountOut, amountOutMin); uint256 balanceAfter = TokenLib.universalBalanceOf(tokenOut, to); if (balanceAfter < balance + amountOutMin) { revert Router__InsufficientAmountReceived( balance, balanceAfter, amountOutMin ); } unchecked { return balanceAfter - balance; } } /** * @dev Helper function to call the logic contract to swap tokens. * It will use the specified logic contract to swap the input token to the output token. * This function will wrap the input token if it is native and unwrap the output token if it is native. * It will also refund the sender if there is any excess amount of native token. * It will allow the logic contract to spend at most amountIn of the input token from the sender, and reset * the allowance after the swap, see {RouterLib.swap}. * * Requirements: * - The logic contract must be a trusted logic contract. * - If the swap is exactIn, the totalIn must be equal to the amountIn. * - If the swap is exactOut, the totalIn must be less than or equal to the amountIn. */ function _swap( address logic, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut, address from, address to, bytes calldata route, bool exactIn ) internal returns (uint256 totalIn, uint256 totalOut) { if (!_trustedLogics.contains(logic)) revert Router__UntrustedLogic(logic); address recipient; (recipient, tokenOut) = tokenOut == address(0) ? (address(this), WNATIVE) : (to, tokenOut); if (tokenIn == address(0)) { tokenIn = WNATIVE; from = address(this); TokenLib.wrap(WNATIVE, amountIn); } if (tokenIn == tokenOut) revert Router__IdenticalTokens(); uint256 balance = TokenLib.universalBalanceOf(tokenOut, recipient); address logic_ = logic; // avoid stack too deep error (totalIn, totalOut) = RouterLib.swap( _allowances, tokenIn, tokenOut, amountIn, amountOut, from, recipient, route, exactIn, logic_ ); if (recipient == address(this)) { totalOut = _verifySwap( tokenOut, recipient, balance, amountOut, totalOut ); TokenLib.unwrap(WNATIVE, totalOut); TokenLib.transferNative(to, totalOut); } else { totalOut = _verifySwap(tokenOut, to, balance, amountOut, totalOut); } unchecked { uint256 refund; if (from == address(this)) { uint256 unwrap = amountIn - totalIn; if (unwrap > 0) TokenLib.unwrap(WNATIVE, unwrap); refund = msg.value + unwrap - amountIn; } else { refund = msg.value; } if (refund > 0) TokenLib.transferNative(msg.sender, refund); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol) pragma solidity ^0.8.20; import {Ownable} from "./Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is specified at deployment time in the constructor for `Ownable`. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); if (pendingOwner() != sender) { revert OwnableUnauthorizedAccount(sender); } _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.20; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position is the index of the value in the `values` array plus 1. // Position 0 is used to mean a value is not in the set. mapping(bytes32 value => uint256) _positions; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._positions[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We cache the value's position to prevent multiple reads from the same storage slot uint256 position = set._positions[value]; if (position != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 valueIndex = position - 1; uint256 lastIndex = set._values.length - 1; if (valueIndex != lastIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the lastValue to the index where the value to delete is set._values[valueIndex] = lastValue; // Update the tracked position of the lastValue (that was just moved) set._positions[lastValue] = position; } // Delete the slot where the moved value was stored set._values.pop(); // Delete the tracked position for the deleted slot delete set._positions[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._positions[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title TokenLib * @dev Helper library for token operations, such as balanceOf, transfer, transferFrom, wrap, and unwrap. */ library TokenLib { error TokenLib__BalanceOfFailed(); error TokenLib__WrapFailed(); error TokenLib__UnwrapFailed(); error TokenLib__NativeTransferFailed(); error TokenLib__TransferFromFailed(); error TokenLib__TransferFailed(); /** * @dev Returns the balance of a token for an account. * * Requirements: * - The call must succeed. * - The target contract must return at least 32 bytes. */ function balanceOf(address token, address account) internal view returns (uint256 amount) { uint256 success; uint256 returnDataSize; assembly ("memory-safe") { mstore(0, 0x70a08231) // balanceOf(address) mstore(32, account) success := staticcall(gas(), token, 28, 36, 0, 32) returnDataSize := returndatasize() amount := mload(0) } if (success == 0) _tryRevertWithReason(); // If call failed, and it didn't already bubble up the revert reason, then the return data size must be 0, // which will revert here with a generic error message if (returnDataSize < 32) revert TokenLib__BalanceOfFailed(); } /** * @dev Returns the balance of a token for an account, or the native balance of the account if the token is the native token. * * Requirements: * - The call must succeed (if the token is not the native token). * - The target contract must return at least 32 bytes (if the token is not the native token). */ function universalBalanceOf(address token, address account) internal view returns (uint256 amount) { return token == address(0) ? account.balance : balanceOf(token, account); } /** * @dev Transfers native tokens to an account. * * Requirements: * - The call must succeed. */ function transferNative(address to, uint256 amount) internal { uint256 success; assembly ("memory-safe") { success := call(gas(), to, amount, 0, 0, 0, 0) } if (success == 0) { _tryRevertWithReason(); revert TokenLib__NativeTransferFailed(); } } /** * @dev Transfers tokens from an account to another account. * This function does not check if the target contract has code, this should be done before calling this function * * Requirements: * - The call must succeed. */ function wrap(address wnative, uint256 amount) internal { uint256 success; assembly ("memory-safe") { mstore(0, 0xd0e30db0) // deposit() success := call(gas(), wnative, amount, 28, 4, 0, 0) } if (success == 0) { _tryRevertWithReason(); revert TokenLib__WrapFailed(); } } /** * @dev Transfers tokens from an account to another account. * This function does not check if the target contract has code, this should be done before calling this function * * Requirements: * - The call must succeed. */ function unwrap(address wnative, uint256 amount) internal { uint256 success; assembly ("memory-safe") { mstore(0, 0x2e1a7d4d) // withdraw(uint256) mstore(32, amount) success := call(gas(), wnative, 0, 28, 36, 0, 0) } if (success == 0) { _tryRevertWithReason(); revert TokenLib__UnwrapFailed(); } } /** * @dev Transfers tokens from an account to another account. * * Requirements: * - The call must succeed * - The target contract must either return true or no value. * - The target contract must have code. */ function transfer(address token, address to, uint256 amount) internal { uint256 success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let m0x40 := mload(0x40) mstore(0, 0xa9059cbb) // transfer(address,uint256) mstore(32, to) mstore(64, amount) success := call(gas(), token, 0, 28, 68, 0, 32) returnSize := returndatasize() returnValue := mload(0) mstore(0x40, m0x40) } if (success == 0) { _tryRevertWithReason(); revert TokenLib__TransferFailed(); } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) revert TokenLib__TransferFailed(); } /** * @dev Transfers tokens from an account to another account. * * Requirements: * - The call must succeed. * - The target contract must either return true or no value. * - The target contract must have code. */ function transferFrom(address token, address from, address to, uint256 amount) internal { uint256 success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let m0x40 := mload(0x40) let m0x60 := mload(0x60) mstore(0, 0x23b872dd) // transferFrom(address,address,uint256) mstore(32, from) mstore(64, to) mstore(96, amount) success := call(gas(), token, 0, 28, 100, 0, 32) returnSize := returndatasize() returnValue := mload(0) mstore(0x40, m0x40) mstore(0x60, m0x60) } if (success == 0) { _tryRevertWithReason(); revert TokenLib__TransferFromFailed(); } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) revert TokenLib__TransferFromFailed(); } /** * @dev Tries to bubble up the revert reason. * This function needs to be called only if the call has failed, and will revert if there is a revert reason. * This function might no revert if there is no revert reason, always use it in conjunction with a revert. */ function _tryRevertWithReason() private pure { assembly ("memory-safe") { if returndatasize() { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./TokenLib.sol"; /** * @title RouterLib * @dev Helper library for router operations, such as validateAndTransfer, transfer, and swap. * The router must implement a fallback function that uses `validateAndTransfer` to validate the allowance * and transfer the tokens and functions that uses `swap` to call the router logic to swap tokens. * The router logic must implement the `swapExactIn` and `swapExactOut` functions to swap tokens and * use the `transfer` function to transfer tokens from the router according to the route selected. */ library RouterLib { error RouterLib__ZeroAmount(); error RouterLib__InsufficientAllowance(uint256 allowance, uint256 amount); /** * @dev Returns the slot for the allowance of a token for a sender from an address. */ function getAllowanceSlot( mapping(bytes32 key => uint256) storage allowances, address token, address sender, address from ) internal pure returns (bytes32 s) { assembly ("memory-safe") { mstore(0, shl(96, token)) mstore(20, shl(96, sender)) // Overwrite the last 8 bytes of the free memory pointer with zero, //which should always be zeros mstore(40, shl(96, from)) let key := keccak256(0, 60) mstore(0, key) mstore(32, allowances.slot) s := keccak256(0, 64) } } /** * @dev Validates the allowance of a token for a sender from an address, and transfers the token. * * Requirements: * - The allowance must be greater than or equal to the amount. * - The amount must be greater than zero. * - If from is not the router, the token must have been approved for the router. */ function validateAndTransfer(mapping(bytes32 key => uint256) storage allowances) internal { address token; address from; address to; uint256 amount; uint256 allowance; uint256 success; assembly ("memory-safe") { token := shr(96, calldataload(4)) from := shr(96, calldataload(24)) to := shr(96, calldataload(44)) amount := calldataload(64) } bytes32 allowanceSlot = getAllowanceSlot(allowances, token, msg.sender, from); assembly ("memory-safe") { allowance := sload(allowanceSlot) if iszero(lt(allowance, amount)) { success := 1 sstore(allowanceSlot, sub(allowance, amount)) } } if (amount == 0) revert RouterLib__ZeroAmount(); // Also prevent calldata <= 64 if (success == 0) revert RouterLib__InsufficientAllowance(allowance, amount); from == address(this) ? TokenLib.transfer(token, to, amount) : TokenLib.transferFrom(token, from, to, amount); } /** * @dev Calls the router to transfer tokens from an account to another account. * * Requirements: * - The call must succeed. * - The target contract must use `validateAndTransfer` inside its fallback function to validate the allowance * and transfer the tokens accordingly. */ function transfer(address router, address token, address from, address to, uint256 amount) internal { assembly ("memory-safe") { let m0x40 := mload(0x40) mstore(0, shr(32, shl(96, token))) mstore(24, shl(96, from)) mstore(44, shl(96, to)) mstore(64, amount) if iszero(call(gas(), router, 0, 0, 96, 0, 0)) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } mstore(0x40, m0x40) } } /** * @dev Swaps tokens using the router logic. * It will also set the allowance for the logic contract to spend the token from the sender and reset it * after the swap is done. * * Requirements: * - The logic contract must not be the zero address. * - The call must succeed. * - The logic contract must call this contract's fallback function to validate the allowance and transfer the tokens. */ function swap( mapping(bytes32 key => uint256) storage allowances, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut, address from, address to, bytes calldata route, bool exactIn, address logic ) internal returns (uint256 totalIn, uint256 totalOut) { bytes32 allowanceSlot = getAllowanceSlot(allowances, tokenIn, logic, from); uint256 length = 256 + route.length; // 32 * 6 + 32 + 32 + route.length bytes memory data = new bytes(length); assembly ("memory-safe") { sstore(allowanceSlot, amountIn) switch exactIn // swapExactIn(tokenIn, tokenOut, amountIn, amountOut, from, to, route) // swapExactOut(tokenIn, tokenOut, amountOut, amountIn, from, to, route) case 1 { mstore(data, 0xbd084435) } default { mstore(data, 0xcb7e0007) } mstore(add(data, 32), tokenIn) mstore(add(data, 64), tokenOut) mstore(add(data, 96), amountIn) mstore(add(data, 128), amountOut) mstore(add(data, 160), from) mstore(add(data, 192), to) mstore(add(data, 224), 224) // 32 * 6 + 32 mstore(add(data, 256), route.length) calldatacopy(add(data, 288), route.offset, route.length) if iszero(call(gas(), logic, 0, add(data, 28), add(length, 4), 0, 64)) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } totalIn := mload(0) totalOut := mload(32) sstore(allowanceSlot, 0) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IRouter { error Router__DeadlineExceeded(); error Router__InsufficientOutputAmount(uint256 outputAmount, uint256 minOutputAmount); error Router__InsufficientAmountReceived(uint256 balanceBefore, uint256 balanceAfter, uint256 amountOutMin); error Router__InvalidTo(); error Router__ZeroAmount(); error Router__OnlyWnative(); error Router__InvalidWnative(); error Router__IdenticalTokens(); error Router__LogicAlreadyAdded(address routerLogic); error Router__LogicNotFound(address routerLogic); error Router__UntrustedLogic(address routerLogic); error Router__Simulations(uint256[] amounts); error Router__SimulateSingle(uint256 amount); event SwapExactIn( address indexed sender, address to, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut ); event SwapExactOut( address indexed sender, address to, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut ); event RouterLogicUpdated(address indexed routerLogic, bool added); function WNATIVE() external view returns (address); function getTrustedLogicAt(uint256 index) external view returns (address); function getTrustedLogicLength() external view returns (uint256); function updateRouterLogic(address routerLogic, bool added) external; function swapExactIn( address logic, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin, address to, uint256 deadline, bytes memory route ) external payable returns (uint256, uint256); function swapExactOut( address logic, address tokenIn, address tokenOut, uint256 amountOut, uint256 amountInMax, address to, uint256 deadline, bytes memory route ) external payable returns (uint256, uint256); function simulate( address logic, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut, address to, bool exactIn, bytes[] calldata route ) external payable; function simulateSingle( address logic, address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOut, address to, bool exactIn, bytes calldata route ) external payable; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
{ "remappings": [ "@forge-std/contracts/=lib/forge-std/src/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"wnative","type":"address"},{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RouterLib__InsufficientAllowance","type":"error"},{"inputs":[],"name":"RouterLib__ZeroAmount","type":"error"},{"inputs":[],"name":"Router__DeadlineExceeded","type":"error"},{"inputs":[],"name":"Router__IdenticalTokens","type":"error"},{"inputs":[{"internalType":"uint256","name":"balanceBefore","type":"uint256"},{"internalType":"uint256","name":"balanceAfter","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"}],"name":"Router__InsufficientAmountReceived","type":"error"},{"inputs":[{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"}],"name":"Router__InsufficientOutputAmount","type":"error"},{"inputs":[],"name":"Router__InvalidTo","type":"error"},{"inputs":[],"name":"Router__InvalidWnative","type":"error"},{"inputs":[{"internalType":"address","name":"routerLogic","type":"address"}],"name":"Router__LogicAlreadyAdded","type":"error"},{"inputs":[{"internalType":"address","name":"routerLogic","type":"address"}],"name":"Router__LogicNotFound","type":"error"},{"inputs":[],"name":"Router__OnlyWnative","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Router__SimulateSingle","type":"error"},{"inputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"Router__Simulations","type":"error"},{"inputs":[{"internalType":"address","name":"routerLogic","type":"address"}],"name":"Router__UntrustedLogic","type":"error"},{"inputs":[],"name":"Router__ZeroAmount","type":"error"},{"inputs":[],"name":"TokenLib__BalanceOfFailed","type":"error"},{"inputs":[],"name":"TokenLib__NativeTransferFailed","type":"error"},{"inputs":[],"name":"TokenLib__TransferFailed","type":"error"},{"inputs":[],"name":"TokenLib__TransferFromFailed","type":"error"},{"inputs":[],"name":"TokenLib__UnwrapFailed","type":"error"},{"inputs":[],"name":"TokenLib__WrapFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"routerLogic","type":"address"},{"indexed":false,"internalType":"bool","name":"added","type":"bool"}],"name":"RouterLogicUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"SwapExactIn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"SwapExactOut","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"WNATIVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getTrustedLogicAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTrustedLogicLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"logic","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"exactIn","type":"bool"},{"internalType":"bytes[]","name":"multiRoutes","type":"bytes[]"}],"name":"simulate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"logic","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"exactIn","type":"bool"},{"internalType":"bytes","name":"route","type":"bytes"}],"name":"simulateSingle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"logic","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"route","type":"bytes"}],"name":"swapExactIn","outputs":[{"internalType":"uint256","name":"totalIn","type":"uint256"},{"internalType":"uint256","name":"totalOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"logic","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"route","type":"bytes"}],"name":"swapExactOut","outputs":[{"internalType":"uint256","name":"totalIn","type":"uint256"},{"internalType":"uint256","name":"totalOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"logic","type":"address"},{"internalType":"bool","name":"add","type":"bool"}],"name":"updateRouterLogic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a03461014a57601f620018d638819003918201601f19168301916001600160401b0383118484101761014f57808492604094855283398101031261014a57602061004982610165565b916001600160a01b0391829161005f9101610165565b1680156101315760018060a01b0319918260015416600155816000549384161760005560405192167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a36001600255813b15610122575060805260405161175c90816200017a82396080518181816101b901528181610370015281816104e10152818161058b015281816105fb01528181610864015281816109c601528181610a5201528181610aa901528181610b6401528181610cd30152610d410152f35b632cac3e4f60e21b8152600490fd5b604051631e4fbdf760e01b815260006004820152602490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b038216820361014a5756fe60808060405260043610156101fb575b5036156101b757346101b25760006060600435811c91601835821c91602c35811c926040359261006282338860601b60005260601b60145260601b602852603c6000206000526005602052604060002090565b90815491858310156101a4575b508415610192571561017457503081036100fd5750506040519163a9059cbb600052602052604052602060006044601c82865af13d9060005192604052156100dc576100d157503b155b6100bf57005b6040516321f1bb1f60e21b8152600490fd5b6001915014156100b9565b3d6100f3576040516321f1bb1f60e21b8152600490fd5b3d6000803e3d6000fd5b9091604051938351926323b872dd6000526020526040528252602060006064601c82885af1903d9260005194604052521561015d5761015257503b155b61014057005b604051633b4add1d60e11b8152600490fd5b60019150141561013a565b3d6100f357604051633b4add1d60e11b8152600490fd5b604490846040519163c67b4be360e01b835260048301526024820152fd5b604051630abd906360e21b8152600490fd5b85830390555060013861006f565b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036101e957005b60405163589a15c360e01b8152600490fd5b60003560e01c908163470a2fd0146111c45750806354f461a1146111a6578063715018a61461114157806379ba5097146110b85780638da5cb5b1461108f578063a4b77eb914610d70578063b381cf4014610d2b578063c7a3e3ce14610b04578063cfc6cb69146107bb578063de55a527146106c3578063e30c39781461069a578063f1910f70146103075763f2fde38b14610297573861000f565b346101b25760203660031901126101b2576102b061121d565b6102b861132c565b60018060a01b0380911690816bffffffffffffffffffffffff60a01b6001541617600155600054167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700600080a3005b610310366112b2565b939796916103219693959196611377565b811561066b575b61033490868a8461156f565b8196339660018060a01b038216610358816000526004602052604060002054151590565b1561065357506001600160a01b03851661064a5730987f0000000000000000000000000000000000000000000000000000000000000000925b6001600160a01b038616156105f6575b6001600160a01b03828116908516146105e4576103be8b856116a5565b976103ec8b838560601b60005260601b60145260601b602852603c6000206000526005602052604060002090565b938161010001610100116105ce5781908e61040a61010084016113e8565b95604051966104199088611398565b610100840180885261042a906113e8565b6020880190601f19013682378a895563bd08443588525287604087015288606087015260808601528c60a08601528d60c086015260e0850160e09052816101008601526101208501376101040191601c01915a9260008093604095f1156100f3576040997fd9a8cfa901e597f6bbb7ea94478cf9ad6f38d0dc3fd24d493e99cb40692e39f1966000519a60006020519455838a3060018060a01b038416146000146105bb5750506104da946115ea565b95610505877f00000000000000000000000000000000000000000000000000000000000000006116ee565b61050f87876116c5565b6001600160a01b031630036105b45786810380610585575b3401035b80610575575b5086516001600160a01b0394851681529084166020820152921660408301526060820184905260808201839052339160a090a2600160025582519182526020820152f35b61057f90336116c5565b87610531565b6105af817f00000000000000000000000000000000000000000000000000000000000000006116ee565b610527565b503461052b565b915093506105c8946115ea565b9561050f565b634e487b7160e01b600052601160045260246000fd5b60405163e454f9b760e01b8152600490fd5b9850507f0000000000000000000000000000000000000000000000000000000000000000309863d0e30db06000526000806004601c88865af16103a1573d6100f35760405163dc0c8cd160e01b8152600490fd5b86988592610391565b602490604051906394fad8f160e01b82526004820152fd5b90506001600160a01b03821661068857610334345b919050610328565b6103346106953384611656565b610680565b346101b25760003660031901126101b2576001546040516001600160a01b039091168152602090f35b346101b25760403660031901126101b2576106dc61121d565b60243590811515918281036101b2576106f361132c565b15610761576001600160a01b03811661070b81611404565b15610749575060207f25e48677e09b350ea4357542e7ea3d9b4a6665edbc68a909f93ed335dce512f6915b6040519384526001600160a01b031692a2005b6024906040519063070c6e8360e31b82526004820152fd5b6001600160a01b03811661077481611486565b156107a3575060207f25e48677e09b350ea4357542e7ea3d9b4a6665edbc68a909f93ed335dce512f691610736565b60249060405190630c10f95960e41b82526004820152fd5b6101003660031901126101b2576107d061121d565b6107d8611233565b906107e1611249565b906107ea61125f565b916107f3611275565b9060e43567ffffffffffffffff81116101b257610814903690600401611284565b939095610827428760843560643561156f565b8094339360018060a01b03841661084b816000526004602052604060002054151590565b1561065357506001600160a01b038116610afb575030957f0000000000000000000000000000000000000000000000000000000000000000925b6001600160a01b031615610aa4575b6001600160a01b03818116908416146105e4576108b187846116a5565b986108df86868460601b60005260601b60145260601b602852603c6000206000526005602052604060002090565b948361010001610100116105ce576000601c61010486808c968e86998d61090b60409d610100016113e8565b9a6109188e519c8d611398565b6101008601808d52610929906113e8565b60208d019290601f19013684376064359055600114610a985763cb7e00078b525b528b8b8a015260643560608a015260843560808a01528d60a08a015260c089015260e08089015281610100890152610120880137019301915af1156100f3576024966000519560006020519455833060018060a01b03831614600014610a815750916109ef93916109be93608435926115ea565b80956109ea827f00000000000000000000000000000000000000000000000000000000000000006116ee565b6116c5565b6001600160a01b03163003610a7b5760643582900380610a4c575b606435903401035b80610a3c575b5015610a3557505b60405190634e37d9e560e01b82526004820152fd5b9050610a20565b610a4690336116c5565b84610a18565b610a76817f00000000000000000000000000000000000000000000000000000000000000006116ee565b610a0a565b34610a12565b935050610a929396608435926115ea565b926109ef565b63bd0844358b5261094a565b5092507f000000000000000000000000000000000000000000000000000000000000000092309363d0e30db06000526000806004601c606435855af1610894573d6100f35760405163dc0c8cd160e01b8152600490fd5b95879692610885565b610b28610b10366112b2565b9498909692959391610b20611377565b868a8461156f565b8196339660018060a01b038216610b4c816000526004602052604060002054151590565b1561065357506001600160a01b038516610d225730987f0000000000000000000000000000000000000000000000000000000000000000925b6001600160a01b03861615610cce575b6001600160a01b03828116908516146105e457610bb28b856116a5565b97610be08b838560601b60005260601b60145260601b602852603c6000206000526005602052604060002090565b938161010001610100116105ce5781908e610bfe61010084016113e8565b9560405196610c0d9088611398565b6101008401808852610c1e906113e8565b6020880190601f19013682378a895563cb7e000788525287604087015288606087015260808601528c60a08601528d60c086015260e0850160e09052816101008601526101208501376101040191601c01915a9260008093604095f1156100f3576040997fbdf9df8586c933e26c968397ba74608d4b9accd48f470ef60ec2d8b98067e5b2966000519a60006020519455838a3060018060a01b038416146000146105bb5750506104da946115ea565b9850507f0000000000000000000000000000000000000000000000000000000000000000309863d0e30db06000526000806004601c88865af1610b95573d6100f35760405163dc0c8cd160e01b8152600490fd5b86988592610b85565b346101b25760003660031901126101b2576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b6101003660031901126101b257610d8561121d565b610d8d611233565b610d95611249565b610d9d61125f565b610da5611275565b9267ffffffffffffffff60e435116101b25736602360e4350112156101b25767ffffffffffffffff60e43560040135116101b25736602460e4356004013560051b60e4350101116101b257610dff60e435600401356113d0565b94610e0d6040519687611398565b600460e4350135808752601f1990610e24906113d0565b013660208801376000936001600160a01b035b60e435600401358610610e9757876040518091635f61f1fd60e11b82526024820160206004840152815180915260206044840192019060005b818110610e7e575050500390fd5b8251845285945060209384019390920191600101610e70565b8560001981146105ce57600101809660e435600401358110156110495760421960e43536030160248260051b60e43501013512156101b25760249060051b60e43501013560e4350167ffffffffffffffff6024820135116101b2576024810135360360448201136101b25760008091610f9b6040519163cfc6cb6960e01b60208401528689166024840152868a1660448401528688166064840152606435608484015260843560a4840152868b1660c48401528c151560e4840152610100610104840152610124602482013581850152836101449260248101356044820185840137602401358181018401879052601f01601f191681010390810184520182611398565b602081519101305af4503d15611088573d610fb5816113e8565b90610fc36040519283611398565b81523d6000602083013e5b805160208201516001600160e01b03198116919060048210611068575b50506001600160e01b031916634e37d9e560e01b0361101457602401519060051b890152610e37565b50871561105f576000905b806000198101116105ce57895160001982011015611049576000190160051b890160200152610e37565b634e487b7160e01b600052603260045260246000fd5b6000199061101f565b6001600160e01b031960049290920360031b82901b161690508b80610feb565b6060610fce565b346101b25760003660031901126101b2576000546040516001600160a01b039091168152602090f35b346101b25760003660031901126101b2576001546001600160a01b033381831603611129576bffffffffffffffffffffffff60a01b8092166001556000549133908316176000553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405163118cdaa760e01b8152336004820152602490fd5b346101b25760003660031901126101b25761115a61132c565b600180546001600160a01b0319908116909155600080549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346101b25760003660031901126101b2576020600354604051908152f35b346101b25760203660031901126101b257600435906003548210156110495760036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b909101546001600160a01b03168152602090f35b600435906001600160a01b03821682036101b257565b602435906001600160a01b03821682036101b257565b604435906001600160a01b03821682036101b257565b60a435906001600160a01b03821682036101b257565b60c4359081151582036101b257565b9181601f840112156101b25782359167ffffffffffffffff83116101b257602083818601950101116101b257565b906101006003198301126101b2576001600160a01b039060043582811681036101b2579260243583811681036101b2579260443581811681036101b25792606435926084359260a43590811681036101b2579160c4359160e4359067ffffffffffffffff82116101b25761132891600401611284565b9091565b6000546001600160a01b0316330361112957565b6003548110156110495760036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0190600090565b60028054146113865760028055565b604051633ee5aeb560e01b8152600490fd5b90601f8019910116810190811067ffffffffffffffff8211176113ba57604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff81116113ba5760051b60200190565b67ffffffffffffffff81116113ba57601f01601f191660200190565b600081815260046020526040812054611481576003546801000000000000000081101561146d57908261145961144284600160409601600355611340565b819391549060031b91821b91600019901b19161790565b905560035492815260046020522055600190565b634e487b7160e01b82526041600452602482fd5b905090565b6000908082526004908160205260408320548015156000146115695760001990808201818111611556576003549083820191821161154357818103611510575b50505060035480156114fd578101906114de82611340565b909182549160031b1b1916905560035582526020526040812055600190565b634e487b7160e01b855260318452602485fd5b61152e61151f61144293611340565b90549060031b1c928392611340565b905585528360205260408520553880806114c6565b634e487b7160e01b875260118652602487fd5b634e487b7160e01b865260118552602486fd5b50505090565b909290916001600160a01b031680159081156115e0575b506115ce5742116115bc57159081156115b3575b506115a157565b6040516398bbadf560e01b8152600490fd5b9050153861159a565b604051632e7d087f60e21b8152600490fd5b60405163c9d3e5fb60e01b8152600490fd5b9050301438611586565b9091938381106116385750906115ff916116a5565b908083018084116105ce57821061161557500390565b6064929160405192636d72bca560e11b8452600484015260248301526044820152fd5b6044908460405191638de8583f60e01b835260048301526024820152fd5b91906020906024601c60009586936370a08231855285525afa8251923d9115611696575b5060201161168457565b6040516301f8168360e21b8152600490fd5b3d1561167a575b3d81803e3d90fd5b6001600160a01b0381166116b857503190565b906116c291611656565b90565b60008080809481945af1156116d75750565b3d61169d5760405163500da30360e11b8152600490fd5b601c9160246000938480948194632e1a7d4d83526020525af11561170f5750565b3d61169d5760405163028e458f60e61b8152600490fdfea264697066735822122024912bdfea342d4cb80e7c261aacc6193b21381a51607c9c8f109393f5df3f1e64736f6c63430008140033000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7000000000000000000000000f961ee51015b1efb4461d40d1f6b58a7832e931d
Deployed Bytecode
0x60808060405260043610156101fb575b5036156101b757346101b25760006060600435811c91601835821c91602c35811c926040359261006282338860601b60005260601b60145260601b602852603c6000206000526005602052604060002090565b90815491858310156101a4575b508415610192571561017457503081036100fd5750506040519163a9059cbb600052602052604052602060006044601c82865af13d9060005192604052156100dc576100d157503b155b6100bf57005b6040516321f1bb1f60e21b8152600490fd5b6001915014156100b9565b3d6100f3576040516321f1bb1f60e21b8152600490fd5b3d6000803e3d6000fd5b9091604051938351926323b872dd6000526020526040528252602060006064601c82885af1903d9260005194604052521561015d5761015257503b155b61014057005b604051633b4add1d60e11b8152600490fd5b60019150141561013a565b3d6100f357604051633b4add1d60e11b8152600490fd5b604490846040519163c67b4be360e01b835260048301526024820152fd5b604051630abd906360e21b8152600490fd5b85830390555060013861006f565b600080fd5b7f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b031633036101e957005b60405163589a15c360e01b8152600490fd5b60003560e01c908163470a2fd0146111c45750806354f461a1146111a6578063715018a61461114157806379ba5097146110b85780638da5cb5b1461108f578063a4b77eb914610d70578063b381cf4014610d2b578063c7a3e3ce14610b04578063cfc6cb69146107bb578063de55a527146106c3578063e30c39781461069a578063f1910f70146103075763f2fde38b14610297573861000f565b346101b25760203660031901126101b2576102b061121d565b6102b861132c565b60018060a01b0380911690816bffffffffffffffffffffffff60a01b6001541617600155600054167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700600080a3005b610310366112b2565b939796916103219693959196611377565b811561066b575b61033490868a8461156f565b8196339660018060a01b038216610358816000526004602052604060002054151590565b1561065357506001600160a01b03851661064a5730987f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7925b6001600160a01b038616156105f6575b6001600160a01b03828116908516146105e4576103be8b856116a5565b976103ec8b838560601b60005260601b60145260601b602852603c6000206000526005602052604060002090565b938161010001610100116105ce5781908e61040a61010084016113e8565b95604051966104199088611398565b610100840180885261042a906113e8565b6020880190601f19013682378a895563bd08443588525287604087015288606087015260808601528c60a08601528d60c086015260e0850160e09052816101008601526101208501376101040191601c01915a9260008093604095f1156100f3576040997fd9a8cfa901e597f6bbb7ea94478cf9ad6f38d0dc3fd24d493e99cb40692e39f1966000519a60006020519455838a3060018060a01b038416146000146105bb5750506104da946115ea565b95610505877f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76116ee565b61050f87876116c5565b6001600160a01b031630036105b45786810380610585575b3401035b80610575575b5086516001600160a01b0394851681529084166020820152921660408301526060820184905260808201839052339160a090a2600160025582519182526020820152f35b61057f90336116c5565b87610531565b6105af817f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76116ee565b610527565b503461052b565b915093506105c8946115ea565b9561050f565b634e487b7160e01b600052601160045260246000fd5b60405163e454f9b760e01b8152600490fd5b9850507f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7309863d0e30db06000526000806004601c88865af16103a1573d6100f35760405163dc0c8cd160e01b8152600490fd5b86988592610391565b602490604051906394fad8f160e01b82526004820152fd5b90506001600160a01b03821661068857610334345b919050610328565b6103346106953384611656565b610680565b346101b25760003660031901126101b2576001546040516001600160a01b039091168152602090f35b346101b25760403660031901126101b2576106dc61121d565b60243590811515918281036101b2576106f361132c565b15610761576001600160a01b03811661070b81611404565b15610749575060207f25e48677e09b350ea4357542e7ea3d9b4a6665edbc68a909f93ed335dce512f6915b6040519384526001600160a01b031692a2005b6024906040519063070c6e8360e31b82526004820152fd5b6001600160a01b03811661077481611486565b156107a3575060207f25e48677e09b350ea4357542e7ea3d9b4a6665edbc68a909f93ed335dce512f691610736565b60249060405190630c10f95960e41b82526004820152fd5b6101003660031901126101b2576107d061121d565b6107d8611233565b906107e1611249565b906107ea61125f565b916107f3611275565b9060e43567ffffffffffffffff81116101b257610814903690600401611284565b939095610827428760843560643561156f565b8094339360018060a01b03841661084b816000526004602052604060002054151590565b1561065357506001600160a01b038116610afb575030957f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7925b6001600160a01b031615610aa4575b6001600160a01b03818116908416146105e4576108b187846116a5565b986108df86868460601b60005260601b60145260601b602852603c6000206000526005602052604060002090565b948361010001610100116105ce576000601c61010486808c968e86998d61090b60409d610100016113e8565b9a6109188e519c8d611398565b6101008601808d52610929906113e8565b60208d019290601f19013684376064359055600114610a985763cb7e00078b525b528b8b8a015260643560608a015260843560808a01528d60a08a015260c089015260e08089015281610100890152610120880137019301915af1156100f3576024966000519560006020519455833060018060a01b03831614600014610a815750916109ef93916109be93608435926115ea565b80956109ea827f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76116ee565b6116c5565b6001600160a01b03163003610a7b5760643582900380610a4c575b606435903401035b80610a3c575b5015610a3557505b60405190634e37d9e560e01b82526004820152fd5b9050610a20565b610a4690336116c5565b84610a18565b610a76817f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76116ee565b610a0a565b34610a12565b935050610a929396608435926115ea565b926109ef565b63bd0844358b5261094a565b5092507f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c792309363d0e30db06000526000806004601c606435855af1610894573d6100f35760405163dc0c8cd160e01b8152600490fd5b95879692610885565b610b28610b10366112b2565b9498909692959391610b20611377565b868a8461156f565b8196339660018060a01b038216610b4c816000526004602052604060002054151590565b1561065357506001600160a01b038516610d225730987f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7925b6001600160a01b03861615610cce575b6001600160a01b03828116908516146105e457610bb28b856116a5565b97610be08b838560601b60005260601b60145260601b602852603c6000206000526005602052604060002090565b938161010001610100116105ce5781908e610bfe61010084016113e8565b9560405196610c0d9088611398565b6101008401808852610c1e906113e8565b6020880190601f19013682378a895563cb7e000788525287604087015288606087015260808601528c60a08601528d60c086015260e0850160e09052816101008601526101208501376101040191601c01915a9260008093604095f1156100f3576040997fbdf9df8586c933e26c968397ba74608d4b9accd48f470ef60ec2d8b98067e5b2966000519a60006020519455838a3060018060a01b038416146000146105bb5750506104da946115ea565b9850507f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7309863d0e30db06000526000806004601c88865af1610b95573d6100f35760405163dc0c8cd160e01b8152600490fd5b86988592610b85565b346101b25760003660031901126101b2576040517f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b03168152602090f35b6101003660031901126101b257610d8561121d565b610d8d611233565b610d95611249565b610d9d61125f565b610da5611275565b9267ffffffffffffffff60e435116101b25736602360e4350112156101b25767ffffffffffffffff60e43560040135116101b25736602460e4356004013560051b60e4350101116101b257610dff60e435600401356113d0565b94610e0d6040519687611398565b600460e4350135808752601f1990610e24906113d0565b013660208801376000936001600160a01b035b60e435600401358610610e9757876040518091635f61f1fd60e11b82526024820160206004840152815180915260206044840192019060005b818110610e7e575050500390fd5b8251845285945060209384019390920191600101610e70565b8560001981146105ce57600101809660e435600401358110156110495760421960e43536030160248260051b60e43501013512156101b25760249060051b60e43501013560e4350167ffffffffffffffff6024820135116101b2576024810135360360448201136101b25760008091610f9b6040519163cfc6cb6960e01b60208401528689166024840152868a1660448401528688166064840152606435608484015260843560a4840152868b1660c48401528c151560e4840152610100610104840152610124602482013581850152836101449260248101356044820185840137602401358181018401879052601f01601f191681010390810184520182611398565b602081519101305af4503d15611088573d610fb5816113e8565b90610fc36040519283611398565b81523d6000602083013e5b805160208201516001600160e01b03198116919060048210611068575b50506001600160e01b031916634e37d9e560e01b0361101457602401519060051b890152610e37565b50871561105f576000905b806000198101116105ce57895160001982011015611049576000190160051b890160200152610e37565b634e487b7160e01b600052603260045260246000fd5b6000199061101f565b6001600160e01b031960049290920360031b82901b161690508b80610feb565b6060610fce565b346101b25760003660031901126101b2576000546040516001600160a01b039091168152602090f35b346101b25760003660031901126101b2576001546001600160a01b033381831603611129576bffffffffffffffffffffffff60a01b8092166001556000549133908316176000553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405163118cdaa760e01b8152336004820152602490fd5b346101b25760003660031901126101b25761115a61132c565b600180546001600160a01b0319908116909155600080549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346101b25760003660031901126101b2576020600354604051908152f35b346101b25760203660031901126101b257600435906003548210156110495760036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b909101546001600160a01b03168152602090f35b600435906001600160a01b03821682036101b257565b602435906001600160a01b03821682036101b257565b604435906001600160a01b03821682036101b257565b60a435906001600160a01b03821682036101b257565b60c4359081151582036101b257565b9181601f840112156101b25782359167ffffffffffffffff83116101b257602083818601950101116101b257565b906101006003198301126101b2576001600160a01b039060043582811681036101b2579260243583811681036101b2579260443581811681036101b25792606435926084359260a43590811681036101b2579160c4359160e4359067ffffffffffffffff82116101b25761132891600401611284565b9091565b6000546001600160a01b0316330361112957565b6003548110156110495760036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0190600090565b60028054146113865760028055565b604051633ee5aeb560e01b8152600490fd5b90601f8019910116810190811067ffffffffffffffff8211176113ba57604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff81116113ba5760051b60200190565b67ffffffffffffffff81116113ba57601f01601f191660200190565b600081815260046020526040812054611481576003546801000000000000000081101561146d57908261145961144284600160409601600355611340565b819391549060031b91821b91600019901b19161790565b905560035492815260046020522055600190565b634e487b7160e01b82526041600452602482fd5b905090565b6000908082526004908160205260408320548015156000146115695760001990808201818111611556576003549083820191821161154357818103611510575b50505060035480156114fd578101906114de82611340565b909182549160031b1b1916905560035582526020526040812055600190565b634e487b7160e01b855260318452602485fd5b61152e61151f61144293611340565b90549060031b1c928392611340565b905585528360205260408520553880806114c6565b634e487b7160e01b875260118652602487fd5b634e487b7160e01b865260118552602486fd5b50505090565b909290916001600160a01b031680159081156115e0575b506115ce5742116115bc57159081156115b3575b506115a157565b6040516398bbadf560e01b8152600490fd5b9050153861159a565b604051632e7d087f60e21b8152600490fd5b60405163c9d3e5fb60e01b8152600490fd5b9050301438611586565b9091938381106116385750906115ff916116a5565b908083018084116105ce57821061161557500390565b6064929160405192636d72bca560e11b8452600484015260248301526044820152fd5b6044908460405191638de8583f60e01b835260048301526024820152fd5b91906020906024601c60009586936370a08231855285525afa8251923d9115611696575b5060201161168457565b6040516301f8168360e21b8152600490fd5b3d1561167a575b3d81803e3d90fd5b6001600160a01b0381166116b857503190565b906116c291611656565b90565b60008080809481945af1156116d75750565b3d61169d5760405163500da30360e11b8152600490fd5b601c9160246000938480948194632e1a7d4d83526020525af11561170f5750565b3d61169d5760405163028e458f60e61b8152600490fdfea264697066735822122024912bdfea342d4cb80e7c261aacc6193b21381a51607c9c8f109393f5df3f1e64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7000000000000000000000000f961ee51015b1efb4461d40d1f6b58a7832e931d
-----Decoded View---------------
Arg [0] : wnative (address): 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7
Arg [1] : initialOwner (address): 0xF961ee51015b1EfB4461D40D1f6b58a7832E931D
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7
Arg [1] : 000000000000000000000000f961ee51015b1efb4461d40d1f6b58a7832e931d
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
MANTLE | 100.00% | $0.997988 | 8.4035 | $8.39 |
[ 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.