@steerprotocol/sdk 1.19.15 → 1.19.16
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/README.md +281 -11
- package/dist/cjs/base/VaultClient.js +95 -1
- package/dist/cjs/base/VaultClient.js.map +1 -1
- package/dist/cjs/base/vault/single-asset/calculateLimitPrice.js +231 -0
- package/dist/cjs/base/vault/single-asset/calculateLimitPrice.js.map +1 -0
- package/dist/cjs/base/vault/single-asset/calculateSwapAmount.js +68 -0
- package/dist/cjs/base/vault/single-asset/calculateSwapAmount.js.map +1 -0
- package/dist/cjs/base/vault/single-asset/estimateLpTokens.js +355 -0
- package/dist/cjs/base/vault/single-asset/estimateLpTokens.js.map +1 -0
- package/dist/cjs/base/vault/single-asset/index.js +109 -0
- package/dist/cjs/base/vault/single-asset/index.js.map +1 -0
- package/dist/cjs/base/vault/single-asset/simulateSwap.js +291 -0
- package/dist/cjs/base/vault/single-asset/simulateSwap.js.map +1 -0
- package/dist/cjs/base/vault/single-asset/singleAssetDeposit.js +324 -0
- package/dist/cjs/base/vault/single-asset/singleAssetDeposit.js.map +1 -0
- package/dist/cjs/base/vault/single-asset/types.js +15 -0
- package/dist/cjs/base/vault/single-asset/types.js.map +1 -0
- package/dist/cjs/base/vault/utils.js +229 -18
- package/dist/cjs/base/vault/utils.js.map +1 -1
- package/dist/cjs/const/abis/index.js +3 -0
- package/dist/cjs/const/abis/index.js.map +1 -1
- package/dist/cjs/const/abis/quoter.js +248 -0
- package/dist/cjs/const/abis/quoter.js.map +1 -0
- package/dist/cjs/const/abis/singleTokenDeposit.js +925 -0
- package/dist/cjs/const/abis/singleTokenDeposit.js.map +1 -0
- package/dist/cjs/const/amm/configs/protocols/uniswap.js +15 -0
- package/dist/cjs/const/amm/configs/protocols/uniswap.js.map +1 -1
- package/dist/cjs/const/deployments/abis.js +277 -0
- package/dist/cjs/const/deployments/abis.js.map +1 -1
- package/dist/cjs/const/deployments/polygon.js +8 -0
- package/dist/cjs/const/deployments/polygon.js.map +1 -1
- package/dist/cjs/const/index.js +6 -5
- package/dist/cjs/const/index.js.map +1 -1
- package/dist/cjs/const/network.js.map +1 -1
- package/dist/cjs/const/quoter.js +38 -0
- package/dist/cjs/const/quoter.js.map +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/base/VaultClient.js +81 -1
- package/dist/esm/base/VaultClient.js.map +1 -1
- package/dist/esm/base/vault/single-asset/calculateLimitPrice.js +224 -0
- package/dist/esm/base/vault/single-asset/calculateLimitPrice.js.map +1 -0
- package/dist/esm/base/vault/single-asset/calculateSwapAmount.js +65 -0
- package/dist/esm/base/vault/single-asset/calculateSwapAmount.js.map +1 -0
- package/dist/esm/base/vault/single-asset/estimateLpTokens.js +350 -0
- package/dist/esm/base/vault/single-asset/estimateLpTokens.js.map +1 -0
- package/dist/esm/base/vault/single-asset/index.js +83 -0
- package/dist/esm/base/vault/single-asset/index.js.map +1 -0
- package/dist/esm/base/vault/single-asset/simulateSwap.js +285 -0
- package/dist/esm/base/vault/single-asset/simulateSwap.js.map +1 -0
- package/dist/esm/base/vault/single-asset/singleAssetDeposit.js +320 -0
- package/dist/esm/base/vault/single-asset/singleAssetDeposit.js.map +1 -0
- package/dist/esm/base/vault/single-asset/types.js +12 -0
- package/dist/esm/base/vault/single-asset/types.js.map +1 -0
- package/dist/esm/base/vault/utils.js +226 -18
- package/dist/esm/base/vault/utils.js.map +1 -1
- package/dist/esm/const/abis/index.js +3 -0
- package/dist/esm/const/abis/index.js.map +1 -1
- package/dist/esm/const/abis/quoter.js +245 -0
- package/dist/esm/const/abis/quoter.js.map +1 -0
- package/dist/esm/const/abis/singleTokenDeposit.js +922 -0
- package/dist/esm/const/abis/singleTokenDeposit.js.map +1 -0
- package/dist/esm/const/amm/configs/protocols/uniswap.js +15 -0
- package/dist/esm/const/amm/configs/protocols/uniswap.js.map +1 -1
- package/dist/esm/const/deployments/abis.js +277 -0
- package/dist/esm/const/deployments/abis.js.map +1 -1
- package/dist/esm/const/deployments/polygon.js +8 -0
- package/dist/esm/const/deployments/polygon.js.map +1 -1
- package/dist/esm/const/index.js +6 -5
- package/dist/esm/const/index.js.map +1 -1
- package/dist/esm/const/network.js.map +1 -1
- package/dist/esm/const/quoter.js +34 -0
- package/dist/esm/const/quoter.js.map +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/types/base/VaultClient.d.ts +136 -4
- package/dist/types/base/VaultClient.d.ts.map +1 -1
- package/dist/types/base/vault/single-asset/calculateLimitPrice.d.ts +59 -0
- package/dist/types/base/vault/single-asset/calculateLimitPrice.d.ts.map +1 -0
- package/dist/types/base/vault/single-asset/calculateSwapAmount.d.ts +30 -0
- package/dist/types/base/vault/single-asset/calculateSwapAmount.d.ts.map +1 -0
- package/dist/types/base/vault/single-asset/estimateLpTokens.d.ts +61 -0
- package/dist/types/base/vault/single-asset/estimateLpTokens.d.ts.map +1 -0
- package/dist/types/base/vault/single-asset/index.d.ts +80 -0
- package/dist/types/base/vault/single-asset/index.d.ts.map +1 -0
- package/dist/types/base/vault/single-asset/simulateSwap.d.ts +119 -0
- package/dist/types/base/vault/single-asset/simulateSwap.d.ts.map +1 -0
- package/dist/types/base/vault/single-asset/singleAssetDeposit.d.ts +141 -0
- package/dist/types/base/vault/single-asset/singleAssetDeposit.d.ts.map +1 -0
- package/dist/types/base/vault/single-asset/types.d.ts +167 -0
- package/dist/types/base/vault/single-asset/types.d.ts.map +1 -0
- package/dist/types/base/vault/utils.d.ts +95 -0
- package/dist/types/base/vault/utils.d.ts.map +1 -1
- package/dist/types/const/abis/index.d.ts +3 -0
- package/dist/types/const/abis/index.d.ts.map +1 -1
- package/dist/types/const/abis/quoter.d.ts +206 -0
- package/dist/types/const/abis/quoter.d.ts.map +1 -0
- package/dist/types/const/abis/singleTokenDeposit.d.ts +47 -0
- package/dist/types/const/abis/singleTokenDeposit.d.ts.map +1 -0
- package/dist/types/const/amm/configs/protocols/uniswap.d.ts.map +1 -1
- package/dist/types/const/deployments/abis.d.ts +215 -0
- package/dist/types/const/deployments/abis.d.ts.map +1 -1
- package/dist/types/const/deployments/polygon.d.ts.map +1 -1
- package/dist/types/const/index.d.ts +6 -5
- package/dist/types/const/index.d.ts.map +1 -1
- package/dist/types/const/network.d.ts +2 -0
- package/dist/types/const/network.d.ts.map +1 -1
- package/dist/types/const/quoter.d.ts +17 -0
- package/dist/types/const/quoter.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.d.ts +3 -0
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bigintToDecimal = bigintToDecimal;
|
|
4
|
+
exports.decimalToBigint = decimalToBigint;
|
|
5
|
+
exports.getQuoteFromSqrtRatioX96 = getQuoteFromSqrtRatioX96;
|
|
6
|
+
exports.calculateLimitPrice = calculateLimitPrice;
|
|
7
|
+
exports.getPoolSlot0 = getPoolSlot0;
|
|
8
|
+
const decimal_js_1 = require("decimal.js");
|
|
9
|
+
const erc20_1 = require("../../../const/abis/erc20");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
11
|
+
const types_1 = require("./types");
|
|
12
|
+
/**
|
|
13
|
+
* Configure Decimal.js for high precision calculations
|
|
14
|
+
*/
|
|
15
|
+
decimal_js_1.Decimal.config({
|
|
16
|
+
precision: 50, // High precision for financial calculations
|
|
17
|
+
rounding: decimal_js_1.Decimal.ROUND_DOWN // Conservative rounding for safety
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Constants matching the Solidity contract using Decimal.js
|
|
21
|
+
*/
|
|
22
|
+
const BASIS_POINTS = new decimal_js_1.Decimal(10000);
|
|
23
|
+
const Q96 = new decimal_js_1.Decimal(2).pow(96);
|
|
24
|
+
const Q192 = Q96.mul(Q96);
|
|
25
|
+
const Q128 = new decimal_js_1.Decimal(2).pow(128);
|
|
26
|
+
const Q64 = new decimal_js_1.Decimal(2).pow(64);
|
|
27
|
+
const UINT128_MAX = new decimal_js_1.Decimal(2).pow(128).sub(1);
|
|
28
|
+
/**
|
|
29
|
+
* High-precision multiplication and division using Decimal.js
|
|
30
|
+
* Equivalent to Solidity's FullMath.mulDiv
|
|
31
|
+
*/
|
|
32
|
+
function mulDiv(a, b, denominator) {
|
|
33
|
+
return a.mul(b).div(denominator);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* High-precision square root using Decimal.js
|
|
37
|
+
*/
|
|
38
|
+
function sqrt(value) {
|
|
39
|
+
if (value.isZero())
|
|
40
|
+
return new decimal_js_1.Decimal(0);
|
|
41
|
+
return value.sqrt();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Convert BigInt to Decimal for calculations
|
|
45
|
+
*/
|
|
46
|
+
function bigintToDecimal(value) {
|
|
47
|
+
return new decimal_js_1.Decimal(value.toString());
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Convert Decimal back to BigInt for return values
|
|
51
|
+
* Uses toFixed(0) to get full decimal representation without scientific notation
|
|
52
|
+
*/
|
|
53
|
+
function decimalToBigint(value) {
|
|
54
|
+
// Use toFixed(0) to get full integer representation without scientific notation
|
|
55
|
+
const stringValue = value.floor().toFixed(0);
|
|
56
|
+
return BigInt(stringValue);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get quote from sqrtRatioX96 using high-precision Decimal arithmetic
|
|
60
|
+
* Equivalent to Solidity's getQuoteFromSqrtRatioX96
|
|
61
|
+
* @param sqrtRatioX96 The sqrt ratio for which to compute the quote
|
|
62
|
+
* @param baseAmount Amount of base token
|
|
63
|
+
* @param baseToken Address of base token
|
|
64
|
+
* @param quoteToken Address of quote token
|
|
65
|
+
* @returns The quote amount as Decimal
|
|
66
|
+
*/
|
|
67
|
+
function getQuoteFromSqrtRatioX96(sqrtRatioX96, baseAmount, baseToken, quoteToken) {
|
|
68
|
+
// Calculate quoteAmount with better precision if it doesn't overflow when multiplied by itself
|
|
69
|
+
if (sqrtRatioX96.lte(UINT128_MAX)) {
|
|
70
|
+
const ratioX192 = sqrtRatioX96.mul(sqrtRatioX96);
|
|
71
|
+
return baseToken < quoteToken
|
|
72
|
+
? mulDiv(ratioX192, baseAmount, Q192)
|
|
73
|
+
: mulDiv(Q192, baseAmount, ratioX192);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const ratioX128 = mulDiv(sqrtRatioX96, sqrtRatioX96, Q64);
|
|
77
|
+
return baseToken < quoteToken
|
|
78
|
+
? mulDiv(ratioX128, baseAmount, Q128)
|
|
79
|
+
: mulDiv(Q128, baseAmount, ratioX128);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Applies slippage protection to sqrtPriceX96 based on swap direction using high-precision arithmetic
|
|
84
|
+
* Equivalent to Solidity's applySlippageProtection function
|
|
85
|
+
* @param sqrtPriceX96 The current square root price
|
|
86
|
+
* @param slippageBP Slippage protection in basis points (e.g., 300 = 3%)
|
|
87
|
+
* @param zeroForOne True if swapping token0 for token1
|
|
88
|
+
* @param token0 Address of token0
|
|
89
|
+
* @param token1 Address of token1
|
|
90
|
+
* @param publicClient Viem public client for reading token decimals
|
|
91
|
+
* @returns The price limit with slippage protection as Decimal
|
|
92
|
+
*/
|
|
93
|
+
async function applySlippageProtection(sqrtPriceX96, slippageBP, zeroForOne, token0, token1, publicClient) {
|
|
94
|
+
// Get current price: how much token1 per 1 unit of token0
|
|
95
|
+
const decimals0 = await publicClient.readContract({
|
|
96
|
+
address: token0,
|
|
97
|
+
abi: erc20_1.erc20Abi,
|
|
98
|
+
functionName: 'decimals'
|
|
99
|
+
});
|
|
100
|
+
const baseAmount = new decimal_js_1.Decimal(10).pow(decimals0);
|
|
101
|
+
const currentQuote = getQuoteFromSqrtRatioX96(sqrtPriceX96, baseAmount, token0, token1);
|
|
102
|
+
let adjustedQuote;
|
|
103
|
+
if (zeroForOne) {
|
|
104
|
+
// Swapping token0 for token1
|
|
105
|
+
// We want to ensure we don't get less than expected token1
|
|
106
|
+
// So we set a minimum acceptable rate (decrease the quote)
|
|
107
|
+
adjustedQuote = mulDiv(currentQuote, BASIS_POINTS.sub(slippageBP), BASIS_POINTS);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// Swapping token1 for token0
|
|
111
|
+
// We want to ensure we don't pay more than expected token1
|
|
112
|
+
// So we set a maximum acceptable rate (increase the quote)
|
|
113
|
+
adjustedQuote = mulDiv(currentQuote, BASIS_POINTS.add(slippageBP), BASIS_POINTS);
|
|
114
|
+
}
|
|
115
|
+
if (adjustedQuote.isZero()) {
|
|
116
|
+
throw new Error('AdjustedQuoteCalculationFailed');
|
|
117
|
+
}
|
|
118
|
+
// Convert adjusted quote back to sqrtPriceX96
|
|
119
|
+
// This is the reverse of getQuoteFromSqrtRatioX96
|
|
120
|
+
let adjustedRatioX192;
|
|
121
|
+
if (token0 < token1) {
|
|
122
|
+
// ratioX192 = (adjustedQuote * 2^192) / baseAmount
|
|
123
|
+
adjustedRatioX192 = mulDiv(adjustedQuote, Q192, baseAmount);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// ratioX192 = (baseAmount * 2^192) / adjustedQuote
|
|
127
|
+
adjustedRatioX192 = mulDiv(baseAmount, Q192, adjustedQuote);
|
|
128
|
+
}
|
|
129
|
+
return sqrt(adjustedRatioX192);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Calculates the sqrt price limit for slippage protection during swaps using high-precision arithmetic
|
|
133
|
+
*
|
|
134
|
+
* @param publicClient - Viem public client for blockchain reads
|
|
135
|
+
* @param params - Parameters for limit price calculation
|
|
136
|
+
* @returns Promise resolving to the calculated sqrt price limit
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* const result = await calculateLimitPrice(publicClient, {
|
|
141
|
+
* pool: '0x...',
|
|
142
|
+
* slippageBP: 500, // 5% slippage
|
|
143
|
+
* zeroForOne: true,
|
|
144
|
+
* ammType: AMMType.UniswapV3,
|
|
145
|
+
* token0: '0x...',
|
|
146
|
+
* token1: '0x...'
|
|
147
|
+
* });
|
|
148
|
+
*
|
|
149
|
+
* if (result.success) {
|
|
150
|
+
* console.log('Sqrt price limit:', result.data);
|
|
151
|
+
* }
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
async function calculateLimitPrice(publicClient, params) {
|
|
155
|
+
try {
|
|
156
|
+
// Get current pool state from slot0
|
|
157
|
+
const slot0Data = await (0, utils_1.getPoolState)(publicClient, {
|
|
158
|
+
poolAddress: params.pool,
|
|
159
|
+
isAlgebraPool: params.ammType === types_1.AMMType.Algebra,
|
|
160
|
+
isAlgebraIntegralPool: params.ammType === types_1.AMMType.AlgebraIntegral,
|
|
161
|
+
isAlgebraDirectionPool: params.ammType === types_1.AMMType.AlgebraDirectional,
|
|
162
|
+
isPoolSharkPool: false // PoolShark not defined in AMMType enum
|
|
163
|
+
});
|
|
164
|
+
if (!slot0Data.success || !slot0Data.data) {
|
|
165
|
+
throw new Error(slot0Data.error || 'Failed to get pool state');
|
|
166
|
+
}
|
|
167
|
+
const sqrtPriceX96BigInt = (0, utils_1.getPoolPrice)(slot0Data.data, {
|
|
168
|
+
isAlgebraPool: params.ammType === types_1.AMMType.Algebra,
|
|
169
|
+
isAlgebraIntegralPool: params.ammType === types_1.AMMType.AlgebraIntegral,
|
|
170
|
+
isPoolSharkPool: false // PoolShark not defined in AMMType enum
|
|
171
|
+
});
|
|
172
|
+
if (!sqrtPriceX96BigInt) {
|
|
173
|
+
throw new Error('Failed to extract pool price');
|
|
174
|
+
}
|
|
175
|
+
// Convert to Decimal for high-precision calculations
|
|
176
|
+
const sqrtPriceX96 = bigintToDecimal(sqrtPriceX96BigInt);
|
|
177
|
+
const slippageBP = new decimal_js_1.Decimal(params.slippageBP);
|
|
178
|
+
// Apply slippage protection using high-precision arithmetic
|
|
179
|
+
const limitSqrtPriceX96Decimal = await applySlippageProtection(sqrtPriceX96, slippageBP, params.zeroForOne, params.token0, params.token1, publicClient);
|
|
180
|
+
return {
|
|
181
|
+
data: decimalToBigint(limitSqrtPriceX96Decimal),
|
|
182
|
+
status: 200,
|
|
183
|
+
success: true
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
return {
|
|
188
|
+
data: null,
|
|
189
|
+
status: 500,
|
|
190
|
+
success: false,
|
|
191
|
+
error: error instanceof Error ? error.message : 'Failed to calculate limit price'
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Gets the current pool state from slot0
|
|
197
|
+
* Currently supports UniswapV3 only
|
|
198
|
+
*
|
|
199
|
+
* @param publicClient - Viem public client for blockchain reads
|
|
200
|
+
* @param poolAddress - Address of the pool
|
|
201
|
+
* @param ammType - Type of AMM
|
|
202
|
+
* @returns Promise resolving to the pool slot0 data
|
|
203
|
+
*/
|
|
204
|
+
async function getPoolSlot0(publicClient, poolAddress, ammType) {
|
|
205
|
+
try {
|
|
206
|
+
const poolState = await (0, utils_1.getPoolStateWithPrice)(publicClient, {
|
|
207
|
+
poolAddress,
|
|
208
|
+
isAlgebraPool: ammType === types_1.AMMType.Algebra,
|
|
209
|
+
isAlgebraIntegralPool: ammType === types_1.AMMType.AlgebraIntegral,
|
|
210
|
+
isAlgebraDirectionPool: ammType === types_1.AMMType.AlgebraDirectional,
|
|
211
|
+
isPoolSharkPool: false // PoolShark not defined in AMMType enum
|
|
212
|
+
});
|
|
213
|
+
if (!poolState.success || !poolState.data) {
|
|
214
|
+
throw new Error(poolState.error || 'Failed to get pool state');
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
data: poolState.data.state,
|
|
218
|
+
status: 200,
|
|
219
|
+
success: true
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
return {
|
|
224
|
+
data: null,
|
|
225
|
+
status: 500,
|
|
226
|
+
success: false,
|
|
227
|
+
error: error instanceof Error ? error.message : 'Failed to get pool slot0 data'
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=calculateLimitPrice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculateLimitPrice.js","sourceRoot":"","sources":["../../../../../src/base/vault/single-asset/calculateLimitPrice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateSwapAmount = calculateSwapAmount;
|
|
4
|
+
const singleTokenDeposit_1 = require("../../../const/abis/singleTokenDeposit");
|
|
5
|
+
const const_1 = require("../../../const");
|
|
6
|
+
/**
|
|
7
|
+
* Calculates the amount that needs to be swapped for a single-asset deposit
|
|
8
|
+
* This function calls the smart contract's calculateSwapAmount function
|
|
9
|
+
*
|
|
10
|
+
* @param publicClient - Viem public client for blockchain reads
|
|
11
|
+
* @param params - Parameters for swap amount calculation
|
|
12
|
+
* @returns Promise resolving to swap amount and current sqrt price
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const result = await calculateSwapAmount(publicClient, {
|
|
17
|
+
* depositAmount: parseEther('100'),
|
|
18
|
+
* isToken0: true,
|
|
19
|
+
* vault: '0x...',
|
|
20
|
+
* pool: '0x...',
|
|
21
|
+
* ammType: AMMType.UniswapV3,
|
|
22
|
+
* singleAssetDepositContract: '0x...'
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* if (result.success) {
|
|
26
|
+
* console.log('Swap amount:', result.data.swapAmount);
|
|
27
|
+
* console.log('Current sqrt price:', result.data.sqrtPrice);
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
async function calculateSwapAmount(publicClient, params) {
|
|
32
|
+
try {
|
|
33
|
+
// Call the smart contract's calculateSwapAmount function
|
|
34
|
+
const chainId = await publicClient.getChainId();
|
|
35
|
+
const singleAssentDeposit = params.singleAssetDepositContract || (0, const_1.getContractAddressByChainIdAndContractName)(chainId, 'SingleAssetDeposit');
|
|
36
|
+
const result = await publicClient.readContract({
|
|
37
|
+
address: singleAssentDeposit,
|
|
38
|
+
abi: singleTokenDeposit_1.singleTokenDepositAbi,
|
|
39
|
+
functionName: 'calculateSwapAmount',
|
|
40
|
+
args: [
|
|
41
|
+
params.depositAmount,
|
|
42
|
+
params.isToken0,
|
|
43
|
+
params.vault,
|
|
44
|
+
params.pool,
|
|
45
|
+
params.ammType
|
|
46
|
+
]
|
|
47
|
+
});
|
|
48
|
+
// The contract returns [swapAmount, sqrtPrice]
|
|
49
|
+
const [swapAmount, sqrtPrice] = result;
|
|
50
|
+
return {
|
|
51
|
+
data: {
|
|
52
|
+
swapAmount,
|
|
53
|
+
sqrtPrice
|
|
54
|
+
},
|
|
55
|
+
status: 200,
|
|
56
|
+
success: true
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
return {
|
|
61
|
+
data: null,
|
|
62
|
+
status: 500,
|
|
63
|
+
success: false,
|
|
64
|
+
error: error instanceof Error ? error.message : 'Failed to calculate swap amount'
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=calculateSwapAmount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculateSwapAmount.js","sourceRoot":"","sources":["../../../../../src/base/vault/single-asset/calculateSwapAmount.ts"],"names":[],"mappings":";;AA+BA,kDA0CC;AAxED,+EAA+E;AAG/E,0CAA4E;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACI,KAAK,UAAU,mBAAmB,CACvC,YAA0B,EAC1B,MAAiC;IAEjC,IAAI,CAAC;QACH,yDAAyD;QAEzD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,UAAU,EAAE,CAAC;QAChD,MAAM,mBAAmB,GAAG,MAAM,CAAC,0BAA0B,IAAI,IAAA,kDAA0C,EAAC,OAAO,EAAE,oBAAoB,CAAC,CAAA;QAE1I,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC;YAC7C,OAAO,EAAE,mBAAmB;YAC5B,GAAG,EAAE,0CAAqB;YAC1B,YAAY,EAAE,qBAAqB;YACnC,IAAI,EAAE;gBACJ,MAAM,CAAC,aAAa;gBACpB,MAAM,CAAC,QAAQ;gBACf,MAAM,CAAC,KAAK;gBACZ,MAAM,CAAC,IAAI;gBACX,MAAM,CAAC,OAAO;aACf;SACF,CAAC,CAAC;QAEH,+CAA+C;QAC/C,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,GAAG,MAA0B,CAAC;QAE3D,OAAO;YACL,IAAI,EAAE;gBACJ,UAAU;gBACV,SAAS;aACV;YACD,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC;SAClF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.estimateLpTokens = estimateLpTokens;
|
|
4
|
+
exports.getShares = getShares;
|
|
5
|
+
exports.getVaultReserves = getVaultReserves;
|
|
6
|
+
const abis_1 = require("../../../const/deployments/abis");
|
|
7
|
+
const network_1 = require("../../../const/network");
|
|
8
|
+
// Use the vault ABI for reading vault state
|
|
9
|
+
const VAULT_ABI = abis_1.abis.QuickSwapUniv3MultiPositionLiquidityManager;
|
|
10
|
+
/**
|
|
11
|
+
* Estimates the amount of LP tokens that will be received based on the final token amounts
|
|
12
|
+
* This calculation follows the Solidity getShares implementation from the vault contract
|
|
13
|
+
*
|
|
14
|
+
* @param publicClient - Viem public client for blockchain reads
|
|
15
|
+
* @param params - Parameters for LP token estimation
|
|
16
|
+
* @returns Promise resolving to the estimated LP tokens and final amounts
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const result = await estimateLpTokens(publicClient, {
|
|
21
|
+
* vault: '0x...',
|
|
22
|
+
* originalAssets: parseEther('100'),
|
|
23
|
+
* swapAmount: parseEther('50'),
|
|
24
|
+
* swapResult: { amount0: -parseEther('50'), amount1: parseEther('150') },
|
|
25
|
+
* isToken0: true
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* if (result.success) {
|
|
29
|
+
* console.log('Estimated LP tokens:', result.data.lpTokens);
|
|
30
|
+
* console.log('Final amount0:', result.data.finalAmount0);
|
|
31
|
+
* console.log('Final amount1:', result.data.finalAmount1);
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
async function estimateLpTokens(publicClient, params) {
|
|
36
|
+
try {
|
|
37
|
+
// Calculate final amounts based on original deposit and swap results
|
|
38
|
+
const finalAmount0 = params.isToken0
|
|
39
|
+
? params.originalAssets - params.swapAmount + (params.swapResult.amount0 < 0n ? -params.swapResult.amount0 : params.swapResult.amount0)
|
|
40
|
+
: (params.swapResult.amount0 < 0n ? -params.swapResult.amount0 : params.swapResult.amount0);
|
|
41
|
+
const finalAmount1 = params.isToken0
|
|
42
|
+
? (params.swapResult.amount1 < 0n ? -params.swapResult.amount1 : params.swapResult.amount1)
|
|
43
|
+
: params.originalAssets - params.swapAmount + (params.swapResult.amount1 < 0n ? -params.swapResult.amount1 : params.swapResult.amount1);
|
|
44
|
+
// Get vault reserves and total supply
|
|
45
|
+
const [totalSupply, tokenBalances] = await Promise.all([
|
|
46
|
+
publicClient.readContract({
|
|
47
|
+
address: params.vault,
|
|
48
|
+
abi: [{
|
|
49
|
+
"inputs": [],
|
|
50
|
+
"name": "totalSupply",
|
|
51
|
+
"outputs": [
|
|
52
|
+
{
|
|
53
|
+
"internalType": "uint256",
|
|
54
|
+
"name": "",
|
|
55
|
+
"type": "uint256"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"stateMutability": "view",
|
|
59
|
+
"type": "function"
|
|
60
|
+
},],
|
|
61
|
+
functionName: 'totalSupply'
|
|
62
|
+
}),
|
|
63
|
+
// Get token0 address first, then balance
|
|
64
|
+
publicClient.readContract({
|
|
65
|
+
address: params.vault,
|
|
66
|
+
abi: [{
|
|
67
|
+
"inputs": [],
|
|
68
|
+
"name": "getTotalAmounts",
|
|
69
|
+
"outputs": [
|
|
70
|
+
{
|
|
71
|
+
"internalType": "uint256",
|
|
72
|
+
"name": "total0",
|
|
73
|
+
"type": "uint256"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"internalType": "uint256",
|
|
77
|
+
"name": "total1",
|
|
78
|
+
"type": "uint256"
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"stateMutability": "view",
|
|
82
|
+
"type": "function"
|
|
83
|
+
},],
|
|
84
|
+
functionName: 'getTotalAmounts'
|
|
85
|
+
})
|
|
86
|
+
]);
|
|
87
|
+
const chainId = await publicClient.getChainId();
|
|
88
|
+
const helper = (0, network_1.getContractAddressByChainIdAndContractName)(chainId, 'Helper');
|
|
89
|
+
const [shares, amount0Used, amount1Used] = await publicClient.readContract({
|
|
90
|
+
address: helper,
|
|
91
|
+
abi: [{
|
|
92
|
+
"inputs": [
|
|
93
|
+
{
|
|
94
|
+
"internalType": "uint256",
|
|
95
|
+
"name": "_totalSupply",
|
|
96
|
+
"type": "uint256"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"internalType": "uint256",
|
|
100
|
+
"name": "total0",
|
|
101
|
+
"type": "uint256"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"internalType": "uint256",
|
|
105
|
+
"name": "total1",
|
|
106
|
+
"type": "uint256"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"internalType": "uint256",
|
|
110
|
+
"name": "amount0Desired",
|
|
111
|
+
"type": "uint256"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"internalType": "uint256",
|
|
115
|
+
"name": "amount1Desired",
|
|
116
|
+
"type": "uint256"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"internalType": "uint256",
|
|
120
|
+
"name": "amount0Min",
|
|
121
|
+
"type": "uint256"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"internalType": "uint256",
|
|
125
|
+
"name": "amount1Min",
|
|
126
|
+
"type": "uint256"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"internalType": "uint256",
|
|
130
|
+
"name": "minShares",
|
|
131
|
+
"type": "uint256"
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
"name": "getShares",
|
|
135
|
+
"outputs": [
|
|
136
|
+
{
|
|
137
|
+
"internalType": "uint256",
|
|
138
|
+
"name": "shares",
|
|
139
|
+
"type": "uint256"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"internalType": "uint256",
|
|
143
|
+
"name": "amount0Used",
|
|
144
|
+
"type": "uint256"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"internalType": "uint256",
|
|
148
|
+
"name": "amount1Used",
|
|
149
|
+
"type": "uint256"
|
|
150
|
+
}
|
|
151
|
+
],
|
|
152
|
+
"stateMutability": "pure",
|
|
153
|
+
"type": "function"
|
|
154
|
+
}],
|
|
155
|
+
functionName: 'getShares',
|
|
156
|
+
args: [
|
|
157
|
+
totalSupply,
|
|
158
|
+
tokenBalances[0],
|
|
159
|
+
tokenBalances[1],
|
|
160
|
+
finalAmount0,
|
|
161
|
+
finalAmount1,
|
|
162
|
+
0n, // amount0Min = 0 as requested
|
|
163
|
+
0n, // amount1Min = 0 as requested
|
|
164
|
+
0n // minShares = 0
|
|
165
|
+
]
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
data: {
|
|
169
|
+
lpTokens: shares,
|
|
170
|
+
finalAmount0: amount0Used,
|
|
171
|
+
finalAmount1: amount1Used
|
|
172
|
+
},
|
|
173
|
+
status: 200,
|
|
174
|
+
success: true
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
return {
|
|
179
|
+
data: null,
|
|
180
|
+
status: 500,
|
|
181
|
+
success: false,
|
|
182
|
+
error: error instanceof Error ? error.message : 'Failed to estimate LP tokens'
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Calculates shares (LP tokens) based on deposit amounts and vault reserves
|
|
188
|
+
* This is a TypeScript implementation of the Solidity getShares function
|
|
189
|
+
*
|
|
190
|
+
* @param totalSupply - Current total supply of LP tokens
|
|
191
|
+
* @param total0 - Current balance of token0 in vault
|
|
192
|
+
* @param total1 - Current balance of token1 in vault
|
|
193
|
+
* @param amount0Desired - Desired amount of token0 to deposit
|
|
194
|
+
* @param amount1Desired - Desired amount of token1 to deposit
|
|
195
|
+
* @param amount0Min - Minimum amount of token0 (set to 0n)
|
|
196
|
+
* @param amount1Min - Minimum amount of token1 (set to 0n)
|
|
197
|
+
* @param minShares - Minimum shares required (set to 0n)
|
|
198
|
+
* @returns Object with shares, amount0Used, and amount1Used
|
|
199
|
+
*/
|
|
200
|
+
function getShares(totalSupply, total0, total1, amount0Desired, amount1Desired, amount0Min, amount1Min, minShares) {
|
|
201
|
+
// If total supply > 0, vault can't be empty.
|
|
202
|
+
if (!(totalSupply === 0n || total0 > 0n || total1 > 0n)) {
|
|
203
|
+
throw new Error('Invalid vault state');
|
|
204
|
+
}
|
|
205
|
+
let shares;
|
|
206
|
+
let amount0Used = 0n;
|
|
207
|
+
let amount1Used = 0n;
|
|
208
|
+
if (totalSupply === 0n) {
|
|
209
|
+
// For first deposit, just use the amounts desired
|
|
210
|
+
amount0Used = amount0Desired;
|
|
211
|
+
amount1Used = amount1Desired;
|
|
212
|
+
shares = amount0Used > amount1Used ? amount0Used : amount1Used;
|
|
213
|
+
if (shares < minShares) {
|
|
214
|
+
throw new Error('Insufficient shares for minimum requirement');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else if (total0 === 0n) {
|
|
218
|
+
// Vault only has token1
|
|
219
|
+
shares = mulDiv(amount1Desired, totalSupply, total1);
|
|
220
|
+
amount1Used = mulDivRoundingUp(shares, total1, totalSupply);
|
|
221
|
+
amount0Used = 0n;
|
|
222
|
+
}
|
|
223
|
+
else if (total1 === 0n) {
|
|
224
|
+
// Vault only has token0
|
|
225
|
+
shares = mulDiv(amount0Desired, totalSupply, total0);
|
|
226
|
+
amount0Used = mulDivRoundingUp(shares, total0, totalSupply);
|
|
227
|
+
amount1Used = 0n;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
// Both tokens present - calculate cross product
|
|
231
|
+
const cross = min(amount0Desired * total1, amount1Desired * total0);
|
|
232
|
+
if (cross === 0n) {
|
|
233
|
+
throw new Error('Invalid deposit ratio - cross product is zero');
|
|
234
|
+
}
|
|
235
|
+
// Round up amounts
|
|
236
|
+
amount0Used = ((cross - 1n) / total1) + 1n;
|
|
237
|
+
amount1Used = ((cross - 1n) / total0) + 1n;
|
|
238
|
+
shares = mulDiv(cross, totalSupply, total0) / total1;
|
|
239
|
+
}
|
|
240
|
+
// Validate requirements
|
|
241
|
+
if (shares === 0n) {
|
|
242
|
+
throw new Error('Zero shares calculated');
|
|
243
|
+
}
|
|
244
|
+
if (amount0Used < amount0Min) {
|
|
245
|
+
throw new Error('Amount0 used less than minimum');
|
|
246
|
+
}
|
|
247
|
+
if (amount1Used < amount1Min) {
|
|
248
|
+
throw new Error('Amount1 used less than minimum');
|
|
249
|
+
}
|
|
250
|
+
return { shares, amount0Used, amount1Used };
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Multiplies two BigInt values and divides by a third (a * b / c)
|
|
254
|
+
* Equivalent to Solidity's FullMath.mulDiv
|
|
255
|
+
*/
|
|
256
|
+
function mulDiv(a, b, c) {
|
|
257
|
+
if (c === 0n) {
|
|
258
|
+
throw new Error('Division by zero');
|
|
259
|
+
}
|
|
260
|
+
return (a * b) / c;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Multiplies two BigInt values, divides by a third, and rounds up
|
|
264
|
+
* Equivalent to Solidity's FullMath.mulDivRoundingUp
|
|
265
|
+
*/
|
|
266
|
+
function mulDivRoundingUp(a, b, c) {
|
|
267
|
+
if (c === 0n) {
|
|
268
|
+
throw new Error('Division by zero');
|
|
269
|
+
}
|
|
270
|
+
const result = (a * b) / c;
|
|
271
|
+
const remainder = (a * b) % c;
|
|
272
|
+
return remainder > 0n ? result + 1n : result;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Returns the minimum of two BigInt values
|
|
276
|
+
*/
|
|
277
|
+
function min(a, b) {
|
|
278
|
+
return a < b ? a : b;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Gets the current vault reserves for both tokens
|
|
282
|
+
*
|
|
283
|
+
* @param publicClient - Viem public client for blockchain reads
|
|
284
|
+
* @param vaultAddress - Address of the vault
|
|
285
|
+
* @returns Promise resolving to [token0Balance, token1Balance, totalSupply]
|
|
286
|
+
*/
|
|
287
|
+
async function getVaultReserves(publicClient, vaultAddress) {
|
|
288
|
+
try {
|
|
289
|
+
const [totalSupply, token0Address, token1Address] = await Promise.all([
|
|
290
|
+
publicClient.readContract({
|
|
291
|
+
address: vaultAddress,
|
|
292
|
+
abi: VAULT_ABI,
|
|
293
|
+
functionName: 'totalSupply'
|
|
294
|
+
}),
|
|
295
|
+
publicClient.readContract({
|
|
296
|
+
address: vaultAddress,
|
|
297
|
+
abi: VAULT_ABI,
|
|
298
|
+
functionName: 'token0'
|
|
299
|
+
}),
|
|
300
|
+
publicClient.readContract({
|
|
301
|
+
address: vaultAddress,
|
|
302
|
+
abi: VAULT_ABI,
|
|
303
|
+
functionName: 'token1'
|
|
304
|
+
})
|
|
305
|
+
]);
|
|
306
|
+
const [token0Balance, token1Balance] = await Promise.all([
|
|
307
|
+
publicClient.readContract({
|
|
308
|
+
address: token0Address,
|
|
309
|
+
abi: [
|
|
310
|
+
{
|
|
311
|
+
type: 'function',
|
|
312
|
+
name: 'balanceOf',
|
|
313
|
+
inputs: [{ name: 'account', type: 'address', internalType: 'address' }],
|
|
314
|
+
outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }],
|
|
315
|
+
stateMutability: 'view'
|
|
316
|
+
}
|
|
317
|
+
],
|
|
318
|
+
functionName: 'balanceOf',
|
|
319
|
+
args: [vaultAddress]
|
|
320
|
+
}),
|
|
321
|
+
publicClient.readContract({
|
|
322
|
+
address: token1Address,
|
|
323
|
+
abi: [
|
|
324
|
+
{
|
|
325
|
+
type: 'function',
|
|
326
|
+
name: 'balanceOf',
|
|
327
|
+
inputs: [{ name: 'account', type: 'address', internalType: 'address' }],
|
|
328
|
+
outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }],
|
|
329
|
+
stateMutability: 'view'
|
|
330
|
+
}
|
|
331
|
+
],
|
|
332
|
+
functionName: 'balanceOf',
|
|
333
|
+
args: [vaultAddress]
|
|
334
|
+
})
|
|
335
|
+
]);
|
|
336
|
+
return {
|
|
337
|
+
data: {
|
|
338
|
+
token0Balance,
|
|
339
|
+
token1Balance,
|
|
340
|
+
totalSupply
|
|
341
|
+
},
|
|
342
|
+
status: 200,
|
|
343
|
+
success: true
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
return {
|
|
348
|
+
data: null,
|
|
349
|
+
status: 500,
|
|
350
|
+
success: false,
|
|
351
|
+
error: error instanceof Error ? error.message : 'Failed to get vault reserves'
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
//# sourceMappingURL=estimateLpTokens.js.map
|