Overview
ETH Balance
0 ETH
ETH Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Sponsored
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60c06040 | 110993905 | 325 days ago | IN | 0 ETH | 0.000587449644 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
124678481 | 8 days ago | 0.16 ETH | ||||
124678481 | 8 days ago | 0.16 ETH | ||||
124115816 | 21 days ago | 0.02 ETH | ||||
124115816 | 21 days ago | 0.02 ETH | ||||
122087840 | 68 days ago | 0.0059 ETH | ||||
122087840 | 68 days ago | 0.0059 ETH | ||||
121367103 | 85 days ago | 0.001 ETH | ||||
121367103 | 85 days ago | 0.001 ETH | ||||
121222167 | 88 days ago | 0.001 ETH | ||||
121222167 | 88 days ago | 0.001 ETH | ||||
121222153 | 88 days ago | 0.001 ETH | ||||
121222153 | 88 days ago | 0.001 ETH | ||||
121011762 | 93 days ago | 0.001 ETH | ||||
121011762 | 93 days ago | 0.001 ETH | ||||
120055018 | 115 days ago | 0.001 ETH | ||||
120055018 | 115 days ago | 0.001 ETH | ||||
120054737 | 115 days ago | 0.001 ETH | ||||
120054737 | 115 days ago | 0.001 ETH | ||||
120054659 | 115 days ago | 0.001 ETH | ||||
120054659 | 115 days ago | 0.001 ETH | ||||
120054352 | 115 days ago | 0.001 ETH | ||||
120054352 | 115 days ago | 0.001 ETH | ||||
118334316 | 155 days ago | 0.307 ETH | ||||
118334316 | 155 days ago | 0.307 ETH | ||||
116823598 | 190 days ago | 0.03 ETH |
Loading...
Loading
Contract Name:
AutoRouterWrapper
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 9999999 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: BSD 3-Clause pragma solidity 0.8.13; import {ISwapWrapper} from "../interfaces/ISwapWrapper.sol"; import {ISwapRouter} from "../lib/ISwapRouter02.sol"; import {ERC20} from "solmate/tokens/ERC20.sol"; import {IWETH9} from "../lib/IWETH9.sol"; import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol"; import "../lib/uniswap/Path.sol"; contract AutoRouterWrapper is ISwapWrapper { using SafeTransferLib for ERC20; using BytesLib for bytes; /// @notice A deployed SwapRouter02(1.1.0). See https://docs.uniswap.org/protocol/reference/deployments. ISwapRouter public immutable swapRouter; /// @notice WETH contract. IWETH9 public immutable weth; /// @notice SwapWrapper name. string public name; /// @dev Address we use to represent ETH. address internal constant eth = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; error TxFailed(); error OnlyMulticallsAllowed(); error PathMismatch(); error UnhandledFunction(bytes4 selector); error ETHAmountInMismatch(); error TotalAmountMismatch(); error RecipientMismatch(bytes4 selector); error TokenInMismatch(bytes4 selector); error TokenOutMismatch(bytes4 selector); /** * @param _name SwapWrapper name. * @param _uniV3SwapRouter Deployed Uniswap v3 SwapRouter. */ constructor(string memory _name, address _uniV3SwapRouter) { name = _name; swapRouter = ISwapRouter(_uniV3SwapRouter); weth = IWETH9(swapRouter.WETH9()); } function swap(address _tokenIn, address _tokenOut, address _recipient, uint256 _amount, bytes calldata _data) external payable returns (uint256) { // If token is ETH and value was sent, ensure the value matches the swap input amount. bool _isInputEth = _tokenIn == eth; if ((_isInputEth && msg.value != _amount) || (!_isInputEth && msg.value > 0)) { revert ETHAmountInMismatch(); } uint256 _prevBalance = getBalance(_tokenOut, _recipient); if (!_isInputEth) { // If caller isn't sending ETH, we need to transfer in tokens... ERC20(_tokenIn).safeTransferFrom(msg.sender, address(this), _amount); ERC20(_tokenIn).safeApprove(address(swapRouter), 0); ERC20(_tokenIn).safeApprove(address(swapRouter), _amount); } uint256 _totalAmountIn = _validateData(_tokenIn, _tokenOut, _recipient, _data); // _totalAmountIn has been modified by the various `check...()` methods, and should now sum to _amount if (_totalAmountIn != _amount) revert TotalAmountMismatch(); (bool _success,) = address(swapRouter).call{value: _isInputEth ? _amount : 0}(_data); if (!_success) revert TxFailed(); uint256 _amountOut = getBalance(_tokenOut, _recipient) - _prevBalance; emit WrapperSwapExecuted(_tokenIn, _tokenOut, msg.sender, _recipient, _totalAmountIn, _amountOut); return _amountOut; } function _validateData(address _tokenIn, address _tokenOut, address _recipient, bytes calldata _data) internal view returns (uint256 _totalAmountIn) { bytes4 _selector = bytes4(_data[:4]); // Check that it's the multicall function that's being called. if (_selector != ISwapRouter.multicall.selector) revert OnlyMulticallsAllowed(); ( /*uint256 deadline*/ , bytes[] memory _calls) = abi.decode(_data[4:], (uint256, bytes[])); uint256 _callsLength = _calls.length; for (uint256 i = 0; i < _callsLength; i++) { bytes memory _call = _calls[i]; // Get the selector _selector = bytes4(_call.slice(0, 4)); // Remove the selector bytes memory _callWithoutSelector = _call.slice(4, _call.length - 4); // check TokenIn if it's the first call of a multicall bool _checkTokenIn = i == 0; // check TokenOut if it's the last call of a multicall bool _checkTokenOut = i == _callsLength - 1; // Check that selector is an approved selector and validate its arguments. if (_selector == ISwapRouter.exactInputSingle.selector) { _totalAmountIn += checkExactInputSingle( _callWithoutSelector, _tokenIn, _tokenOut, _recipient, _checkTokenIn, _checkTokenOut ); } else if (_selector == ISwapRouter.exactInput.selector) { _totalAmountIn += checkExactInput( _callWithoutSelector, _tokenIn, _tokenOut, _recipient, _checkTokenIn, _checkTokenOut ); } else if (_selector == ISwapRouter.sweepToken.selector) { checkSweepToken(_callWithoutSelector, _tokenOut, _recipient); } else if (_selector == ISwapRouter.swapExactTokensForTokens.selector) { _totalAmountIn += checkSwapExactTokensForTokens( _callWithoutSelector, _tokenIn, _tokenOut, _recipient, _checkTokenIn, _checkTokenOut ); } else if (_selector == ISwapRouter.unwrapWETH9.selector) { checkUnwrapWETH9(_callWithoutSelector, _recipient); } else { revert UnhandledFunction(_selector); } } } function checkExactInputSingle( bytes memory _data, address _tokenInExpected, address _tokenOutExpected, address _recipientExpected, bool _checkTokenIn, bool _checkTokenOut ) internal view returns (uint256) { ( address _tokenIn, address _tokenOut, /*uint24 _fee*/ , address _recipient, uint256 _amountIn, /*uint256 _amountOutMinimum*/ , /*uint160 _sqrtPriceLimitX96*/ ) = abi.decode(_data, (address, address, uint24, address, uint256, uint256, uint160)); if (_checkTokenIn) { bool _tokensMatch = checkTokens(_tokenIn, _tokenInExpected); if (!_tokensMatch) revert TokenInMismatch(ISwapRouter.exactInputSingle.selector); } if (_checkTokenOut) { bool _tokensMatch = checkTokens(_tokenOut, _tokenOutExpected); if (!_tokensMatch) revert TokenOutMismatch(ISwapRouter.exactInputSingle.selector); } checkRecipient(_recipient, _recipientExpected, ISwapRouter.exactInputSingle.selector); return _amountIn; } function checkExactInput( bytes memory _data, address _tokenInExpected, address _tokenOutExpected, address _recipientExpected, bool _checkTokenIn, bool _checkTokenOut ) internal view returns (uint256) { ( bytes memory _path, address _recipient, uint256 _amountIn, /*uint256 amountOutMinimum*/ // First 32 bytes point to the location of dynamic bytes _path ) = abi.decode(_data.slice(32, _data.length - 32), (bytes, address, uint256, uint256)); if (_checkTokenIn) { (address _tokenA, /*address _tokenB*/,) = Path.decodeFirstPool(_path); bool _tokensMatch = checkTokens(_tokenA, _tokenInExpected); if (!_tokensMatch) revert TokenInMismatch(ISwapRouter.exactInput.selector); } if (_checkTokenOut) { ( /*address _tokenA*/ , address _tokenB,) = Path.decodeLastPool(_path); bool _tokensMatch = checkTokens(_tokenB, _tokenOutExpected); if (!_tokensMatch) revert TokenOutMismatch(ISwapRouter.exactInput.selector); } checkRecipient(_recipient, _recipientExpected, ISwapRouter.exactInput.selector); return _amountIn; } function checkSweepToken(bytes memory _data, address _tokenOutExpected, address _recipientExpected) internal view { (address _token, /*uint256 _amountMinimum*/, address _recipient) = abi.decode(_data, (address, uint256, address)); bool _tokensMatch = checkTokens(_token, _tokenOutExpected); if (!_tokensMatch) { revert TokenOutMismatch(ISwapRouter.sweepToken.selector); } checkRecipient(_recipient, _recipientExpected, ISwapRouter.sweepToken.selector); } function checkSwapExactTokensForTokens( bytes memory _data, address _tokenInExpected, address _tokenOutExpected, address _recipientExpected, bool _checkTokenIn, bool _checkTokenOut ) internal view returns (uint256) { ( uint256 _amountIn, /*uint256 amountOutMin*/ , address[] memory _path, address _recipient ) = abi.decode(_data, (uint256, uint256, address[], address)); if (_checkTokenIn) { bool _tokensMatch = checkTokens(_path[0], _tokenInExpected); if (!_tokensMatch) revert TokenInMismatch(ISwapRouter.swapExactTokensForTokens.selector); } if (_checkTokenOut) { bool _tokensMatch = checkTokens(_path[_path.length - 1], _tokenOutExpected); if (!_tokensMatch) revert TokenOutMismatch(ISwapRouter.swapExactTokensForTokens.selector); } checkRecipient(_recipient, _recipientExpected, ISwapRouter.swapExactTokensForTokens.selector); return _amountIn; } function checkUnwrapWETH9(bytes memory _data, address _recipientExpected) internal pure { ( /*uint256 amountOutMin*/ , address _recipient) = abi.decode(_data, (uint256, address)); checkRecipient(_recipient, _recipientExpected, ISwapRouter.unwrapWETH9.selector); } function checkRecipient(address _recipient, address _recipientExpected, bytes4 _selector) internal pure { if (_selector == ISwapRouter.sweepToken.selector || _selector == ISwapRouter.unwrapWETH9.selector) { if (_recipient != _recipientExpected) revert RecipientMismatch(_selector); } else { // address(2) is a flag for identifying address(this). // See https://github.com/Uniswap/swap-router-contracts/blob/9dc4a9cce101be984e148e1af6fe605ebcfa658a/contracts/libraries/Constants.sol#L14 if (_recipient != _recipientExpected && _recipient != address(2)) { revert RecipientMismatch(_selector); } } } function getBalance(address _tokenOut, address _recipient) internal view returns (uint256) { if (_tokenOut == address(eth)) { return address(_recipient).balance; } else { return ERC20(_tokenOut).balanceOf(address(_recipient)); } } // Return true if two tokens match, OR if _tokenExpected is eth, token must be weth. function checkTokens(address _token, address _tokenExpected) internal view returns (bool) { // `TokenIn` should never == eth by the time this check is reached. return _token == _tokenExpected || (_tokenExpected == eth ? _token == address(weth) : false); } /// @notice Required to receive ETH on `weth.withdraw()` receive() external payable {} }
//SPDX-License-Identifier: BSD 3-Clause pragma solidity >=0.8.0; error ETHAmountInMismatch(); /** * @notice ISwapWrapper is the interface that all swap wrappers should implement. * This will be used to support swap protocols like Uniswap V2 and V3, Sushiswap, 1inch, etc. */ interface ISwapWrapper { /// @notice Event emitted after a successful swap. event WrapperSwapExecuted( address indexed tokenIn, address indexed tokenOut, address sender, address indexed recipient, uint256 amountIn, uint256 amountOut ); /// @notice Name of swap wrapper for UX readability. function name() external returns (string memory); /** * @notice Swap function. Generally we expect the implementer to call some exactAmountIn-like swap method, and so the documentation * is written with this in mind. However, the method signature is general enough to support exactAmountOut swaps as well. * @param _tokenIn Token to be swapped (or 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for ETH). * @param _tokenOut Token to receive (or 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE for ETH). * @param _recipient Receiver of `_tokenOut`. * @param _amount Amount of `_tokenIn` that should be swapped. * @param _data Additional data that the swap wrapper may require to execute the swap. * @return Amount of _tokenOut received. */ function swap(address _tokenIn, address _tokenOut, address _recipient, uint256 _amount, bytes calldata _data) external payable returns (uint256); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.13; import "./IUniswapV3SwapCallback.sol"; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } struct ExactInputParams { bytes path; address recipient; uint256 amountIn; uint256 amountOutMinimum; } function exactInput(ExactInputParams memory params) external payable returns (uint256 amountOut); function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); function multicall(uint256 deadline, bytes[] calldata data) external payable returns (bytes[] memory); function sweepToken(address token, uint256 amountMinimum, address recipient) external payable; function unwrapWETH9WithFee(uint256 amountMinimum, address recipient, uint256 feeBips, address feeRecipient) external payable; function wrapETH(uint256 value) external payable; function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; function WETH9() external view returns (address payable); //V2 Periphery function swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to) external payable returns (uint256 amountOut); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*/////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*/////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*/////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*/////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: BSD-2-Clause // !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.5.2. SEE SOURCE BELOW. !! pragma solidity 0.8.13; interface IWETH9 { function name() external view returns (string memory); function approve(address guy, uint256 wad) external returns (bool); function totalSupply() external view returns (uint256); function transferFrom(address src, address dst, uint256 wad) external returns (bool); function withdraw(uint256 wad) external; function decimals() external view returns (uint8); function balanceOf(address) external view returns (uint256); function symbol() external view returns (string memory); function transfer(address dst, uint256 wad) external returns (bool); function deposit() external payable; function allowance(address, address) external view returns (uint256); event Approval(address indexed src, address indexed guy, uint256 wad); event Transfer(address indexed src, address indexed dst, uint256 wad); event Deposit(address indexed dst, uint256 wad); event Withdrawal(address indexed src, uint256 wad); } // THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON: /* [{"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}]*/
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. library SafeTransferLib { /*/////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool callStatus; assembly { // Transfer the ETH and store if it succeeded or not. callStatus := call(gas(), to, amount, 0, 0, 0, 0) } require(callStatus, "ETH_TRANSFER_FAILED"); } /*/////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "from" argument. mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 100 because the calldata length is 4 + 32 * 3. callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 68 because the calldata length is 4 + 32 * 2. callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 68 because the calldata length is 4 + 32 * 2. callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "APPROVE_FAILED"); } /*/////////////////////////////////////////////////////////////// INTERNAL HELPER LOGIC //////////////////////////////////////////////////////////////*/ function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) { assembly { // Get how many bytes the call returned. let returnDataSize := returndatasize() // If the call reverted: if iszero(callStatus) { // Copy the revert message into memory. returndatacopy(0, 0, returnDataSize) // Revert with the same message. revert(0, returnDataSize) } switch returnDataSize case 32 { // Copy the return data into memory. returndatacopy(0, 0, returnDataSize) // Set success to whether it returned true. success := iszero(iszero(mload(0))) } case 0 { // There was no return data. success := 1 } default { // It returned some malformed input. success := 0 } } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.0; import "./BytesLib.sol"; /// @title MODIFIED FILE: Functions for manipulating path data for multihop swaps /// @notice Additional `decodeLastPool` method was added to the orignal file linked below. /// @notice Link: https://github.com/Uniswap/v3-periphery/blob/b325bb0905d922ae61fcc7df85ee802e8df5e96c/contracts/libraries/Path.sol library Path { using BytesLib for bytes; /// @dev The length of the bytes encoded address uint256 private constant ADDR_SIZE = 20; /// @dev The length of the bytes encoded fee uint256 private constant FEE_SIZE = 3; /// @dev The offset of a single token address and pool fee uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE; /// @dev The offset of an encoded pool key uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE; /// @dev The minimum length of an encoding that contains 2 or more pools uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET; /// @notice Returns true iff the path contains two or more pools /// @param path The encoded swap path /// @return True if path contains two or more pools, otherwise false function hasMultiplePools(bytes memory path) internal pure returns (bool) { return path.length >= MULTIPLE_POOLS_MIN_LENGTH; } /// @notice Returns the number of pools in the path /// @param path The encoded swap path /// @return The number of pools in the path function numPools(bytes memory path) internal pure returns (uint256) { // Ignore the first token address. From then on every fee and token offset indicates a pool. return ((path.length - ADDR_SIZE) / NEXT_OFFSET); } /// @notice Decodes the first pool in path /// @param path The bytes encoded swap path /// @return tokenA The first token of the given pool /// @return tokenB The second token of the given pool /// @return fee The fee level of the pool function decodeFirstPool(bytes memory path) internal pure returns (address tokenA, address tokenB, uint24 fee) { tokenA = path.toAddress(0); fee = path.toUint24(ADDR_SIZE); tokenB = path.toAddress(NEXT_OFFSET); } /// @notice Gets the segment corresponding to the first pool in the path /// @param path The bytes encoded swap path /// @return The segment containing all data necessary to target the first pool in the path function getFirstPool(bytes memory path) internal pure returns (bytes memory) { return path.slice(0, POP_OFFSET); } /// @notice Skips a token + fee element from the buffer and returns the remainder /// @param path The swap path /// @return The remaining token + fee elements in the path function skipToken(bytes memory path) internal pure returns (bytes memory) { return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET); } /// @notice Custom method we've added: Decodes the last pool in path /// @param path The bytes encoded swap path /// @return tokenA The first token of the given pool /// @return tokenB The second token of the given pool /// @return fee The fee level of the pool function decodeLastPool(bytes memory path) internal pure returns (address tokenA, address tokenB, uint24 fee) { path = path.slice(path.length - POP_OFFSET, POP_OFFSET); tokenA = path.toAddress(0); fee = path.toUint24(ADDR_SIZE); tokenB = path.toAddress(NEXT_OFFSET); } }
// Sourced from https://github.com/Uniswap/v3-core/blob/ed88be38ab2032d82bf10ac6f8d03aa631889d48/contracts/interfaces/callback/IUniswapV3SwapCallback.sol // Modified solidity pragma. // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.13; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external; }
// SPDX-License-Identifier: GPL-2.0-or-later /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. * @notice Link: https://github.com/Uniswap/v3-periphery/blob/b325bb0905d922ae61fcc7df85ee802e8df5e96c/contracts/libraries/BytesLib.sol */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) { require(_start + 3 >= _start, "toUint24_overflow"); require(_bytes.length >= _start + 3, "toUint24_outOfBounds"); uint24 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x3), _start)) } return tempUint; } }
{ "remappings": [ "ds-test/=lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "murky/=lib/murky/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/", "weird-erc20/=lib/solmate/lib/weird-erc20/src/" ], "optimizer": { "enabled": true, "runs": 9999999 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_uniV3SwapRouter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ETHAmountInMismatch","type":"error"},{"inputs":[],"name":"OnlyMulticallsAllowed","type":"error"},{"inputs":[],"name":"PathMismatch","type":"error"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"RecipientMismatch","type":"error"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"TokenInMismatch","type":"error"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"TokenOutMismatch","type":"error"},{"inputs":[],"name":"TotalAmountMismatch","type":"error"},{"inputs":[],"name":"TxFailed","type":"error"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"UnhandledFunction","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"WrapperSwapExecuted","type":"event"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"swap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"swapRouter","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH9","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c06040523480156200001157600080fd5b506040516200217c3803806200217c8339810160408190526200003491620001b7565b815162000049906000906020850190620000d0565b506001600160a01b0381166080819052604080516312a9293f60e21b81529051634aa4a4fc916004808201926020929091908290030181865afa15801562000095573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000bb9190620002a8565b6001600160a01b031660a052506200030b9050565b828054620000de90620002cf565b90600052602060002090601f0160209004810192826200010257600085556200014d565b82601f106200011d57805160ff19168380011785556200014d565b828001600101855582156200014d579182015b828111156200014d57825182559160200191906001019062000130565b506200015b9291506200015f565b5090565b5b808211156200015b576000815560010162000160565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114620001a257600080fd5b50565b8051620001b2816200018c565b919050565b60008060408385031215620001cb57600080fd5b82516001600160401b0380821115620001e357600080fd5b818501915085601f830112620001f857600080fd5b8151818111156200020d576200020d62000176565b604051601f8201601f19908116603f0116810190838211818310171562000238576200023862000176565b816040528281526020935088848487010111156200025557600080fd5b600091505b828210156200027957848201840151818301850152908301906200025a565b828211156200028b5760008484830101525b95506200029d915050858201620001a5565b925050509250929050565b600060208284031215620002bb57600080fd5b8151620002c8816200018c565b9392505050565b600181811c90821680620002e457607f821691505b6020821081036200030557634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a051611e316200034b60003960008181608c015261121801526000818160e50152818161028e015281816102d001526103430152611e316000f3fe6080604052600436106100435760003560e01c806306fdde031461004f5780633fc8cef31461007a578063c31c9c07146100d3578063da1452631461010757600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b50610064610128565b6040516100719190611677565b60405180910390f35b34801561008657600080fd5b506100ae7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610071565b3480156100df57600080fd5b506100ae7f000000000000000000000000000000000000000000000000000000000000000081565b61011a6101153660046116ed565b6101b6565b604051908152602001610071565b60008054610135906117a0565b80601f0160208091040260200160405190810160405280929190818152602001828054610161906117a0565b80156101ae5780601f10610183576101008083540402835291602001916101ae565b820191906000526020600020905b81548152906001019060200180831161019157829003601f168201915b505050505081565b600073ffffffffffffffffffffffffffffffffffffffff871673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148080156101f25750843414155b806102065750801580156102065750600034115b1561023d576040517f61746dbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610249888861049d565b9050816102f55761027273ffffffffffffffffffffffffffffffffffffffff8a16333089610593565b6102b473ffffffffffffffffffffffffffffffffffffffff8a167f00000000000000000000000000000000000000000000000000000000000000006000610682565b6102f573ffffffffffffffffffffffffffffffffffffffff8a167f000000000000000000000000000000000000000000000000000000000000000088610682565b60006103048a8a8a898961074f565b905086811461033f576040517f1ae3648700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1684610384576000610386565b885b88886040516103969291906117f3565b60006040518083038185875af1925050503d80600081146103d3576040519150601f19603f3d011682016040523d82523d6000602084013e6103d8565b606091505b5050905080610413576040517f2b96f51300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000836104208c8c61049d565b61042a9190611832565b604080513381526020810186905290810182905290915073ffffffffffffffffffffffffffffffffffffffff808c16918d8216918f16907fb1b8682cc43fc0063470cc507f616e8f273f9df242d968fe84580a72f2b779619060600160405180910390a49b9a5050505050505050505050565b60007fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8416016104fa575073ffffffffffffffffffffffffffffffffffffffff81163161058d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906370a0823190602401602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190611849565b90505b92915050565b60006040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015273ffffffffffffffffffffffffffffffffffffffff8416602482015282604482015260008060648360008a5af191505061061081610ac0565b61067b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c454400000000000000000000000060448201526064015b60405180910390fd5b5050505050565b60006040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201528260248201526000806044836000895af19150506106e381610ac0565b610749576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c45440000000000000000000000000000000000006044820152606401610672565b50505050565b60008061075f6004828587611862565b6107689161188c565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167f5ae401dc00000000000000000000000000000000000000000000000000000000146107e5576040517f364a674500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107f48460048188611862565b81019061080191906119bc565b8051909250905060005b81811015610ab357600083828151811061082757610827611abc565b602002602001015190506108486000600483610b079092919063ffffffff16565b61085190611aeb565b9450600061086f60048084516108679190611832565b849190610b07565b905082156000610880600187611832565b851490507ffb1ba551000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008916016108ec576108db838f8f8f8686610c81565b6108e5908a611b3b565b9850610a9c565b7f47a7e7c1000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000891601610943576108db838f8f8f8686610dbf565b7f20d54a45000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000089160161099c57610997838e8e610f2f565b610a9c565b7fb8d4bc0d000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008916016109f3576108db838f8f8f8686610fe5565b7fb6bfb484000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000891601610a4657610997838d61115d565b6040517f9a0778260000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000089166004820152602401610672565b505050508080610aab90611b53565b91505061080b565b5050505095945050505050565b60003d82610ad257806000803e806000fd5b8060208114610aea578015610afb5760009250610b00565b816000803e60005115159250610b00565b600192505b5050919050565b606081610b1581601f611b3b565b1015610b7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610672565b610b878284611b3b565b84511015610bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610672565b606082158015610c105760405191506000825260208201604052610c78565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015610c49578051835260209283019201610c31565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60008060008060008a806020019051810190610c9d9190611b9b565b50509450945050935093508615610d17576000610cba858c6111a7565b905080610d15576040517f5c4440c90000000000000000000000000000000000000000000000000000000081527f04e45aaf000000000000000000000000000000000000000000000000000000006004820152602401610672565b505b8515610d86576000610d29848b6111a7565b905080610d84576040517f27f5b90d0000000000000000000000000000000000000000000000000000000081527f04e45aaf000000000000000000000000000000000000000000000000000000006004820152602401610672565b505b610db182897f04e45aaf0000000000000000000000000000000000000000000000000000000061126c565b9a9950505050505050505050565b600080600080610ddf6020808c51610dd79190611832565b8c9190610b07565b806020019051810190610df29190611c2c565b509250925092508515610e78576000610e0a84611439565b505090506000610e1a828c6111a7565b905080610e75576040517f5c4440c90000000000000000000000000000000000000000000000000000000081527fb858183f000000000000000000000000000000000000000000000000000000006004820152602401610672565b50505b8415610ef7576000610e8984611475565b509150506000610e99828b6111a7565b905080610ef4576040517f27f5b90d0000000000000000000000000000000000000000000000000000000081527fb858183f000000000000000000000000000000000000000000000000000000006004820152602401610672565b50505b610f2282887fb858183f0000000000000000000000000000000000000000000000000000000061126c565b9998505050505050505050565b60008084806020019051810190610f469190611cc8565b92505091506000610f5783866111a7565b905080610fb2576040517f27f5b90d0000000000000000000000000000000000000000000000000000000081527fdf2ab5bb000000000000000000000000000000000000000000000000000000006004820152602401610672565b610fdd82857fdf2ab5bb0000000000000000000000000000000000000000000000000000000061126c565b505050505050565b60008060008089806020019051810190610fff9190611d0b565b93509350509250851561108f5760006110328360008151811061102457611024611abc565b60200260200101518b6111a7565b90508061108d576040517f5c4440c90000000000000000000000000000000000000000000000000000000081527f472b43f3000000000000000000000000000000000000000000000000000000006004820152602401610672565b505b84156111245760006110c783600185516110a99190611832565b815181106110b9576110b9611abc565b60200260200101518a6111a7565b905080611122576040517f27f5b90d0000000000000000000000000000000000000000000000000000000081527f472b43f3000000000000000000000000000000000000000000000000000000006004820152602401610672565b505b61114f81887f472b43f30000000000000000000000000000000000000000000000000000000061126c565b509098975050505050505050565b6000828060200190518101906111739190611dcb565b91506111a2905081837f49404b7c0000000000000000000000000000000000000000000000000000000061126c565b505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16148061058a575073ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461121657600061058a565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16149392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081167fdf2ab5bb0000000000000000000000000000000000000000000000000000000014806112fd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f49404b7c00000000000000000000000000000000000000000000000000000000145b1561138b578173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146111a2576040517f02a3e6980000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610672565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156113de575073ffffffffffffffffffffffffffffffffffffffff8316600214155b156111a2576040517f02a3e6980000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610672565b6000808061144784826114c7565b9250611454846014611557565b905061146c61146560036014611b3b565b85906114c7565b91509193909250565b600080806114be6014611489600382611b3b565b6114939190611b3b565b855161149f9190611832565b60146114ac600382611b3b565b6114b69190611b3b565b869190610b07565b93506114478460005b60006114d4826014611b3b565b8351101561153e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e647300000000000000000000006044820152606401610672565b5001602001516c01000000000000000000000000900490565b600081611565816003611b3b565b10156115cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f746f55696e7432345f6f766572666c6f770000000000000000000000000000006044820152606401610672565b6115d8826003611b3b565b83511015611642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f746f55696e7432345f6f75744f66426f756e64730000000000000000000000006044820152606401610672565b50016003015190565b60005b8381101561166657818101518382015260200161164e565b838111156107495750506000910152565b602081526000825180602084015261169681604085016020870161164b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff811681146116ea57600080fd5b50565b60008060008060008060a0878903121561170657600080fd5b8635611711816116c8565b95506020870135611721816116c8565b94506040870135611731816116c8565b935060608701359250608087013567ffffffffffffffff8082111561175557600080fd5b818901915089601f83011261176957600080fd5b81358181111561177857600080fd5b8a602082850101111561178a57600080fd5b6020830194508093505050509295509295509295565b600181811c908216806117b457607f821691505b6020821081036117ed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561184457611844611803565b500390565b60006020828403121561185b57600080fd5b5051919050565b6000808585111561187257600080fd5b8386111561187f57600080fd5b5050820193919092039150565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156118cc5780818660040360031b1b83161692505b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561194a5761194a6118d4565b604052919050565b600067ffffffffffffffff82111561196c5761196c6118d4565b5060051b60200190565b600067ffffffffffffffff821115611990576119906118d4565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60008060408084860312156119d057600080fd5b8335925060208085013567ffffffffffffffff808211156119f057600080fd5b818701915087601f830112611a0457600080fd5b8135611a17611a1282611952565b611903565b81815260059190911b8301840190848101908a831115611a3657600080fd5b8585015b83811015611aaa57803585811115611a525760008081fd5b8601603f81018d13611a645760008081fd5b87810135611a74611a1282611976565b8181528e8b838501011115611a895760008081fd5b818b84018b83013760009181018a0191909152845250918601918601611a3a565b50809750505050505050509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815160208301517fffffffff0000000000000000000000000000000000000000000000000000000080821693506004831015611b335780818460040360031b1b83161693505b505050919050565b60008219821115611b4e57611b4e611803565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b8457611b84611803565b5060010190565b8051611b96816116c8565b919050565b600080600080600080600060e0888a031215611bb657600080fd5b8751611bc1816116c8565b6020890151909750611bd2816116c8565b604089015190965062ffffff81168114611beb57600080fd5b6060890151909550611bfc816116c8565b809450506080880151925060a0880151915060c0880151611c1c816116c8565b8091505092959891949750929550565b60008060008060808587031215611c4257600080fd5b845167ffffffffffffffff811115611c5957600080fd5b8501601f81018713611c6a57600080fd5b8051611c78611a1282611976565b818152886020838501011115611c8d57600080fd5b611c9e82602083016020860161164b565b8096505050506020850151611cb2816116c8565b6040860151606090960151949790965092505050565b600080600060608486031215611cdd57600080fd5b8351611ce8816116c8565b602085015160408601519194509250611d00816116c8565b809150509250925092565b60008060008060808587031215611d2157600080fd5b845193506020808601519350604086015167ffffffffffffffff811115611d4757600080fd5b8601601f81018813611d5857600080fd5b8051611d66611a1282611952565b81815260059190911b8201830190838101908a831115611d8557600080fd5b928401925b82841015611dac578351611d9d816116c8565b82529284019290840190611d8a565b8096505050505050611dc060608601611b8b565b905092959194509250565b60008060408385031215611dde57600080fd5b825191506020830151611df0816116c8565b80915050925092905056fea26469706673582212206f1b85be2ca7af517505ed12d9d5b77d7fbee1026625e1a000767ff619b1c1f664736f6c634300080d0033000000000000000000000000000000000000000000000000000000000000004000000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45000000000000000000000000000000000000000000000000000000000000001a556e6973776170204175746f526f757465722057726170706572000000000000
Deployed Bytecode
0x6080604052600436106100435760003560e01c806306fdde031461004f5780633fc8cef31461007a578063c31c9c07146100d3578063da1452631461010757600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b50610064610128565b6040516100719190611677565b60405180910390f35b34801561008657600080fd5b506100ae7f000000000000000000000000420000000000000000000000000000000000000681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610071565b3480156100df57600080fd5b506100ae7f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc4581565b61011a6101153660046116ed565b6101b6565b604051908152602001610071565b60008054610135906117a0565b80601f0160208091040260200160405190810160405280929190818152602001828054610161906117a0565b80156101ae5780601f10610183576101008083540402835291602001916101ae565b820191906000526020600020905b81548152906001019060200180831161019157829003601f168201915b505050505081565b600073ffffffffffffffffffffffffffffffffffffffff871673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148080156101f25750843414155b806102065750801580156102065750600034115b1561023d576040517f61746dbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610249888861049d565b9050816102f55761027273ffffffffffffffffffffffffffffffffffffffff8a16333089610593565b6102b473ffffffffffffffffffffffffffffffffffffffff8a167f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc456000610682565b6102f573ffffffffffffffffffffffffffffffffffffffff8a167f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc4588610682565b60006103048a8a8a898961074f565b905086811461033f576040517f1ae3648700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc4573ffffffffffffffffffffffffffffffffffffffff1684610384576000610386565b885b88886040516103969291906117f3565b60006040518083038185875af1925050503d80600081146103d3576040519150601f19603f3d011682016040523d82523d6000602084013e6103d8565b606091505b5050905080610413576040517f2b96f51300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000836104208c8c61049d565b61042a9190611832565b604080513381526020810186905290810182905290915073ffffffffffffffffffffffffffffffffffffffff808c16918d8216918f16907fb1b8682cc43fc0063470cc507f616e8f273f9df242d968fe84580a72f2b779619060600160405180910390a49b9a5050505050505050505050565b60007fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8416016104fa575073ffffffffffffffffffffffffffffffffffffffff81163161058d565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906370a0823190602401602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190611849565b90505b92915050565b60006040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015273ffffffffffffffffffffffffffffffffffffffff8416602482015282604482015260008060648360008a5af191505061061081610ac0565b61067b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c454400000000000000000000000060448201526064015b60405180910390fd5b5050505050565b60006040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201528260248201526000806044836000895af19150506106e381610ac0565b610749576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c45440000000000000000000000000000000000006044820152606401610672565b50505050565b60008061075f6004828587611862565b6107689161188c565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167f5ae401dc00000000000000000000000000000000000000000000000000000000146107e5576040517f364a674500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107f48460048188611862565b81019061080191906119bc565b8051909250905060005b81811015610ab357600083828151811061082757610827611abc565b602002602001015190506108486000600483610b079092919063ffffffff16565b61085190611aeb565b9450600061086f60048084516108679190611832565b849190610b07565b905082156000610880600187611832565b851490507ffb1ba551000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008916016108ec576108db838f8f8f8686610c81565b6108e5908a611b3b565b9850610a9c565b7f47a7e7c1000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000891601610943576108db838f8f8f8686610dbf565b7f20d54a45000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000089160161099c57610997838e8e610f2f565b610a9c565b7fb8d4bc0d000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008916016109f3576108db838f8f8f8686610fe5565b7fb6bfb484000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000891601610a4657610997838d61115d565b6040517f9a0778260000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000089166004820152602401610672565b505050508080610aab90611b53565b91505061080b565b5050505095945050505050565b60003d82610ad257806000803e806000fd5b8060208114610aea578015610afb5760009250610b00565b816000803e60005115159250610b00565b600192505b5050919050565b606081610b1581601f611b3b565b1015610b7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610672565b610b878284611b3b565b84511015610bf1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610672565b606082158015610c105760405191506000825260208201604052610c78565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015610c49578051835260209283019201610c31565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60008060008060008a806020019051810190610c9d9190611b9b565b50509450945050935093508615610d17576000610cba858c6111a7565b905080610d15576040517f5c4440c90000000000000000000000000000000000000000000000000000000081527f04e45aaf000000000000000000000000000000000000000000000000000000006004820152602401610672565b505b8515610d86576000610d29848b6111a7565b905080610d84576040517f27f5b90d0000000000000000000000000000000000000000000000000000000081527f04e45aaf000000000000000000000000000000000000000000000000000000006004820152602401610672565b505b610db182897f04e45aaf0000000000000000000000000000000000000000000000000000000061126c565b9a9950505050505050505050565b600080600080610ddf6020808c51610dd79190611832565b8c9190610b07565b806020019051810190610df29190611c2c565b509250925092508515610e78576000610e0a84611439565b505090506000610e1a828c6111a7565b905080610e75576040517f5c4440c90000000000000000000000000000000000000000000000000000000081527fb858183f000000000000000000000000000000000000000000000000000000006004820152602401610672565b50505b8415610ef7576000610e8984611475565b509150506000610e99828b6111a7565b905080610ef4576040517f27f5b90d0000000000000000000000000000000000000000000000000000000081527fb858183f000000000000000000000000000000000000000000000000000000006004820152602401610672565b50505b610f2282887fb858183f0000000000000000000000000000000000000000000000000000000061126c565b9998505050505050505050565b60008084806020019051810190610f469190611cc8565b92505091506000610f5783866111a7565b905080610fb2576040517f27f5b90d0000000000000000000000000000000000000000000000000000000081527fdf2ab5bb000000000000000000000000000000000000000000000000000000006004820152602401610672565b610fdd82857fdf2ab5bb0000000000000000000000000000000000000000000000000000000061126c565b505050505050565b60008060008089806020019051810190610fff9190611d0b565b93509350509250851561108f5760006110328360008151811061102457611024611abc565b60200260200101518b6111a7565b90508061108d576040517f5c4440c90000000000000000000000000000000000000000000000000000000081527f472b43f3000000000000000000000000000000000000000000000000000000006004820152602401610672565b505b84156111245760006110c783600185516110a99190611832565b815181106110b9576110b9611abc565b60200260200101518a6111a7565b905080611122576040517f27f5b90d0000000000000000000000000000000000000000000000000000000081527f472b43f3000000000000000000000000000000000000000000000000000000006004820152602401610672565b505b61114f81887f472b43f30000000000000000000000000000000000000000000000000000000061126c565b509098975050505050505050565b6000828060200190518101906111739190611dcb565b91506111a2905081837f49404b7c0000000000000000000000000000000000000000000000000000000061126c565b505050565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16148061058a575073ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461121657600061058a565b7f000000000000000000000000420000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16149392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081167fdf2ab5bb0000000000000000000000000000000000000000000000000000000014806112fd57507fffffffff0000000000000000000000000000000000000000000000000000000081167f49404b7c00000000000000000000000000000000000000000000000000000000145b1561138b578173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146111a2576040517f02a3e6980000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610672565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156113de575073ffffffffffffffffffffffffffffffffffffffff8316600214155b156111a2576040517f02a3e6980000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610672565b6000808061144784826114c7565b9250611454846014611557565b905061146c61146560036014611b3b565b85906114c7565b91509193909250565b600080806114be6014611489600382611b3b565b6114939190611b3b565b855161149f9190611832565b60146114ac600382611b3b565b6114b69190611b3b565b869190610b07565b93506114478460005b60006114d4826014611b3b565b8351101561153e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e647300000000000000000000006044820152606401610672565b5001602001516c01000000000000000000000000900490565b600081611565816003611b3b565b10156115cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f746f55696e7432345f6f766572666c6f770000000000000000000000000000006044820152606401610672565b6115d8826003611b3b565b83511015611642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f746f55696e7432345f6f75744f66426f756e64730000000000000000000000006044820152606401610672565b50016003015190565b60005b8381101561166657818101518382015260200161164e565b838111156107495750506000910152565b602081526000825180602084015261169681604085016020870161164b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff811681146116ea57600080fd5b50565b60008060008060008060a0878903121561170657600080fd5b8635611711816116c8565b95506020870135611721816116c8565b94506040870135611731816116c8565b935060608701359250608087013567ffffffffffffffff8082111561175557600080fd5b818901915089601f83011261176957600080fd5b81358181111561177857600080fd5b8a602082850101111561178a57600080fd5b6020830194508093505050509295509295509295565b600181811c908216806117b457607f821691505b6020821081036117ed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561184457611844611803565b500390565b60006020828403121561185b57600080fd5b5051919050565b6000808585111561187257600080fd5b8386111561187f57600080fd5b5050820193919092039150565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156118cc5780818660040360031b1b83161692505b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561194a5761194a6118d4565b604052919050565b600067ffffffffffffffff82111561196c5761196c6118d4565b5060051b60200190565b600067ffffffffffffffff821115611990576119906118d4565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60008060408084860312156119d057600080fd5b8335925060208085013567ffffffffffffffff808211156119f057600080fd5b818701915087601f830112611a0457600080fd5b8135611a17611a1282611952565b611903565b81815260059190911b8301840190848101908a831115611a3657600080fd5b8585015b83811015611aaa57803585811115611a525760008081fd5b8601603f81018d13611a645760008081fd5b87810135611a74611a1282611976565b8181528e8b838501011115611a895760008081fd5b818b84018b83013760009181018a0191909152845250918601918601611a3a565b50809750505050505050509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815160208301517fffffffff0000000000000000000000000000000000000000000000000000000080821693506004831015611b335780818460040360031b1b83161693505b505050919050565b60008219821115611b4e57611b4e611803565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b8457611b84611803565b5060010190565b8051611b96816116c8565b919050565b600080600080600080600060e0888a031215611bb657600080fd5b8751611bc1816116c8565b6020890151909750611bd2816116c8565b604089015190965062ffffff81168114611beb57600080fd5b6060890151909550611bfc816116c8565b809450506080880151925060a0880151915060c0880151611c1c816116c8565b8091505092959891949750929550565b60008060008060808587031215611c4257600080fd5b845167ffffffffffffffff811115611c5957600080fd5b8501601f81018713611c6a57600080fd5b8051611c78611a1282611976565b818152886020838501011115611c8d57600080fd5b611c9e82602083016020860161164b565b8096505050506020850151611cb2816116c8565b6040860151606090960151949790965092505050565b600080600060608486031215611cdd57600080fd5b8351611ce8816116c8565b602085015160408601519194509250611d00816116c8565b809150509250925092565b60008060008060808587031215611d2157600080fd5b845193506020808601519350604086015167ffffffffffffffff811115611d4757600080fd5b8601601f81018813611d5857600080fd5b8051611d66611a1282611952565b81815260059190911b8201830190838101908a831115611d8557600080fd5b928401925b82841015611dac578351611d9d816116c8565b82529284019290840190611d8a565b8096505050505050611dc060608601611b8b565b905092959194509250565b60008060408385031215611dde57600080fd5b825191506020830151611df0816116c8565b80915050925092905056fea26469706673582212206f1b85be2ca7af517505ed12d9d5b77d7fbee1026625e1a000767ff619b1c1f664736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000004000000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45000000000000000000000000000000000000000000000000000000000000001a556e6973776170204175746f526f757465722057726170706572000000000000
-----Decoded View---------------
Arg [0] : _name (string): Uniswap AutoRouter Wrapper
Arg [1] : _uniV3SwapRouter (address): 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45
Arg [2] : 000000000000000000000000000000000000000000000000000000000000001a
Arg [3] : 556e6973776170204175746f526f757465722057726170706572000000000000
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.