diff --git a/.gitmodules b/.gitmodules index bf0767ae7..6bd6cae0f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "lib/rain.interpreter"] path = lib/rain.interpreter url = https://github.com/rainprotocol/rain.interpreter +[submodule "lib/v2-periphery"] + path = lib/v2-periphery + url = https://github.com/Uniswap/v2-periphery diff --git a/lib/v2-periphery b/lib/v2-periphery new file mode 160000 index 000000000..0335e8f7e --- /dev/null +++ b/lib/v2-periphery @@ -0,0 +1 @@ +Subproject commit 0335e8f7e1bd1e8d8329fd300aea2ef2f36dd19f diff --git a/src/concrete/UniV2PoolOrderBookArbOrderTaker.sol b/src/concrete/UniV2PoolOrderBookArbOrderTaker.sol new file mode 100644 index 000000000..edd1536b5 --- /dev/null +++ b/src/concrete/UniV2PoolOrderBookArbOrderTaker.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: CAL +pragma solidity =0.8.19; + +import "v2-periphery/interfaces/IUniswapV2Router02.sol"; + +import "../abstract/OrderBookV3ArbOrderTaker.sol"; +import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; +import {Address} from "openzeppelin-contracts/contracts/utils/Address.sol"; + +bytes32 constant CALLER_META_HASH = bytes32(0x00); + +contract UniV2PoolOrderBookArbOrderTaker is OrderBookV3ArbOrderTaker { + using SafeERC20 for IERC20; + using Address for address; + + IUniswapV2Router02 public sUniV2Router02; + + constructor(DeployerDiscoverableMetaV2ConstructionConfig memory config) + OrderBookV3ArbOrderTaker(CALLER_META_HASH, config) + {} + + /// @inheritdoc OrderBookV3ArbOrderTaker + function _beforeInitialize(bytes memory data) internal virtual override { + (address uniV2Router02) = abi.decode(data, (address)); + sUniV2Router02 = IUniswapV2Router02(uniV2Router02); + } + + /// @inheritdoc OrderBookV3ArbOrderTaker + function onTakeOrders( + address inputToken, + address outputToken, + uint256 inputAmountSent, + uint256 totalOutputAmount, + bytes calldata takeOrdersData + ) public virtual override { + super.onTakeOrders(inputToken, outputToken, inputAmountSent, totalOutputAmount, takeOrdersData); + IERC20(inputToken).safeApprove(address(sUniV2Router02), 0); + IERC20(inputToken).safeApprove(address(sUniV2Router02), type(uint256).max); + address[] memory path = new address[](2); + path[0] = inputToken; + path[1] = outputToken; + (uint256[] memory amounts) = sUniV2Router02.swapExactTokensForTokens( + inputAmountSent, totalOutputAmount, path, address(this), block.timestamp + ); + IERC20(inputToken).safeApprove(address(sUniV2Router02), 0); + (amounts); + } + + /// Allow receiving gas. + fallback() external onlyNotInitializing {} +}