From c823feb85da039097272446b1d42d5147ae686b7 Mon Sep 17 00:00:00 2001 From: Attens1423 Date: Tue, 17 Oct 2023 12:12:16 +0800 Subject: [PATCH] fix uni --- contracts/SmartRoute/adapter/UniV3Adapter.sol | 15 ++++-- contracts/external/Multicall.sol | 10 ++-- contracts/external/uniswap/PoolAddress.sol | 48 +++++++++++++++++++ 3 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 contracts/external/uniswap/PoolAddress.sol diff --git a/contracts/SmartRoute/adapter/UniV3Adapter.sol b/contracts/SmartRoute/adapter/UniV3Adapter.sol index 9434c14..9979a7a 100644 --- a/contracts/SmartRoute/adapter/UniV3Adapter.sol +++ b/contracts/SmartRoute/adapter/UniV3Adapter.sol @@ -15,20 +15,26 @@ import {UniversalERC20} from "../lib/UniversalERC20.sol"; import {SafeERC20} from "../../lib/SafeERC20.sol"; import {TickMath} from '../../external/uniswap/TickMath.sol'; import {IWETH} from "../../intf/IWETH.sol"; +import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; +import {PoolAddress} from '../../external/uniswap/PoolAddress.sol'; // to adapter like dodo V1 -contract UniV3Adapter is IDODOAdapter, IUniswapV3SwapCallback { +contract UniV3Adapter is IDODOAdapter, IUniswapV3SwapCallback, InitializableOwnable { using SafeMath for uint; // ============ Storage ============ address constant _ETH_ADDRESS_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public immutable _WETH_; + address public immutable _V3_FACTORY_; constructor ( - address payable weth + address payable weth, + address factory ) public { _WETH_ = weth; + _V3_FACTORY_ = factory; + initOwner(msg.sender); } function _uniV3Swap(address to, address pool, uint160 sqrtX96, bytes memory data) internal { @@ -37,8 +43,6 @@ contract UniV3Adapter is IDODOAdapter, IUniswapV3SwapCallback { uint256 sellAmount = IERC20(fromToken).balanceOf(address(this)); bool zeroForOne = fromToken < toToken; - // transfer - //IERC20(fromToken).transfer(pool, sellAmount); // swap IUniV3(pool).swap( to, @@ -70,6 +74,9 @@ contract UniV3Adapter is IDODOAdapter, IUniswapV3SwapCallback { ) external override { require(amount0Delta > 0 || amount1Delta > 0); // swaps entirely within 0-liquidity regions are not supported (address tokenIn, address tokenOut, uint24 fee) = abi.decode(_data, (address, address, uint24)); + // verifyCallback + address poolAddress = PoolAddress.computeAddress(_V3_FACTORY_, PoolAddress.getPoolKey(tokenIn, tokenOut, fee)); + require(msg.sender == poolAddress || msg.sender == _OWNER_, "not available call address"); (bool isExactInput, uint256 amountToPay) = amount0Delta > 0 diff --git a/contracts/external/Multicall.sol b/contracts/external/Multicall.sol index bb3431f..a5ba7be 100644 --- a/contracts/external/Multicall.sol +++ b/contracts/external/Multicall.sol @@ -1,7 +1,3 @@ -/** - *Submitted for verification at Etherscan.io on 2019-06-10 -*/ - pragma solidity 0.6.9; pragma experimental ABIEncoderV2; @@ -10,17 +6,19 @@ pragma experimental ABIEncoderV2; /// @author Joshua Levine /// @author Nick Johnson +// WithValid contract Multicall { struct Call { address target; bytes callData; } - function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) { + function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData, bool[] memory dataValid) { blockNumber = block.number; returnData = new bytes[](calls.length); + dataValid = new bool[](calls.length); for(uint256 i = 0; i < calls.length; i++) { (bool success, bytes memory ret) = calls[i].target.call(calls[i].callData); - require(success); + dataValid[i] = success; returnData[i] = ret; } } diff --git a/contracts/external/uniswap/PoolAddress.sol b/contracts/external/uniswap/PoolAddress.sol new file mode 100644 index 0000000..c3049fa --- /dev/null +++ b/contracts/external/uniswap/PoolAddress.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity >=0.5.0; + +/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee +library PoolAddress { + bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54; + + /// @notice The identifying key of the pool + struct PoolKey { + address token0; + address token1; + uint24 fee; + } + + /// @notice Returns PoolKey: the ordered tokens with the matched fee levels + /// @param tokenA The first token of a pool, unsorted + /// @param tokenB The second token of a pool, unsorted + /// @param fee The fee level of the pool + /// @return Poolkey The pool details with ordered token0 and token1 assignments + function getPoolKey( + address tokenA, + address tokenB, + uint24 fee + ) internal pure returns (PoolKey memory) { + if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); + return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); + } + + /// @notice Deterministically computes the pool address given the factory and PoolKey + /// @param factory The Uniswap V3 factory contract address + /// @param key The PoolKey + /// @return pool The contract address of the V3 pool + function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { + require(key.token0 < key.token1); + pool = address( + uint256( + keccak256( + abi.encodePacked( + hex'ff', + factory, + keccak256(abi.encode(key.token0, key.token1, key.fee)), + POOL_INIT_CODE_HASH + ) + ) + ) + ); + } +} \ No newline at end of file