@gauntlet-xyz/sdk 1.0.5 → 2.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.
- package/dist/constants.d.ts +16 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +28 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.d.ts +18 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +20 -2
- package/dist/errors.js.map +1 -1
- package/dist/evm/abis/priceAndFeeCalculatorV2.d.ts +233 -0
- package/dist/evm/abis/priceAndFeeCalculatorV2.d.ts.map +1 -0
- package/dist/evm/abis/priceAndFeeCalculatorV2.js +119 -0
- package/dist/evm/abis/priceAndFeeCalculatorV2.js.map +1 -0
- package/dist/evm/abis/provisionerV2.d.ts +460 -0
- package/dist/evm/abis/provisionerV2.d.ts.map +1 -0
- package/dist/evm/abis/provisionerV2.js +203 -0
- package/dist/evm/abis/provisionerV2.js.map +1 -0
- package/dist/evm/adapters/aera.d.ts +3 -3
- package/dist/evm/adapters/aera.d.ts.map +1 -1
- package/dist/evm/adapters/aera.js +179 -103
- package/dist/evm/adapters/aera.js.map +1 -1
- package/dist/evm/adapters/types.d.ts +12 -1
- package/dist/evm/adapters/types.d.ts.map +1 -1
- package/dist/evm/aeraContracts/priceAndFeeCalculator.d.ts +41 -0
- package/dist/evm/aeraContracts/priceAndFeeCalculator.d.ts.map +1 -0
- package/dist/evm/aeraContracts/priceAndFeeCalculator.js +140 -0
- package/dist/evm/aeraContracts/priceAndFeeCalculator.js.map +1 -0
- package/dist/evm/aeraContracts/v1.d.ts +2317 -0
- package/dist/evm/aeraContracts/v1.d.ts.map +1 -0
- package/dist/evm/aeraContracts/v1.js +59 -0
- package/dist/evm/aeraContracts/v1.js.map +1 -0
- package/dist/evm/aeraContracts/v2.d.ts +2802 -0
- package/dist/evm/aeraContracts/v2.d.ts.map +1 -0
- package/dist/evm/aeraContracts/v2.js +217 -0
- package/dist/evm/aeraContracts/v2.js.map +1 -0
- package/dist/evm/aeraContracts.d.ts +23 -2316
- package/dist/evm/aeraContracts.d.ts.map +1 -1
- package/dist/evm/aeraContracts.js +117 -24
- package/dist/evm/aeraContracts.js.map +1 -1
- package/dist/evm/deposit.d.ts +5 -1
- package/dist/evm/deposit.d.ts.map +1 -1
- package/dist/evm/deposit.js +28 -14
- package/dist/evm/deposit.js.map +1 -1
- package/dist/evm/depositReceiverApproval.d.ts +17 -0
- package/dist/evm/depositReceiverApproval.d.ts.map +1 -0
- package/dist/evm/depositReceiverApproval.js +32 -0
- package/dist/evm/depositReceiverApproval.js.map +1 -0
- package/dist/evm/index.d.ts +8 -1
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +4 -0
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/operationMode.d.ts +9 -0
- package/dist/evm/operationMode.d.ts.map +1 -0
- package/dist/evm/operationMode.js +41 -0
- package/dist/evm/operationMode.js.map +1 -0
- package/dist/evm/types.d.ts +7 -3
- package/dist/evm/types.d.ts.map +1 -1
- package/dist/evm/types.js +4 -1
- package/dist/evm/types.js.map +1 -1
- package/dist/evm/userCurrentBalance.d.ts.map +1 -1
- package/dist/evm/userCurrentBalance.js +68 -58
- package/dist/evm/userCurrentBalance.js.map +1 -1
- package/dist/evm/withdraw.d.ts +5 -1
- package/dist/evm/withdraw.d.ts.map +1 -1
- package/dist/evm/withdraw.js +25 -13
- package/dist/evm/withdraw.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/manifest/vaults.json +31 -139
- package/package.json +1 -1
- package/src/constants.ts +32 -0
- package/src/errors.ts +44 -5
- package/src/evm/abis/priceAndFeeCalculatorV2.ts +118 -0
- package/src/evm/abis/provisionerV2.ts +202 -0
- package/src/evm/adapters/aera.ts +419 -137
- package/src/evm/adapters/types.ts +19 -1
- package/src/evm/aeraContracts/priceAndFeeCalculator.ts +223 -0
- package/src/evm/aeraContracts/v1.ts +157 -0
- package/src/evm/aeraContracts/v2.ts +466 -0
- package/src/evm/aeraContracts.ts +173 -52
- package/src/evm/deposit.ts +48 -16
- package/src/evm/depositReceiverApproval.ts +51 -0
- package/src/evm/index.ts +23 -1
- package/src/evm/operationMode.ts +60 -0
- package/src/evm/types.ts +9 -3
- package/src/evm/userCurrentBalance.ts +80 -55
- package/src/evm/withdraw.ts +42 -15
- package/src/index.ts +19 -0
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Address,
|
|
3
|
+
type Client,
|
|
4
|
+
type GetContractReturnType,
|
|
5
|
+
type PublicClient,
|
|
6
|
+
getContract,
|
|
7
|
+
} from 'viem';
|
|
8
|
+
import { priceAndFeeCalculatorV2Abi } from '../abis/priceAndFeeCalculatorV2';
|
|
9
|
+
import { provisionerV2Abi } from '../abis/provisionerV2';
|
|
10
|
+
import {
|
|
11
|
+
Rounding,
|
|
12
|
+
convertTokenToUnitsIfActive,
|
|
13
|
+
convertUnitsToTokenIfActive,
|
|
14
|
+
} from './priceAndFeeCalculator';
|
|
15
|
+
import { MAX_BPS } from '../../constants';
|
|
16
|
+
import { StalePriceError } from '../../errors';
|
|
17
|
+
import type { ContractVersion } from '../types';
|
|
18
|
+
|
|
19
|
+
export type PriceAndFeeCalculatorContract<T extends Client> = GetContractReturnType<
|
|
20
|
+
typeof priceAndFeeCalculatorV2Abi,
|
|
21
|
+
T,
|
|
22
|
+
Address
|
|
23
|
+
>;
|
|
24
|
+
|
|
25
|
+
export function getPriceAndFeeCalculator<T extends Client>(
|
|
26
|
+
client: T,
|
|
27
|
+
address: Address
|
|
28
|
+
): PriceAndFeeCalculatorContract<T> {
|
|
29
|
+
return getContract({
|
|
30
|
+
address,
|
|
31
|
+
abi: priceAndFeeCalculatorV2Abi,
|
|
32
|
+
client,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getProvisioner<T extends Client>(client: T, address: Address) {
|
|
37
|
+
return getContract({
|
|
38
|
+
address,
|
|
39
|
+
abi: provisionerV2Abi,
|
|
40
|
+
client,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function getTokenDetails(client: PublicClient, provisioner: Address, token: Address) {
|
|
45
|
+
return getProvisioner(client, provisioner).read.tokensDetails([token]);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function getDepositUnitsOut({
|
|
49
|
+
client,
|
|
50
|
+
provisioner,
|
|
51
|
+
feeCalculator,
|
|
52
|
+
feeCalculatorVersion,
|
|
53
|
+
vault,
|
|
54
|
+
token,
|
|
55
|
+
tokensIn,
|
|
56
|
+
multiplierIndex,
|
|
57
|
+
}: {
|
|
58
|
+
client: PublicClient;
|
|
59
|
+
provisioner: Address;
|
|
60
|
+
feeCalculator: Address;
|
|
61
|
+
feeCalculatorVersion: ContractVersion;
|
|
62
|
+
vault: Address;
|
|
63
|
+
token: Address;
|
|
64
|
+
tokensIn: bigint;
|
|
65
|
+
multiplierIndex: 4 | 6;
|
|
66
|
+
}): Promise<bigint> {
|
|
67
|
+
const tokenDetails = await getTokenDetails(client, provisioner, token);
|
|
68
|
+
const multiplier = BigInt(tokenDetails[multiplierIndex]);
|
|
69
|
+
const adjustedTokensIn = (tokensIn * multiplier) / MAX_BPS;
|
|
70
|
+
|
|
71
|
+
return convertTokenToUnitsIfActive(
|
|
72
|
+
client,
|
|
73
|
+
feeCalculator,
|
|
74
|
+
feeCalculatorVersion,
|
|
75
|
+
vault,
|
|
76
|
+
token,
|
|
77
|
+
adjustedTokensIn,
|
|
78
|
+
Rounding.Floor
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function getRedeemTokenOut({
|
|
83
|
+
client,
|
|
84
|
+
provisioner,
|
|
85
|
+
feeCalculator,
|
|
86
|
+
feeCalculatorVersion,
|
|
87
|
+
vault,
|
|
88
|
+
token,
|
|
89
|
+
unitsIn,
|
|
90
|
+
multiplierIndex,
|
|
91
|
+
}: {
|
|
92
|
+
client: PublicClient;
|
|
93
|
+
provisioner: Address;
|
|
94
|
+
feeCalculator: Address;
|
|
95
|
+
feeCalculatorVersion: ContractVersion;
|
|
96
|
+
vault: Address;
|
|
97
|
+
token: Address;
|
|
98
|
+
unitsIn: bigint;
|
|
99
|
+
multiplierIndex: 5 | 7;
|
|
100
|
+
}): Promise<bigint> {
|
|
101
|
+
const [tokenDetails, tokensOut] = await Promise.all([
|
|
102
|
+
getTokenDetails(client, provisioner, token),
|
|
103
|
+
convertUnitsToTokenIfActive(
|
|
104
|
+
client,
|
|
105
|
+
feeCalculator,
|
|
106
|
+
feeCalculatorVersion,
|
|
107
|
+
vault,
|
|
108
|
+
token,
|
|
109
|
+
unitsIn,
|
|
110
|
+
Rounding.Floor
|
|
111
|
+
),
|
|
112
|
+
]);
|
|
113
|
+
const multiplier = BigInt(tokenDetails[multiplierIndex]);
|
|
114
|
+
|
|
115
|
+
return (tokensOut * multiplier) / MAX_BPS;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function getWithdrawUnitsIn({
|
|
119
|
+
client,
|
|
120
|
+
provisioner,
|
|
121
|
+
feeCalculator,
|
|
122
|
+
feeCalculatorVersion,
|
|
123
|
+
vault,
|
|
124
|
+
token,
|
|
125
|
+
tokensOut,
|
|
126
|
+
multiplierIndex,
|
|
127
|
+
}: {
|
|
128
|
+
client: PublicClient;
|
|
129
|
+
provisioner: Address;
|
|
130
|
+
feeCalculator: Address;
|
|
131
|
+
feeCalculatorVersion: ContractVersion;
|
|
132
|
+
vault: Address;
|
|
133
|
+
token: Address;
|
|
134
|
+
tokensOut: bigint;
|
|
135
|
+
multiplierIndex: 5 | 7;
|
|
136
|
+
}): Promise<bigint> {
|
|
137
|
+
const tokenDetails = await getTokenDetails(client, provisioner, token);
|
|
138
|
+
const multiplier = BigInt(tokenDetails[multiplierIndex]);
|
|
139
|
+
const preMultiplierTokens = (tokensOut * MAX_BPS + multiplier - 1n) / multiplier;
|
|
140
|
+
|
|
141
|
+
return convertTokenToUnitsIfActive(
|
|
142
|
+
client,
|
|
143
|
+
feeCalculator,
|
|
144
|
+
feeCalculatorVersion,
|
|
145
|
+
vault,
|
|
146
|
+
token,
|
|
147
|
+
preMultiplierTokens,
|
|
148
|
+
Rounding.Ceil
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function getSyncRedeemMultiplier(
|
|
153
|
+
client: PublicClient,
|
|
154
|
+
provisioner: Address,
|
|
155
|
+
vault: Address,
|
|
156
|
+
token: Address,
|
|
157
|
+
feeCalculator: Address
|
|
158
|
+
): Promise<bigint> {
|
|
159
|
+
const [tokenDetails, syncRedeemDetails, anchorTimestamp] = await client.multicall({
|
|
160
|
+
contracts: [
|
|
161
|
+
{
|
|
162
|
+
address: provisioner,
|
|
163
|
+
abi: provisionerV2Abi,
|
|
164
|
+
functionName: 'tokensDetails',
|
|
165
|
+
args: [token],
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
address: provisioner,
|
|
169
|
+
abi: provisionerV2Abi,
|
|
170
|
+
functionName: 'getSyncRedeemDetails',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
address: feeCalculator,
|
|
174
|
+
abi: priceAndFeeCalculatorV2Abi,
|
|
175
|
+
functionName: 'getAnchorTimestamp',
|
|
176
|
+
args: [vault],
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
allowFailure: false,
|
|
180
|
+
});
|
|
181
|
+
const block = await client.getBlock();
|
|
182
|
+
const syncRedeemMultiplier = BigInt(tokenDetails[7]);
|
|
183
|
+
const maxPriceAge = BigInt(syncRedeemDetails[0]);
|
|
184
|
+
const maxDynamicPremiumBps = BigInt(syncRedeemDetails[2]);
|
|
185
|
+
const blockTimestamp = BigInt(block.timestamp);
|
|
186
|
+
const priceTimestamp = BigInt(anchorTimestamp);
|
|
187
|
+
|
|
188
|
+
if (priceTimestamp + maxPriceAge < blockTimestamp) {
|
|
189
|
+
throw new StalePriceError({
|
|
190
|
+
blockTimestamp,
|
|
191
|
+
maxPriceAge,
|
|
192
|
+
priceTimestamp,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const dynamicPremiumBps =
|
|
197
|
+
maxDynamicPremiumBps === 0n || maxPriceAge === 0n
|
|
198
|
+
? 0n
|
|
199
|
+
: ((blockTimestamp - priceTimestamp) * maxDynamicPremiumBps + maxPriceAge - 1n) / maxPriceAge;
|
|
200
|
+
|
|
201
|
+
return syncRedeemMultiplier - dynamicPremiumBps;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export async function getSyncRedeemTokenOut(
|
|
205
|
+
client: PublicClient,
|
|
206
|
+
provisioner: Address,
|
|
207
|
+
feeCalculator: Address,
|
|
208
|
+
feeCalculatorVersion: ContractVersion,
|
|
209
|
+
vault: Address,
|
|
210
|
+
token: Address,
|
|
211
|
+
unitsIn: bigint
|
|
212
|
+
): Promise<bigint> {
|
|
213
|
+
const [tokenAmount, multiplier] = await Promise.all([
|
|
214
|
+
convertUnitsToTokenIfActive(
|
|
215
|
+
client,
|
|
216
|
+
feeCalculator,
|
|
217
|
+
feeCalculatorVersion,
|
|
218
|
+
vault,
|
|
219
|
+
token,
|
|
220
|
+
unitsIn,
|
|
221
|
+
Rounding.Floor
|
|
222
|
+
),
|
|
223
|
+
getSyncRedeemMultiplier(client, provisioner, vault, token, feeCalculator),
|
|
224
|
+
]);
|
|
225
|
+
|
|
226
|
+
return (tokenAmount * multiplier) / MAX_BPS;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export async function getAsyncDepositUnitsOut(
|
|
230
|
+
client: PublicClient,
|
|
231
|
+
provisioner: Address,
|
|
232
|
+
feeCalculator: Address,
|
|
233
|
+
feeCalculatorVersion: ContractVersion,
|
|
234
|
+
vault: Address,
|
|
235
|
+
token: Address,
|
|
236
|
+
tokensIn: bigint
|
|
237
|
+
): Promise<bigint> {
|
|
238
|
+
return getDepositUnitsOut({
|
|
239
|
+
client,
|
|
240
|
+
provisioner,
|
|
241
|
+
feeCalculator,
|
|
242
|
+
feeCalculatorVersion,
|
|
243
|
+
vault,
|
|
244
|
+
token,
|
|
245
|
+
tokensIn,
|
|
246
|
+
multiplierIndex: 4,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export async function getSyncDepositUnitsOut(
|
|
251
|
+
client: PublicClient,
|
|
252
|
+
provisioner: Address,
|
|
253
|
+
feeCalculator: Address,
|
|
254
|
+
feeCalculatorVersion: ContractVersion,
|
|
255
|
+
vault: Address,
|
|
256
|
+
token: Address,
|
|
257
|
+
tokensIn: bigint
|
|
258
|
+
): Promise<bigint> {
|
|
259
|
+
return getDepositUnitsOut({
|
|
260
|
+
client,
|
|
261
|
+
provisioner,
|
|
262
|
+
feeCalculator,
|
|
263
|
+
feeCalculatorVersion,
|
|
264
|
+
vault,
|
|
265
|
+
token,
|
|
266
|
+
tokensIn,
|
|
267
|
+
multiplierIndex: 6,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export async function getAsyncRedeemTokenOut(
|
|
272
|
+
client: PublicClient,
|
|
273
|
+
provisioner: Address,
|
|
274
|
+
feeCalculator: Address,
|
|
275
|
+
feeCalculatorVersion: ContractVersion,
|
|
276
|
+
vault: Address,
|
|
277
|
+
token: Address,
|
|
278
|
+
unitsIn: bigint
|
|
279
|
+
): Promise<bigint> {
|
|
280
|
+
return getRedeemTokenOut({
|
|
281
|
+
client,
|
|
282
|
+
provisioner,
|
|
283
|
+
feeCalculator,
|
|
284
|
+
feeCalculatorVersion,
|
|
285
|
+
vault,
|
|
286
|
+
token,
|
|
287
|
+
unitsIn,
|
|
288
|
+
multiplierIndex: 5,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export async function getAsyncWithdrawUnitsIn(
|
|
293
|
+
client: PublicClient,
|
|
294
|
+
provisioner: Address,
|
|
295
|
+
feeCalculator: Address,
|
|
296
|
+
feeCalculatorVersion: ContractVersion,
|
|
297
|
+
vault: Address,
|
|
298
|
+
token: Address,
|
|
299
|
+
tokensOut: bigint
|
|
300
|
+
): Promise<bigint> {
|
|
301
|
+
return getWithdrawUnitsIn({
|
|
302
|
+
client,
|
|
303
|
+
provisioner,
|
|
304
|
+
feeCalculator,
|
|
305
|
+
feeCalculatorVersion,
|
|
306
|
+
vault,
|
|
307
|
+
token,
|
|
308
|
+
tokensOut,
|
|
309
|
+
multiplierIndex: 5,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export async function getSyncWithdrawUnitsIn(
|
|
314
|
+
client: PublicClient,
|
|
315
|
+
provisioner: Address,
|
|
316
|
+
feeCalculator: Address,
|
|
317
|
+
feeCalculatorVersion: ContractVersion,
|
|
318
|
+
vault: Address,
|
|
319
|
+
token: Address,
|
|
320
|
+
tokensOut: bigint
|
|
321
|
+
): Promise<bigint> {
|
|
322
|
+
const multiplier = await getSyncRedeemMultiplier(
|
|
323
|
+
client,
|
|
324
|
+
provisioner,
|
|
325
|
+
vault,
|
|
326
|
+
token,
|
|
327
|
+
feeCalculator
|
|
328
|
+
);
|
|
329
|
+
const prePremiumTokens = (tokensOut * MAX_BPS + multiplier - 1n) / multiplier;
|
|
330
|
+
|
|
331
|
+
return convertTokenToUnitsIfActive(
|
|
332
|
+
client,
|
|
333
|
+
feeCalculator,
|
|
334
|
+
feeCalculatorVersion,
|
|
335
|
+
vault,
|
|
336
|
+
token,
|
|
337
|
+
prePremiumTokens,
|
|
338
|
+
Rounding.Ceil
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export function depositTxRequest(
|
|
343
|
+
provisioner: Address,
|
|
344
|
+
token: Address,
|
|
345
|
+
tokensIn: bigint,
|
|
346
|
+
minUnitsOut: bigint,
|
|
347
|
+
receiver: Address,
|
|
348
|
+
account: Address
|
|
349
|
+
) {
|
|
350
|
+
return {
|
|
351
|
+
address: provisioner,
|
|
352
|
+
abi: provisionerV2Abi,
|
|
353
|
+
functionName: 'deposit' as const,
|
|
354
|
+
args: [token, tokensIn, minUnitsOut, receiver] as const,
|
|
355
|
+
account,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export function requestDepositTxRequest(
|
|
360
|
+
provisioner: Address,
|
|
361
|
+
token: Address,
|
|
362
|
+
tokensIn: bigint,
|
|
363
|
+
minUnitsOut: bigint,
|
|
364
|
+
solverTip: bigint,
|
|
365
|
+
deadline: bigint,
|
|
366
|
+
maxPriceAge: bigint,
|
|
367
|
+
isFixedPrice: boolean,
|
|
368
|
+
receiver: Address,
|
|
369
|
+
account: Address
|
|
370
|
+
) {
|
|
371
|
+
return {
|
|
372
|
+
address: provisioner,
|
|
373
|
+
abi: provisionerV2Abi,
|
|
374
|
+
functionName: 'requestDeposit' as const,
|
|
375
|
+
args: [
|
|
376
|
+
token,
|
|
377
|
+
tokensIn,
|
|
378
|
+
minUnitsOut,
|
|
379
|
+
solverTip,
|
|
380
|
+
deadline,
|
|
381
|
+
maxPriceAge,
|
|
382
|
+
isFixedPrice,
|
|
383
|
+
receiver,
|
|
384
|
+
] as const,
|
|
385
|
+
account,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export function setDepositReceiverApprovalTxRequest(
|
|
390
|
+
provisioner: Address,
|
|
391
|
+
depositor: Address,
|
|
392
|
+
approved: boolean,
|
|
393
|
+
receiver: Address
|
|
394
|
+
) {
|
|
395
|
+
return {
|
|
396
|
+
address: provisioner,
|
|
397
|
+
abi: provisionerV2Abi,
|
|
398
|
+
functionName: 'setDepositReceiverApproval' as const,
|
|
399
|
+
args: [depositor, approved] as const,
|
|
400
|
+
account: receiver,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export function requestRedeemTxRequest(
|
|
405
|
+
provisioner: Address,
|
|
406
|
+
token: Address,
|
|
407
|
+
unitsIn: bigint,
|
|
408
|
+
minTokenOut: bigint,
|
|
409
|
+
solverTip: bigint,
|
|
410
|
+
deadline: bigint,
|
|
411
|
+
maxPriceAge: bigint,
|
|
412
|
+
isFixedPrice: boolean,
|
|
413
|
+
receiver: Address,
|
|
414
|
+
account: Address
|
|
415
|
+
) {
|
|
416
|
+
return {
|
|
417
|
+
address: provisioner,
|
|
418
|
+
abi: provisionerV2Abi,
|
|
419
|
+
functionName: 'requestRedeem' as const,
|
|
420
|
+
args: [
|
|
421
|
+
token,
|
|
422
|
+
unitsIn,
|
|
423
|
+
minTokenOut,
|
|
424
|
+
solverTip,
|
|
425
|
+
deadline,
|
|
426
|
+
maxPriceAge,
|
|
427
|
+
isFixedPrice,
|
|
428
|
+
receiver,
|
|
429
|
+
] as const,
|
|
430
|
+
account,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
export function redeemTxRequest(
|
|
435
|
+
provisioner: Address,
|
|
436
|
+
token: Address,
|
|
437
|
+
unitsIn: bigint,
|
|
438
|
+
minTokenOut: bigint,
|
|
439
|
+
receiver: Address,
|
|
440
|
+
account: Address
|
|
441
|
+
) {
|
|
442
|
+
return {
|
|
443
|
+
address: provisioner,
|
|
444
|
+
abi: provisionerV2Abi,
|
|
445
|
+
functionName: 'redeem' as const,
|
|
446
|
+
args: [token, unitsIn, minTokenOut, receiver] as const,
|
|
447
|
+
account,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export function withdrawTxRequest(
|
|
452
|
+
provisioner: Address,
|
|
453
|
+
token: Address,
|
|
454
|
+
tokensOut: bigint,
|
|
455
|
+
maxUnitsIn: bigint,
|
|
456
|
+
receiver: Address,
|
|
457
|
+
account: Address
|
|
458
|
+
) {
|
|
459
|
+
return {
|
|
460
|
+
address: provisioner,
|
|
461
|
+
abi: provisionerV2Abi,
|
|
462
|
+
functionName: 'withdraw' as const,
|
|
463
|
+
args: [token, tokensOut, maxUnitsIn, receiver] as const,
|
|
464
|
+
account,
|
|
465
|
+
};
|
|
466
|
+
}
|
package/src/evm/aeraContracts.ts
CHANGED
|
@@ -1,11 +1,82 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import {
|
|
2
|
+
ContractFunctionExecutionError,
|
|
3
|
+
ContractFunctionRevertedError,
|
|
4
|
+
ContractFunctionZeroDataError,
|
|
5
|
+
type Address,
|
|
6
|
+
type Client,
|
|
7
|
+
type GetContractReturnType,
|
|
8
|
+
type PublicClient,
|
|
9
|
+
getContract,
|
|
10
|
+
zeroAddress,
|
|
11
|
+
} from 'viem';
|
|
12
|
+
import { UnimplementedFeatureError, UnsupportedFeatureError } from '../errors';
|
|
6
13
|
import { multiDepositorVaultAbi } from './abis/multiDepositorVault';
|
|
7
|
-
import { priceAndFeeCalculatorAbi } from './abis/priceAndFeeCalculator';
|
|
8
14
|
import { provisionerAbi } from './abis/provisioner';
|
|
15
|
+
import { provisionerV2Abi } from './abis/provisionerV2';
|
|
16
|
+
import { MAX_BPS } from '../constants';
|
|
17
|
+
import { ContractVersion, type EvmVaultDeployment } from './types';
|
|
18
|
+
|
|
19
|
+
const contractVersionCache = new Map<string, ContractVersion>();
|
|
20
|
+
|
|
21
|
+
const contractVersionAbi = [
|
|
22
|
+
{
|
|
23
|
+
type: 'function',
|
|
24
|
+
inputs: [],
|
|
25
|
+
name: 'version',
|
|
26
|
+
outputs: [{ name: '', internalType: 'string', type: 'string' }],
|
|
27
|
+
stateMutability: 'view',
|
|
28
|
+
},
|
|
29
|
+
] as const;
|
|
30
|
+
|
|
31
|
+
export interface AeraRuntimeContracts {
|
|
32
|
+
provisioner: {
|
|
33
|
+
address: Address;
|
|
34
|
+
version: ContractVersion;
|
|
35
|
+
};
|
|
36
|
+
feeCalculator: {
|
|
37
|
+
address: Address;
|
|
38
|
+
version: ContractVersion;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface AeraTokenModeSupport {
|
|
43
|
+
asyncDeposit: boolean;
|
|
44
|
+
asyncRedeem: boolean;
|
|
45
|
+
syncDeposit: boolean;
|
|
46
|
+
syncRedeem: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function applySlippageDown(amount: bigint, slippageBps: number): bigint {
|
|
50
|
+
return (amount * (MAX_BPS - BigInt(slippageBps))) / MAX_BPS;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function applySlippageUp(amount: bigint, slippageBps: number): bigint {
|
|
54
|
+
return (amount * (MAX_BPS + BigInt(slippageBps)) + MAX_BPS - 1n) / MAX_BPS;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function contractVersionCacheKey(client: PublicClient, address: Address): string {
|
|
58
|
+
return `${client.chain?.id ?? 'unknown'}:${address.toLowerCase()}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isVersionUnavailableError(error: unknown): boolean {
|
|
62
|
+
if (!(error instanceof ContractFunctionExecutionError) || error.functionName !== 'version') {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (error.cause instanceof ContractFunctionRevertedError) {
|
|
67
|
+
const hasDecodedError =
|
|
68
|
+
error.cause.signature !== undefined ||
|
|
69
|
+
error.cause.data !== undefined ||
|
|
70
|
+
(error.cause.raw !== undefined && error.cause.raw !== '0x');
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
!hasDecodedError &&
|
|
74
|
+
(error.cause.reason === undefined || error.cause.reason === 'execution reverted')
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return error.cause instanceof ContractFunctionZeroDataError;
|
|
79
|
+
}
|
|
9
80
|
|
|
10
81
|
export type MultiDepositorVaultContract<T extends Client> = GetContractReturnType<
|
|
11
82
|
typeof multiDepositorVaultAbi,
|
|
@@ -24,59 +95,109 @@ export function getMultiDepositorVault<T extends Client>(
|
|
|
24
95
|
});
|
|
25
96
|
}
|
|
26
97
|
|
|
27
|
-
export
|
|
28
|
-
|
|
29
|
-
T,
|
|
30
|
-
Address
|
|
31
|
-
>;
|
|
32
|
-
|
|
33
|
-
export function getPriceAndFeeCalculator<T extends Client>(
|
|
34
|
-
client: T,
|
|
98
|
+
export async function resolveContractVersion(
|
|
99
|
+
client: PublicClient,
|
|
35
100
|
address: Address
|
|
36
|
-
):
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
101
|
+
): Promise<ContractVersion> {
|
|
102
|
+
const cacheKey = contractVersionCacheKey(client, address);
|
|
103
|
+
const cached = contractVersionCache.get(cacheKey);
|
|
104
|
+
if (cached) return cached;
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const versionString = await client.readContract({
|
|
108
|
+
address,
|
|
109
|
+
abi: contractVersionAbi,
|
|
110
|
+
functionName: 'version',
|
|
111
|
+
});
|
|
112
|
+
const version = versionString.startsWith('2.') ? ContractVersion.V2 : ContractVersion.V1;
|
|
113
|
+
contractVersionCache.set(cacheKey, version);
|
|
114
|
+
|
|
115
|
+
return version;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (!isVersionUnavailableError(error)) throw error;
|
|
118
|
+
|
|
119
|
+
contractVersionCache.set(cacheKey, ContractVersion.V1);
|
|
120
|
+
return ContractVersion.V1;
|
|
121
|
+
}
|
|
42
122
|
}
|
|
43
123
|
|
|
44
|
-
export function
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
124
|
+
export async function resolveAeraRuntimeContracts(
|
|
125
|
+
client: PublicClient,
|
|
126
|
+
vault: EvmVaultDeployment
|
|
127
|
+
): Promise<AeraRuntimeContracts> {
|
|
128
|
+
if (vault.vaultType !== 'multi-depositor') {
|
|
129
|
+
throw new UnimplementedFeatureError('Aera: single depositor vaults');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const [provisionerAddress, feeCalculatorAddress] = await Promise.all([
|
|
133
|
+
client.readContract({
|
|
134
|
+
address: vault.vaultAddress,
|
|
135
|
+
abi: multiDepositorVaultAbi,
|
|
136
|
+
functionName: 'provisioner',
|
|
137
|
+
}),
|
|
138
|
+
client.readContract({
|
|
139
|
+
address: vault.vaultAddress,
|
|
140
|
+
abi: multiDepositorVaultAbi,
|
|
141
|
+
functionName: 'feeCalculator',
|
|
142
|
+
}),
|
|
143
|
+
]);
|
|
144
|
+
|
|
145
|
+
if (provisionerAddress === zeroAddress) {
|
|
146
|
+
throw new UnsupportedFeatureError('Aera: vault without provisioner');
|
|
147
|
+
}
|
|
148
|
+
if (feeCalculatorAddress === zeroAddress) {
|
|
149
|
+
throw new UnsupportedFeatureError('Aera: vault without price and fee calculator');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const [provisionerVersion, feeCalculatorVersion] = await Promise.all([
|
|
153
|
+
resolveContractVersion(client, provisionerAddress),
|
|
154
|
+
resolveContractVersion(client, feeCalculatorAddress),
|
|
155
|
+
]);
|
|
156
|
+
|
|
55
157
|
return {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
158
|
+
provisioner: {
|
|
159
|
+
address: provisionerAddress,
|
|
160
|
+
version: provisionerVersion,
|
|
161
|
+
},
|
|
162
|
+
feeCalculator: {
|
|
163
|
+
address: feeCalculatorAddress,
|
|
164
|
+
version: feeCalculatorVersion,
|
|
165
|
+
},
|
|
61
166
|
};
|
|
62
167
|
}
|
|
63
168
|
|
|
64
|
-
export function
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
169
|
+
export async function resolveAeraTokenModeSupport(
|
|
170
|
+
client: PublicClient,
|
|
171
|
+
runtime: AeraRuntimeContracts,
|
|
172
|
+
token: Address
|
|
173
|
+
): Promise<AeraTokenModeSupport> {
|
|
174
|
+
if (runtime.provisioner.version === ContractVersion.V2) {
|
|
175
|
+
const tokenDetails = await client.readContract({
|
|
176
|
+
address: runtime.provisioner.address,
|
|
177
|
+
abi: provisionerV2Abi,
|
|
178
|
+
functionName: 'tokensDetails',
|
|
179
|
+
args: [token],
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
asyncDeposit: Boolean(tokenDetails[0]),
|
|
184
|
+
asyncRedeem: Boolean(tokenDetails[1]),
|
|
185
|
+
syncDeposit: Boolean(tokenDetails[2]),
|
|
186
|
+
syncRedeem: Boolean(tokenDetails[3]),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const tokenDetails = await client.readContract({
|
|
191
|
+
address: runtime.provisioner.address,
|
|
77
192
|
abi: provisionerAbi,
|
|
78
|
-
functionName: '
|
|
79
|
-
args: [token
|
|
80
|
-
|
|
193
|
+
functionName: 'tokensDetails',
|
|
194
|
+
args: [token],
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
asyncDeposit: Boolean(tokenDetails[0]),
|
|
199
|
+
asyncRedeem: Boolean(tokenDetails[1]),
|
|
200
|
+
syncDeposit: false,
|
|
201
|
+
syncRedeem: false,
|
|
81
202
|
};
|
|
82
203
|
}
|