punkkit-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/.env +47 -0
  2. package/.gitmodules +3 -0
  3. package/README.md +158 -0
  4. package/config/auction.config.ts +40 -0
  5. package/config/env.config.ts +204 -0
  6. package/config/uniswap.config.ts +107 -0
  7. package/config/voucher.config.ts +10 -0
  8. package/contracts/MutiVoucher.sol +78 -0
  9. package/contracts/auction/ChainXAuction.sol +177 -0
  10. package/contracts/auction/ChainXAuctionV2.sol +672 -0
  11. package/contracts/auction/ChainXWrappedETH.sol +80 -0
  12. package/contracts/auction/ChainYLiquidityManager.sol +57 -0
  13. package/contracts/auction/ChainYShadowETH.sol +148 -0
  14. package/contracts/auction/ChainYVault.sol +195 -0
  15. package/contracts/auction/ChainYVaultCoinbase.sol +276 -0
  16. package/contracts/auction/ChainYVaultV2.sol +318 -0
  17. package/contracts/auction/coinbase-and-stake/README.md +55 -0
  18. package/contracts/auction/coinbase-and-stake/coinbase.sol +142 -0
  19. package/contracts/auction/coinbase-and-stake/invokeCoinbase.sol +159 -0
  20. package/contracts/auction/coinbase-and-stake/invokeStake.sol +82 -0
  21. package/contracts/auction/coinbase-and-stake/stake.sol +92 -0
  22. package/contracts/auction/interfaces/IUniswapV2Factory.sol +15 -0
  23. package/contracts/auction/interfaces/IUniswapV2Pair.sol +53 -0
  24. package/contracts/auction/interfaces/IUniswapV2Router02.sol +25 -0
  25. package/contracts/auction/interfaces/IUnlockStrategy.sol +18 -0
  26. package/contracts/auction/libraries/EventParser.sol +32 -0
  27. package/contracts/auction/libraries/TransactionParser.sol +70 -0
  28. package/contracts/auction/strategies/MatchResultWithdrawnStrategy.sol +33 -0
  29. package/contracts/auction/utils/BytesLib.sol +180 -0
  30. package/contracts/auction/utils/RLPReader.sol +355 -0
  31. package/contracts/uniswap/Create2.sol +80 -0
  32. package/contracts/uniswap/DynamicFee.sol +100 -0
  33. package/contracts/uniswap/Example.sol +35 -0
  34. package/contracts/uniswap/HookMiner.sol +52 -0
  35. package/contracts/uniswap/LimitOrder.sol +486 -0
  36. package/contracts/uniswap/LiquidPool.sol +179 -0
  37. package/contracts/uniswap/MockERC20.sol +20 -0
  38. package/hardhat.config.ts +35 -0
  39. package/ignition/modules/LimitOrder.ts +33 -0
  40. package/package.json +32 -0
  41. package/scripts/auction/deploy.ts +23 -0
  42. package/scripts/auction/deployCoinbase.ts +21 -0
  43. package/scripts/auction/deployXAuction.ts +23 -0
  44. package/scripts/auction/deployYVault.ts +22 -0
  45. package/scripts/deploy_voucher.ts +20 -0
  46. package/scripts/uniswap/deploy/deploy.ts +65 -0
  47. package/scripts/uniswap/deploy/deploy_create2.ts +11 -0
  48. package/scripts/uniswap/deploy/deploy_example.ts +35 -0
  49. package/scripts/uniswap/deploy/deploy_hooks.ts +74 -0
  50. package/scripts/uniswap/deploy/deploy_mockERC20.ts +42 -0
  51. package/scripts/uniswap/deploy/help.ts +96 -0
  52. package/scripts/uniswap/deploy/init.ts +70 -0
  53. package/src/auction/chainXAuction.ts +209 -0
  54. package/src/auction/chainYVault.ts +153 -0
  55. package/src/auction/event.ts +19 -0
  56. package/src/auction/serialize.ts +162 -0
  57. package/src/auction/type.ts +71 -0
  58. package/src/lib/signer.ts +20 -0
  59. package/src/lib/unlock.ts +14 -0
  60. package/src/uniswap/1-marketprice/addLiquidity.ts +80 -0
  61. package/src/uniswap/1-marketprice/removeLiquidity.ts +63 -0
  62. package/src/uniswap/1-marketprice/swap.ts +100 -0
  63. package/src/uniswap/2-limitorder/kill.ts +70 -0
  64. package/src/uniswap/2-limitorder/place.ts +93 -0
  65. package/src/uniswap/2-limitorder/withdraw.ts +78 -0
  66. package/src/uniswap/3-dynamicfee/dynamicfee.ts +321 -0
  67. package/src/uniswap/lib/ERC20.ts +49 -0
  68. package/src/uniswap/lib/contract.ts +18 -0
  69. package/src/uniswap/lib/limitOrder.ts +40 -0
  70. package/src/uniswap/lib/liqCalculation.ts +152 -0
  71. package/src/uniswap/lib/listen.ts +57 -0
  72. package/src/uniswap/lib/pool.ts +62 -0
  73. package/src/uniswap/lib/swap.ts +8 -0
  74. package/src/uniswap/lib/types.ts +21 -0
  75. package/src/uniswap/lib/utils.ts +26 -0
  76. package/src/uniswap/playgroud/abiencode.ts +21 -0
  77. package/src/uniswap/playgroud/amount0.ts +47 -0
  78. package/src/uniswap/playgroud/errordecode.ts +54 -0
  79. package/src/uniswap/playgroud/errorsigs.ts +86 -0
  80. package/src/voucher.ts +122 -0
  81. package/test/auction/ChainXAuctionV2.test.ts +265 -0
  82. package/test/auction/ChainYVaultV2.test.js +163 -0
  83. package/test/auction/ChainYVaultV2.test.ts +183 -0
  84. package/test/auction/auction.test.ts +106 -0
  85. package/test/connect_punk.test.ts +26 -0
  86. package/test/create2.test.ts +44 -0
  87. package/test/normal.ts +43 -0
  88. package/test/test-config.ts +18 -0
  89. package/test/uniswap/example.test.ts +62 -0
  90. package/test/uniswap/limitOrder.test.ts +184 -0
  91. package/test/uniswap/mockERC20.test.ts +142 -0
  92. package/test/voucher_hardhat.test.ts +120 -0
  93. package/test/voucher_punk.test.ts +83 -0
  94. package/tsconfig.json +11 -0
