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
package/.env ADDED
@@ -0,0 +1,47 @@
1
+ # RPC 和 钱包配置。使用hardhat本地测试时候需要注释掉,会使用hardhat默认rpc以及账户
2
+ RPC_URL= "http://127.0.0.1:8666"
3
+ PRIVATE_KEY="0x6c19b85fa2d365e74b4b36556e1369fb9d680789e6e9350f9b62412efe3a76cc"
4
+ ACCOUNT_ADDR="0x9748b3f8B628f11abD2474085DD44F8ffD8EB3e6"
5
+
6
+
7
+ # 地址配置
8
+ Coinbase="0xAa9e62EB6d74d66Ff6720D1A8143c8237067Ff58"
9
+ ChainYVaultV2="0xAa9e62EB6d74d66Ff6720D1A8143c8237067Ff58"
10
+ ChainXAuctionV2="0x88566F811b751Fa527A0816d99d6968E00f2eBef"
11
+ IUnlockStrategy=""
12
+
13
+ Create2= "0x5FbDB2315678afecb367f032d93F642f64180aa3"
14
+ Token0= "0x3E8d9Ad590542AE8731960202CE0334B5c7c317D"
15
+ Token1= "0xF8407E61094a14601a7224AB628152B309788659"
16
+ PoolManager= "0xDB0412DaB8210ccA6d9875eE0be7b580A3c12046"
17
+ LiquidPool= "0x931D3dd4922c67C2C727c2Cf20313c5e541cB7A3"
18
+ LimitOrder= "0x2267dCcfebEa4C2A54A14F7ffa997a089Eb99040"
19
+ DynamicFee= "0x53660445Cda97cAD89c88cA67C099418412AD040"
20
+
21
+ MutiVoucher="0000000000000000000000000000000000000044"
22
+ # ABI配置
23
+ IUnlockStrategy_abi_path='artifacts/contracts/auction/interfaces/IUnlockStrategy.sol/IUnlockStrategy.json'
24
+ ChainYVault_abi_path='artifacts/contracts/auction/ChainYVaultV2.sol/ChainYVaultV2.json'
25
+ ChainXAuction_abi_path='artifacts/contracts/auction/ChainXAuctionV2.sol/ChainXAuctionV2.json'
26
+ Coinbase_abi_path='artifacts/contracts/auction/coinbase-and-stake/coinbase.sol/Coinbase.json'
27
+
28
+ PoolManager_abi_path='artifacts/@uniswap/v4-core/src/PoolManager.sol/PoolManager.json'
29
+ MockERC20_abi_path='artifacts/contracts/uniswap/MockERC20.sol/MockERC20.json'
30
+ LiquidPool_abi_path='artifacts/contracts/uniswap/LiquidPool.sol/LiquidPool.json'
31
+ LimitOrder_abi_path='artifacts/contracts/uniswap/LimitOrder.sol/LimitOrder.json'
32
+ DynamicFee_abi_path='artifacts/contracts/uniswap/DynamicFee.sol/DynamicFee.json'
33
+ Create2_abi_path='artifacts/contracts/uniswap/Create2.sol/Create2.json'
34
+ Example_abi_path='artifacts/contracts/uniswap/Example.sol/Example.json'
35
+
36
+ MutiVoucher_abi_path='artifacts/contracts/MutiVoucher.sol/MutiVoucher.json'
37
+
38
+ # uniswap 全局配置
39
+ # SALT 用于 Create2 部署
40
+ SALT="0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
41
+ SALT_LIMITORDER="0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"
42
+ # 价格配置 (1 token0 = PRICE_INIT token1)
43
+ PRICE_INIT=1
44
+ PRICE_LIMIT=1.1
45
+ # 初始流动性和供应量 (单位: ETH)
46
+ INITIAL_LIQUIDITY=1000
47
+ INITIAL_SUPPLY=210000000
package/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "contracts/auction/coinbase-and-stake"]
2
+ path = contracts/auction/coinbase-and-stake
3
+ url = git@github.com:LazyDreamingDog/coinbase-and-stake.git
package/README.md ADDED
@@ -0,0 +1,158 @@
1
+ # Uniswap V4 Hook Deployment & Use cases
2
+
3
+ ## 1. Run Uniswap V4 built-in tests
4
+
5
+ In [Uniswap V4 core](https://github.com/Uniswap/v4-core) repo:
6
+
7
+ ```bash
8
+ npx hardhat test
9
+ ```
10
+
11
+ ## 2. Compile pool and hook contracts
12
+
13
+ In [Our Uniswap v4 periphery](https://github.com/tofudfy/v4-periphery) repo:
14
+
15
+ ```bash
16
+ npx hardhat compile
17
+ ```
18
+
19
+ Move the required ABI files from `artifacts/contracts` to [SDK repo](https://github.com/tofudfy/v4-sdk) `scripts/frontend/abi`.
20
+
21
+ ## 3. Deploy pool and hook contracts
22
+
23
+ In [Our Uniswap V4 SDK](https://github.com/tofudfy/v4-sdk) repo:
24
+
25
+ 1. Start a local blockchain node
26
+
27
+ ```bash
28
+ npx hardhat node
29
+ ```
30
+
31
+ 2. Deploy [Uniswap V4 core](https://github.com/Uniswap/v4-core) contracts
32
+
33
+ 3. Configure blockchain networks, wallet, and contract addresses in:
34
+ `scripts/config.ts`
35
+
36
+ 4. Run the hook deployment script:
37
+
38
+ ```bash
39
+ npx hardhat run scripts/depoly/depoly.ts
40
+ ```
41
+
42
+ - Limit Order Hook: `contracts/LimitOrder.sol`
43
+ - Dynamic Fee Hook: `contracts/DynamicFee.sol`
44
+
45
+ ## 4. Initialize the PoolManager contract
46
+
47
+ Run the initialization script:
48
+
49
+ ```bash
50
+ npx hardhat run scripts/frontend/init/init.ts
51
+ ```
52
+
53
+ ## 5. Contract interactions
54
+
55
+ ### 5.1 Trading at Market Price
56
+
57
+ - Add liquidity:
58
+
59
+ ```bash
60
+ npx hardhat run scripts/frontend/marketprice/addLiquidity.ts
61
+ ```
62
+
63
+ - Swap:
64
+
65
+ ```bash
66
+ npx hardhat run scripts/frontend/marketprice/swap.ts
67
+ ```
68
+
69
+ - Remove liquidity:
70
+
71
+ ```bash
72
+ npx hardhat run scripts/frontend/marketprice/removeLiquidity.ts
73
+ ```
74
+
75
+ ### 5.2 Trading of Limit Order
76
+
77
+ (*Requires `addLiquidity` operation first, otherwise order placement will fail*)
78
+
79
+ - Place order:
80
+
81
+ ```bash
82
+ npx hardhat run scripts/frontend/limitorder/place.ts
83
+ ```
84
+
85
+ - [Todo] Cancel order:
86
+
87
+ ```bash
88
+ npx hardhat run scripts/frontend/limitorder/kill.ts
89
+ ```
90
+
91
+ - [Todo] Withdraw liquidity:
92
+
93
+ ```bash
94
+ npx hardhat run scripts/frontend/limitorder/withdraw.ts
95
+ ```
96
+
97
+ ### 5.3 Dynamic fee
98
+
99
+ - Adjust fee:
100
+
101
+ ```bash
102
+ npx hardhat test scripts/feehook/testfeehook.ts
103
+ ```
104
+
105
+ ## UniswapV4及hook部署使用
106
+
107
+ 1. 运行uniswapv4自带测试:
108
+ 命令行输入`npx hardhat test`
109
+ 2. 合约编译:`npx hardhat compile`
110
+ 将必要的abi文件从`artifacts/contracts`移至`scripts/frontend/abi`
111
+ 3. 部署uniswapv4合约以及hook合约:
112
+ 1. 运行本地区块链节点网络:`npx hardhat node`
113
+ 2. 配置文件,配置区块链网络、钱包以及合约地址:`scripts/frontend/lib/address.ts`
114
+ 3. hook合约部署脚本:`npx hardhat run scripts/frontend/depoly/depoly.ts`
115
+ + 限价交易hook:`contracts/LimitOrder.sol`
116
+ + 动态手续费hook:`contracts/DynamicFee.sol`
117
+
118
+ 4. 初始化poolmanager合约:
119
+ 运行初始化脚本:`npx hardhat run scripts/frontend/init/init.ts`
120
+
121
+ 5. 合约调用:
122
+ 1. 市价交易:
123
+ + 添加流动性:`npx hardhat run scripts/frontend/marketprice/addLiquidity.ts`
124
+ + 交易:`npx hardhat run scripts/frontend/marketprice/swap.ts`
125
+ + 撤销流动性:`npx hardhat run scripts/frontend/marketprice/removeLiquidity.ts`
126
+ 2. 限价交易:(接`添加流动性`操作,否则无法正常`挂单`)
127
+ + 挂单:`npx hardhat run scripts/frontend/limitorder/place.ts`
128
+ + [失败]撤单:`npx hardhat run scripts/frontend/limitorder/kill.ts`
129
+ + [失败]提取流动性:`npx hardhat run scripts/frontend/limitorder/withdraw.ts`
130
+ 3. 动态手续费:
131
+ + [存疑]调整手续费:`npx hardhat test scripts/feehook/testfeehook.ts`
132
+ ## 待完成事项
133
+
134
+ + 类似挖矿的流动性激励hook合约
135
+
136
+ # lq documents
137
+
138
+ ## 部署
139
+ | 依赖 | 版本 |
140
+ | ---- | ---- |
141
+ | nvm | 0.39.7 |
142
+ | npm | v20.19.5 |
143
+
144
+ 运行命令:
145
+ ```shell
146
+ npm install
147
+
148
+ npx hardhat node # 单独使用命令行执行
149
+
150
+ npx hardhat run scripts/deploy/deploy.ts
151
+ npx hardhat run scripts/deploy/inits.ts
152
+ ```
153
+ ## 测试
154
+ voucher测试通过
155
+
156
+ ```shell
157
+ npx hardhat test test/voucher.ts
158
+ ```
@@ -0,0 +1,40 @@
1
+ import {
2
+ RPC_URL,
3
+ PRIVATE_KEY,
4
+ config,
5
+ } from "./env.config";
6
+ import {join} from "path";
7
+
8
+ const chainXAuctionV2Addr=config.contracts.auction.chainXAuctionV2;
9
+ const chainYVaultV2Addr=config.contracts.auction.chainYVaultV2;
10
+ const coinbaseAddr=config.contracts.auction.coinbase;
11
+
12
+ const AUCTION_ADDR={
13
+ chainXAuction:chainXAuctionV2Addr,
14
+ chainYVault:chainYVaultV2Addr,
15
+ coinbase:coinbaseAddr,
16
+ }
17
+
18
+ // ABI路径
19
+ const ABI_PATHS = config.abiPaths.auction;
20
+ function relativePath(filepath:string):string{
21
+ const ROOT = '..';
22
+ return join(ROOT,filepath)
23
+ }
24
+
25
+ const AUCTION_ABI = {
26
+ coinbase: require(relativePath(ABI_PATHS.coinbase)),
27
+ chainXAuction: require(relativePath(ABI_PATHS.chainXAuction)),
28
+ chainYVault: require(relativePath(ABI_PATHS.chainYVault)),
29
+ } as const;
30
+
31
+ export { RPC_URL, PRIVATE_KEY };
32
+ export { AUCTION_ADDR,AUCTION_ABI};
33
+
34
+ if (require.main === module) {
35
+ console.log("=== Auction 配置验证 ===\n");
36
+ console.log("合约地址:");
37
+ console.log("ChainYVaultV2:", chainYVaultV2Addr);
38
+ console.log("ChainXAuctionV2:", chainXAuctionV2Addr);
39
+ console.log("Coinbase:", coinbaseAddr);
40
+ }
@@ -0,0 +1,204 @@
1
+ import * as dotenv from "dotenv";
2
+ import { ethers } from "ethers";
3
+ import * as path from "path";
4
+
5
+ // 加载环境变量
6
+ dotenv.config({ path: path.resolve(__dirname, "../.env") });
7
+
8
+ /**
9
+ * 环境变量配置接口定义
10
+ */
11
+ export interface EnvConfig {
12
+ // RPC 和钱包配置
13
+ rpc: {
14
+ url: string;
15
+ };
16
+ wallet: {
17
+ privateKey: string;
18
+ address: string;
19
+ };
20
+
21
+ // 合约地址配置
22
+ contracts: {
23
+ mutiVoucher:string;
24
+ auction: {
25
+ chainYVaultV2: string;
26
+ chainXAuctionV2: string;
27
+ coinbase: string;
28
+ };
29
+ uniswap: {
30
+ create2: string;
31
+ token0: string;
32
+ token1: string;
33
+ poolManager: string;
34
+ liquidPool: string;
35
+ limitOrder: string;
36
+ dynamicFee: string;
37
+ };
38
+ };
39
+ // ABI 文件路径配置 (完整路径)
40
+ abiPaths: {
41
+ mutiVoucher:string;
42
+ auction: {
43
+ chainYVault: string;
44
+ chainXAuction: string;
45
+ coinbase:string;
46
+ };
47
+ uniswap: {
48
+ poolManager: string;
49
+ mockERC20: string;
50
+ liquidPool: string;
51
+ limitOrder: string;
52
+ dynamicFee: string;
53
+ create2: string;
54
+ example: string;
55
+ };
56
+ };
57
+ // Pool 配置
58
+ pool: {
59
+ salt: string;
60
+ saltLimitOrder: string;
61
+ priceInit: number;
62
+ priceLimit: number;
63
+ initialLiquidity: bigint;
64
+ initialSupply: bigint;
65
+ dynamicFeeFlag: number;
66
+ };
67
+ // 路径配置
68
+ paths: {
69
+ abiRootDir: string; // ABI 文件根目录
70
+ };
71
+ }
72
+
73
+ /**
74
+ * 从环境变量中获取值,如果不存在则使用默认值
75
+ */
76
+ function getEnvValue(key: string, defaultValue: string): string {
77
+ const value = process.env[key];
78
+ if (value === undefined || value === "") {
79
+ return defaultValue;
80
+ }
81
+ return value;
82
+ }
83
+
84
+ /**
85
+ * 从环境变量中获取数字值
86
+ */
87
+ function getEnvNumber(key: string, defaultValue: number): number {
88
+ const value = process.env[key];
89
+ if (value === undefined || value === "") {
90
+ return defaultValue;
91
+ }
92
+ const parsed = parseFloat(value);
93
+ if (isNaN(parsed)) {
94
+ console.warn(`Warning: ${key} is not a valid number, using default value ${defaultValue}`);
95
+ return defaultValue;
96
+ }
97
+ return parsed;
98
+ }
99
+
100
+ /**
101
+ * 从环境变量中获取 BigInt 值
102
+ */
103
+ function getEnvBigInt(key: string, defaultValue: string): bigint {
104
+ const value = getEnvValue(key, defaultValue);
105
+ try {
106
+ return ethers.utils.parseEther(value).toBigInt();
107
+ } catch (error) {
108
+ console.warn(`Warning: ${key} is not a valid ether value, using default value ${defaultValue}`);
109
+ return ethers.utils.parseEther(defaultValue).toBigInt();
110
+ }
111
+ }
112
+
113
+ /**
114
+ * 拼接 ABI 文件路径
115
+ * @param rootDir ABI 根目录
116
+ * @param relativePath 相对路径
117
+ * @returns 完整路径
118
+ */
119
+ function joinAbiPath(rootDir: string, relativePath: string): string {
120
+ // 移除路径中的多余斜杠
121
+ const cleanRoot = rootDir.replace(/\/+$/, "");
122
+ const cleanRelative = relativePath.replace(/^\/+/, "");
123
+ return `${cleanRoot}/${cleanRelative}`;
124
+ }
125
+
126
+ /**
127
+ * 加载并解析环境变量配置
128
+ */
129
+ function loadConfig(): EnvConfig {
130
+ // 获取 ABI 根目录
131
+ const abiRootDir = getEnvValue("ABI_ROOT_DIR", "chain-core/ABI");
132
+
133
+ return {
134
+ rpc: {
135
+ url: getEnvValue("RPC_URL", "http://127.0.0.1:8545/"),
136
+ },
137
+ wallet: {
138
+ privateKey: getEnvValue(
139
+ "PRIVATE_KEY",
140
+ "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
141
+ ),
142
+ address: getEnvValue(
143
+ "ACCOUNT_ADDR",
144
+ "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
145
+ ),
146
+ },
147
+ contracts: {
148
+ mutiVoucher:getEnvValue("MutiVoucher",""),
149
+ auction: {
150
+ chainYVaultV2: getEnvValue("ChainYVaultV2", ""),
151
+ chainXAuctionV2: getEnvValue("ChainXAuctionV2", ""),
152
+ coinbase: getEnvValue("Coinbase", ""),
153
+ },
154
+ uniswap: {
155
+ create2: getEnvValue("Create2", "0x5FbDB2315678afecb367f032d93F642f64180aa3"),
156
+ token0: getEnvValue("Token0", "0x3e7B83B8bb8eE2D4d74ec805aeb1465e65E15E24"),
157
+ token1: getEnvValue("Token1", "0xF4DB8B5cC187B286Eb54Bf76c6b041286a46E4Ee"),
158
+ poolManager: getEnvValue("PoolManager", "0xDB0412DaB8210ccA6d9875eE0be7b580A3c12046"),
159
+ liquidPool: getEnvValue("LiquidPool", "0xBFd16A06062060FA08EFca22e3b6d334EcF3E2f0"),
160
+ limitOrder: getEnvValue("LimitOrder", "0x7982Cd1B4162c145e6c1a0f7fD3De4676950D040"),
161
+ dynamicFee: getEnvValue("DynamicFee", "0x541eEcD8E9A59476E436A766123B27330e149040"),
162
+ },
163
+ },
164
+ abiPaths: {
165
+ mutiVoucher: getEnvValue("MutiVoucher_abi_path", "MutiVoucher.json"),
166
+ auction: {
167
+ chainYVault: getEnvValue("ChainYVault_abi_path", "ChainYVaultV2.json"),
168
+ chainXAuction: getEnvValue("ChainXAuction_abi_path", "ChainXAuctionV2.json"),
169
+ coinbase: getEnvValue("Coinbase_abi_path", "Coinbase.json"),
170
+ },
171
+ uniswap: {
172
+ poolManager: getEnvValue("PoolManager_abi_path", "PoolManager.json"),
173
+ mockERC20: getEnvValue("MockERC20_abi_path", "MockERC20.json"),
174
+ liquidPool: getEnvValue("LiquidPool_abi_path", "LiquidPool.json"),
175
+ limitOrder: getEnvValue("LimitOrder_abi_path", "LimitOrder.json"),
176
+ dynamicFee: getEnvValue("DynamicFee_abi_path", "DynamicFee.json"),
177
+ create2: getEnvValue("Create2_abi_path", "Create2.json"),
178
+ example: getEnvValue("Example_abi_path", "Example.json"),
179
+ },
180
+ },
181
+ pool: {
182
+ salt: getEnvValue("SALT", ethers.utils.keccak256("0x00")),
183
+ saltLimitOrder: getEnvValue("SALT_LIMITORDER", ethers.utils.keccak256("0x01")),
184
+ priceInit: getEnvNumber("PRICE_INIT", 1),
185
+ priceLimit: getEnvNumber("PRICE_LIMIT", 1.1),
186
+ initialLiquidity: getEnvBigInt("INITIAL_LIQUIDITY", "1000"),
187
+ initialSupply: getEnvBigInt("INITIAL_SUPPLY", "210000000"),
188
+ dynamicFeeFlag: 0x800000,
189
+ },
190
+ paths: {
191
+ abiRootDir,
192
+ },
193
+
194
+ };
195
+ }
196
+
197
+ /**
198
+ * 导出配置对象
199
+ */
200
+ export const config: EnvConfig = loadConfig();
201
+ export const RPC_URL = config.rpc.url;
202
+ export const PRIVATE_KEY = config.wallet.privateKey;
203
+ export const ACCOUNT_ADDR = config.wallet.address;
204
+
@@ -0,0 +1,107 @@
1
+ // 从集中的配置解析器导入所有配置
2
+ import {
3
+ config,
4
+ RPC_URL,
5
+ PRIVATE_KEY,
6
+ } from "./env.config";
7
+ import {join} from "path";
8
+
9
+
10
+
11
+ // ============================== 导出配置供其他模块使用 ======================================
12
+ export { RPC_URL, PRIVATE_KEY };
13
+ export { CONTRACT_ADDRESSES,CONTRACTS_ABI,POOL_KEYS};
14
+ export { SALT, SALT_LIMITORDER, PRICE_INIT, PRICE_LIMIT, INITIAL_LIQUIDITY, INITIAL_SUPPLY };
15
+
16
+
17
+
18
+ // ============================== Contract Address ============================================
19
+ const CONTRACT_ADDRESSES = {
20
+ Create2: config.contracts.uniswap.create2,
21
+ Token0: config.contracts.uniswap.token0,
22
+ Token1: config.contracts.uniswap.token1,
23
+ PoolManager: config.contracts.uniswap.poolManager,
24
+ LiquidPool: config.contracts.uniswap.liquidPool,
25
+ LimitOrder: config.contracts.uniswap.limitOrder,
26
+ DynamicFee: config.contracts.uniswap.dynamicFee,
27
+ };
28
+
29
+ // ============================== Contract ABIs ============================================
30
+ function relativePath(filepath:string):string{
31
+ const ROOT = '..';
32
+ return join(ROOT,filepath)
33
+ }
34
+ // Uniswap ABI 路径
35
+ const ABI_PATHS = config.abiPaths.uniswap;
36
+
37
+ const CONTRACTS_ABI={
38
+ PoolManager: require(relativePath(ABI_PATHS.poolManager)),
39
+ MockERC20: require(relativePath(ABI_PATHS.mockERC20)),
40
+ LiquidPool: require(relativePath(ABI_PATHS.liquidPool)),
41
+ LimitOrder: require(relativePath(ABI_PATHS.limitOrder)),
42
+ DynamicFee: require(relativePath(ABI_PATHS.dynamicFee)),
43
+ Create2: require(relativePath(ABI_PATHS.create2)),
44
+ Example: require(relativePath(ABI_PATHS.example)),
45
+ }
46
+
47
+ // ============================== Pool Keys ================================================
48
+ // Pool 配置
49
+ const SALT = config.pool.salt;
50
+ const SALT_LIMITORDER = config.pool.saltLimitOrder;
51
+ const PRICE_INIT = config.pool.priceInit;
52
+ const PRICE_LIMIT = config.pool.priceLimit;
53
+ const INITIAL_LIQUIDITY = config.pool.initialLiquidity;
54
+ const INITIAL_SUPPLY = config.pool.initialSupply;
55
+ const DYNAMIC_FEE_FLAG = config.pool.dynamicFeeFlag;
56
+
57
+
58
+ const POOL_KEYS = {
59
+ limitOrderPoolKey: {
60
+ currency0: CONTRACT_ADDRESSES.Token0,
61
+ currency1: CONTRACT_ADDRESSES.Token1,
62
+ fee: 60,
63
+ tickSpacing: 60,
64
+ hooks: CONTRACT_ADDRESSES.LimitOrder,
65
+ },
66
+ dynamicFeePoolKey: {
67
+ currency0: CONTRACT_ADDRESSES.Token0,
68
+ currency1: CONTRACT_ADDRESSES.Token1,
69
+ fee: DYNAMIC_FEE_FLAG,
70
+ tickSpacing: 60,
71
+ hooks: CONTRACT_ADDRESSES.DynamicFee,
72
+ },
73
+ };
74
+
75
+
76
+ if (require.main === module) {
77
+ console.log("=== Uniswap 配置验证 ===\n");
78
+
79
+ console.log("ABI 路径:");
80
+ console.log("- PoolManager:", ABI_PATHS.poolManager);
81
+ console.log("- MockERC20:", ABI_PATHS.mockERC20);
82
+ console.log("- LiquidPool:", ABI_PATHS.liquidPool);
83
+ console.log("- LimitOrder:", ABI_PATHS.limitOrder);
84
+ console.log("- DynamicFee:", ABI_PATHS.dynamicFee);
85
+ console.log("- Create2:", ABI_PATHS.create2);
86
+ console.log("- Example:", ABI_PATHS.example);
87
+
88
+ console.log("\n合约地址:");
89
+ console.log("- Token0:", CONTRACT_ADDRESSES.Token0);
90
+ console.log("- Token1:", CONTRACT_ADDRESSES.Token1);
91
+ console.log("- PoolManager:", CONTRACT_ADDRESSES.PoolManager);
92
+ console.log("- LiquidPool:", CONTRACT_ADDRESSES.LiquidPool);
93
+ console.log("- LimitOrder:", CONTRACT_ADDRESSES.LimitOrder);
94
+ console.log("- DynamicFee:", CONTRACT_ADDRESSES.DynamicFee);
95
+ console.log("- Create2:", CONTRACT_ADDRESSES.Create2);
96
+
97
+ console.log("\nPool 配置:");
98
+ console.log("- SALT:", SALT.toString());
99
+ console.log("- SALT_LIMITORDER:", SALT_LIMITORDER.toString());
100
+ console.log("- PRICE_INIT:", PRICE_INIT);
101
+ console.log("- PRICE_LIMIT:", PRICE_LIMIT);
102
+ console.log("- INITIAL_LIQUIDITY:", INITIAL_LIQUIDITY.toString());
103
+ console.log("- INITIAL_SUPPLY:", INITIAL_SUPPLY.toString());
104
+ console.log("- DYNAMIC_FEE_FLAG:", DYNAMIC_FEE_FLAG.toString(16));
105
+
106
+ console.log("poolKeys:", POOL_KEYS);
107
+ }
@@ -0,0 +1,10 @@
1
+ import { config } from "./env.config";
2
+ import { join } from "path";
3
+ // MutiVoucher 相关
4
+ function relativePath(filepath:string):string{
5
+ const ROOT = '..';
6
+ return join(ROOT,filepath)
7
+ }
8
+
9
+ export const MUTI_VOUCHER_ADDR=config.contracts.mutiVoucher
10
+ export const MUTI_VOUCHER_ABI = require(relativePath(config.abiPaths.mutiVoucher));
@@ -0,0 +1,78 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.15;
3
+
4
+ // import "./utils/ownable.sol";
5
+
6
+ contract MutiVoucher {
7
+ struct Voucher {
8
+ uint256 conversionRate; // exchange rate with ETH
9
+ mapping(address => uint256) balances;
10
+ }
11
+ bytes32[] private voucherNames;
12
+ mapping(bytes32 => Voucher) private vouchers;
13
+
14
+ event VoucherCreated(bytes32 voucherName, uint256 conversionRate);
15
+ event VoucherPurchased(address buyer, bytes32 voucherName, uint256 amount);
16
+ event VoucherUsed(address user, bytes32 voucherName, uint256 amount);
17
+
18
+ // Create new voucher and store in vouchers
19
+ function createVoucher(
20
+ bytes32 name,
21
+ uint256 conversionRate
22
+ ) external {
23
+ require(
24
+ conversionRate > 0,
25
+ "Conversion rate must be greater than zero"
26
+ );
27
+ require(vouchers[name].conversionRate == 0, "Voucher already exist");
28
+
29
+ // Create new voucher
30
+ Voucher storage newVoucher = vouchers[name];
31
+ newVoucher.conversionRate = conversionRate;
32
+ voucherNames.push(name);
33
+
34
+ emit VoucherCreated(name, conversionRate);
35
+ }
36
+
37
+ function getVoucherInfo(
38
+ bytes32 name
39
+ ) external view returns (uint256 conversionRate) {
40
+ require(vouchers[name].conversionRate > 0, "Voucher doesn't exist");
41
+ return vouchers[name].conversionRate;
42
+ }
43
+
44
+ function buy(bytes32 name) external payable {
45
+ require(vouchers[name].conversionRate > 0, "Voucher doesn't exist");
46
+ require(msg.value > 0, "Message value must be greater than zero");
47
+ // Attention the unit of value is wei
48
+ uint256 expectedAmount = msg.value * vouchers[name].conversionRate;
49
+ vouchers[name].balances[msg.sender] += expectedAmount;
50
+ emit VoucherPurchased(msg.sender, name, expectedAmount);
51
+ }
52
+
53
+ function use(bytes32 name, uint256 amount) external {
54
+ require(vouchers[name].conversionRate > 0, "Voucher doesn't exist");
55
+ require(amount > 0, "Amount must be greater than zero");
56
+ require(
57
+ vouchers[name].balances[msg.sender] >= amount,
58
+ "Insufficient balance"
59
+ );
60
+
61
+ // Reduce balance
62
+ vouchers[name].balances[msg.sender] -= amount;
63
+ emit VoucherUsed(msg.sender, name, amount);
64
+ }
65
+
66
+ // Query balance of an address in voucher
67
+ function balanceOf(
68
+ bytes32 name,
69
+ address user
70
+ ) external view returns (uint256) {
71
+ require(vouchers[name].conversionRate > 0, "Voucher doesn't exist");
72
+ return vouchers[name].balances[user];
73
+ }
74
+
75
+ function getAllVouchers() external view returns (bytes32[] memory) {
76
+ return voucherNames;
77
+ }
78
+ }