Untitled
// SPDX-License-Identifier: MIT pragma solidity ^0.8.26; import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; struct SwapCoreDescription { address tokenIn; address tokenOut; uint256 sourceChainId; uint256 targetChainId; address source; address target; uint256 amountIn; uint256 channel; string extra; } struct SourceSwapDescription { SwapCoreDescription core; address maker; address makerToken; address router; // 可能需要改成数组,因为未必只调用一个call就swap成功,比如universalRouter 需要 permit2 bytes routerCallData; } struct TargetSwapDescription { SwapCoreDescription core; address makerToken; uint256 makerTokenAmount; address router; bytes routerCallData; } struct InternalSwapDescription { address target; address tokenIn; address tokenOut; uint256 amountIn; address router; bytes routerCallData; } contract OwltoRouter { // 原链直接swap到maker function swapOnSourceChain(SourceSwapDescription calldata desc) external payable returns (bool) { receiveToken(desc.core.tokenIn, desc.core.amountIn); InternalSwapDescription memory swapDesc = InternalSwapDescription({ target: desc.maker, tokenIn: desc.core.tokenIn, tokenOut: desc.makerToken, amountIn: desc.core.amountIn, router: desc.router, routerCallData: desc.routerCallData }); return swap(swapDesc); } // 目标链先判断是否同链,然后swap到target地址 function swapOnTargetChain(TargetSwapDescription calldata desc) external payable returns (bool) { receiveToken(desc.core.tokenIn, desc.core.amountIn); address tokenIn = isOnTheSameChain(desc.core) ? desc.core.tokenIn : desc.makerToken; uint256 amountIn = isOnTheSameChain(desc.core) ? desc.core.amountIn : desc.makerTokenAmount; InternalSwapDescription memory swapDesc = InternalSwapDescription({ target: desc.core.target, tokenIn: tokenIn, tokenOut: desc.core.tokenOut, amountIn: amountIn, router: desc.router, routerCallData: desc.routerCallData }); return swap(swapDesc); } function isOnTheSameChain(SwapCoreDescription calldata desc) internal pure returns (bool) { return desc.sourceChainId == desc.targetChainId; } function receiveToken(address token, uint256 amount) internal { if (token != address(0)) { TransferHelper.safeTransferFrom( token, msg.sender, address(this), amount ); } } function swap(InternalSwapDescription memory desc) public returns (bool) { if (desc.tokenIn == desc.tokenOut) { return send(desc.target, desc.tokenIn, desc.amountIn); } require(desc.router != address(0), "no router"); (bool ok, ) = desc.router.call(desc.routerCallData); return ok; } function send( address target, address token, uint256 amount ) internal returns (bool) { bool ok = true; if (token == address(0)) { (ok, ) = target.call{value: amount}(""); } else { TransferHelper.safeTransferFrom( token, address(this), target, amount ); } return ok; } }
Leave a Comment