@steerprotocol/sdk 1.30.8 → 1.31.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.
- package/dist/cjs/base/PoolClient.js +137 -0
- package/dist/cjs/base/PoolClient.js.map +1 -1
- package/dist/cjs/base/VaultClient.js +111 -2
- package/dist/cjs/base/VaultClient.js.map +1 -1
- package/dist/cjs/const/feeManagerContracts.js +25 -0
- package/dist/cjs/const/feeManagerContracts.js.map +1 -0
- package/dist/cjs/const/network.js +7 -0
- package/dist/cjs/const/network.js.map +1 -1
- package/dist/cjs/const/protocol.js +68 -92
- package/dist/cjs/const/protocol.js.map +1 -1
- package/dist/cjs/scripts/processDeployments.js +1 -0
- package/dist/cjs/scripts/processDeployments.js.map +1 -1
- package/dist/esm/base/PoolClient.js +137 -0
- package/dist/esm/base/PoolClient.js.map +1 -1
- package/dist/esm/base/VaultClient.js +111 -2
- package/dist/esm/base/VaultClient.js.map +1 -1
- package/dist/esm/const/feeManagerContracts.js +25 -0
- package/dist/esm/const/feeManagerContracts.js.map +1 -0
- package/dist/esm/const/network.js +7 -0
- package/dist/esm/const/network.js.map +1 -1
- package/dist/esm/const/protocol.js +68 -92
- package/dist/esm/const/protocol.js.map +1 -1
- package/dist/esm/scripts/processDeployments.js +1 -0
- package/dist/esm/scripts/processDeployments.js.map +1 -1
- package/dist/types/base/PoolClient.d.ts +22 -0
- package/dist/types/base/PoolClient.d.ts.map +1 -1
- package/dist/types/base/VaultClient.d.ts +20 -0
- package/dist/types/base/VaultClient.d.ts.map +1 -1
- package/dist/types/const/feeManagerContracts.d.ts +6 -0
- package/dist/types/const/feeManagerContracts.d.ts.map +1 -0
- package/dist/types/const/network.d.ts +1 -0
- package/dist/types/const/network.d.ts.map +1 -1
- package/dist/types/const/protocol.d.ts +4 -19
- package/dist/types/const/protocol.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/__tests__/base/PoolClient.test.ts +355 -104
- package/src/__tests__/base/StakingClient.test.ts +72 -72
- package/src/__tests__/base/VaultClient.protocol-filter.test.ts +64 -137
- package/src/__tests__/base/VaultClient.test.ts +460 -60
- package/src/__tests__/base/vault/single-asset/calculateLimitPrice.test.ts +32 -14
- package/src/__tests__/base/vault/single-asset/calculateSwapAmount.test.ts +7 -4
- package/src/__tests__/base/vault/single-asset/estimateLpTokens.test.ts +105 -570
- package/src/__tests__/base/vault/single-asset/simulateSwap.test.ts +45 -66
- package/src/__tests__/base/vault/single-asset/singleAssetDepositClient.test.ts +178 -381
- package/src/__tests__/const/network.feeManager.test.ts +47 -0
- package/src/__tests__/fixtures/live/single-asset.fixture.json +116 -0
- package/src/__tests__/fixtures/live/staking-pools.fixture.json +353 -0
- package/src/__tests__/fixtures/live/vaults.fixture.json +5392 -0
- package/src/base/PoolClient.ts +200 -1
- package/src/base/VaultClient.ts +169 -2
- package/src/const/feeManagerContracts.ts +28 -0
- package/src/const/network.ts +10 -1
- package/src/const/protocol.ts +18 -39
- package/src/scripts/processDeployments.ts +1 -0
|
@@ -1,400 +1,197 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
1
|
+
import { parseEther } from 'viem';
|
|
2
|
+
import { SingleAssetDepositClient } from '../../../../base/vault/single-asset/singleAssetDeposit.js';
|
|
3
|
+
import { AMMType } from '../../../../base/vault/single-asset/types.js';
|
|
4
|
+
|
|
5
|
+
jest.mock('../../../../base/vault/single-asset/calculateSwapAmount.js', () => ({
|
|
6
|
+
calculateSwapAmount: jest.fn(),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
jest.mock('../../../../base/vault/single-asset/calculateLimitPrice.js', () => ({
|
|
10
|
+
calculateLimitPrice: jest.fn(),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock('../../../../base/vault/single-asset/simulateSwap.js', () => ({
|
|
14
|
+
determineSwapDirection: jest.fn((isToken0: boolean) => isToken0),
|
|
15
|
+
simulateSwapWithSlippage: jest.fn(),
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
jest.mock('../../../../base/vault/single-asset/estimateLpTokens.js', () => ({
|
|
19
|
+
estimateLpTokens: jest.fn(),
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
import { calculateSwapAmount } from '../../../../base/vault/single-asset/calculateSwapAmount.js';
|
|
23
|
+
import { calculateLimitPrice } from '../../../../base/vault/single-asset/calculateLimitPrice.js';
|
|
24
|
+
import { simulateSwapWithSlippage } from '../../../../base/vault/single-asset/simulateSwap.js';
|
|
25
|
+
import { estimateLpTokens } from '../../../../base/vault/single-asset/estimateLpTokens.js';
|
|
27
26
|
|
|
28
27
|
describe('SingleAssetDepositClient', () => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
28
|
+
let client: SingleAssetDepositClient;
|
|
29
|
+
let publicClient: any;
|
|
30
|
+
let walletClient: any;
|
|
31
|
+
|
|
32
|
+
const addresses = {
|
|
33
|
+
vault: '0xea102e191687b47d23f1239c6bca03389fd98a32' as `0x${string}`,
|
|
34
|
+
pool: '0xba2d4a755982eefbd24c52cea01c9ff5d3813bd4' as `0x${string}`,
|
|
35
|
+
contract: '0x3456789012345678901234567890123456789012' as `0x${string}`,
|
|
36
|
+
receiver: '0x9876543210987654321098765432109876543210' as `0x${string}`,
|
|
37
|
+
user: '0x9876543210987654321098765432109876543210' as `0x${string}`,
|
|
38
|
+
token0: '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619' as `0x${string}`,
|
|
39
|
+
token1: '0xd1a718f77ab5d22e3955050658d7f65ae857a85e' as `0x${string}`,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
jest.clearAllMocks();
|
|
44
|
+
|
|
45
|
+
publicClient = {
|
|
46
|
+
chain: { id: 137 },
|
|
47
|
+
getChainId: jest.fn().mockResolvedValue(137),
|
|
48
|
+
readContract: jest.fn().mockImplementation(async ({ functionName }: { functionName: string }) => {
|
|
49
|
+
if (functionName === 'token0') return addresses.token0;
|
|
50
|
+
if (functionName === 'token1') return addresses.token1;
|
|
51
|
+
if (functionName === 'fee') return 3000;
|
|
52
|
+
if (functionName === 'vaultDetailsByAddress') {
|
|
53
|
+
return { vaultType: 'MultiPositionUniswapV3' };
|
|
54
|
+
}
|
|
55
|
+
return { vaultType: 'MultiPositionUniswapV3' };
|
|
56
|
+
}),
|
|
57
|
+
simulateContract: jest.fn(),
|
|
41
58
|
};
|
|
42
59
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const walletClient = createWalletClient({chain: hyperEvmChain, transport: http()});
|
|
60
|
+
walletClient = {
|
|
61
|
+
getAddresses: jest.fn().mockResolvedValue([addresses.user]),
|
|
62
|
+
writeContract: jest.fn(),
|
|
63
|
+
};
|
|
48
64
|
|
|
49
|
-
|
|
50
|
-
|
|
65
|
+
client = new SingleAssetDepositClient(publicClient, walletClient);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe('previewDeposit', () => {
|
|
69
|
+
const baseParams = {
|
|
70
|
+
assets: parseEther('100'),
|
|
71
|
+
receiver: addresses.receiver,
|
|
72
|
+
vault: addresses.vault,
|
|
73
|
+
isToken0: true,
|
|
74
|
+
depositSlippagePercent: 5n,
|
|
75
|
+
swapSlippageBP: 500,
|
|
76
|
+
ammType: AMMType.UniswapV3,
|
|
77
|
+
singleAssetDepositContract: addresses.contract,
|
|
78
|
+
};
|
|
51
79
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
80
|
+
it('successfully previews a complete single-asset deposit', async () => {
|
|
81
|
+
(calculateSwapAmount as jest.Mock).mockResolvedValue({
|
|
82
|
+
success: true,
|
|
83
|
+
status: 200,
|
|
84
|
+
data: {
|
|
85
|
+
swapAmount: parseEther('25'),
|
|
86
|
+
sqrtPrice: 79228162514264337593543950336n,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
(calculateLimitPrice as jest.Mock).mockResolvedValue({
|
|
91
|
+
success: true,
|
|
92
|
+
status: 200,
|
|
93
|
+
data: 75266754285251620654291905318n,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
(simulateSwapWithSlippage as jest.Mock).mockResolvedValue({
|
|
97
|
+
success: true,
|
|
98
|
+
status: 200,
|
|
99
|
+
data: {
|
|
100
|
+
swapSimulation: {
|
|
101
|
+
amount0: -parseEther('25'),
|
|
102
|
+
amount1: parseEther('50'),
|
|
103
|
+
sqrtPriceX96After: 75266754285251620654291905318n,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
(estimateLpTokens as jest.Mock).mockResolvedValue({
|
|
109
|
+
success: true,
|
|
110
|
+
status: 200,
|
|
111
|
+
data: {
|
|
112
|
+
lpTokens: parseEther('95'),
|
|
113
|
+
finalAmount0: parseEther('75'),
|
|
114
|
+
finalAmount1: parseEther('50'),
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const result = await client.previewDeposit(baseParams, addresses.pool);
|
|
119
|
+
|
|
120
|
+
expect(result.success).toBe(true);
|
|
121
|
+
expect(result.status).toBe(200);
|
|
122
|
+
expect(result.data?.swapAmount).toBe(parseEther('25'));
|
|
123
|
+
expect(result.data?.lpEstimation.lpTokens).toBe(parseEther('95'));
|
|
124
|
+
expect(result.data?.zeroForOne).toBe(true);
|
|
55
125
|
});
|
|
56
126
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
ammType: AMMType.UniswapV3
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
it.only('should successfully preview a complete single-asset deposit', async () => {
|
|
69
|
-
|
|
70
|
-
// const params: SingleAssetDepositParams = {
|
|
71
|
-
// "assets":1000000000000000000n,"receiver":"0x50f72c67ab509dDaFFd35c385ffB904B9E255547","vault":"0xea102e191687b47d23f1239c6bca03389fd98a32","isToken0":true,"depositSlippagePercent":85n,"swapSlippageBP":500,"ammType":0}
|
|
72
|
-
|
|
73
|
-
const params: SingleAssetDepositParams = {
|
|
74
|
-
ammType: 4,
|
|
75
|
-
assets: 1000000000000000000n,
|
|
76
|
-
depositSlippagePercent: 85n,
|
|
77
|
-
isToken0: false,
|
|
78
|
-
receiver: "0x50f72c67ab509dDaFFd35c385ffB904B9E255547",
|
|
79
|
-
swapSlippageBP: 500,
|
|
80
|
-
vault: "0xbf39c114d2ddf657f26c158a2a04c399c4cb1c2d"
|
|
81
|
-
}
|
|
82
|
-
const result = await realSteerClient.vaults.previewSingleAssetDeposit(params, '0x51323f313e36a93fac2e1e929e48b961ffce5510');
|
|
83
|
-
|
|
84
|
-
console.log('Preview deposit update')
|
|
85
|
-
|
|
86
|
-
expect(result.success).toBe(true);
|
|
87
|
-
expect(result.status).toBe(200);
|
|
88
|
-
expect(result.data).toEqual({
|
|
89
|
-
swapAmount: parseEther('25'),
|
|
90
|
-
currentSqrtPrice: BigInt('79228162514264337593543950336'),
|
|
91
|
-
sqrtPriceLimitX96: BigInt('75266754285251620654291905318'),
|
|
92
|
-
swapSimulation: {
|
|
93
|
-
amount0: -parseEther('25'),
|
|
94
|
-
amount1: parseEther('50')
|
|
95
|
-
},
|
|
96
|
-
lpEstimation: {
|
|
97
|
-
lpTokens: parseEther('95'),
|
|
98
|
-
finalAmount0: parseEther('75'),
|
|
99
|
-
finalAmount1: parseEther('50')
|
|
100
|
-
},
|
|
101
|
-
zeroForOne: true
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should handle token1 deposit', async () => {
|
|
107
|
-
const token1Params = {
|
|
108
|
-
... baseParams,
|
|
109
|
-
isToken0: false
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const result = await client.previewDeposit(token1Params, mockAddresses.pool);
|
|
114
|
-
|
|
115
|
-
expect(result.success).toBe(true);
|
|
116
|
-
expect(result.data ?. zeroForOne).toBe(false);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('should handle calculateSwapAmount failure', async () => {
|
|
120
|
-
|
|
121
|
-
const result = await client.previewDeposit(baseParams, mockAddresses.pool);
|
|
122
|
-
|
|
123
|
-
expect(result.success).toBe(false);
|
|
124
|
-
expect(result.status).toBe(500);
|
|
125
|
-
expect(result.error).toBe('Swap calculation failed');
|
|
126
|
-
expect(result.data).toBeNull();
|
|
127
|
-
|
|
128
|
-
// Should not call subsequent functions
|
|
129
|
-
});
|
|
127
|
+
it('returns swap calculation failure', async () => {
|
|
128
|
+
(calculateSwapAmount as jest.Mock).mockResolvedValue({
|
|
129
|
+
success: false,
|
|
130
|
+
status: 500,
|
|
131
|
+
error: 'Swap calculation failed',
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const result = await client.previewDeposit(baseParams, addresses.pool);
|
|
130
135
|
|
|
136
|
+
expect(result.success).toBe(false);
|
|
137
|
+
expect(result.status).toBe(500);
|
|
138
|
+
expect(result.error).toBe('Swap calculation failed');
|
|
139
|
+
expect(result.data).toBeNull();
|
|
131
140
|
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('deposit', () => {
|
|
144
|
+
const baseParams = {
|
|
145
|
+
assets: parseEther('100'),
|
|
146
|
+
receiver: addresses.receiver,
|
|
147
|
+
vault: addresses.vault,
|
|
148
|
+
isToken0: true,
|
|
149
|
+
depositSlippagePercent: 5n,
|
|
150
|
+
swapSlippageBP: 500,
|
|
151
|
+
ammType: AMMType.UniswapV3,
|
|
152
|
+
singleAssetDepositContract: addresses.contract,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
it('successfully executes deposit', async () => {
|
|
156
|
+
const txHash = `0x${'a'.repeat(64)}` as `0x${string}`;
|
|
157
|
+
publicClient.simulateContract.mockResolvedValue({ request: { to: addresses.contract } });
|
|
158
|
+
walletClient.writeContract.mockResolvedValue(txHash);
|
|
159
|
+
|
|
160
|
+
const result = await client.deposit(baseParams);
|
|
132
161
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
isToken0: true,
|
|
139
|
-
depositSlippagePercent: 5n,
|
|
140
|
-
swapSlippageBP: 500,
|
|
141
|
-
ammType: AMMType.UniswapV3,
|
|
142
|
-
singleAssetDepositContract: mockAddresses.contract
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
it('should successfully execute deposit', async () => {
|
|
146
|
-
const mockTxHash = '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890';
|
|
147
|
-
|
|
148
|
-
walletClient.getAddresses = jest.fn().mockResolvedValue([mockAddresses.user]);
|
|
149
|
-
publicClient.simulateContract = jest.fn().mockResolvedValue({
|
|
150
|
-
request: {
|
|
151
|
-
address: mockAddresses.contract,
|
|
152
|
-
abi: expect.any(Array),
|
|
153
|
-
functionName: 'deposit',
|
|
154
|
-
args: [
|
|
155
|
-
parseEther('100'),
|
|
156
|
-
mockAddresses.receiver,
|
|
157
|
-
mockAddresses.vault,
|
|
158
|
-
true,
|
|
159
|
-
5n,
|
|
160
|
-
500,
|
|
161
|
-
AMMType.UniswapV3
|
|
162
|
-
]
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
walletClient.writeContract = jest.fn().mockResolvedValue(mockTxHash);
|
|
166
|
-
|
|
167
|
-
const result = await client.deposit(baseParams);
|
|
168
|
-
|
|
169
|
-
expect(result.success).toBe(true);
|
|
170
|
-
expect(result.status).toBe(200);
|
|
171
|
-
expect(result.data).toBe(mockTxHash);
|
|
172
|
-
|
|
173
|
-
expect(publicClient.simulateContract).toHaveBeenCalledWith({
|
|
174
|
-
address: mockAddresses.contract,
|
|
175
|
-
abi: expect.any(Array),
|
|
176
|
-
functionName: 'deposit',
|
|
177
|
-
args: [
|
|
178
|
-
parseEther('100'),
|
|
179
|
-
mockAddresses.receiver,
|
|
180
|
-
mockAddresses.vault,
|
|
181
|
-
true,
|
|
182
|
-
5n,
|
|
183
|
-
500,
|
|
184
|
-
AMMType.UniswapV3
|
|
185
|
-
],
|
|
186
|
-
account: mockAddresses.user
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
expect(walletClient.writeContract).toHaveBeenCalled();
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it('should handle no account found', async () => {
|
|
193
|
-
walletClient.getAddresses = jest.fn().mockResolvedValue([]);
|
|
194
|
-
|
|
195
|
-
const result = await client.deposit(baseParams);
|
|
196
|
-
|
|
197
|
-
expect(result.success).toBe(false);
|
|
198
|
-
expect(result.error).toBe('No account found');
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it('should handle simulation failure', async () => {
|
|
202
|
-
walletClient.getAddresses = jest.fn().mockResolvedValue([mockAddresses.user]);
|
|
203
|
-
publicClient.simulateContract = jest.fn().mockRejectedValue(new Error('Simulation failed'));
|
|
204
|
-
|
|
205
|
-
const result = await client.deposit(baseParams);
|
|
206
|
-
|
|
207
|
-
expect(result.success).toBe(false);
|
|
208
|
-
expect(result.error).toBe('Simulation failed');
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it('should handle transaction failure', async () => {
|
|
212
|
-
walletClient.getAddresses = jest.fn().mockResolvedValue([mockAddresses.user]);
|
|
213
|
-
publicClient.simulateContract = jest.fn().mockResolvedValue({request: {}});
|
|
214
|
-
walletClient.writeContract = jest.fn().mockRejectedValue(new Error('Transaction failed'));
|
|
215
|
-
|
|
216
|
-
const result = await client.deposit(baseParams);
|
|
217
|
-
|
|
218
|
-
expect(result.success).toBe(false);
|
|
219
|
-
expect(result.error).toBe('Transaction failed');
|
|
220
|
-
});
|
|
162
|
+
expect(result.success).toBe(true);
|
|
163
|
+
expect(result.status).toBe(200);
|
|
164
|
+
expect(result.data).toBe(txHash);
|
|
165
|
+
expect(publicClient.simulateContract).toHaveBeenCalled();
|
|
166
|
+
expect(walletClient.writeContract).toHaveBeenCalled();
|
|
221
167
|
});
|
|
222
168
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
swapSlippageBP: 500,
|
|
231
|
-
ammType: AMMType.UniswapV3,
|
|
232
|
-
singleAssetDepositContract: mockAddresses.contract
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
it('should successfully prepare deposit transaction', async () => {
|
|
236
|
-
walletClient.getAddresses = jest.fn().mockResolvedValue([mockAddresses.user]);
|
|
237
|
-
publicClient.simulateContract = jest.fn().mockResolvedValue({
|
|
238
|
-
request: {
|
|
239
|
-
address: mockAddresses.contract,
|
|
240
|
-
functionName: 'deposit',
|
|
241
|
-
args: [/* mock args */
|
|
242
|
-
]
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
const result = await client.prepareDepositTx(baseParams);
|
|
247
|
-
|
|
248
|
-
expect(result.success).toBe(true);
|
|
249
|
-
expect(result.status).toBe(200);
|
|
250
|
-
expect(result.data).toEqual({
|
|
251
|
-
address: mockAddresses.contract,
|
|
252
|
-
abi: expect.any(Array),
|
|
253
|
-
functionName: 'deposit',
|
|
254
|
-
args: [
|
|
255
|
-
parseEther('100'),
|
|
256
|
-
mockAddresses.receiver,
|
|
257
|
-
mockAddresses.vault,
|
|
258
|
-
true,
|
|
259
|
-
5n,
|
|
260
|
-
500,
|
|
261
|
-
AMMType.UniswapV3
|
|
262
|
-
]
|
|
263
|
-
});
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
it('should handle preparation errors', async () => {
|
|
267
|
-
walletClient.getAddresses = jest.fn().mockResolvedValue([]);
|
|
268
|
-
|
|
269
|
-
const result = await client.prepareDepositTx(baseParams);
|
|
270
|
-
|
|
271
|
-
expect(result.success).toBe(false);
|
|
272
|
-
expect(result.error).toBe('No account found');
|
|
273
|
-
});
|
|
169
|
+
it('returns error when no account exists', async () => {
|
|
170
|
+
walletClient.getAddresses.mockResolvedValue([]);
|
|
171
|
+
|
|
172
|
+
const result = await client.deposit(baseParams);
|
|
173
|
+
|
|
174
|
+
expect(result.success).toBe(false);
|
|
175
|
+
expect(result.error).toBe('No account found');
|
|
274
176
|
});
|
|
275
177
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
swapSlippageBP: 500,
|
|
284
|
-
ammType: AMMType.UniswapV3,
|
|
285
|
-
singleAssetDepositContract: mockAddresses.contract
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
it('should not throw for valid parameters', () => {
|
|
289
|
-
expect(() => client.validateDepositParams(validParams)).not.toThrow();
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it('should throw for zero assets', () => {
|
|
293
|
-
expect(() => client.validateDepositParams({
|
|
294
|
-
... validParams,
|
|
295
|
-
assets: BigInt('0')
|
|
296
|
-
})).toThrow('Assets amount must be greater than 0');
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
it('should throw for invalid vault address', () => {
|
|
300
|
-
expect(() => client.validateDepositParams({
|
|
301
|
-
... validParams,
|
|
302
|
-
vault: '0x0000000000000000000000000000000000000000'
|
|
303
|
-
})).toThrow('Invalid vault address');
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
it('should throw for invalid receiver address', () => {
|
|
307
|
-
expect(() => client.validateDepositParams({
|
|
308
|
-
... validParams,
|
|
309
|
-
receiver: '0x0000000000000000000000000000000000000000'
|
|
310
|
-
})).toThrow('Invalid receiver address');
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
it('should throw for invalid contract address', () => {
|
|
314
|
-
expect(() => client.validateDepositParams({
|
|
315
|
-
... validParams,
|
|
316
|
-
singleAssetDepositContract: '0x0000000000000000000000000000000000000000'
|
|
317
|
-
})).toThrow('Invalid single-asset deposit contract address');
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
it('should throw for excessive deposit slippage', () => {
|
|
321
|
-
expect(() => client.validateDepositParams({
|
|
322
|
-
... validParams,
|
|
323
|
-
depositSlippagePercent: 101n
|
|
324
|
-
})).toThrow('Deposit slippage percent cannot exceed 100%');
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
it('should throw for excessive swap slippage', () => {
|
|
328
|
-
expect(() => client.validateDepositParams({
|
|
329
|
-
... validParams,
|
|
330
|
-
swapSlippageBP: 10001
|
|
331
|
-
})).toThrow('Swap slippage BP cannot exceed 10000 (100%)');
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
it('should throw for invalid AMM type', () => {
|
|
335
|
-
expect(() => client.validateDepositParams({
|
|
336
|
-
... validParams,
|
|
337
|
-
ammType: 999 as AMMType
|
|
338
|
-
})).toThrow('Invalid AMM type');
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
it('should handle edge case values', () => { // Test maximum allowed values
|
|
342
|
-
expect(() => client.validateDepositParams({
|
|
343
|
-
... validParams,
|
|
344
|
-
depositSlippagePercent: 100n,
|
|
345
|
-
swapSlippageBP: 10000
|
|
346
|
-
})).not.toThrow();
|
|
347
|
-
|
|
348
|
-
// Test minimum values
|
|
349
|
-
expect(() => client.validateDepositParams({
|
|
350
|
-
... validParams,
|
|
351
|
-
assets: BigInt('1'),
|
|
352
|
-
depositSlippagePercent: 0n,
|
|
353
|
-
swapSlippageBP: 0
|
|
354
|
-
})).not.toThrow();
|
|
355
|
-
});
|
|
178
|
+
it('returns simulation failure', async () => {
|
|
179
|
+
publicClient.simulateContract.mockRejectedValue(new Error('Simulation failed'));
|
|
180
|
+
|
|
181
|
+
const result = await client.deposit(baseParams);
|
|
182
|
+
|
|
183
|
+
expect(result.success).toBe(false);
|
|
184
|
+
expect(result.error).toBe('Simulation failed');
|
|
356
185
|
});
|
|
357
186
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
swapSlippageBP: 300,
|
|
367
|
-
ammType: AMMType.UniswapV3,
|
|
368
|
-
singleAssetDepositContract: mockAddresses.contract
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const result = await client.previewDeposit(params, mockAddresses.pool);
|
|
373
|
-
|
|
374
|
-
expect(result.success).toBe(true);
|
|
375
|
-
expect(result.data ?. swapAmount).toBe(parseEther('50'));
|
|
376
|
-
expect(result.data ?. lpEstimation.finalAmount0).toBe(parseEther('50'));
|
|
377
|
-
expect(result.data ?. lpEstimation.finalAmount1).toBe(parseEther('50'));
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
it('should handle imbalanced pool scenario', async () => {
|
|
381
|
-
const params = {
|
|
382
|
-
assets: parseEther('100'),
|
|
383
|
-
receiver: mockAddresses.receiver,
|
|
384
|
-
vault: mockAddresses.vault,
|
|
385
|
-
isToken0: true,
|
|
386
|
-
depositSlippagePercent: 5n,
|
|
387
|
-
swapSlippageBP: 500,
|
|
388
|
-
ammType: AMMType.UniswapV3,
|
|
389
|
-
singleAssetDepositContract: mockAddresses.contract
|
|
390
|
-
};
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const result = await client.previewDeposit(params, mockAddresses.pool);
|
|
394
|
-
|
|
395
|
-
expect(result.success).toBe(true);
|
|
396
|
-
expect(result.data ?. swapAmount).toBe(parseEther('80'));
|
|
397
|
-
expect(result.data ?. lpEstimation.lpTokens).toBe(parseEther('60'));
|
|
398
|
-
});
|
|
187
|
+
it('returns transaction failure', async () => {
|
|
188
|
+
publicClient.simulateContract.mockResolvedValue({ request: { to: addresses.contract } });
|
|
189
|
+
walletClient.writeContract.mockRejectedValue(new Error('Transaction failed'));
|
|
190
|
+
|
|
191
|
+
const result = await client.deposit(baseParams);
|
|
192
|
+
|
|
193
|
+
expect(result.success).toBe(false);
|
|
194
|
+
expect(result.error).toBe('Transaction failed');
|
|
399
195
|
});
|
|
196
|
+
});
|
|
400
197
|
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ChainId } from '../../const/chain.js';
|
|
2
|
+
import type { NetworkConfig } from '../../const/network.js';
|
|
3
|
+
import { feeManagerContractsByChainId } from '../../const/feeManagerContracts.js';
|
|
4
|
+
import { getContractAddressByChainIdAndContractName, networks } from '../../const/network.js';
|
|
5
|
+
|
|
6
|
+
describe('network FeeManager overlay', () => {
|
|
7
|
+
it('backfills FeeManager for chains missing it in legacy SDK deployment files', () => {
|
|
8
|
+
expect(getContractAddressByChainIdAndContractName(ChainId.Base, 'FeeManager')).toBe(
|
|
9
|
+
feeManagerContractsByChainId[ChainId.Base]?.address
|
|
10
|
+
);
|
|
11
|
+
expect(getContractAddressByChainIdAndContractName(ChainId.Avalanche, 'FeeManager')).toBe(
|
|
12
|
+
feeManagerContractsByChainId[ChainId.Avalanche]?.address
|
|
13
|
+
);
|
|
14
|
+
expect(getContractAddressByChainIdAndContractName(ChainId.Linea, 'FeeManager')).toBe(
|
|
15
|
+
feeManagerContractsByChainId[ChainId.Linea]?.address
|
|
16
|
+
);
|
|
17
|
+
expect(getContractAddressByChainIdAndContractName(ChainId.Scroll, 'FeeManager')).toBe(
|
|
18
|
+
feeManagerContractsByChainId[ChainId.Scroll]?.address
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('prefers contracts package FeeManager values when they conflict', () => {
|
|
23
|
+
expect(getContractAddressByChainIdAndContractName(ChainId.BeraChainBartio, 'FeeManager')).toBe(
|
|
24
|
+
feeManagerContractsByChainId[ChainId.BeraChainBartio]?.address
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('keeps SDK-only FeeManager entries when contracts map has no chain match', () => {
|
|
29
|
+
expect(feeManagerContractsByChainId[ChainId.Hyperevm]).toBeUndefined();
|
|
30
|
+
expect(getContractAddressByChainIdAndContractName(ChainId.Hyperevm, 'FeeManager')).toBe(
|
|
31
|
+
'0x8BfAdC53bfd06F051685b42690076d9c94aaBCBd'
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('exposes materially more FeeManager-enabled networks than legacy baseline', () => {
|
|
36
|
+
const feeManagerEnabledNetworks = (Object.values(networks) as NetworkConfig[]).filter(
|
|
37
|
+
(network) => Boolean(network.FeeManager?.address)
|
|
38
|
+
);
|
|
39
|
+
const chainIds = feeManagerEnabledNetworks.map((network) => network.chainId);
|
|
40
|
+
|
|
41
|
+
expect(feeManagerEnabledNetworks.length).toBeGreaterThan(4);
|
|
42
|
+
expect(chainIds).toContain(ChainId.Base);
|
|
43
|
+
expect(chainIds).toContain(ChainId.Avalanche);
|
|
44
|
+
expect(chainIds).toContain(ChainId.Linea);
|
|
45
|
+
expect(chainIds).toContain(ChainId.Scroll);
|
|
46
|
+
});
|
|
47
|
+
});
|