Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: SwapRouter 合约 #128

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 99 additions & 25 deletions demo-contract/contracts/wtfswap/SwapRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,63 +17,137 @@ contract SwapRouter is ISwapRouter {
function exactInput(
ExactInputParams calldata params
) external payable override returns (uint256 amountOut) {
// 用 index 记录当前正在读取的 index
uint256 index = 0;
// while 循环遍历 indexPath,获取每个 pool 的价格
while (index < params.indexPath.length) {
uint256 amountIn = params.amountIn;

for (uint256 i = 0; i < params.indexPath.length; i++) {
address _pool = poolManager.getPool(
params.tokenIn,
params.tokenOut,
params.indexPath[index]
params.indexPath[i]
);
IPool pool = IPool(_pool);
// TODO 交易
bytes memory data;
// 交易的钱统一转给本合约,最后都完成之后在 swapCallback 中打给用户
pool.swap(msg.sender, true, 12, 12, data);
amountOut += 2;
index++;

(uint256 amount0Out, uint256 amount1Out) = pool.getAmountsOut(
amountIn
);
amountOut = params.tokenIn < params.tokenOut
? amount1Out
: amount0Out;

bytes memory data = abi.encode(
msg.sender,
params.tokenIn,
params.tokenOut
);
pool.swap(
msg.sender,
params.tokenIn < params.tokenOut,
amountIn,
amountOut,
data
);

amountIn = amountOut; // 为下一次循环准备
}
}

// 确定输出的 token 交易
function exactOutput(
ExactOutputParams calldata params
) external payable override returns (uint256 amountIn) {}
) external payable override returns (uint256 amountIn) {
uint256 amountOut = params.amountOut;

for (uint256 i = params.indexPath.length; i > 0; i--) {
address _pool = poolManager.getPool(
params.tokenIn,
params.tokenOut,
params.indexPath[i - 1]
);
IPool pool = IPool(_pool);

(uint256 amount0In, uint256 amount1In) = pool.getAmountsIn(
amountOut
);
amountIn = params.tokenIn < params.tokenOut ? amount0In : amount1In;

bytes memory data = abi.encode(
msg.sender,
params.tokenIn,
params.tokenOut
);
pool.swap(
msg.sender,
params.tokenIn > params.tokenOut,
amountIn,
amountOut,
data
);

amountOut = amountIn; // 为下一次循环准备
}
}

// 确认输入的 token,估算可以获得多少输出的 token
function quoteExactInput(
QuoteExactInputParams memory params
) external view override returns (uint256 amountOut) {
// 用 index 记录当前正在读取的 index
uint256 index = 0;
// while 循环遍历 indexPath,获取每个 pool 的价格
while (index < params.indexPath.length) {
uint256 amountIn = params.amountIn;

for (uint256 i = 0; i < params.indexPath.length; i++) {
address _pool = poolManager.getPool(
params.tokenIn,
params.tokenOut,
params.indexPath[index]
params.indexPath[i]
);
IPool pool = IPool(_pool);
uint160 sqrtPriceX96 = pool.sqrtPriceX96();
// TODO 计算 amountOut
amountOut = sqrtPriceX96;
// 更新 index
index++;

(uint256 amount0Out, uint256 amount1Out) = pool.getAmountsOut(
amountIn
);
amountOut = params.tokenIn < params.tokenOut
? amount1Out
: amount0Out;

amountIn = amountOut; // 为下一次循环准备
}
}

// 确认输出的 token,估算需要多少输入的 token
function quoteExactOutput(
QuoteExactOutputParams memory params
) external view override returns (uint256 amountIn) {}
) external view override returns (uint256 amountIn) {
uint256 amountOut = params.amountOut;

for (uint256 i = params.indexPath.length; i > 0; i--) {
address _pool = poolManager.getPool(
params.tokenIn,
params.tokenOut,
params.indexPath[i - 1]
);
IPool pool = IPool(_pool);

(uint256 amount0In, uint256 amount1In) = pool.getAmountsIn(
amountOut
);
amountIn = params.tokenIn < params.tokenOut ? amount0In : amount1In;

amountOut = amountIn; // 为下一次循环准备
}
}

function swapCallback(
uint256 amount0In,
uint256 amount1In,
bytes calldata data
) external override {
// 每次 swap 后 pool 会调用这个方法
// 最后一次 swap 完成后这里统一把钱打给用户
(address sender, address tokenIn, address tokenOut) = abi.decode(
data,
(address, address, address)
);
uint256 amountIn = tokenIn < tokenOut ? amount0In : amount1In;
require(
IERC20(tokenIn).transferFrom(sender, msg.sender, amountIn),
"Transfer failed"
);
}
}