Skip to content

Commit

Permalink
add swapExactOuputSingle
Browse files Browse the repository at this point in the history
  • Loading branch information
ewilz committed Sep 5, 2023
1 parent cf82527 commit 9ebc9d5
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/RouterBytecode.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4676
4838
2 changes: 1 addition & 1 deletion .forge-snapshots/RouterExactIn1Hop.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
193938
193914
2 changes: 1 addition & 1 deletion .forge-snapshots/RouterExactIn2Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
271014
270990
2 changes: 1 addition & 1 deletion .forge-snapshots/RouterExactIn3Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
348095
348071
1 change: 0 additions & 1 deletion .forge-snapshots/RouterExactInSingle.snap

This file was deleted.

1 change: 1 addition & 0 deletions .forge-snapshots/RouterExactInputSingle.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
192342
2 changes: 1 addition & 1 deletion .forge-snapshots/RouterExactOut1Hop.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
193086
193062
2 changes: 1 addition & 1 deletion .forge-snapshots/RouterExactOut2Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
271039
271015
2 changes: 1 addition & 1 deletion .forge-snapshots/RouterExactOut3Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
349020
348996
1 change: 1 addition & 0 deletions .forge-snapshots/RouterExactOutputSingle.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
191562
26 changes: 25 additions & 1 deletion contracts/Routing.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ abstract contract Routing {
uint128 amountOutMinimum;
}

struct ExactOutputSingleParams {
PoolKey poolKey;
bool zeroForOne;
address recipient;
uint128 amountOut;
uint128 amountInMaximum;
uint160 sqrtPriceLimitX96;
}

struct ExactOutputParams {
Currency currencyOut;
PathKey[] path;
Expand Down Expand Up @@ -90,6 +99,8 @@ abstract contract Routing {
_swapExactInputSingle(abi.decode(swapInfo.params, (ExactInputSingleParams)), swapInfo.msgSender);
} else if (swapInfo.swapType == SwapType.ExactOutput) {
_swapExactOutput(abi.decode(swapInfo.params, (ExactOutputParams)), swapInfo.msgSender);
} else if (swapInfo.swapType == SwapType.ExactOutputSingle) {
_swapExactOutputSingle(abi.decode(swapInfo.params, (ExactOutputSingleParams)), swapInfo.msgSender);
} else {
revert InvalidSwapType();
}
Expand Down Expand Up @@ -133,10 +144,23 @@ abstract contract Routing {
}
}

function _swapExactOutputSingle(ExactOutputSingleParams memory params, address msgSender) private {
_swapExactPrivate(
params.poolKey,
params.zeroForOne,
-int256(int128(params.amountOut)),
params.sqrtPriceLimitX96,
msgSender,
true,
true
);
}

function _swapExactOutput(ExactOutputParams memory params, address msgSender) private {
unchecked {
for (uint256 i = params.path.length; i > 0; i--) {
(PoolKey memory poolKey, bool oneForZero) = _getPoolAndSwapDirection(params.path[i - 1], params.currencyOut);
(PoolKey memory poolKey, bool oneForZero) =
_getPoolAndSwapDirection(params.path[i - 1], params.currencyOut);
uint128 amountIn = uint128(
_swapExactPrivate(
poolKey,
Expand Down
46 changes: 43 additions & 3 deletions test/Routing.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ contract RoutingTest is Test, Deployers, GasSnapshot {
snapSize("RouterBytecode", address(router));
}

function testRouter_swapExactInSingle_zeroForOne() public {
function testRouter_swapExactInputSingle_zeroForOne() public {
uint256 amountIn = 1 ether;
uint256 expectedAmountOut = 992054607780215625;

Expand All @@ -71,7 +71,7 @@ contract RoutingTest is Test, Deployers, GasSnapshot {
uint256 prevBalance0 = token0.balanceOf(address(this));
uint256 prevBalance1 = token1.balanceOf(address(this));

snapStart("RouterExactInSingle");
snapStart("RouterExactInputSingle");
router.swap(Routing.SwapType.ExactInputSingle, abi.encode(params));
snapEnd();

Expand All @@ -82,7 +82,7 @@ contract RoutingTest is Test, Deployers, GasSnapshot {
assertEq(newBalance1 - prevBalance1, expectedAmountOut);
}

function testRouter_swapExactInSingle_oneForZero() public {
function testRouter_swapExactInputSingle_oneForZero() public {
uint256 amountIn = 1 ether;
uint256 expectedAmountOut = 992054607780215625;

Expand Down Expand Up @@ -199,6 +199,46 @@ contract RoutingTest is Test, Deployers, GasSnapshot {
assertEq(token3.balanceOf(address(router)), 0);
}

function testRouter_swapExactOutputSingle_zeroForOne() public {
uint256 amountOut = 1 ether;
uint256 expectedAmountIn = 1008049273448486163;

Routing.ExactOutputSingleParams memory params =
Routing.ExactOutputSingleParams(key0, true, address(this), uint128(amountOut), 0, 0);

uint256 prevBalance0 = token0.balanceOf(address(this));
uint256 prevBalance1 = token1.balanceOf(address(this));

snapStart("RouterExactOutputSingle");
router.swap(Routing.SwapType.ExactOutputSingle, abi.encode(params));
snapEnd();

uint256 newBalance0 = token0.balanceOf(address(this));
uint256 newBalance1 = token1.balanceOf(address(this));

assertEq(prevBalance0 - newBalance0, expectedAmountIn);
assertEq(newBalance1 - prevBalance1, amountOut);
}

function testRouter_swapExactOutputSingle_oneForZero() public {
uint256 amountOut = 1 ether;
uint256 expectedAmountIn = 1008049273448486163;

Routing.ExactOutputSingleParams memory params =
Routing.ExactOutputSingleParams(key0, false, address(this), uint128(amountOut), 0, 0);

uint256 prevBalance0 = token0.balanceOf(address(this));
uint256 prevBalance1 = token1.balanceOf(address(this));

router.swap(Routing.SwapType.ExactOutputSingle, abi.encode(params));

uint256 newBalance0 = token0.balanceOf(address(this));
uint256 newBalance1 = token1.balanceOf(address(this));

assertEq(prevBalance1 - newBalance1, expectedAmountIn);
assertEq(newBalance0 - prevBalance0, amountOut);
}

function testRouter_swapExactOut_1Hop_zeroForOne() public {
uint256 amountOut = 1 ether;
uint256 expectedAmountIn = 1008049273448486163;
Expand Down

0 comments on commit 9ebc9d5

Please sign in to comment.