@@ -0,0 +1,321 @@
1
+ import { ethers } from "hardhat";
2
+ import type { Contract } from "ethers";
3
+ import { PoolKey, SwapParams, ModifyPositionParams } from "../lib/types";
4
+
5
+ let provider = new ethers.providers.JsonRpcProvider('http://localhost:8545');
6
+ let wallet = new ethers.Wallet("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", provider)
7
+
8
+
9
+
10
+ function calculateTickFromPrice(price: number, tickSpacing = 60): number {
11
+ let unroundedTick = Math.floor(Math.log(price) / Math.log(1.0001));
12
+ return Math.round(unroundedTick / tickSpacing) * tickSpacing;
13
+ }
14
+
15
+ async function checkAllowance(contract: Contract, ownerAddress: string, spenderAddress: string) {
16
+ // Check the amount of tokens that an owner allowed to a spender
17
+ let allowance = await contract.allowance(ownerAddress, spenderAddress);
18
+ console.log(`Allowance: ${allowance.toString()}`);
19
+ }
20
+
21
+ async function isdepolyed(address: string) {
22
+ let code = await provider.getCode(address);
23
+ if (code !== "0x") {
24
+ console.log(`The contract ${address} has been deployed.`);
25
+ } else {
26
+ console.log(`The contract ${address} has not been deployed. `);
27
+ }
28
+ }
29
+
30
+ async function donate(contract: Contract, poolKey: PoolKey, amount0: bigint, amount1: bigint) {
31
+ // Donate
32
+ console.log("begin donate")
33
+ let to0params = {
34
+ tickLower: 840000, // lower price 0.5
35
+ tickUpper: 876600, // upper price 1.5
36
+ liquidityDelta: 0
37
+ }
38
+ let tx1 = await contract.setPositionParameters(poolKey, to0params);
39
+ await tx1.wait();
40
+ let swapParams = {
41
+ zeroForOne: false,
42
+ amountSpecified: 0,
43
+ sqrtPriceLimitX96: 0
44
+ }
45
+ let tx2 = await contract.setSwapParameters(poolKey, swapParams);
46
+ await tx2.wait();
47
+
48
+ let tx3 = await contract.setDonateParameters(poolKey, amount0, amount1);
49
+ await tx3.wait();
50
+
51
+ let tx4 = await contract.donate();
52
+ await tx4.wait();
53
+
54
+ console.log("donate successfully");
55
+ }
56
+
57
+ async function modifyPosition(contract: Contract, poolKey: PoolKey, modifyPositionParams: ModifyPositionParams) {
58
+ // Set position parameters
59
+ let tx = await contract.setPositionParameters(poolKey, modifyPositionParams);
60
+ await tx.wait();
61
+ console.log("Position parameters set successfully");
62
+ // Add liquidity
63
+ tx = await contract.addLiquidity();
64
+ await tx.wait();
65
+ }
66
+ //function kill(IPoolManager.PoolKey calldata key, int24 tickLower, bool zeroForOne, address to)
67
+ async function killLimitOrder(contract: Contract, poolKey: PoolKey, tickLower: number, zeroForOne: boolean, to: string) {
68
+ let tx = await contract.kill(poolKey, tickLower, zeroForOne, to);
69
+ await tx.wait();
70
+ console.log("kill successfully");
71
+ //emit Kill(msg.sender, epoch, key, tickLower, zeroForOne, liquidity);
72
+ await contract.on("Kill", (owner, epoch, key, tickLower, zeroForOne, liquidity, event) => {
73
+ console.log("Kill event emitted:");
74
+ console.log("Owner: ", owner);
75
+ console.log("Epoch: ", epoch.toString());
76
+ console.log("Key: ", key);
77
+ console.log("TickLower: ", tickLower.toString());
78
+ console.log("ZeroForOne: ", zeroForOne);
79
+ console.log("Liquidity: ", liquidity.toString());
80
+
81
+ // Handle event here
82
+ });
83
+ }
84
+
85
+ async function placeLimitOrder(contract: Contract, poolKey: PoolKey, tickLower: number, zeroForOne: boolean, liquidity: number) {
86
+ let tx = await contract.place(poolKey, tickLower, zeroForOne, liquidity);
87
+ await tx.wait();
88
+ console.log("limit order set successfully");
89
+
90
+ await contract.on("Place", (owner, epoch, key, tickLower, zeroForOne, liquidity, event) => {
91
+ console.log("Place event emitted:");
92
+ console.log("Owner: ", owner);
93
+ console.log("Epoch: ", epoch.toString());
94
+ console.log("Key: ", key);
95
+ console.log("TickLower: ", tickLower.toString());
96
+ console.log("ZeroForOne: ", zeroForOne);
97
+ console.log("Liquidity: ", liquidity.toString());
98
+
99
+ // Handle event here
100
+ });
101
+ }
102
+
103
+ async function withdrawLimitOrder(contract: Contract, epoch: number, to: string) {
104
+ let tx = await contract.withdraw(epoch, to);
105
+ await tx.wait();
106
+ console.log("limit order withdraw successfully");
107
+ await contract.on("Withdraw", (owner, epoch, liquidity, event) => {
108
+ console.log("Withdraw event emitted:");
109
+ console.log("Owner: ", owner);
110
+ console.log("Epoch: ", epoch.toString());
111
+ console.log("Liquidity: ", liquidity.toString());
112
+ });
113
+ }
114
+
115
+ async function initialize(contract: Contract, key: PoolKey, sqrtPriceX96: bigint) {
116
+ let tick = await contract.initialize(key, sqrtPriceX96);
117
+ console.log(`Returned tick: ${JSON.stringify(tick)}`);
118
+ }
119
+
120
+ async function approveERC20(contract: Contract, toAddress: string, amount: bigint) {
121
+ let tx = await contract.approve(toAddress, amount);
122
+ let receipt = await tx.wait();
123
+ console.log(`Transaction hash: ${receipt.transactionHash}`);
124
+ }
125
+
126
+ function getPoolId(poolKey: PoolKey): string {
127
+ return ethers.utils.solidityKeccak256(
128
+ ["bytes"],
129
+ [ethers.utils.defaultAbiCoder.encode(
130
+ ["address", "address", "uint24", "int24", "address"],
131
+ [poolKey.currency0, poolKey.currency1, poolKey.fee, poolKey.tickSpacing, poolKey.hooks]
132
+ )]
133
+ );
134
+ }
135
+
136
+ async function getSlot0(contract: Contract, poolKey: PoolKey) {
137
+ let poolId = getPoolId(poolKey);
138
+ console.log(`PoolId: ${poolId}`);
139
+ let slot0 = await contract.getSlot0(poolId);
140
+ console.log(`Returned slot0: ${JSON.stringify(slot0)}`);
141
+ }
142
+
143
+ async function getLiquidity(contract: Contract, poolKey: PoolKey) {
144
+ let poolId = getPoolId(poolKey);
145
+ console.log(`PoolId: ${poolId}`);
146
+ //let liq0 = await contract.getLiquidity(poolId);
147
+ let liq0 = await contract.functions['getLiquidity(bytes32)'](poolId);
148
+
149
+ console.log(`Returned liquidity: ${liq0}`);
150
+ }
151
+
152
+ async function getERC20Balance(contract: Contract, address: string) {
153
+ // 查询ERC20余额
154
+ let balance = await contract.balanceOf(address);
155
+ console.log(`ERC20 Balance: ${balance.toString()}`);
156
+ return balance;
157
+ }
158
+
159
+ async function executeSwap(contract: Contract, poolKey: PoolKey, swapParams: SwapParams) {
160
+
161
+ // Set position parameters
162
+ console.log("begin swap")
163
+ let to0params = {
164
+ tickLower: 840000, // lower price 0.5
165
+ tickUpper: 876600, // upper price 1.5
166
+ liquidityDelta: 0
167
+ }
168
+ let tx1 = await contract.setPositionParameters(poolKey, to0params);
169
+ await tx1.wait();
170
+ let tx2 = await contract.setSwapParameters(poolKey, swapParams);
171
+ console.log("begin swap1")
172
+ await tx2.wait();
173
+ console.log("Position parameters set successfully");
174
+ // swap
175
+ let tx3 = await contract.executeSwap();
176
+ await tx3.wait();
177
+ }
178
+
179
+ async function depolyContract(contractName: string, params?: any): Promise<Contract> {
180
+ const Factory = await ethers.getContractFactory(contractName);
181
+ let contract;
182
+ if (params === undefined) {
183
+ contract = await Factory.deploy();
184
+ } else {
185
+ console.log(`params: ${JSON.stringify(params)}`);
186
+ contract = await Factory.deploy(params);
187
+ //depolyContract("depoly1");
188
+ }
189
+ await contract.deployed();
190
+ console.log(`${contractName} deployed to ${contract.address}`);
191
+ return contract;
192
+ }
193
+
194
+ async function delay(milliseconds: any) {
195
+ // 这个新的 Promise 将在指定的毫秒数后 resolve
196
+ return new Promise(resolve => setTimeout(resolve, milliseconds));
197
+ }
198
+
199
+ describe("PoolManager", function () {
200
+ it("Should return the new greeting once it's changed", async function () {
201
+ const token0 = await depolyContract("Token0");
202
+ const token1 = await depolyContract("Token1");
203
+ // await isdepolyed(token0.address);
204
+ // await isdepolyed(token1.address);
205
+ const totalSupply0 = await token0.totalSupply();
206
+ console.log(`Token0 deployed to ${token0.address} with an initial supply ${totalSupply0}`);
207
+ const totalSupply1 = await token1.totalSupply();
208
+ console.log(`Token1 deployed to ${token1.address} with an initial supply ${totalSupply1}`);
209
+ getERC20Balance(token0, wallet.address);
210
+ getERC20Balance(token1, wallet.address);
211
+ const token0Address = token0.address < token1.address ? token0.address : token1.address;
212
+ const token1Address = token0.address > token1.address ? token0.address : token1.address;
213
+ //await isdepolyed(token0Address);
214
+ //await isdepolyed(token1Address);
215
+
216
+ //depoly poolManager
217
+ const poolManager = await depolyContract("PoolManager", 88888888888);
218
+ // const Factory = await ethers.getContractFactory("PoolManager");
219
+ // const controllerGasLimit = 88888888888;
220
+ // const contractpm = await Factory.deploy(controllerGasLimit);
221
+ // await contractpm.deployed();
222
+ const poolManagerAddress = poolManager.address;
223
+ //console.log("PoolManager Contract deployed to:", poolManagerAddress);
224
+ await isdepolyed(poolManagerAddress);
225
+
226
+ //depoly hook
227
+ // 部署 LimitOrder 合约
228
+ const dynamicFee = await depolyContract("DynamicFee", poolManagerAddress);
229
+ console.log("LimitOrder Contract deployed to:", dynamicFee.address);
230
+ // await isdepolyed(limitOrder.address);
231
+
232
+ //initial poolManager
233
+ let sqrtPriceX96 = BigInt("792281625142643375935439503360")// price = 100 token1/token0
234
+ const DYNAMIC_FEE_FLAG = 0x800000;
235
+ let poolKey: PoolKey = {
236
+ currency0: token0Address,
237
+ currency1: token1Address,
238
+ fee: DYNAMIC_FEE_FLAG,
239
+ tickSpacing: 60,
240
+ hooks: dynamicFee.address,
241
+ };
242
+ //await getSlot0(poolManager, poolKey);
243
+ await initialize(poolManager, poolKey, sqrtPriceX96);
244
+ //await getSlot0(poolManager, poolKey);
245
+
246
+ //approve ERC20 token to limitOrder
247
+ //await approveERC20(token0,poolManager.address,ethers.utils.parseUnits("21000000", 18))
248
+ //await approveERC20(token1,poolManager.address,ethers.utils.parseUnits("21000000", 18))
249
+
250
+ const MyLiquidityProvider = await depolyContract("MyLiquidityProvider", poolManagerAddress);
251
+ //approve ERC20 token to MyLiquidityProvider
252
+ const wei = ethers.utils.parseUnits("21000000", 18).toBigInt();
253
+ await approveERC20(token0, MyLiquidityProvider.address, wei);
254
+ await approveERC20(token1, MyLiquidityProvider.address, wei);
255
+
256
+ //add liquidity
257
+ let modifyPositionParams: ModifyPositionParams = {
258
+ tickLower: 45000, // lower price 90
259
+ tickUpper: 46980, // upper price 110
260
+ //liquidityDelta: 194868329805051412324060
261
+ liquidityDelta: BigInt('10000000000000000000000')// 10000token0 10000token1
262
+ };
263
+
264
+ //console.log(`modifyPositionParams: ${JSON.stringify(modifyPositionParams)}`);
265
+ //console.log(`Poolkey: ${JSON.stringify(poolKey)}`);
266
+ await getERC20Balance(token0, wallet.address);
267
+ await getERC20Balance(token1, wallet.address);
268
+
269
+ await modifyPosition(MyLiquidityProvider, poolKey, modifyPositionParams);
270
+ console.log("Liquidity added successfully");
271
+
272
+ await getERC20Balance(token0, wallet.address);
273
+ await getERC20Balance(token1, wallet.address);
274
+ //swap
275
+ let sqrtpricelimit = ethers.BigNumber.from('7922816251426433759354395033600').toBigInt();
276
+ let amountswap = ethers.BigNumber.from('1083456789101112134000').toBigInt();
277
+ console.log("amountswap:", amountswap.toString())
278
+
279
+ let swapParams: SwapParams = {
280
+ zeroForOne: false,
281
+ amountSpecified: amountswap,
282
+ sqrtPriceLimitX96: sqrtpricelimit
283
+ }
284
+ //console.log("sprtprice to price",sqrtPricetoPrice(pricetoSqrtPrice(110)))
285
+
286
+ let token0beforswap = await getERC20Balance(token0, wallet.address);
287
+ let token1beforswap = await getERC20Balance(token1, wallet.address);
288
+
289
+ //await getSlot0(poolManager, poolKey);
290
+ await executeSwap(MyLiquidityProvider, poolKey, swapParams);
291
+ //await getSlot0(poolManager, poolKey);
292
+
293
+
294
+ console.log("swap successfully");
295
+ let token0afterswap = await getERC20Balance(token0, wallet.address);
296
+ let token1afterswap = await getERC20Balance(token1, wallet.address);
297
+
298
+ console.log("token0 change:", token0afterswap.sub(token0beforswap).toString())
299
+ console.log("token1 change:", token1afterswap.sub(token1beforswap).toString())
300
+ //price=token0 change/token1 change
301
+ console.log("price:", token1afterswap.sub(token1beforswap).toString() / token0afterswap.sub(token0beforswap).toString())
302
+
303
+ token0beforswap = await getERC20Balance(token0, wallet.address);
304
+ token1beforswap = await getERC20Balance(token1, wallet.address);
305
+
306
+ //await getSlot0(poolManager, poolKey);
307
+ await executeSwap(MyLiquidityProvider, poolKey, swapParams);
308
+ //await getSlot0(poolManager, poolKey);
309
+
310
+
311
+ console.log("swap successfully");
312
+ token0afterswap = await getERC20Balance(token0, wallet.address);
313
+ token1afterswap = await getERC20Balance(token1, wallet.address);
314
+
315
+ console.log("token0 change:", token0afterswap.sub(token0beforswap).toString())
316
+ console.log("token1 change:", token1afterswap.sub(token1beforswap).toString())
317
+ //price=token0 change/token1 change
318
+ console.log("price:", token1afterswap.sub(token1beforswap).toString() / token0afterswap.sub(token0beforswap).toString())
319
+
320
+ })
321
+ });
@@ -0,0 +1,49 @@
1
+ import { Contract } from "ethers";
2
+ // Check if the spender is approved to spend at least 'amount' tokens from ownerAddress
3
+ export async function isApproved(contract: Contract, ownerAddress: string, spenderAddress: string, amount: bigint) {
4
+ let allowance = await contract.allowance(ownerAddress, spenderAddress);
5
+ if (allowance >= amount) {
6
+ return true;
7
+ }
8
+ else {
9
+ return false;
10
+ }
11
+ }
12
+
13
+ export async function approveERC20(contract: Contract, spenderAddress: string, amount: bigint) {
14
+ let tx = await contract.approve(spenderAddress, amount);
15
+ await tx.wait();
16
+ }
17
+
18
+ export async function getAllowance(contract: Contract, ownerAddress: string, spenderAddress: string): Promise<bigint> {
19
+ const allowance = await contract.allowance(ownerAddress, spenderAddress);
20
+ return allowance;
21
+ }
22
+
23
+ export async function checkAndApproveERC20(contract: Contract, ownerAddress: string, spenderAddress: string, amount: bigint) {
24
+ const allowance = await getAllowance(contract, ownerAddress, spenderAddress);
25
+
26
+ if (allowance >= amount) {
27
+ return;
28
+ }
29
+
30
+ const tx = await contract.approve(spenderAddress, amount);
31
+ const receipt = await tx.wait();
32
+ }
33
+
34
+ export async function getERC20Balance(contract: Contract, address: string): Promise<bigint> {
35
+ const balance: bigint = BigInt(await contract.balanceOf(address));
36
+ // console.log(`ERC20 Balance: ${balance.toString()}`);
37
+ return balance;
38
+ }
39
+
40
+ export async function transferERC20(contract: Contract, toAddress: string, amount: bigint) {
41
+ const tx = await contract.transfer(toAddress, amount);
42
+ const receipt = await tx.wait();
43
+ }
44
+
45
+
46
+ export async function mintERC20(contract: Contract, toAddress: string, amount: bigint) {
47
+ const tx = await contract.mint(toAddress, amount);
48
+ await tx.wait();
49
+ }
@@ -0,0 +1,18 @@
1
+ import {Wallet , Contract} from "ethers";
2
+ import { CONTRACT_ADDRESSES , CONTRACTS_ABI} from "../../../config/uniswap.config";
3
+ import { ethers } from "hardhat";
4
+
5
+ export async function getContract(wallet:Wallet, name:string): Promise<Contract> {
6
+ switch(name){
7
+ case "Token0":
8
+ return new ethers.Contract(CONTRACT_ADDRESSES.Token0,CONTRACTS_ABI.MockERC20,wallet);
9
+ case "Token1":
10
+ return new ethers.Contract(CONTRACT_ADDRESSES.Token1,CONTRACTS_ABI.MockERC20,wallet);
11
+ case "LiquidPool":
12
+ return new ethers.Contract(CONTRACT_ADDRESSES.LiquidPool,CONTRACTS_ABI.LiquidPool,wallet);
13
+ case "LimitOrder":
14
+ return new ethers.Contract(CONTRACT_ADDRESSES.LimitOrder,CONTRACTS_ABI.LimitOrder,wallet);
15
+ default:
16
+ throw new Error(`Contract(${name}) initial method not defined`);
17
+ }
18
+ }
@@ -0,0 +1,40 @@
1
+ import { Contract, providers, Wallet } from "ethers";
2
+ import { PoolKey } from "./types";
3
+ import { getPoolId } from "./pool";
4
+ import { RPC_URL, PRIVATE_KEY, POOL_KEYS } from "../../../config/uniswap.config";
5
+ import {ethers} from "hardhat";
6
+ import { getContract } from "./contract";
7
+
8
+ export async function getTickLowerLast(contract:Contract, poolKey: PoolKey): Promise<bigint> {
9
+ const poolId = getPoolId(poolKey);
10
+ return contract.getTickLowerLast(poolId);
11
+ }
12
+
13
+ // epoach is uint232 in solidity
14
+ export async function getEpoch(contract:Contract, poolKey: PoolKey, tickLower: bigint, zeroForOne: boolean): Promise<bigint> {
15
+ const poolId = getPoolId(poolKey);
16
+ return contract.getEpoch(poolId, tickLower, zeroForOne);
17
+ }
18
+
19
+ // uint256
20
+ export async function getEpochLiquidity(contract:Contract, epoch: bigint, ownerAddress:string): Promise<bigint> {
21
+ return contract.getEpochLiquidity(epoch, ownerAddress);
22
+ }
23
+
24
+ export async function getTick(contract:Contract, poolKey: PoolKey): Promise<bigint> {
25
+ const poolId = getPoolId(poolKey);
26
+ return contract.getTick(poolId);
27
+ }
28
+
29
+ async function test(){
30
+ const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
31
+ const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
32
+ let contract= await getContract(wallet,"LiquidPool");
33
+
34
+ let zeroForOne=true;
35
+ let tickLower=BigInt(-60);
36
+ let epoch=getEpoch(contract, POOL_KEYS.limitOrderPoolKey,tickLower,zeroForOne);
37
+
38
+ }
39
+
40
+ test();
@@ -0,0 +1,152 @@
1
+ // Constants
2
+ const MAX_TICK = BigInt('887272');
3
+ const q32 = BigInt(2) ** BigInt(32);
4
+ const q96 = BigInt(2) ** BigInt(96);
5
+ const q128 = BigInt(2) ** BigInt(128);
6
+ const q256 = BigInt(2) ** BigInt(256);
7
+
8
+ // Function to calculate tick from price with optional spacing
9
+ export function calculateTickFromPriceWithSpacing(price: number, tickSpacing = 60): number {
10
+ const unroundedTick = calculateTickFromPrice(price);
11
+ return Math.floor(unroundedTick / tickSpacing) * tickSpacing;
12
+ }
13
+
14
+ // Function to calculate tick from price without spacing
15
+ export function calculateTickFromPrice(price: number): number {
16
+ return Math.floor(Math.log(price) / Math.log(1.0001));
17
+ }
18
+
19
+ function getAbsTick(tick: bigint): bigint {
20
+ // Ensure tick is within the int24 range
21
+ const int24Max: bigint = BigInt(2) ** BigInt(23) - BigInt(1);
22
+ const int24Min: bigint = BigInt(-2) ** BigInt(23);
23
+ if (tick > int24Max || tick < int24Min) {
24
+ throw new Error('tick is out of int24 range');
25
+ }
26
+
27
+ // Determine the mask: 0 if tick >= 0, -1 if tick < 0
28
+ const mask: bigint = tick < BigInt(0) ? BigInt(-1) : BigInt(0);
29
+
30
+ // Calculate absTick
31
+ const absTick: bigint = (mask ^ (tick + mask));
32
+
33
+ return absTick;
34
+ }
35
+
36
+ export function getSqrtPriceAtTick(tick: number): bigint {
37
+ const absTick: bigint = getAbsTick(BigInt(tick));
38
+
39
+ if (absTick > MAX_TICK) {
40
+ throw new Error("Invalid tick");
41
+ }
42
+
43
+ let price = (absTick & BigInt(1)) === BigInt(0)
44
+ ? q128
45
+ : BigInt("0xfffcb933bd6fad37aa2d162d1a594001");
46
+
47
+ if (absTick & BigInt(2)) price = (price * BigInt("0xfff97272373d413259a46990580e213a")) >> BigInt(128);
48
+ if (absTick & BigInt(4)) price = (price * BigInt("0xfff2e50f5f656932ef12357cf3c7fdcc")) >> BigInt(128);
49
+ if (absTick & BigInt(8)) price = (price * BigInt("0xffe5caca7e10e4e61c3624eaa0941cd0")) >> BigInt(128);
50
+ if (absTick & BigInt(16)) price = (price * BigInt("0xffcb9843d60f6159c9db58835c926644")) >> BigInt(128);
51
+ if (absTick & BigInt(32)) price = (price * BigInt("0xff973b41fa98c081472e6896dfb254c0")) >> BigInt(128);
52
+ if (absTick & BigInt(64)) price = (price * BigInt("0xff2ea16466c96a3843ec78b326b52861")) >> BigInt(128);
53
+ if (absTick & BigInt(128)) price = (price * BigInt("0xfe5dee046a99a2a811c461f1969c3053")) >> BigInt(128);
54
+ if (absTick & BigInt(256)) price = (price * BigInt("0xfcbe86c7900a88aedcffc83b479aa3a4")) >> BigInt(128);
55
+ if (absTick & BigInt(512)) price = (price * BigInt("0xf987a7253ac413176f2b074cf7815e54")) >> BigInt(128);
56
+ if (absTick & BigInt(1024)) price = (price * BigInt("0xf3392b0822b70005940c7a398e4b70f3")) >> BigInt(128);
57
+ if (absTick & BigInt(2048)) price = (price * BigInt("0xe7159475a2c29b7443b29c7fa6e889d9")) >> BigInt(128);
58
+ if (absTick & BigInt(4096)) price = (price * BigInt("0xd097f3bdfd2022b8845ad8f792aa5825")) >> BigInt(128);
59
+ if (absTick & BigInt(8192)) price = (price * BigInt("0xa9f746462d870fdf8a65dc1f90e061e5")) >> BigInt(128);
60
+ if (absTick & BigInt(16384)) price = (price * BigInt("0x70d869a156d2a1b890bb3df62baf32f7")) >> BigInt(128);
61
+ if (absTick & BigInt(32768)) price = (price * BigInt("0x31be135f97d08fd981231505542fcfa6")) >> BigInt(128);
62
+ if (absTick & BigInt(65536)) price = (price * BigInt("0x9aa508b5b7a84e1c677de54f3e99bc9")) >> BigInt(128);
63
+ if (absTick & BigInt(131072)) price = (price * BigInt("0x5d6af8dedb81196699c329225ee604")) >> BigInt(128);
64
+ if (absTick & BigInt(262144)) price = (price * BigInt("0x2216e584f5fa1ea926041bedfe98")) >> BigInt(128);
65
+ if (absTick & BigInt(524288)) price = (price * BigInt("0x48a170391f7dc42444e8fa2")) >> BigInt(128);
66
+
67
+ if (tick > 0) {
68
+ price = (q256 - BigInt(1)) / price;
69
+ }
70
+
71
+ return (price + q32 - BigInt(1)) >> BigInt(32); // Convert from Q128.128 to Q128.96 and round up
72
+ }
73
+
74
+ // Function to calculate price from tick
75
+ export function calculatePriceFromTick(tick: number): number {
76
+ return Math.exp(tick * Math.log(1.0001));
77
+ }
78
+
79
+ // Function to convert price to sqrtPriceX96
80
+ export function priceToSqrtPrice(price: number): bigint {
81
+ return BigInt(Math.floor(Math.sqrt(price) * Number(q96)));
82
+ }
83
+
84
+ // Function to convert sqrtPriceX96 to price
85
+ function sqrtPricetoPrice(sqrtprice: bigint): number {
86
+ return (Number(sqrtprice) ** 2) / Number(q96 ** BigInt(2));
87
+ }
88
+
89
+ // Liquidity calculations for amount0 and amount1
90
+ export function liquidity0(amount: bigint, pa: bigint, pb: bigint): bigint {
91
+ if (pa > pb) {
92
+ [pa, pb] = [pb, pa];
93
+ }
94
+
95
+ return (amount * pa * pb) / (q96 * (pb - pa));
96
+ }
97
+
98
+ export function liquidity1(amount: bigint, pa: bigint, pb: bigint): bigint {
99
+ if (pa > pb) {
100
+ [pa, pb] = [pb, pa];
101
+ }
102
+ return (amount * q96) / (pb - pa);
103
+ }
104
+
105
+ function divRoundingUp(a: bigint, b: bigint): bigint {
106
+ const remainder = a % b;
107
+ const quotient = a / b;
108
+ return remainder === BigInt(0) ? quotient : quotient + BigInt(1);
109
+ }
110
+
111
+ // Amount calculations for liquidity0 and liquidity1
112
+ export function amount0(liquidity0: bigint, pa: bigint, pb: bigint): bigint {
113
+ if (pa > pb) {
114
+ [pa, pb] = [pb, pa];
115
+ }
116
+ const diff = pb - pa;
117
+ return divRoundingUp((liquidity0 * q96 * diff), pa * pb);
118
+ }
119
+
120
+ export function amount1(liquidity1: bigint, pa: bigint, pb: bigint): bigint {
121
+ if (pa > pb) {
122
+ [pa, pb] = [pb, pa];
123
+ }
124
+ const diff = pb - pa;
125
+ return divRoundingUp(liquidity1 * diff, q96);
126
+ }
127
+
128
+ // Simplified version to calculate liquidity delta
129
+ /// @liquidity delta, @amount0 used, @amount1 used
130
+ export function calculateLiqDelta(ticklow: number, sqrt_cur: bigint, tickupp: number, amt0: bigint, amt1: bigint): [bigint, bigint, bigint] {
131
+ const sqrt_low = getSqrtPriceAtTick(ticklow);
132
+ const sqrt_upp = getSqrtPriceAtTick(tickupp);
133
+ // console.log(`sqrt_low: ${sqrt_low}, sqrt_upp: ${sqrt_upp}, sqrt_cur: ${sqrt_cur}`);
134
+
135
+
136
+ if (sqrt_low > sqrt_cur) {
137
+ // 当前价格比最低价格还要小,流动性按照token0数量计算
138
+ const liq0 = liquidity0(amt0, sqrt_low, sqrt_upp);
139
+ return [liq0, amount0(liq0, sqrt_low, sqrt_upp), BigInt(0)];
140
+ } else if (sqrt_cur > sqrt_upp) {
141
+ // 当前价格比最高价格还要高,流动性按照token1数量计算
142
+ const liq1 = liquidity1(amt1, sqrt_upp, sqrt_low);
143
+ return [liq1, BigInt(0), amount1(liq1, sqrt_low, sqrt_upp)];
144
+ } else {
145
+ // 按照流动性最高的来计算
146
+ const liq0 = liquidity0(amt0, sqrt_cur, sqrt_upp);
147
+ const liq1 = liquidity1(amt1, sqrt_cur, sqrt_low);
148
+
149
+ const liq = liq0 < liq1 ? liq1 : liq0;
150
+ return [liq, amount0(liq, sqrt_cur, sqrt_upp), amount1(liq, sqrt_low, sqrt_cur)];
151
+ }
152
+ }
@@ -0,0 +1,57 @@
1
+ import { Contract } from "ethers";
2
+
3
+ export async function listenAllEvents(hook: Contract): Promise<void> {
4
+ hook.on('*', (event) => {
5
+ console.log(`${event.event} event emitted:`);
6
+ for (const key in event.args) {
7
+ if (event.args.hasOwnProperty(key)) {
8
+ console.log(`${key}: ${event.args[key].toString()}`);
9
+ }
10
+ }
11
+ });
12
+ }
13
+
14
+ export async function listenPlaceEvent(contract: Contract): Promise<void> {
15
+ contract.once("Place", (owner, epoch, key, tickLower, zeroForOne, liquidity) => {
16
+ console.log("Place event emitted:");
17
+ console.log("Owner: ", owner);
18
+ console.log("Epoch: ", epoch.toString());
19
+ console.log("Key: ", key);
20
+ console.log("TickLower: ", tickLower.toString());
21
+ console.log("ZeroForOne: ", zeroForOne);
22
+ console.log("Liquidity: ", liquidity.toString());
23
+ });
24
+ }
25
+
26
+ export async function listenKillEvent(contract: Contract): Promise<void> {
27
+ contract.once("Kill", (owner, epoch, key, tickLower, zeroForOne, liquidity) => {
28
+ console.log("Kill event emitted:");
29
+ console.log("Owner: ", owner);
30
+ console.log("Epoch: ", epoch.toString());
31
+ console.log("Key: ", key);
32
+ console.log("TickLower: ", tickLower.toString());
33
+ console.log("ZeroForOne: ", zeroForOne);
34
+ console.log("Liquidity: ", liquidity.toString());
35
+ });
36
+ }
37
+
38
+ export async function listenWithdrawEvent(contract: Contract): Promise<void> {
39
+ contract.once("Withdraw", (owner, epoch, liquidity) => {
40
+ console.log("Withdraw event emitted:");
41
+ console.log("Owner: ", owner);
42
+ console.log("Epoch: ", epoch.toString());
43
+ console.log("Liquidity: ", liquidity.toString());
44
+ });
45
+ }
46
+
47
+ export async function listenFillEvent(contract: Contract): Promise<void> {
48
+ contract.once("Fill", (owner, epoch, key, tickLower, zeroForOne, liquidity) => {
49
+ console.log("Fill event emitted:");
50
+ console.log("Owner: ", owner);
51
+ console.log("Epoch: ", epoch.toString());
52
+ console.log("Key: ", key);
53
+ console.log("TickLower: ", tickLower.toString());
54
+ console.log("ZeroForOne: ", zeroForOne);
55
+ console.log("Liquidity: ", liquidity.toString());
56
+ });
57
+ }