Skip to content

Commit

Permalink
add origin payer for unxv3 swap
Browse files Browse the repository at this point in the history
  • Loading branch information
ume committed Dec 13, 2024
1 parent da4c52e commit 3f3a42a
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 53 deletions.
2 changes: 1 addition & 1 deletion contracts/8/DexRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ contract DexRouter is
amount
);

(uint256 swappedAmount, ) = _uniswapV3Swap(
uint256 swappedAmount = _uniswapV3Swap(
payer,
payable(middleReceiver),
amount,
Expand Down
120 changes: 72 additions & 48 deletions contracts/8/UnxswapV3Router.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,14 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
/// @param minReturn The minimum amount of tokens that must be received for the swap to be valid, safeguarding against excessive slippage.
/// @param pools An array of pool identifiers defining the swap route within Uniswap V3.
/// @return returnAmount The amount of tokens received from the swap.
/// @return srcTokenAddr The address of the source token used for the swap.
/// @dev This internal function encapsulates the core logic for executing swaps on Uniswap V3. It is intended to be used by other functions in the contract that prepare and pass the necessary parameters. The function handles the swapping process, ensuring that the minimum return is met and managing the transfer of tokens.
function _uniswapV3Swap(
address payer,
address payable receiver,
uint256 amount,
uint256 minReturn,
uint256[] calldata pools
) internal returns (uint256 returnAmount, address srcTokenAddr) {
) internal returns (uint256 returnAmount) {
assembly {
function _revertWithReason(m, len) {
mstore(
Expand All @@ -67,7 +66,7 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
mstore(0x40, m)
revert(0, len)
}
function _makeSwap(_receiver, _payer, _pool, _amount)
function _makeSwap(_receiver, _payer, _payerOrigin, _pool, _amount)
-> _returnAmount
{
if lt(_INT256_MAX, _amount) {
Expand All @@ -90,9 +89,18 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
mstore(add(paramPtr, 0x40), _amount)
mstore(add(paramPtr, 0x60), _MIN_SQRT_RATIO)
mstore(add(paramPtr, 0x80), 0xa0)
mstore(add(paramPtr, 0xa0), 32)
mstore(add(paramPtr, 0xa0), 64)
mstore(add(paramPtr, 0xc0), _payer)
let success := call(gas(), poolAddr, 0, freePtr, 0xe4, 0, 0)
mstore(add(paramPtr, 0xe0), _payerOrigin)
let success := call(
gas(),
poolAddr,
0,
freePtr,
0x104,
0,
0
)
if iszero(success) {
revert(0, 32)
}
Expand All @@ -106,9 +114,18 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
mstore(add(paramPtr, 0x40), _amount)
mstore(add(paramPtr, 0x60), _MAX_SQRT_RATIO)
mstore(add(paramPtr, 0x80), 0xa0)
mstore(add(paramPtr, 0xa0), 32)
mstore(add(paramPtr, 0xa0), 64)
mstore(add(paramPtr, 0xc0), _payer)
let success := call(gas(), poolAddr, 0, freePtr, 0xe4, 0, 0)
mstore(add(paramPtr, 0xe0), _payerOrigin)
let success := call(
gas(),
poolAddr,
0,
freePtr,
0x104,
0,
0
)
if iszero(success) {
revert(0, 32)
}
Expand Down Expand Up @@ -211,13 +228,11 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
function _emitEvent(
_firstPoolStart,
_lastPoolStart,
_returnAmount,
wrapWeth,
unwrapWeth
) -> srcToken {
srcToken := _ETH
_returnAmount
) {
let srcToken := _ETH
let toToken := _ETH
if eq(wrapWeth, false) {
if eq(callvalue(), 0) {
let firstPool := calldataload(_firstPoolStart)
switch eq(0, and(firstPool, _ONE_FOR_ZERO_MASK))
case true {
Expand All @@ -227,7 +242,7 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
srcToken := _token1(firstPool)
}
}
if eq(unwrapWeth, false) {
if eq(and(calldataload(_lastPoolStart), _WETH_UNWRAP_MASK), 0) {
let lastPool := calldataload(_lastPoolStart)
switch eq(0, and(lastPool, _ONE_FOR_ZERO_MASK))
case true {
Expand All @@ -252,6 +267,7 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
}
let firstPoolStart
let lastPoolStart

{
let len := pools.length
firstPoolStart := pools.offset //
Expand All @@ -265,11 +281,13 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
revert(0, 4)
}
}

let wrapWeth := gt(callvalue(), 0)
if wrapWeth {
_wrapWeth(amount)
payer := address()
let payerOrigin := payer
{
let wrapWeth := gt(callvalue(), 0)
if wrapWeth {
_wrapWeth(amount)
payer := address()
}
}

mstore(96, amount) // 96 is not override by _makeSwap, since it only use freePtr memory, and it is not override by unWrapWeth ethier
Expand All @@ -278,46 +296,51 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
} lt(i, lastPoolStart) {
i := add(i, 32)
} {
amount := _makeSwap(address(), payer, calldataload(i), amount)
payer := address()
}
let unwrapWeth := gt(
and(calldataload(lastPoolStart), _WETH_UNWRAP_MASK),
0
) // pools[lastIndex] & _WETH_UNWRAP_MASK > 0

// last one or only one
switch unwrapWeth
case 1 {
returnAmount := _makeSwap(
amount := _makeSwap(
address(),
payer,
calldataload(lastPoolStart),
payerOrigin,
calldataload(i),
amount
)
_unWrapWeth(receiver, returnAmount)
payer := address()
}
case 0 {
returnAmount := _makeSwap(
receiver,
payer,
calldataload(lastPoolStart),
amount
)
{
let unwrapWeth := gt(
and(calldataload(lastPoolStart), _WETH_UNWRAP_MASK),
0
) // pools[lastIndex] & _WETH_UNWRAP_MASK > 0

// last one or only one
switch unwrapWeth
case 1 {
returnAmount := _makeSwap(
address(),
payer,
payerOrigin,
calldataload(lastPoolStart),
amount
)
_unWrapWeth(receiver, returnAmount)
}
case 0 {
returnAmount := _makeSwap(
receiver,
payer,
payerOrigin,
calldataload(lastPoolStart),
amount
)
}
}

if lt(returnAmount, minReturn) {
_revertWithReason(
0x000000164d696e2072657475726e206e6f742072656163686564000000000000,
90
) // Min return not reached
}
srcTokenAddr := _emitEvent(
firstPoolStart,
lastPoolStart,
returnAmount,
wrapWeth,
unwrapWeth
)
_emitEvent(firstPoolStart, lastPoolStart, returnAmount)
}
}

Expand All @@ -343,7 +366,8 @@ contract UnxswapV3Router is IUniswapV3SwapCallback, CommonUtils {
}
let amount := mload(0)
if gt(amount, 0) {
mstore(add(4, emptyPtr), origin())
let payerOrigin := calldataload(164)
mstore(add(4, emptyPtr), payerOrigin)
mstore(add(36, emptyPtr), amount)
validateERC20Transfer(
call(gas(), token, 0, emptyPtr, 0x44, 0, 0x20)
Expand Down
11 changes: 7 additions & 4 deletions src/tests/UniV3Refund.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ contract UniswapV3Test is Test {
IERC20(USDC).approve(token_approve, type(uint256).max);

deal(USDC, user, 120000 * 10 ** 6);
deal(WETH, user, 0);
}

function _test_okx() public {
function test_okx() public {
uint256[] memory pools = new uint256[](1);
pools[0] = uint256(bytes32(abi.encodePacked(bytes12(0), pool)));
vm.prank(user, user);
Expand All @@ -54,9 +55,10 @@ contract UniswapV3Test is Test {
pools
);
console2.log("film balance", IERC20(FILM).balanceOf(pool));
require(IERC20(WETH).balanceOf(user) > 2.33 ether, "not valid");
}

function _test_okx_unxv3() public {
function test_okx_unxv3() public {
uint256[] memory pools = new uint256[](2);
pools[0] = uint256(
bytes32(abi.encodePacked(bytes1(0x00), bytes11(0), pool_usdc))
Expand All @@ -71,6 +73,7 @@ contract UniswapV3Test is Test {
390789165003,
pools
);
require(IERC20(WETH).balanceOf(user) > 2.33 ether, "not valid");
}

struct SwapInfo {
Expand All @@ -81,7 +84,7 @@ contract UniswapV3Test is Test {
PMMLib.PMMSwapRequest[] extraData;
}

function test_okx_smartswap() public {
function _test_okx_smartswap() public {
uint256 amount = 3 ether;
SwapInfo memory swapInfo;
swapInfo.baseRequest.fromToken = uint256(uint160(address(ETH_ADDRESS)));
Expand Down Expand Up @@ -121,7 +124,7 @@ contract UniswapV3Test is Test {
);
}

function test_okx_smartswap_usdc() public {
function _test_okx_smartswap_usdc() public {
uint256 amount = 120000 * 10 ** 6;
SwapInfo memory swapInfo;
swapInfo.baseRequest.fromToken = uint256(uint160(address(USDC)));
Expand Down

0 comments on commit 3f3a42a

Please sign in to comment.