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

cleanup Integration tests #97

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
187008
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
180029
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
141165
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
239700
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
151880
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
250739
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
295192
82 changes: 65 additions & 17 deletions test/foundry-tests/integration/RelayOrderReactorIntegration.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS
/// Same input and fee token.
/// Filler balance is nonzero of input token.
/// P2 nonce is dirty.
/// Specifies fee recipient. TODO: use msg.sender when supported
/// No fee recipient specified.
function test_execute_bestCase() public {
ERC20 tokenIn = DAI;
ERC20 tokenOut = USDC;
Expand Down Expand Up @@ -137,11 +137,11 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS
SignedOrder(abi.encode(order), signOrder(swapperPrivateKey, address(PERMIT2), order));

_checkpointBalances(swapper, filler, tokenIn, tokenOut, gasToken);
_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "testExecuteSameToken");
_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "test_execute_bestCase");

vm.prank(filler);
snapStart("RelayOrderReactorIntegrationTest-testExecuteSameToken");
reactor.execute(signedOrder, filler);
snapStart("RelayOrderReactorIntegrationTest-test_execute_bestCase");
reactor.execute(signedOrder);
snapEnd();

assertEq(tokenIn.balanceOf(UNIVERSAL_ROUTER), routerInputBalanceStart, "No leftover input in router");
Expand Down Expand Up @@ -195,10 +195,10 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS
SignedOrder(abi.encode(order), signOrder(swapperPrivateKey, address(PERMIT2), order));

_checkpointBalances(swapper, filler, tokenIn, tokenOut, gasToken);
_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "testExecuteAverageCase");
_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "test_execute_AverageCase");

vm.prank(filler);
snapStart("RelayOrderReactorIntegrationTest-testExecuteAverageCase");
snapStart("RelayOrderReactorIntegrationTest-test_execute_AverageCase");
reactor.execute(signedOrder, filler);
snapEnd();

Expand Down Expand Up @@ -243,11 +243,11 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS
SignedOrder memory signedOrder =
SignedOrder(abi.encode(order), signOrder(swapperPrivateKey, address(PERMIT2), order));

_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "testExecuteWorstCase");
_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "test_execute_worstCase");
_checkpointBalances(swapper, filler, tokenIn, tokenOut, gasToken);

vm.prank(filler);
snapStart("RelayOrderReactorIntegrationTest-testExecuteWorstCase");
snapStart("RelayOrderReactorIntegrationTest-test_execute_worstCase");
reactor.execute(signedOrder, filler);
snapEnd();

Expand Down Expand Up @@ -306,12 +306,12 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS

// TODO: This snapshot should always pull tokens in from permit2 and then expose an option to benchmark it with an an allowance on the UR vs. without.
// For this test, we should benchmark that the user has not permitted permit2, and also has not approved the UR.
_snapshotClassicSwapCall(USDC, 100 * USDC_ONE, methodParameters, "testPermitAndExecute");
_snapshotClassicSwapCall(USDC, 100 * USDC_ONE, methodParameters, "test_multicall_permitAndExecute");

_checkpointBalances(swapper2, filler, USDC, DAI, USDC);

vm.prank(filler);
snapStart("RelayOrderReactorIntegrationTest-testPermitAndExecute");
snapStart("RelayOrderReactorIntegrationTest-test_multicall_permitAndExecute");
reactor.multicall(data);
snapEnd();

Expand Down Expand Up @@ -361,10 +361,10 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS
routerOutputBalanceStart = UNIVERSAL_ROUTER.balance;
fillerGasInputBalanceStart = USDC.balanceOf(filler);

_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "testExecuteWithNativeAsOutput");
_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "test_executeWithNativeOutput");

vm.prank(filler);
snapStart("RelayOrderReactorIntegrationTest-testExecuteWithNativeAsOutput");
snapStart("RelayOrderReactorIntegrationTest-test_executeWithNativeOutput");
reactor.execute(signedOrder, filler);
snapEnd();

Expand Down Expand Up @@ -437,10 +437,10 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS
SignedOrder(abi.encode(order), signOrder(swapperPrivateKey, address(PERMIT2), order));

_checkpointBalances(swapper, filler, tokenIn, tokenOut, gasToken);
_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "testExecuteDifferentRecipient");
_snapshotClassicSwapCall(tokenIn, 100 * ONE, methodParameters, "test_execute_differentFeeRecipient");

vm.prank(filler);
snapStart("RelayOrderReactorIntegrationTest-testExecuteDifferentRecipient");
snapStart("RelayOrderReactorIntegrationTest-test_execute_differentFeeRecipient");
reactor.execute(signedOrder, feeRecipient);
snapEnd();

Expand All @@ -456,7 +456,55 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS
assertEq(tokenOut.balanceOf((feeRecipient)), 10 * USDC_ONE, "fee recipient balance");
}

