Skip to content

Commit 5296a1b

Browse files
committed
add ether order and filling and withdrawal
1 parent a69da46 commit 5296a1b

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

test/EtherTest.t.sol

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import { SetupHook } from "./SetupHook.t.sol";
5+
import { AsyncOrder } from "@async-swap/types/AsyncOrder.sol";
6+
import { MockERC20 } from "solmate/src/test/utils/mocks/MockERC20.sol";
7+
import { Currency } from "v4-core/interfaces/IPoolManager.sol";
8+
import { LPFeeLibrary } from "v4-core/libraries/LPFeeLibrary.sol";
9+
import { StateLibrary } from "v4-core/libraries/StateLibrary.sol";
10+
import { CurrencyLibrary } from "v4-core/types/Currency.sol";
11+
import { PoolKey } from "v4-core/types/PoolKey.sol";
12+
13+
/// @title Ether Test contract
14+
contract EtherTest is SetupHook {
15+
16+
using CurrencyLibrary for Currency;
17+
18+
address alice = makeAddr("alice");
19+
address bob = makeAddr("bob");
20+
21+
function setUp() public override {
22+
super.setUp();
23+
// Override the default setup to use Ether
24+
deployEtherPool();
25+
topUp(alice, 50 ether);
26+
topUp(bob, 50 ether);
27+
vm.deal(alice, 50 ether);
28+
vm.deal(bob, 50 ether);
29+
}
30+
31+
function deployEtherPool() public {
32+
vm.startPrank(owner);
33+
address tokenB = address(new MockERC20("TEST Token 2", "TST2", 18));
34+
currency1 = Currency.wrap(address(tokenB));
35+
vm.stopPrank();
36+
37+
token1 = MockERC20(Currency.unwrap(currency1));
38+
currency0 = Currency.wrap(address(0)); // Ether
39+
40+
vm.label(address(token1), "token1");
41+
vm.label(address(0), "Ether");
42+
43+
// Create pool key with Ether as currency0
44+
key = PoolKey({
45+
currency0: currency0,
46+
currency1: currency1,
47+
fee: LPFeeLibrary.DYNAMIC_FEE_FLAG,
48+
tickSpacing: int24(60),
49+
hooks: hook
50+
});
51+
poolId = key.toId();
52+
53+
// Initialize the pool
54+
manager.initialize(key, 2 ** 96);
55+
56+
// Mint token1 to owner
57+
token1.mint(owner, 2 ** 128 - 1);
58+
}
59+
60+
function testInitializeEtherPool() public view {
61+
assertEq(Currency.unwrap(key.currency0), address(0));
62+
assertEq(Currency.unwrap(key.currency1), address(token1));
63+
}
64+
65+
function testFuzz_EtherSwapOrder(uint256 swapAmount, bool zeroForOne) public {
66+
swapAmount = bound(swapAmount, 1, 50 ether);
67+
68+
uint256 token0Before = alice.balance;
69+
uint256 token1Before = token1.balanceOf(alice);
70+
71+
// Alice creates async swap order: Ether -> token1
72+
vm.startPrank(alice);
73+
AsyncOrder memory aliceOrder =
74+
AsyncOrder({ key: key, owner: alice, zeroForOne: zeroForOne, amountIn: swapAmount, sqrtPrice: 2 ** 96 });
75+
if (zeroForOne) {
76+
router.swap{ value: swapAmount }(aliceOrder, abi.encode(alice, address(router)));
77+
} else {
78+
token1.approve(address(router), swapAmount);
79+
router.swap(aliceOrder, abi.encode(alice, address(router)));
80+
}
81+
vm.stopPrank();
82+
83+
// Verify Alice's order
84+
assertEq(hook.asyncOrderAmount(poolId, alice, zeroForOne), swapAmount);
85+
assertTrue(hook.isExecutor(poolId, alice, address(router)));
86+
87+
// Check Alice's Ether balance decreased
88+
if (zeroForOne) {
89+
assertEq(alice.balance, token0Before - swapAmount);
90+
} else {
91+
assertEq(token1.balanceOf(alice), token1Before - swapAmount);
92+
}
93+
}
94+
95+
function testEtherOrderFill() public {
96+
uint256 swapAmount = 1 ether;
97+
98+
// Alice creates order
99+
vm.startPrank(alice);
100+
AsyncOrder memory aliceOrder =
101+
AsyncOrder({ key: key, owner: alice, zeroForOne: true, amountIn: swapAmount, sqrtPrice: 2 ** 96 });
102+
103+
router.swap{ value: swapAmount }(aliceOrder, abi.encode(alice, address(router)));
104+
vm.stopPrank();
105+
assertEq(manager.balanceOf(address(hook), currency0.toId()), 1 ether);
106+
107+
// Bob fills Alice's order with token1
108+
vm.startPrank(bob);
109+
token1.approve(address(hook), swapAmount);
110+
router.fillOrder(aliceOrder, "");
111+
vm.stopPrank();
112+
113+
// Verify order completion
114+
assertEq(hook.asyncOrderAmount(poolId, alice, true), 0);
115+
116+
// Alice should have received token1 in the pool manager
117+
assertEq(manager.balanceOf(alice, currency1.toId()), swapAmount);
118+
assertEq(manager.balanceOf(bob, currency0.toId()), swapAmount);
119+
}
120+
121+
function testEtherWithdrawal() public {
122+
uint256 swapAmount = 1 ether;
123+
124+
// Alice creates order
125+
vm.startPrank(alice);
126+
AsyncOrder memory aliceOrder =
127+
AsyncOrder({ key: key, owner: alice, zeroForOne: true, amountIn: swapAmount, sqrtPrice: 4295128740 });
128+
129+
router.swap{ value: swapAmount }(aliceOrder, abi.encode(alice, address(router)));
130+
vm.stopPrank();
131+
132+
// Alice withdraws her Ether order
133+
uint256 balanceBefore = alice.balance;
134+
vm.prank(alice);
135+
router.withdraw(key, true, swapAmount);
136+
137+
// Verify withdrawal
138+
assertEq(alice.balance, balanceBefore + swapAmount);
139+
assertEq(hook.asyncOrderAmount(poolId, alice, true), 0);
140+
}
141+
142+
}

0 commit comments

Comments
 (0)