Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers. Name tag integration is not available in advanced view.
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
||||
---|---|---|---|---|---|---|---|
17025772 | 680 days ago | 0 ETH | |||||
17025772 | 680 days ago | 0 ETH | |||||
17025772 | 680 days ago | 0 ETH | |||||
17025772 | 680 days ago | 0 ETH | |||||
17025772 | 680 days ago | 0 ETH | |||||
17025772 | 680 days ago | 0 ETH | |||||
17001524 | 683 days ago | 0 ETH | |||||
17001524 | 683 days ago | 0 ETH | |||||
17001524 | 683 days ago | 0 ETH | |||||
17001524 | 683 days ago | 0 ETH | |||||
17001524 | 683 days ago | 0 ETH | |||||
17001524 | 683 days ago | 0 ETH | |||||
16980467 | 686 days ago | 0 ETH | |||||
16980467 | 686 days ago | 0 ETH | |||||
16980467 | 686 days ago | 0 ETH | |||||
16980467 | 686 days ago | 0 ETH | |||||
16980467 | 686 days ago | 0 ETH | |||||
16980467 | 686 days ago | 0 ETH | |||||
16971581 | 687 days ago | 0 ETH | |||||
16971581 | 687 days ago | 0 ETH | |||||
16971581 | 687 days ago | 0 ETH | |||||
16971581 | 687 days ago | 0 ETH | |||||
16971581 | 687 days ago | 0 ETH | |||||
16971581 | 687 days ago | 0 ETH | |||||
16951244 | 690 days ago | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
SwapRouter
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.16; import { ERC20, SafeTransferLib } from "src/base/ERC4626.sol"; import { Multicall } from "src/base/Multicall.sol"; import { IUniswapV2Router02 as IUniswapV2Router } from "src/interfaces/external/IUniswapV2Router02.sol"; import { IUniswapV3Router } from "src/interfaces/external/IUniswapV3Router.sol"; /** * @title Sommelier Swap Router * @notice Provides a universal interface allowing Sommelier contracts to interact with multiple * different exchanges to perform swaps. * @dev Perform multiple swaps using Multicall. * @author crispymangoes, Brian Le */ contract SwapRouter is Multicall { using SafeTransferLib for ERC20; /** * @param UNIV2 Uniswap V2 * @param UNIV3 Uniswap V3 */ enum Exchange { UNIV2, UNIV3 } /** * @notice Get the selector of the function to call in order to perform swap with a given exchange. */ mapping(Exchange => bytes4) public getExchangeSelector; // ========================================== CONSTRUCTOR ========================================== /** * @notice Uniswap V2 swap router contract. */ IUniswapV2Router public immutable uniswapV2Router; // 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D /** * @notice Uniswap V3 swap router contract. */ IUniswapV3Router public immutable uniswapV3Router; // 0xE592427A0AEce92De3Edee1F18E0157C05861564 /** * @param _uniswapV2Router address of the Uniswap V2 swap router contract * @param _uniswapV3Router address of the Uniswap V3 swap router contract */ constructor(IUniswapV2Router _uniswapV2Router, IUniswapV3Router _uniswapV3Router) { // Set up all exchanges. uniswapV2Router = _uniswapV2Router; uniswapV3Router = _uniswapV3Router; // Set up mapping between IDs and selectors. getExchangeSelector[Exchange.UNIV2] = SwapRouter(this).swapWithUniV2.selector; getExchangeSelector[Exchange.UNIV3] = SwapRouter(this).swapWithUniV3.selector; } // ======================================= SWAP OPERATIONS ======================================= /** * @notice Attempted to perform a swap that reverted without a message. */ error SwapRouter__SwapReverted(); /** * @notice Attempted to perform a swap with mismatched assetIn and swap data. * @param actual the address encoded into the swap data * @param expected the address passed in with assetIn */ error SwapRouter__AssetInMisMatch(address actual, address expected); /** * @notice Attempted to perform a swap with mismatched assetOut and swap data. * @param actual the address encoded into the swap data * @param expected the address passed in with assetIn */ error SwapRouter__AssetOutMisMatch(address actual, address expected); /** * @notice Perform a swap using a supported exchange. * @param exchange value dictating which exchange to use to make the swap * @param swapData encoded data used for the swap * @param receiver address to send the received assets to * @return amountOut amount of assets received from the swap */ function swap( Exchange exchange, bytes memory swapData, address receiver, ERC20 assetIn, ERC20 assetOut ) external returns (uint256 amountOut) { // Route swap call to appropriate function using selector. (bool success, bytes memory result) = address(this).delegatecall( abi.encodeWithSelector(getExchangeSelector[exchange], swapData, receiver, assetIn, assetOut) ); if (!success) { // If there is return data, the call reverted with a reason or a custom error so we // bubble up the error message. if (result.length > 0) { assembly { let returndata_size := mload(result) revert(add(32, result), returndata_size) } } else { revert SwapRouter__SwapReverted(); } } amountOut = abi.decode(result, (uint256)); } /** * @notice Perform a swap using Uniswap V2. * @param swapData bytes variable storing the following swap information: * address[] path: array of addresses dictating what swap path to follow * uint256 amount: amount of the first asset in the path to swap * uint256 amountOutMin: the minimum amount of the last asset in the path to receive * @param receiver address to send the received assets to * @return amountOut amount of assets received from the swap */ function swapWithUniV2( bytes memory swapData, address receiver, ERC20 assetIn, ERC20 assetOut ) public returns (uint256 amountOut) { (address[] memory path, uint256 amount, uint256 amountOutMin) = abi.decode( swapData, (address[], uint256, uint256) ); // Check that path matches assetIn and assetOut. if (assetIn != ERC20(path[0])) revert SwapRouter__AssetInMisMatch(path[0], address(assetIn)); if (assetOut != ERC20(path[path.length - 1])) revert SwapRouter__AssetOutMisMatch(path[path.length - 1], address(assetOut)); // Transfer assets to this contract to swap. assetIn.safeTransferFrom(msg.sender, address(this), amount); // Approve assets to be swapped through the router. assetIn.safeApprove(address(uniswapV2Router), amount); // Execute the swap. uint256[] memory amountsOut = uniswapV2Router.swapExactTokensForTokens( amount, amountOutMin, path, receiver, block.timestamp + 60 ); amountOut = amountsOut[amountsOut.length - 1]; _checkApprovalIsZero(assetIn, address(uniswapV2Router)); } /** * @notice Perform a swap using Uniswap V3. * @param swapData bytes variable storing the following swap information * address[] path: array of addresses dictating what swap path to follow * uint24[] poolFees: array of pool fees dictating what swap pools to use * uint256 amount: amount of the first asset in the path to swap * uint256 amountOutMin: the minimum amount of the last asset in the path to receive * @param receiver address to send the received assets to * @return amountOut amount of assets received from the swap */ function swapWithUniV3( bytes memory swapData, address receiver, ERC20 assetIn, ERC20 assetOut ) public returns (uint256 amountOut) { (address[] memory path, uint24[] memory poolFees, uint256 amount, uint256 amountOutMin) = abi.decode( swapData, (address[], uint24[], uint256, uint256) ); // Check that path matches assetIn and assetOut. if (assetIn != ERC20(path[0])) revert SwapRouter__AssetInMisMatch(path[0], address(assetIn)); if (assetOut != ERC20(path[path.length - 1])) revert SwapRouter__AssetOutMisMatch(path[path.length - 1], address(assetOut)); // Transfer assets to this contract to swap. assetIn.safeTransferFrom(msg.sender, address(this), amount); // Approve assets to be swapped through the router. assetIn.safeApprove(address(uniswapV3Router), amount); // Encode swap parameters. bytes memory encodePackedPath = abi.encodePacked(address(assetIn)); for (uint256 i = 1; i < path.length; i++) encodePackedPath = abi.encodePacked(encodePackedPath, poolFees[i - 1], path[i]); // Execute the swap. amountOut = uniswapV3Router.exactInput( IUniswapV3Router.ExactInputParams({ path: encodePackedPath, recipient: receiver, deadline: block.timestamp + 60, amountIn: amount, amountOutMinimum: amountOutMin }) ); _checkApprovalIsZero(assetIn, address(uniswapV3Router)); } // ======================================= HELPER FUNCTIONS ======================================= /** * @notice Emitted when a swap does not use all the assets swap router approved. */ error SwapRouter__UnusedApproval(); /** * @notice Helper function that reverts if the Swap Router has unused approval after a swap is made. */ function _checkApprovalIsZero(ERC20 asset, address spender) internal view { if (asset.allowance(address(this), spender) != 0) revert SwapRouter__UnusedApproval(); } }
// 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/transmissions11/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 decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal INITIAL_CHAIN_ID; bytes32 internal 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 { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), 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: AGPL-3.0-only pragma solidity >=0.8.0; import { ERC20 } from "src/base/ERC20.sol"; import { SafeTransferLib } from "src/base/SafeTransferLib.sol"; import { Math } from "src/utils/Math.sol"; /// @notice Minimal ERC4626 tokenized Vault implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol) abstract contract ERC4626 is ERC20 { using SafeTransferLib for ERC20; using Math for uint256; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /*////////////////////////////////////////////////////////////// IMMUTABLES //////////////////////////////////////////////////////////////*/ ERC20 public asset; constructor( ERC20 _asset, string memory _name, string memory _symbol, uint8 _decimals ) ERC20(_name, _symbol, _decimals) { asset = _asset; } /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LOGIC //////////////////////////////////////////////////////////////*/ function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) { // Check for rounding error since we round down in previewDeposit. require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES"); beforeDeposit(assets, shares, receiver); // Need to transfer before minting or ERC777s could reenter. asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares, receiver); } function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) { assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up. beforeDeposit(assets, shares, receiver); // Need to transfer before minting or ERC777s could reenter. asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares, receiver); } function withdraw( uint256 assets, address receiver, address owner ) public virtual returns (uint256 shares) { shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up. if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } beforeWithdraw(assets, shares, receiver, owner); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); asset.safeTransfer(receiver, assets); afterWithdraw(assets, shares, receiver, owner); } function redeem( uint256 shares, address receiver, address owner ) public virtual returns (uint256 assets) { if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } // Check for rounding error since we round down in previewRedeem. require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS"); beforeWithdraw(assets, shares, receiver, owner); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); asset.safeTransfer(receiver, assets); afterWithdraw(assets, shares, receiver, owner); } /*////////////////////////////////////////////////////////////// ACCOUNTING LOGIC //////////////////////////////////////////////////////////////*/ function totalAssets() public view virtual returns (uint256); function convertToShares(uint256 assets) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets()); } function convertToAssets(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply); } function previewDeposit(uint256 assets) public view virtual returns (uint256) { return convertToShares(assets); } function previewMint(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply); } function previewWithdraw(uint256 assets) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets()); } function previewRedeem(uint256 shares) public view virtual returns (uint256) { return convertToAssets(shares); } /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LIMIT LOGIC //////////////////////////////////////////////////////////////*/ function maxDeposit(address) public view virtual returns (uint256) { return type(uint256).max; } function maxMint(address) public view virtual returns (uint256) { return type(uint256).max; } function maxWithdraw(address owner) public view virtual returns (uint256) { return convertToAssets(balanceOf[owner]); } function maxRedeem(address owner) public view virtual returns (uint256) { return balanceOf[owner]; } /*////////////////////////////////////////////////////////////// INTERNAL HOOKS LOGIC //////////////////////////////////////////////////////////////*/ function beforeDeposit( uint256 assets, uint256 shares, address receiver ) internal virtual {} function afterDeposit( uint256 assets, uint256 shares, address receiver ) internal virtual {} function beforeWithdraw( uint256 assets, uint256 shares, address receiver, address owner ) internal virtual {} function afterWithdraw( uint256 assets, uint256 shares, address receiver, address owner ) internal virtual {} }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; import { IMulticall } from "src/interfaces/IMulticall.sol"; /** * @title Multicall * @notice Enables calling multiple methods in a single call to the contract * From: https://github.com/Uniswap/v3-periphery/blob/1d69caf0d6c8cfeae9acd1f34ead30018d6e6400/contracts/base/Multicall.sol */ abstract contract Multicall is IMulticall { /// @inheritdoc IMulticall function multicall(bytes[] calldata data) public payable override returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); if (!success) { // Next 5 lines from https://ethereum.stackexchange.com/a/83577 // solhint-disable-next-line reason-string if (result.length < 68) revert(); assembly { result := add(result, 0x04) } revert(abi.decode(result, (string))); } results[i] = result; } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import { ERC20 } from "src/base/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument. mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; /// @title Multicall interface /// @notice Enables calling multiple methods in a single call to the contract // From: https://github.com/Uniswap/v3-periphery/contracts/interfaces/IMulticall.sol interface IMulticall { /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed /// @dev The `msg.value` should not be trusted for any method callable from multicall. /// @param data The encoded function data for each of the calls to make to this contract /// @return results The results from each of the calls passed in via data function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns ( uint256 amountA, uint256 amountB, uint256 liquidity ); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETH( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountToken, uint256 amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETHWithPermit( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountToken, uint256 amountETH); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) external pure returns (uint256 amountB); function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountOut); function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountIn); function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); } interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; /// @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; } /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface IUniswapV3Router is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.16; library Math { /** * @notice Substract with a floor of 0 for the result. */ function subMinZero(uint256 x, uint256 y) internal pure returns (uint256) { return x > y ? x - y : 0; } /** * @notice Used to change the decimals of precision used for an amount. */ function changeDecimals( uint256 amount, uint8 fromDecimals, uint8 toDecimals ) internal pure returns (uint256) { if (fromDecimals == toDecimals) { return amount; } else if (fromDecimals < toDecimals) { return amount * 10**(toDecimals - fromDecimals); } else { return amount / 10**(fromDecimals - toDecimals); } } // ===================================== OPENZEPPELIN'S MATH ===================================== function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } // ================================= SOLMATE's FIXEDPOINTMATHLIB ================================= uint256 public constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // Divide z by the denominator. z := div(z, denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // First, divide z - 1 by the denominator and add 1. // We allow z - 1 to underflow if z is 0, because we multiply the // end result by 0 if z is zero, ensuring we return 0 if z is zero. z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1)) } } }
{ "remappings": [ "@chainlink/=lib/chainlink/", "@compound/=lib/compound-protocol/contracts/", "@ds-test/=lib/forge-std/lib/ds-test/src/", "@ensdomains/=node_modules/@ensdomains/", "@forge-std/=lib/forge-std/src/", "@openzeppelin/=lib/openzeppelin-contracts/", "@solmate/=lib/solmate/src/", "@uniswap/v3-core/=lib/v3-core/", "@uniswap/v3-periphery/=lib/v3-periphery/", "@uniswapV3C/=lib/v3-core.git/contracts/", "@uniswapV3P/=lib/v3-periphery.git/contracts/", "chainlink/=lib/chainlink/contracts/src/v0.8/dev/vendor/@arbitrum/nitro-contracts/src/", "compound-protocol/=lib/compound-protocol/", "ds-test/=lib/forge-std/lib/ds-test/src/", "eth-gas-reporter/=node_modules/eth-gas-reporter/", "forge-std/=lib/forge-std/src/", "hardhat/=node_modules/hardhat/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/", "v3-core.git/=lib/v3-core.git/contracts/", "v3-periphery.git/=lib/v3-periphery.git/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "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":"contract IUniswapV2Router02","name":"_uniswapV2Router","type":"address"},{"internalType":"contract IUniswapV3Router","name":"_uniswapV3Router","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"actual","type":"address"},{"internalType":"address","name":"expected","type":"address"}],"name":"SwapRouter__AssetInMisMatch","type":"error"},{"inputs":[{"internalType":"address","name":"actual","type":"address"},{"internalType":"address","name":"expected","type":"address"}],"name":"SwapRouter__AssetOutMisMatch","type":"error"},{"inputs":[],"name":"SwapRouter__SwapReverted","type":"error"},{"inputs":[],"name":"SwapRouter__UnusedApproval","type":"error"},{"inputs":[{"internalType":"enum SwapRouter.Exchange","name":"","type":"uint8"}],"name":"getExchangeSelector","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"enum SwapRouter.Exchange","name":"exchange","type":"uint8"},{"internalType":"bytes","name":"swapData","type":"bytes"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"contract ERC20","name":"assetIn","type":"address"},{"internalType":"contract ERC20","name":"assetOut","type":"address"}],"name":"swap","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"swapData","type":"bytes"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"contract ERC20","name":"assetIn","type":"address"},{"internalType":"contract ERC20","name":"assetOut","type":"address"}],"name":"swapWithUniV2","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"swapData","type":"bytes"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"contract ERC20","name":"assetIn","type":"address"},{"internalType":"contract ERC20","name":"assetOut","type":"address"}],"name":"swapWithUniV3","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV3Router","outputs":[{"internalType":"contract IUniswapV3Router","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c060405234801561001057600080fd5b506040516115bc3803806115bc83398101604081905261002f916100cd565b6001600160a01b039182166080521660a052600060208190527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5805463ffffffff19908116635a0c82791790915560019091527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d8054909116639d453f8d179055610107565b6001600160a01b03811681146100ca57600080fd5b50565b600080604083850312156100e057600080fd5b82516100eb816100b5565b60208401519092506100fc816100b5565b809150509250929050565b60805160a0516114686101546000396000818160d8015281816106ed015281816107c5015261089501526000818160870152818161046201528181610493015261055f01526114686000f3fe6080604052600436106100705760003560e01c80635a0c82791161004e5780635a0c8279146101285780639d453f8d14610148578063a1fbdf3914610168578063ac9650d8146101b157600080fd5b80631694505e146100755780632c76d7a6146100c65780632dfe1690146100fa575b600080fd5b34801561008157600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100d257600080fd5b506100a97f000000000000000000000000000000000000000000000000000000000000000081565b34801561010657600080fd5b5061011a610115366004610ca8565b6101d1565b6040519081526020016100bd565b34801561013457600080fd5b5061011a610143366004610d30565b6102ff565b34801561015457600080fd5b5061011a610163366004610d30565b61058f565b34801561017457600080fd5b50610198610183366004610da5565b60006020819052908152604090205460e01b81565b6040516001600160e01b031990911681526020016100bd565b6101c46101bf366004610dc7565b6108c6565b6040516100bd9190610e8c565b600080803081808a60018111156101ea576101ea610eee565b60018111156101fb576101fb610eee565b815260200190815260200160002060009054906101000a900460e01b8888888860405160240161022e9493929190610f04565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161026c9190610f40565b600060405180830381855af49150503d80600081146102a7576040519150601f19603f3d011682016040523d82523d6000602084013e6102ac565b606091505b5091509150816102df578051156102c65780518082602001fd5b6040516347167cef60e11b815260040160405180910390fd5b808060200190518101906102f39190610f5c565b98975050505050505050565b600080600080878060200190518101906103199190611008565b9250925092508260008151811061033257610332611058565b60200260200101516001600160a01b0316866001600160a01b0316146103a7578260008151811061036557610365611058565b60200260200101518660405163e539288160e01b815260040161039e9291906001600160a01b0392831681529116602082015260400190565b60405180910390fd5b82600184516103b69190611084565b815181106103c6576103c6611058565b60200260200101516001600160a01b0316856001600160a01b03161461043e5782600184516103f59190611084565b8151811061040557610405611058565b6020026020010151856040516347052b6760e01b815260040161039e9291906001600160a01b0392831681529116602082015260400190565b6104536001600160a01b038716333085610a1e565b6104876001600160a01b0387167f000000000000000000000000000000000000000000000000000000000000000084610aa8565b60006001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166338ed17398484878c6104c742603c61109d565b6040518663ffffffff1660e01b81526004016104e79594939291906110b0565b6000604051808303816000875af1158015610506573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261052e9190810190611121565b9050806001825161053f9190611084565b8151811061054f5761054f611058565b60200260200101519450610583877f0000000000000000000000000000000000000000000000000000000000000000610b25565b50505050949350505050565b6000806000806000888060200190518101906105ab91906111b2565b9350935093509350836000815181106105c6576105c6611058565b60200260200101516001600160a01b0316876001600160a01b03161461063257836000815181106105f9576105f9611058565b60200260200101518760405163e539288160e01b815260040161039e9291906001600160a01b0392831681529116602082015260400190565b83600185516106419190611084565b8151811061065157610651611058565b60200260200101516001600160a01b0316866001600160a01b0316146106c95783600185516106809190611084565b8151811061069057610690611058565b6020026020010151866040516347052b6760e01b815260040161039e9291906001600160a01b0392831681529116602082015260400190565b6106de6001600160a01b038816333085610a1e565b6107126001600160a01b0388167f000000000000000000000000000000000000000000000000000000000000000084610aa8565b60408051606089901b6bffffffffffffffffffffffff1916602082015281516014818303018152603490910190915260015b85518110156107c257818561075a600184611084565b8151811061076a5761076a611058565b602002602001015187838151811061078457610784611058565b602002602001015160405160200161079e9392919061128d565b604051602081830303815290604052915080806107ba906112d9565b915050610744565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c04b8d596040518060a001604052808481526020018c6001600160a01b0316815260200142603c61081f919061109d565b8152602001868152602001858152506040518263ffffffff1660e01b815260040161084a91906112f2565b6020604051808303816000875af1158015610869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088d9190610f5c565b95506108b9887f0000000000000000000000000000000000000000000000000000000000000000610b25565b5050505050949350505050565b60608167ffffffffffffffff8111156108e1576108e1610bcb565b60405190808252806020026020018201604052801561091457816020015b60608152602001906001900390816108ff5790505b50905060005b82811015610a17576000803086868581811061093857610938611058565b905060200281019061094a919061134a565b604051610958929190611398565b600060405180830381855af49150503d8060008114610993576040519150601f19603f3d011682016040523d82523d6000602084013e610998565b606091505b5091509150816109e4576044815110156109b157600080fd5b600481019050808060200190518101906109cb91906113a8565b60405162461bcd60e51b815260040161039e919061141f565b808484815181106109f7576109f7611058565b602002602001018190525050508080610a0f906112d9565b91505061091a565b5092915050565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080610aa15760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b604482015260640161039e565b5050505050565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610b1f5760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b604482015260640161039e565b50505050565b604051636eb1769f60e11b81523060048201526001600160a01b03828116602483015283169063dd62ed3e90604401602060405180830381865afa158015610b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b959190610f5c565b15610bb357604051637404a95160e01b815260040160405180910390fd5b5050565b803560028110610bc657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610c0a57610c0a610bcb565b604052919050565b600067ffffffffffffffff821115610c2c57610c2c610bcb565b50601f01601f191660200190565b600082601f830112610c4b57600080fd5b8135610c5e610c5982610c12565b610be1565b818152846020838601011115610c7357600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b0381168114610ca557600080fd5b50565b600080600080600060a08688031215610cc057600080fd5b610cc986610bb7565b9450602086013567ffffffffffffffff811115610ce557600080fd5b610cf188828901610c3a565b9450506040860135610d0281610c90565b92506060860135610d1281610c90565b91506080860135610d2281610c90565b809150509295509295909350565b60008060008060808587031215610d4657600080fd5b843567ffffffffffffffff811115610d5d57600080fd5b610d6987828801610c3a565b9450506020850135610d7a81610c90565b92506040850135610d8a81610c90565b91506060850135610d9a81610c90565b939692955090935050565b600060208284031215610db757600080fd5b610dc082610bb7565b9392505050565b60008060208385031215610dda57600080fd5b823567ffffffffffffffff80821115610df257600080fd5b818501915085601f830112610e0657600080fd5b813581811115610e1557600080fd5b8660208260051b8501011115610e2a57600080fd5b60209290920196919550909350505050565b60005b83811015610e57578181015183820152602001610e3f565b50506000910152565b60008151808452610e78816020860160208601610e3c565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015610ee157603f19888603018452610ecf858351610e60565b94509285019290850190600101610eb3565b5092979650505050505050565b634e487b7160e01b600052602160045260246000fd5b608081526000610f176080830187610e60565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b60008251610f52818460208701610e3c565b9190910192915050565b600060208284031215610f6e57600080fd5b5051919050565b600067ffffffffffffffff821115610f8f57610f8f610bcb565b5060051b60200190565b600082601f830112610faa57600080fd5b81516020610fba610c5983610f75565b82815260059290921b84018101918181019086841115610fd957600080fd5b8286015b84811015610ffd578051610ff081610c90565b8352918301918301610fdd565b509695505050505050565b60008060006060848603121561101d57600080fd5b835167ffffffffffffffff81111561103457600080fd5b61104086828701610f99565b93505060208401519150604084015190509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156110975761109761106e565b92915050565b808201808211156110975761109761106e565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156111005784516001600160a01b0316835293830193918301916001016110db565b50506001600160a01b03969096166060850152505050608001529392505050565b6000602080838503121561113457600080fd5b825167ffffffffffffffff81111561114b57600080fd5b8301601f8101851361115c57600080fd5b805161116a610c5982610f75565b81815260059190911b8201830190838101908783111561118957600080fd5b928401925b828410156111a75783518252928401929084019061118e565b979650505050505050565b600080600080608085870312156111c857600080fd5b845167ffffffffffffffff808211156111e057600080fd5b6111ec88838901610f99565b955060209150818701518181111561120357600080fd5b87019050601f8101881361121657600080fd5b8051611224610c5982610f75565b81815260059190911b8201830190838101908a83111561124357600080fd5b928401925b8284101561127357835162ffffff811681146112645760008081fd5b82529284019290840190611248565b60408a01516060909a0151989b909a509650505050505050565b6000845161129f818460208901610e3c565b60e89490941b6001600160e81b0319169190930190815260609190911b6bffffffffffffffffffffffff1916600382015260170192915050565b6000600182016112eb576112eb61106e565b5060010190565b602081526000825160a0602084015261130e60c0840182610e60565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b6000808335601e1984360301811261136157600080fd5b83018035915067ffffffffffffffff82111561137c57600080fd5b60200191503681900382131561139157600080fd5b9250929050565b8183823760009101908152919050565b6000602082840312156113ba57600080fd5b815167ffffffffffffffff8111156113d157600080fd5b8201601f810184136113e257600080fd5b80516113f0610c5982610c12565b81815285602083850101111561140557600080fd5b611416826020830160208601610e3c565b95945050505050565b602081526000610dc06020830184610e6056fea2646970667358221220d7ec814f57cdb98d279e0fd08bc654057583499820ea222569f8adb86e2ecd3164736f6c634300081000330000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Deployed Bytecode
0x6080604052600436106100705760003560e01c80635a0c82791161004e5780635a0c8279146101285780639d453f8d14610148578063a1fbdf3914610168578063ac9650d8146101b157600080fd5b80631694505e146100755780632c76d7a6146100c65780632dfe1690146100fa575b600080fd5b34801561008157600080fd5b506100a97f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100d257600080fd5b506100a97f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156481565b34801561010657600080fd5b5061011a610115366004610ca8565b6101d1565b6040519081526020016100bd565b34801561013457600080fd5b5061011a610143366004610d30565b6102ff565b34801561015457600080fd5b5061011a610163366004610d30565b61058f565b34801561017457600080fd5b50610198610183366004610da5565b60006020819052908152604090205460e01b81565b6040516001600160e01b031990911681526020016100bd565b6101c46101bf366004610dc7565b6108c6565b6040516100bd9190610e8c565b600080803081808a60018111156101ea576101ea610eee565b60018111156101fb576101fb610eee565b815260200190815260200160002060009054906101000a900460e01b8888888860405160240161022e9493929190610f04565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161026c9190610f40565b600060405180830381855af49150503d80600081146102a7576040519150601f19603f3d011682016040523d82523d6000602084013e6102ac565b606091505b5091509150816102df578051156102c65780518082602001fd5b6040516347167cef60e11b815260040160405180910390fd5b808060200190518101906102f39190610f5c565b98975050505050505050565b600080600080878060200190518101906103199190611008565b9250925092508260008151811061033257610332611058565b60200260200101516001600160a01b0316866001600160a01b0316146103a7578260008151811061036557610365611058565b60200260200101518660405163e539288160e01b815260040161039e9291906001600160a01b0392831681529116602082015260400190565b60405180910390fd5b82600184516103b69190611084565b815181106103c6576103c6611058565b60200260200101516001600160a01b0316856001600160a01b03161461043e5782600184516103f59190611084565b8151811061040557610405611058565b6020026020010151856040516347052b6760e01b815260040161039e9291906001600160a01b0392831681529116602082015260400190565b6104536001600160a01b038716333085610a1e565b6104876001600160a01b0387167f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d84610aa8565b60006001600160a01b037f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d166338ed17398484878c6104c742603c61109d565b6040518663ffffffff1660e01b81526004016104e79594939291906110b0565b6000604051808303816000875af1158015610506573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261052e9190810190611121565b9050806001825161053f9190611084565b8151811061054f5761054f611058565b60200260200101519450610583877f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d610b25565b50505050949350505050565b6000806000806000888060200190518101906105ab91906111b2565b9350935093509350836000815181106105c6576105c6611058565b60200260200101516001600160a01b0316876001600160a01b03161461063257836000815181106105f9576105f9611058565b60200260200101518760405163e539288160e01b815260040161039e9291906001600160a01b0392831681529116602082015260400190565b83600185516106419190611084565b8151811061065157610651611058565b60200260200101516001600160a01b0316866001600160a01b0316146106c95783600185516106809190611084565b8151811061069057610690611058565b6020026020010151866040516347052b6760e01b815260040161039e9291906001600160a01b0392831681529116602082015260400190565b6106de6001600160a01b038816333085610a1e565b6107126001600160a01b0388167f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156484610aa8565b60408051606089901b6bffffffffffffffffffffffff1916602082015281516014818303018152603490910190915260015b85518110156107c257818561075a600184611084565b8151811061076a5761076a611058565b602002602001015187838151811061078457610784611058565b602002602001015160405160200161079e9392919061128d565b604051602081830303815290604052915080806107ba906112d9565b915050610744565b507f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615646001600160a01b031663c04b8d596040518060a001604052808481526020018c6001600160a01b0316815260200142603c61081f919061109d565b8152602001868152602001858152506040518263ffffffff1660e01b815260040161084a91906112f2565b6020604051808303816000875af1158015610869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088d9190610f5c565b95506108b9887f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564610b25565b5050505050949350505050565b60608167ffffffffffffffff8111156108e1576108e1610bcb565b60405190808252806020026020018201604052801561091457816020015b60608152602001906001900390816108ff5790505b50905060005b82811015610a17576000803086868581811061093857610938611058565b905060200281019061094a919061134a565b604051610958929190611398565b600060405180830381855af49150503d8060008114610993576040519150601f19603f3d011682016040523d82523d6000602084013e610998565b606091505b5091509150816109e4576044815110156109b157600080fd5b600481019050808060200190518101906109cb91906113a8565b60405162461bcd60e51b815260040161039e919061141f565b808484815181106109f7576109f7611058565b602002602001018190525050508080610a0f906112d9565b91505061091a565b5092915050565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080610aa15760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b604482015260640161039e565b5050505050565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610b1f5760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b604482015260640161039e565b50505050565b604051636eb1769f60e11b81523060048201526001600160a01b03828116602483015283169063dd62ed3e90604401602060405180830381865afa158015610b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b959190610f5c565b15610bb357604051637404a95160e01b815260040160405180910390fd5b5050565b803560028110610bc657600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610c0a57610c0a610bcb565b604052919050565b600067ffffffffffffffff821115610c2c57610c2c610bcb565b50601f01601f191660200190565b600082601f830112610c4b57600080fd5b8135610c5e610c5982610c12565b610be1565b818152846020838601011115610c7357600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b0381168114610ca557600080fd5b50565b600080600080600060a08688031215610cc057600080fd5b610cc986610bb7565b9450602086013567ffffffffffffffff811115610ce557600080fd5b610cf188828901610c3a565b9450506040860135610d0281610c90565b92506060860135610d1281610c90565b91506080860135610d2281610c90565b809150509295509295909350565b60008060008060808587031215610d4657600080fd5b843567ffffffffffffffff811115610d5d57600080fd5b610d6987828801610c3a565b9450506020850135610d7a81610c90565b92506040850135610d8a81610c90565b91506060850135610d9a81610c90565b939692955090935050565b600060208284031215610db757600080fd5b610dc082610bb7565b9392505050565b60008060208385031215610dda57600080fd5b823567ffffffffffffffff80821115610df257600080fd5b818501915085601f830112610e0657600080fd5b813581811115610e1557600080fd5b8660208260051b8501011115610e2a57600080fd5b60209290920196919550909350505050565b60005b83811015610e57578181015183820152602001610e3f565b50506000910152565b60008151808452610e78816020860160208601610e3c565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015610ee157603f19888603018452610ecf858351610e60565b94509285019290850190600101610eb3565b5092979650505050505050565b634e487b7160e01b600052602160045260246000fd5b608081526000610f176080830187610e60565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b60008251610f52818460208701610e3c565b9190910192915050565b600060208284031215610f6e57600080fd5b5051919050565b600067ffffffffffffffff821115610f8f57610f8f610bcb565b5060051b60200190565b600082601f830112610faa57600080fd5b81516020610fba610c5983610f75565b82815260059290921b84018101918181019086841115610fd957600080fd5b8286015b84811015610ffd578051610ff081610c90565b8352918301918301610fdd565b509695505050505050565b60008060006060848603121561101d57600080fd5b835167ffffffffffffffff81111561103457600080fd5b61104086828701610f99565b93505060208401519150604084015190509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156110975761109761106e565b92915050565b808201808211156110975761109761106e565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156111005784516001600160a01b0316835293830193918301916001016110db565b50506001600160a01b03969096166060850152505050608001529392505050565b6000602080838503121561113457600080fd5b825167ffffffffffffffff81111561114b57600080fd5b8301601f8101851361115c57600080fd5b805161116a610c5982610f75565b81815260059190911b8201830190838101908783111561118957600080fd5b928401925b828410156111a75783518252928401929084019061118e565b979650505050505050565b600080600080608085870312156111c857600080fd5b845167ffffffffffffffff808211156111e057600080fd5b6111ec88838901610f99565b955060209150818701518181111561120357600080fd5b87019050601f8101881361121657600080fd5b8051611224610c5982610f75565b81815260059190911b8201830190838101908a83111561124357600080fd5b928401925b8284101561127357835162ffffff811681146112645760008081fd5b82529284019290840190611248565b60408a01516060909a0151989b909a509650505050505050565b6000845161129f818460208901610e3c565b60e89490941b6001600160e81b0319169190930190815260609190911b6bffffffffffffffffffffffff1916600382015260170192915050565b6000600182016112eb576112eb61106e565b5060010190565b602081526000825160a0602084015261130e60c0840182610e60565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b6000808335601e1984360301811261136157600080fd5b83018035915067ffffffffffffffff82111561137c57600080fd5b60200191503681900382131561139157600080fd5b9250929050565b8183823760009101908152919050565b6000602082840312156113ba57600080fd5b815167ffffffffffffffff8111156113d157600080fd5b8201601f810184136113e257600080fd5b80516113f0610c5982610c12565b81815285602083850101111561140557600080fd5b611416826020830160208601610e3c565b95945050505050565b602081526000610dc06020830184610e6056fea2646970667358221220d7ec814f57cdb98d279e0fd08bc654057583499820ea222569f8adb86e2ecd3164736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
-----Decoded View---------------
Arg [0] : _uniswapV2Router (address): 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
Arg [1] : _uniswapV3Router (address): 0xE592427A0AEce92De3Edee1F18E0157C05861564
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d
Arg [1] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.