diff --git a/test/PartialOrderReactor.t.sol b/test/PartialOrderReactor.t.sol index c9fb277..606abfe 100644 --- a/test/PartialOrderReactor.t.sol +++ b/test/PartialOrderReactor.t.sol @@ -12,6 +12,7 @@ contract PartialOrderReactorTest is BaseTest { uint256 public swapperPK; ERC20Mock public inToken; ERC20Mock public outToken; + uint256 public inTokenTotalSupply = 10 ether; RePermit public repermit; @@ -27,51 +28,117 @@ contract PartialOrderReactorTest is BaseTest { vm.label(address(inToken), "inToken"); vm.label(address(outToken), "outToken"); - inToken.mint(swapper, 10 ether); + inToken.mint(swapper, inTokenTotalSupply); hoax(swapper); inToken.approve(address(repermit), type(uint256).max); } function test_Execute_SwapTheFullAmount() public { uint256 inAmount = 1 ether; + uint256 inAmountRequest = inAmount; uint256 outAmount = 0.5 ether; uint256 outAmountGas = 0.1 ether; - SignedOrder[] memory orders = new SignedOrder[](1); - orders[0] = createAndSignPartialOrder( - address(repermit), - swapper, - swapperPK, - address(inToken), - address(outToken), - inAmount, - outAmount, - outAmountGas - ); - //simulate swap + SignedOrder[] memory orders = createOrderPartialOrder(inAmount, inAmountRequest, outAmount, outAmountGas); + + simulateSwap(inAmountRequest, outAmount, outAmountGas, orders); + + assertEq(outToken.balanceOf(swapper), 0.5 ether, "swapper end outAmount"); + assertEq(outToken.balanceOf(address(config.treasury)), 0.1 ether, "gas fee"); + assertEq(inToken.balanceOf(address(config.executor)), 0, "no inToken leftovers"); + assertEq(outToken.balanceOf(address(config.executor)), 0, "no outToken leftovers"); + assertEq(inToken.balanceOf(address(swapper)), inTokenTotalSupply - inAmountRequest, "user has the correct inToken balance"); + } + + function test_Execute_SwapTwice() public { + uint256 inAmount = 1 ether; + uint256 inAmountRequest = 0.5 ether; // 50% + uint256 outAmount = 0.5 ether; + uint256 outAmountGas = 0.1 ether; + + SignedOrder[] memory orders = createOrderPartialOrder(inAmount, inAmountRequest, outAmount, outAmountGas); + simulateSwap(inAmountRequest, outAmount, outAmountGas, orders); + + assertEq(outToken.balanceOf(swapper), 0.25 ether, "swapper end outAmount"); + assertEq(outToken.balanceOf(address(config.treasury)), 0.05 ether, "gas fee"); + assertEq(inToken.balanceOf(address(config.executor)), 0, "no inToken leftovers"); + assertEq(outToken.balanceOf(address(config.executor)), 0, "no outToken leftovers"); + assertEq(inToken.balanceOf(address(swapper)), inTokenTotalSupply - inAmountRequest, "user has the correct inToken balance"); + + simulateSwap(inAmountRequest, outAmount, outAmountGas, orders); + + assertEq(outToken.balanceOf(swapper), 0.5 ether, "swapper end outAmount"); + assertEq(outToken.balanceOf(address(config.treasury)), 0.1 ether, "gas fee"); + assertEq(inToken.balanceOf(address(config.executor)), 0, "no inToken leftovers"); + assertEq(outToken.balanceOf(address(config.executor)), 0, "no outToken leftovers"); + assertEq(inToken.balanceOf(address(swapper)), inTokenTotalSupply - inAmountRequest * 2, "no inToken leftovers"); + } + + function test_Execute_SwapPartialAmount() public { + uint256 inAmount = 1 ether; + uint256 inAmountRequest = 0.4 ether; + uint256 outAmount = 0.5 ether; + uint256 outAmountGas = 0.07 ether; + + SignedOrder[] memory orders = createOrderPartialOrder(inAmount, inAmountRequest, outAmount, outAmountGas); + simulateSwap(inAmountRequest, outAmount, outAmountGas, orders); + + assertEq(outToken.balanceOf(swapper), 0.2 ether, "swapper end outAmount"); + assertEq(outToken.balanceOf(address(config.treasury)), 0.028 ether, "gas fee"); + assertEq(inToken.balanceOf(address(config.executor)), 0, "no inToken leftovers"); + assertEq(outToken.balanceOf(address(config.executor)), 0, "no outToken leftovers"); + assertEq(inToken.balanceOf(address(swapper)), inTokenTotalSupply - inAmountRequest, "no inToken leftovers"); + } + + + function test_Revert_inAmountRequestGreaterThenInAmount() public { + uint256 inAmount = 1 ether; + uint256 inAmountRequest = 1.01 ether; // 101% + uint256 outAmount = 0.5 ether; + uint256 outAmountGas = 0.07 ether; + + SignedOrder[] memory orders = createOrderPartialOrder(inAmount, inAmountRequest, outAmount, outAmountGas); Call[] memory calls = new Call[](2); calls[0] = - Call(address(inToken), abi.encodeWithSelector(inToken.burn.selector, address(config.executor), inAmount)); + Call(address(inToken), abi.encodeWithSelector(inToken.burn.selector, address(config.executor), inAmountRequest)); calls[1] = Call( address(outToken), abi.encodeWithSelector(outToken.mint.selector, address(config.executor), outAmount + outAmountGas + 1) ); hoax(config.treasury.owner()); + vm.expectRevert(abi.encodeWithSelector(RePermit.InsufficientAllowance.selector, address(0))); config.executor.execute(orders, calls); - assertEq(outToken.balanceOf(swapper), outAmount, "swapper end outAmount"); - assertEq(outToken.balanceOf(address(config.treasury)), outAmountGas, "gas fee"); - assertEq(inToken.balanceOf(address(config.executor)), 0, "no inToken leftovers"); - assertEq(outToken.balanceOf(address(config.executor)), 0, "no outToken leftovers"); } - function test_Execute_SwapTwice() public { + + function test_Revert_InsufficentAlowanceAfterSpending() public { uint256 inAmount = 1 ether; + uint256 inAmountRequest = 0.75 ether; uint256 outAmount = 0.5 ether; - uint256 outAmountGas = 0.1 ether; + uint256 outAmountGas = 0.07 ether; + + SignedOrder[] memory orders = createOrderPartialOrder(inAmount, inAmountRequest, outAmount, outAmountGas); + simulateSwap(inAmountRequest, outAmount, outAmountGas, orders); + + Call[] memory calls = new Call[](2); + calls[0] = + Call(address(inToken), abi.encodeWithSelector(inToken.burn.selector, address(config.executor), inAmountRequest)); + calls[1] = Call( + address(outToken), + abi.encodeWithSelector(outToken.mint.selector, address(config.executor), outAmount + outAmountGas + 1) + ); + + assertEq(inToken.balanceOf(address(swapper)), inTokenTotalSupply - inAmountRequest, "no inToken leftovers"); + + hoax(config.treasury.owner()); + vm.expectRevert(abi.encodeWithSelector(RePermit.InsufficientAllowance.selector, address(0.75 ether))); + config.executor.execute(orders, calls); + } - SignedOrder[] memory orders = new SignedOrder[](1); + function createOrderPartialOrder(uint256 inAmount, uint256 inAmountRequest, uint256 outAmount, uint256 outAmountGas) internal view returns (SignedOrder[] memory orders) { + orders = new SignedOrder[](1); orders[0] = createAndSignPartialOrder( address(repermit), swapper, @@ -79,13 +146,18 @@ contract PartialOrderReactorTest is BaseTest { address(inToken), address(outToken), inAmount, + inAmountRequest, outAmount, outAmountGas ); - //simulate swap + } + + + function simulateSwap(uint256 inAmountRequest, uint256 outAmount, uint256 outAmountGas, SignedOrder[] memory orders) internal { + Call[] memory calls = new Call[](2); calls[0] = - Call(address(inToken), abi.encodeWithSelector(inToken.burn.selector, address(config.executor), inAmount)); + Call(address(inToken), abi.encodeWithSelector(inToken.burn.selector, address(config.executor), inAmountRequest)); calls[1] = Call( address(outToken), abi.encodeWithSelector(outToken.mint.selector, address(config.executor), outAmount + outAmountGas + 1) @@ -93,10 +165,5 @@ contract PartialOrderReactorTest is BaseTest { hoax(config.treasury.owner()); config.executor.execute(orders, calls); - - assertEq(outToken.balanceOf(swapper), outAmount, "swapper end outAmount"); - assertEq(outToken.balanceOf(address(config.treasury)), outAmountGas, "gas fee"); - assertEq(inToken.balanceOf(address(config.executor)), 0, "no inToken leftovers"); - assertEq(outToken.balanceOf(address(config.executor)), 0, "no outToken leftovers"); } } diff --git a/test/base/BaseTest.sol b/test/base/BaseTest.sol index 52745a3..c993118 100644 --- a/test/base/BaseTest.sol +++ b/test/base/BaseTest.sol @@ -75,7 +75,8 @@ abstract contract BaseTest is Base, PermitSignature { uint256 privateKey, address inToken, address outToken, - uint256 inAmount, + uint256 orderAmount, + uint256 partialOrderAmount, uint256 outAmount, uint256 outAmountGas ) internal view returns (SignedOrder memory result) { @@ -89,7 +90,7 @@ abstract contract BaseTest is Base, PermitSignature { order.exclusiveFiller = address(config.executor); order.input.token = inToken; - order.input.amount = inAmount; + order.input.amount = orderAmount; order.outputs = new PartialOrderLib.PartialOutput[](2); order.outputs[0] = PartialOrderLib.PartialOutput(outToken, outAmount, swapper); @@ -97,6 +98,6 @@ abstract contract BaseTest is Base, PermitSignature { } result.sig = signRePermit(repermit, privateKey, order); - result.order = abi.encode(order, inAmount); + result.order = abi.encode(order, partialOrderAmount); } }