function test_execute_noActions_noInputs_noFee_succeeds() public {
/// @notice test an exact output V3 swap with a sweep of the tokenIn
function test_execute_exactOutputWithSweep() public {
ERC20 tokenIn = DAI;
ERC20 tokenOut = USDC;
// gas token diff than tokenIn to test the sweep
ERC20 gasToken = USDC;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a note but its definitely odd UX to have exact output swap where gasToken is in the same output token cause the end balance won't be the specified "exact"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but nice test 👍


uint256 amountOut = 100 * USDC_ONE;
uint256 amountInMax = 105 * ONE;

// for exact out we send the amountInMax
Input memory input = InputBuilder.init(tokenIn).withAmount(105 * ONE).withRecipient(UNIVERSAL_ROUTER);
// 10 usdc fee
FeeEscalator memory fee =
FeeEscalatorBuilder.init(gasToken).withStartAmount(10 * USDC_ONE).withEndAmount(10 * USDC_ONE);

MethodParameters memory methodParameters = readFixture(json, "._UNISWAP_V3_DAI_USDC_EXACT_OUT_WITH_SWEEP");

OrderInfo memory orderInfo = OrderInfoBuilder.init(address(reactor)).withSwapper(swapper).withDeadline(
block.timestamp + 100
).withNonce(1);

RelayOrder memory order =
RelayOrderBuilder.init(orderInfo, input, fee).withUniversalRouterCalldata(methodParameters.data);

SignedOrder memory signedOrder =
SignedOrder(abi.encode(order), signOrder(swapperPrivateKey, address(PERMIT2), order));

_checkpointBalances(swapper, filler, tokenIn, tokenOut, gasToken);
_snapshotClassicSwapCall(tokenIn, 105 * ONE, methodParameters, "test_execute_exactOutput");

snapStart("RelayOrderReactorIntegrationTest-test_execute_exactOutput");
reactor.execute(signedOrder);
snapEnd();

assertEq(tokenIn.balanceOf(UNIVERSAL_ROUTER), routerInputBalanceStart, "No leftover input in router");
assertEq(tokenOut.balanceOf(UNIVERSAL_ROUTER), routerOutputBalanceStart, "No leftover output in reactor");
assertEq(tokenIn.balanceOf(address(reactor)), 0, "No leftover input in reactor");
assertEq(tokenOut.balanceOf(address(reactor)), 0, "No leftover output in reactor");
assertGe(tokenIn.balanceOf(swapper), swapperInputBalanceStart - amountInMax, "Swapper input tokens");
assertGe(
tokenOut.balanceOf(swapper),
swapperOutputBalanceStart + amountOut - 10 * USDC_ONE,
"Swapper did not receive enough output"
);
assertEq(gasToken.balanceOf(address(this)), 10 * USDC_ONE, "fee recipient balance");
}

function test_execute_noUniversalRouterCalldata_noInputs_noFee_succeeds() public {
FeeEscalator memory fee;
Input memory input;
RelayOrder memory order = RelayOrderBuilder.initDefault(USDC, address(reactor), swapper);
Expand All @@ -470,7 +518,7 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS
assertEq(order.universalRouterCalldata.length, 0);
}

function test_execute_noActions_noInputs_withFee_succeeds() public {
function test_execute_noUniversalRouterCalldata_noInputs_withFee_succeeds() public {
// Essentially a relayed transfer.
Input memory input;
RelayOrder memory order = RelayOrderBuilder.initDefault(USDC, address(reactor), swapper);
Expand All @@ -488,7 +536,7 @@ contract RelayOrderReactorIntegrationTest is GasSnapshot, Test, Interop, PermitS
assertEq(USDC.balanceOf(address(filler)), USDC_ONE);
}

function test_execute_noActions_withInputs_withFee_succeeds() public {
function test_execute_noUniversalRouterCalldata_withInputs_withFee_succeeds() public {
// Even if no universalRouterCalldata are encoded, a transfer of tokens from an Input and a Fee can still happen.
RelayOrder memory order = RelayOrderBuilder.initDefault(USDC, address(reactor), swapper);
order.input = order.input.withRecipient(address(this)).withAmount(USDC_ONE);
Expand Down
8 changes: 8 additions & 0 deletions test/foundry-tests/interop.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,13 @@
"_UNISWAP_V3_DAI_USDC_RECIPIENT_REACTOR_WITH_SWEEP": {
"calldata": "0x24856bc300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000100000000000000000000000000378718523232a14be8a24e291b5a5075be04d1210000000000000000000000000000000000000000000000056bc75e2d631000000000000000000000000000000000000000000000000000000000000005a995c000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b6b175474e89094c44da98b954eedeac495271d0f000bb8a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000342079f0e9da82bb28a27a6edc814a33660203830000000000000000000000000000000000000000000000000000000005a995c0",
"value": "0"
},
"_UNISWAP_V2_DAI_USDC": {
"calldata": "0x24856bc30000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000342079f0e9da82bb28a27a6edc814a33660203830000000000000000000000000000000000000000000000056bc75e2d631000000000000000000000000000000000000000000000000000000000000005a8308800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"value": "0"
},
"_UNISWAP_V3_DAI_USDC_EXACT_OUT_WITH_SWEEP": {
"calldata": "0x24856bc300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000201040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000100000000000000000000000000342079f0e9da82bb28a27a6edc814a33660203830000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000005b12aefafa804000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb86b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000342079f0e9da82bb28a27a6edc814a33660203830000000000000000000000000000000000000000000000000000000000000000",
"value": "0"
}
}
22 changes: 10 additions & 12 deletions test/foundry-tests/lib/FeeEscalatorLib.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ contract FeeEscalatorLibTest is Test {
using FeeEscalatorLib for FeeEscalator;
using FeeEscalatorBuilder for FeeEscalator;

function testRelayFeeEscalationNoEscalation(uint256 amount, uint256 startTime, uint256 endTime) public {
function test_resolve_noEscalation(uint256 amount, uint256 startTime, uint256 endTime) public {
vm.assume(endTime >= startTime);
assertEq(FeeEscalatorLib.resolve(amount, amount, startTime, endTime), amount);
}

function testRelayFeeEscalationNoEscalationYet() public {
function test_resolve_noEscalationYet() public {
vm.warp(100);
// at startTime
assertEq(FeeEscalatorLib.resolve(1 ether, 2 ether, 100, 200), 1 ether);
Expand All @@ -28,7 +28,7 @@ contract FeeEscalatorLibTest is Test {
assertEq(FeeEscalatorLib.resolve(1 ether, 2 ether, 100, 200), 1 ether);
}

function testRelayFeeEscalation() public {
function test_resolve() public {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_resolve_midwayEscalation?

vm.warp(150);
assertEq(FeeEscalatorLib.resolve(1 ether, 2 ether, 100, 200), 1.5 ether);

Expand All @@ -42,20 +42,20 @@ contract FeeEscalatorLibTest is Test {
assertEq(FeeEscalatorLib.resolve(1 ether, 2 ether, 100, 200), 1.9 ether);
}

function testRelayFeeEscalationFullyEscalated() public {
function test_resolve_fullyEscalated() public {
vm.warp(200);
assertEq(FeeEscalatorLib.resolve(1 ether, 2 ether, 100, 200), 2 ether);

vm.warp(250);
assertEq(FeeEscalatorLib.resolve(1 ether, 2 ether, 100, 200), 2 ether);
}

function testRelayFeeEscalationRevertsWithWrongEndStartTimes() public {
function test_resolve_reverts_withWrongEndStartTimes() public {
vm.expectRevert(ReactorErrors.EndTimeBeforeStartTime.selector);
FeeEscalatorLib.resolve(1 ether, 2 ether, 200, 100);
}

function testRelayFeeEscalationEqualAmounts(uint256 amount, uint256 startTime, uint256 endTime) public {
function test_resolve_equalAmounts(uint256 amount, uint256 startTime, uint256 endTime) public {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_fuzz_resolve_equalAmounts_doesNotEscalate

vm.assume(endTime >= startTime);
uint256 time = startTime;
bound(time, startTime, startTime);
Expand All @@ -64,22 +64,20 @@ contract FeeEscalatorLibTest is Test {
assertEq(FeeEscalatorLib.resolve(amount, amount, startTime, endTime), amount);
}

function testRelayFeeEscalationInvalidAmounts() public {
function test_resolve_reverts_withInvalidAmounts() public {
vm.expectRevert(ReactorErrors.InvalidAmounts.selector);
FeeEscalatorLib.resolve(2 ether, 1 ether, 100, 200);
}

function testRelayFeeEscalationBounded(uint256 startAmount, uint256 endAmount, uint256 startTime, uint256 endTime)
public
{
function test_resolve_bounded(uint256 startAmount, uint256 endAmount, uint256 startTime, uint256 endTime) public {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_fuzz_resolve_bounded

vm.assume(endAmount > startAmount);
vm.assume(endTime >= startTime);
uint256 resolved = FeeEscalatorLib.resolve(startAmount, endAmount, startTime, endTime);
assertGe(resolved, startAmount);
assertLe(resolved, endAmount);
}

function testToTokenPermissions() public {
function test_toTokenPermissions() public {
address token = makeAddr("token");
FeeEscalator memory fee =
FeeEscalator({token: token, startAmount: 1 ether, endAmount: 2 ether, startTime: 100, endTime: 200});
Expand All @@ -89,7 +87,7 @@ contract FeeEscalatorLibTest is Test {
assertEq(permission.amount, 2 ether);
}

function testToTransferDetails() public {
function test_toTransferDetails() public {
address filler = makeAddr("filler");
FeeEscalator memory fee =
FeeEscalator({token: address(this), startAmount: 1 ether, endAmount: 1 ether, startTime: 0, endTime: 0});
Expand Down
Loading
Loading