Untitled
unknown
plain_text
a year ago
3.7 kB
10
Indexable
// 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;
}
}
Editor is loading...
Leave a Comment