@paraswap/dex-lib 2.16.3 → 2.16.4-balancer-v2-buy
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/.idea/aws.xml +17 -0
- package/.idea/codeStyles/Project.xml +19 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/paraswap-dex-lib.iml +9 -0
- package/.idea/vcs.xml +6 -0
- package/build/config.js +5 -5
- package/build/dex/balancer-v2/balancer-v2.d.ts +9 -14
- package/build/dex/balancer-v2/balancer-v2.js +19 -16
- package/build/dex/balancer-v2/balancer-v2.js.map +1 -1
- package/build/dex/balancer-v2/config.d.ts +2 -7
- package/build/dex/balancer-v2/config.js +20 -30
- package/build/dex/balancer-v2/config.js.map +1 -1
- package/build/dex/balancer-v2/pools/balancer-v2-pool.d.ts +25 -0
- package/build/dex/balancer-v2/pools/balancer-v2-pool.js +107 -0
- package/build/dex/balancer-v2/pools/balancer-v2-pool.js.map +1 -0
- package/build/dex/balancer-v2/pools/linear/LinearMath.d.ts +20 -0
- package/build/dex/balancer-v2/pools/linear/LinearMath.js +186 -0
- package/build/dex/balancer-v2/pools/linear/LinearMath.js.map +1 -0
- package/build/dex/balancer-v2/pools/linear/LinearPool.d.ts +51 -0
- package/build/dex/balancer-v2/pools/linear/LinearPool.js +477 -0
- package/build/dex/balancer-v2/pools/linear/LinearPool.js.map +1 -0
- package/build/dex/balancer-v2/pools/phantom-stable/PhantomStableMath.d.ts +10 -0
- package/build/dex/balancer-v2/pools/phantom-stable/PhantomStableMath.js +314 -0
- package/build/dex/balancer-v2/pools/phantom-stable/PhantomStableMath.js.map +1 -0
- package/build/dex/balancer-v2/pools/phantom-stable/PhantomStablePool.d.ts +50 -0
- package/build/dex/balancer-v2/pools/phantom-stable/PhantomStablePool.js +367 -0
- package/build/dex/balancer-v2/pools/phantom-stable/PhantomStablePool.js.map +1 -0
- package/build/dex/balancer-v2/pools/stable/StableMath.d.ts +7 -0
- package/build/dex/balancer-v2/pools/stable/StableMath.js +111 -0
- package/build/dex/balancer-v2/pools/stable/StableMath.js.map +1 -0
- package/build/dex/balancer-v2/pools/stable/StablePool.d.ts +30 -0
- package/build/dex/balancer-v2/pools/stable/StablePool.js +129 -0
- package/build/dex/balancer-v2/pools/stable/StablePool.js.map +1 -0
- package/build/dex/balancer-v2/pools/weighted/WeightedMath.d.ts +6 -0
- package/build/dex/balancer-v2/pools/weighted/WeightedMath.js +61 -0
- package/build/dex/balancer-v2/pools/weighted/WeightedMath.js.map +1 -0
- package/build/dex/balancer-v2/pools/weighted/WeightedPool.d.ts +30 -0
- package/build/dex/balancer-v2/pools/weighted/WeightedPool.js +112 -0
- package/build/dex/balancer-v2/pools/weighted/WeightedPool.js.map +1 -0
- package/build/dex/balancer-v2/types.d.ts +1 -0
- package/build/dex/balancer-v2/types.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +5 -5
- package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +204 -224
- package/src/dex/balancer-v2/balancer-v2.ts +41 -29
- package/src/dex/balancer-v2/config.ts +23 -35
- package/src/dex/balancer-v2/pools/balancer-v2-pool.ts +274 -0
- package/src/dex/balancer-v2/{LinearMath.ts → pools/linear/LinearMath.ts} +81 -23
- package/src/dex/balancer-v2/{LinearPool.ts → pools/linear/LinearPool.ts} +241 -5
- package/src/dex/balancer-v2/{StableMath.ts → pools/phantom-stable/PhantomStableMath.ts} +101 -21
- package/src/dex/balancer-v2/{PhantomStablePool.ts → pools/phantom-stable/PhantomStablePool.ts} +165 -11
- package/src/dex/balancer-v2/pools/stable/StableMath.ts +204 -0
- package/src/dex/balancer-v2/pools/stable/StablePool.ts +221 -0
- package/src/dex/balancer-v2/pools/weighted/WeightedMath.ts +84 -0
- package/src/dex/balancer-v2/pools/weighted/WeightedPool.ts +189 -0
- package/src/dex/balancer-v2/types.ts +1 -0
- package/tests/constants-e2e.ts +9 -4
- package/build/abi/DirectSwap.json +0 -970
- package/build/dex/test-dex/config.d.ts +0 -4
- package/build/dex/test-dex/config.js +0 -15
- package/build/dex/test-dex/config.js.map +0 -1
- package/build/dex/test-dex/test-dex-pool.d.ts +0 -39
- package/build/dex/test-dex/test-dex-pool.js +0 -63
- package/build/dex/test-dex/test-dex-pool.js.map +0 -1
- package/build/dex/test-dex/test-dex.d.ts +0 -37
- package/build/dex/test-dex/test-dex.js +0 -126
- package/build/dex/test-dex/test-dex.js.map +0 -1
- package/build/dex/test-dex/types.d.ts +0 -6
- package/build/dex/test-dex/types.js +0 -3
- package/build/dex/test-dex/types.js.map +0 -1
- package/build/dex/woo-fi-v2/woo-fi-math.d.ts +0 -16
- package/build/dex/woo-fi-v2/woo-fi-math.js +0 -137
- package/build/dex/woo-fi-v2/woo-fi-math.js.map +0 -1
- package/src/dex/balancer-v2/balancer-v2-pool.ts +0 -744
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Interface } from '@ethersproject/abi';
|
|
2
2
|
import { BigNumber } from '@ethersproject/bignumber';
|
|
3
|
-
import { isSameAddress, decodeThrowError } from '
|
|
3
|
+
import { isSameAddress, decodeThrowError } from '../../utils';
|
|
4
4
|
import * as LinearMath from './LinearMath';
|
|
5
|
-
import { BasePool } from '
|
|
6
|
-
import { callData, SubgraphPoolBase, PoolState, TokenState } from '
|
|
7
|
-
import LinearPoolABI from '
|
|
8
|
-
import { SwapSide } from '
|
|
5
|
+
import { BasePool } from '../balancer-v2-pool';
|
|
6
|
+
import { callData, SubgraphPoolBase, PoolState, TokenState } from '../../types';
|
|
7
|
+
import LinearPoolABI from '../../../../abi/balancer-v2/linearPoolAbi.json';
|
|
8
|
+
import { SwapSide } from '../../../../constants';
|
|
9
9
|
import { keyBy } from 'lodash';
|
|
10
10
|
|
|
11
11
|
export enum PairTypes {
|
|
@@ -30,6 +30,7 @@ type LinearPoolPairData = {
|
|
|
30
30
|
mainIndex: number;
|
|
31
31
|
lowerTarget: bigint;
|
|
32
32
|
upperTarget: bigint;
|
|
33
|
+
rate: bigint;
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
/*
|
|
@@ -79,9 +80,223 @@ export class LinearPool extends BasePool {
|
|
|
79
80
|
poolPairData.swapFee,
|
|
80
81
|
poolPairData.lowerTarget,
|
|
81
82
|
poolPairData.upperTarget,
|
|
83
|
+
poolPairData.rate,
|
|
82
84
|
);
|
|
83
85
|
}
|
|
84
86
|
|
|
87
|
+
onBuy(amounts: bigint[], poolPairData: LinearPoolPairData): bigint[] {
|
|
88
|
+
return this._swapGivenOut(
|
|
89
|
+
amounts,
|
|
90
|
+
poolPairData.tokens,
|
|
91
|
+
poolPairData.balances,
|
|
92
|
+
poolPairData.indexIn,
|
|
93
|
+
poolPairData.indexOut,
|
|
94
|
+
poolPairData.bptIndex,
|
|
95
|
+
poolPairData.wrappedIndex,
|
|
96
|
+
poolPairData.mainIndex,
|
|
97
|
+
poolPairData.scalingFactors,
|
|
98
|
+
poolPairData.swapFee,
|
|
99
|
+
poolPairData.lowerTarget,
|
|
100
|
+
poolPairData.upperTarget,
|
|
101
|
+
poolPairData.rate,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
_swapGivenOut(
|
|
106
|
+
tokenAmountsOut: bigint[],
|
|
107
|
+
tokens: string[],
|
|
108
|
+
balances: bigint[],
|
|
109
|
+
indexIn: number,
|
|
110
|
+
indexOut: number,
|
|
111
|
+
bptIndex: number,
|
|
112
|
+
wrappedIndex: number,
|
|
113
|
+
mainIndex: number,
|
|
114
|
+
scalingFactors: bigint[],
|
|
115
|
+
swapFeePercentage: bigint,
|
|
116
|
+
lowerTarget: bigint,
|
|
117
|
+
upperTarget: bigint,
|
|
118
|
+
rate: bigint,
|
|
119
|
+
): bigint[] {
|
|
120
|
+
let pairType: PairTypes;
|
|
121
|
+
if (isSameAddress(tokens[indexIn], tokens[bptIndex])) {
|
|
122
|
+
if (isSameAddress(tokens[indexOut], tokens[wrappedIndex]))
|
|
123
|
+
pairType = PairTypes.BptToWrappedToken;
|
|
124
|
+
else pairType = PairTypes.BptToMainToken;
|
|
125
|
+
} else if (isSameAddress(tokens[indexOut], tokens[bptIndex])) {
|
|
126
|
+
if (isSameAddress(tokens[indexIn], tokens[wrappedIndex]))
|
|
127
|
+
pairType = PairTypes.WrappedTokenToBpt;
|
|
128
|
+
else pairType = PairTypes.MainTokenToBpt;
|
|
129
|
+
} else {
|
|
130
|
+
if (isSameAddress(tokens[indexIn], tokens[wrappedIndex]))
|
|
131
|
+
pairType = PairTypes.WrappedTokenToMainToken;
|
|
132
|
+
else pairType = PairTypes.MainTokenToWrappedToken;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const balancesUpscaled = this._upscaleArray(balances, scalingFactors);
|
|
136
|
+
const tokenAmountsOutScaled = tokenAmountsOut.map(a =>
|
|
137
|
+
this._upscale(a, scalingFactors[indexOut]),
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// VirtualBPTSupply must be used for the maths
|
|
141
|
+
const virtualBptSupply = this.MAX_TOKEN_BALANCE.sub(
|
|
142
|
+
balances[bptIndex],
|
|
143
|
+
).toBigInt();
|
|
144
|
+
|
|
145
|
+
const amountsIn = this._onSwapGivenOut(
|
|
146
|
+
tokenAmountsOutScaled,
|
|
147
|
+
balancesUpscaled[mainIndex],
|
|
148
|
+
balancesUpscaled[wrappedIndex],
|
|
149
|
+
swapFeePercentage,
|
|
150
|
+
lowerTarget,
|
|
151
|
+
upperTarget,
|
|
152
|
+
virtualBptSupply,
|
|
153
|
+
pairType,
|
|
154
|
+
rate,
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
return amountsIn.map(a => this._downscaleUp(a, scalingFactors[indexIn]));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
_onSwapGivenOut(
|
|
161
|
+
tokenAmountsIn: bigint[],
|
|
162
|
+
mainBalance: bigint,
|
|
163
|
+
wrappedBalance: bigint,
|
|
164
|
+
fee: bigint,
|
|
165
|
+
lowerTarget: bigint,
|
|
166
|
+
upperTarget: bigint,
|
|
167
|
+
virtualBptSupply: bigint,
|
|
168
|
+
pairType: PairTypes,
|
|
169
|
+
rate: bigint,
|
|
170
|
+
): bigint[] {
|
|
171
|
+
const amountsIn: bigint[] = [];
|
|
172
|
+
|
|
173
|
+
switch (pairType) {
|
|
174
|
+
case PairTypes.BptToMainToken:
|
|
175
|
+
tokenAmountsIn.forEach(amountIn => {
|
|
176
|
+
let amt: bigint;
|
|
177
|
+
try {
|
|
178
|
+
amt = LinearMath._calcBptInPerMainOut(
|
|
179
|
+
amountIn,
|
|
180
|
+
mainBalance,
|
|
181
|
+
wrappedBalance,
|
|
182
|
+
virtualBptSupply,
|
|
183
|
+
{
|
|
184
|
+
rate,
|
|
185
|
+
fee: fee,
|
|
186
|
+
lowerTarget: lowerTarget,
|
|
187
|
+
upperTarget: upperTarget,
|
|
188
|
+
},
|
|
189
|
+
);
|
|
190
|
+
} catch (err) {
|
|
191
|
+
amt = 0n;
|
|
192
|
+
}
|
|
193
|
+
amountsIn.push(amt);
|
|
194
|
+
});
|
|
195
|
+
break;
|
|
196
|
+
case PairTypes.MainTokenToBpt:
|
|
197
|
+
tokenAmountsIn.forEach(amountIn => {
|
|
198
|
+
let amt: bigint;
|
|
199
|
+
try {
|
|
200
|
+
amt = LinearMath._calcMainInPerBptOut(
|
|
201
|
+
amountIn,
|
|
202
|
+
mainBalance,
|
|
203
|
+
wrappedBalance,
|
|
204
|
+
virtualBptSupply,
|
|
205
|
+
{
|
|
206
|
+
rate,
|
|
207
|
+
fee: fee,
|
|
208
|
+
lowerTarget: lowerTarget,
|
|
209
|
+
upperTarget: upperTarget,
|
|
210
|
+
},
|
|
211
|
+
);
|
|
212
|
+
} catch (err) {
|
|
213
|
+
amt = 0n;
|
|
214
|
+
}
|
|
215
|
+
amountsIn.push(amt);
|
|
216
|
+
});
|
|
217
|
+
break;
|
|
218
|
+
case PairTypes.MainTokenToWrappedToken:
|
|
219
|
+
tokenAmountsIn.forEach(amountIn => {
|
|
220
|
+
let amt: bigint;
|
|
221
|
+
try {
|
|
222
|
+
amt = LinearMath._calcMainInPerWrappedOut(amountIn, mainBalance, {
|
|
223
|
+
rate,
|
|
224
|
+
fee: fee,
|
|
225
|
+
lowerTarget: lowerTarget,
|
|
226
|
+
upperTarget: upperTarget,
|
|
227
|
+
});
|
|
228
|
+
} catch (err) {
|
|
229
|
+
amt = 0n;
|
|
230
|
+
}
|
|
231
|
+
amountsIn.push(amt);
|
|
232
|
+
});
|
|
233
|
+
break;
|
|
234
|
+
case PairTypes.WrappedTokenToMainToken:
|
|
235
|
+
tokenAmountsIn.forEach(amountIn => {
|
|
236
|
+
let amt: bigint;
|
|
237
|
+
try {
|
|
238
|
+
amt = LinearMath._calcWrappedInPerMainOut(amountIn, mainBalance, {
|
|
239
|
+
rate,
|
|
240
|
+
fee: fee,
|
|
241
|
+
lowerTarget: lowerTarget,
|
|
242
|
+
upperTarget: upperTarget,
|
|
243
|
+
});
|
|
244
|
+
} catch (err) {
|
|
245
|
+
amt = 0n;
|
|
246
|
+
}
|
|
247
|
+
amountsIn.push(amt);
|
|
248
|
+
});
|
|
249
|
+
break;
|
|
250
|
+
case PairTypes.BptToWrappedToken:
|
|
251
|
+
tokenAmountsIn.forEach(amountIn => {
|
|
252
|
+
let amt: bigint;
|
|
253
|
+
try {
|
|
254
|
+
amt = LinearMath._calcBptInPerWrappedOut(
|
|
255
|
+
amountIn,
|
|
256
|
+
mainBalance,
|
|
257
|
+
wrappedBalance,
|
|
258
|
+
virtualBptSupply,
|
|
259
|
+
{
|
|
260
|
+
rate,
|
|
261
|
+
fee: fee,
|
|
262
|
+
lowerTarget: lowerTarget,
|
|
263
|
+
upperTarget: upperTarget,
|
|
264
|
+
},
|
|
265
|
+
);
|
|
266
|
+
} catch (err) {
|
|
267
|
+
amt = 0n;
|
|
268
|
+
}
|
|
269
|
+
amountsIn.push(amt);
|
|
270
|
+
});
|
|
271
|
+
break;
|
|
272
|
+
case PairTypes.WrappedTokenToBpt:
|
|
273
|
+
tokenAmountsIn.forEach(amountIn => {
|
|
274
|
+
let amt: bigint;
|
|
275
|
+
try {
|
|
276
|
+
amt = LinearMath._calcWrappedInPerBptOut(
|
|
277
|
+
amountIn,
|
|
278
|
+
mainBalance,
|
|
279
|
+
wrappedBalance,
|
|
280
|
+
virtualBptSupply,
|
|
281
|
+
{
|
|
282
|
+
rate,
|
|
283
|
+
fee: fee,
|
|
284
|
+
lowerTarget: lowerTarget,
|
|
285
|
+
upperTarget: upperTarget,
|
|
286
|
+
},
|
|
287
|
+
);
|
|
288
|
+
} catch (err) {
|
|
289
|
+
amt = 0n;
|
|
290
|
+
}
|
|
291
|
+
amountsIn.push(amt);
|
|
292
|
+
});
|
|
293
|
+
break;
|
|
294
|
+
default:
|
|
295
|
+
amountsIn.push(0n);
|
|
296
|
+
}
|
|
297
|
+
return amountsIn;
|
|
298
|
+
}
|
|
299
|
+
|
|
85
300
|
_swapGivenIn(
|
|
86
301
|
tokenAmountsIn: bigint[],
|
|
87
302
|
tokens: string[],
|
|
@@ -95,6 +310,7 @@ export class LinearPool extends BasePool {
|
|
|
95
310
|
swapFeePercentage: bigint,
|
|
96
311
|
lowerTarget: bigint,
|
|
97
312
|
upperTarget: bigint,
|
|
313
|
+
rate: bigint,
|
|
98
314
|
): bigint[] {
|
|
99
315
|
/*
|
|
100
316
|
Linear pools allow trading between:
|
|
@@ -136,6 +352,7 @@ export class LinearPool extends BasePool {
|
|
|
136
352
|
upperTarget,
|
|
137
353
|
virtualBptSupply,
|
|
138
354
|
pairType,
|
|
355
|
+
rate,
|
|
139
356
|
);
|
|
140
357
|
|
|
141
358
|
// amountOut tokens are exiting the Pool, so we round down.
|
|
@@ -159,6 +376,7 @@ export class LinearPool extends BasePool {
|
|
|
159
376
|
upperTarget: bigint,
|
|
160
377
|
virtualBptSupply: bigint,
|
|
161
378
|
pairType: PairTypes,
|
|
379
|
+
rate: bigint,
|
|
162
380
|
): bigint[] {
|
|
163
381
|
const amountsOut: bigint[] = [];
|
|
164
382
|
|
|
@@ -173,6 +391,7 @@ export class LinearPool extends BasePool {
|
|
|
173
391
|
wrappedBalance,
|
|
174
392
|
virtualBptSupply,
|
|
175
393
|
{
|
|
394
|
+
rate,
|
|
176
395
|
fee: fee,
|
|
177
396
|
lowerTarget: lowerTarget,
|
|
178
397
|
upperTarget: upperTarget,
|
|
@@ -194,6 +413,7 @@ export class LinearPool extends BasePool {
|
|
|
194
413
|
wrappedBalance,
|
|
195
414
|
virtualBptSupply,
|
|
196
415
|
{
|
|
416
|
+
rate,
|
|
197
417
|
fee: fee,
|
|
198
418
|
lowerTarget: lowerTarget,
|
|
199
419
|
upperTarget: upperTarget,
|
|
@@ -210,6 +430,7 @@ export class LinearPool extends BasePool {
|
|
|
210
430
|
let amt: bigint;
|
|
211
431
|
try {
|
|
212
432
|
amt = LinearMath._calcWrappedOutPerMainIn(amountIn, mainBalance, {
|
|
433
|
+
rate,
|
|
213
434
|
fee: fee,
|
|
214
435
|
lowerTarget: lowerTarget,
|
|
215
436
|
upperTarget: upperTarget,
|
|
@@ -225,6 +446,7 @@ export class LinearPool extends BasePool {
|
|
|
225
446
|
let amt: bigint;
|
|
226
447
|
try {
|
|
227
448
|
amt = LinearMath._calcMainOutPerWrappedIn(amountIn, mainBalance, {
|
|
449
|
+
rate,
|
|
228
450
|
fee: fee,
|
|
229
451
|
lowerTarget: lowerTarget,
|
|
230
452
|
upperTarget: upperTarget,
|
|
@@ -245,6 +467,7 @@ export class LinearPool extends BasePool {
|
|
|
245
467
|
wrappedBalance,
|
|
246
468
|
virtualBptSupply,
|
|
247
469
|
{
|
|
470
|
+
rate,
|
|
248
471
|
fee: fee,
|
|
249
472
|
lowerTarget: lowerTarget,
|
|
250
473
|
upperTarget: upperTarget,
|
|
@@ -266,6 +489,7 @@ export class LinearPool extends BasePool {
|
|
|
266
489
|
wrappedBalance,
|
|
267
490
|
virtualBptSupply,
|
|
268
491
|
{
|
|
492
|
+
rate,
|
|
269
493
|
fee: fee,
|
|
270
494
|
lowerTarget: lowerTarget,
|
|
271
495
|
upperTarget: upperTarget,
|
|
@@ -317,6 +541,7 @@ export class LinearPool extends BasePool {
|
|
|
317
541
|
indexOut,
|
|
318
542
|
scalingFactors,
|
|
319
543
|
bptIndex,
|
|
544
|
+
rate: poolState.rate!,
|
|
320
545
|
swapFee: poolState.swapFee,
|
|
321
546
|
amp: poolState.amp || 0n,
|
|
322
547
|
wrappedIndex: poolState.wrappedIndex || 0,
|
|
@@ -352,6 +577,10 @@ export class LinearPool extends BasePool {
|
|
|
352
577
|
target: pool.address,
|
|
353
578
|
callData: this.poolInterface.encodeFunctionData('getTargets'),
|
|
354
579
|
});
|
|
580
|
+
poolCallData.push({
|
|
581
|
+
target: pool.address,
|
|
582
|
+
callData: this.poolInterface.encodeFunctionData('getRate'),
|
|
583
|
+
});
|
|
355
584
|
return poolCallData;
|
|
356
585
|
}
|
|
357
586
|
|
|
@@ -391,6 +620,12 @@ export class LinearPool extends BasePool {
|
|
|
391
620
|
data[startIndex++],
|
|
392
621
|
pool.address,
|
|
393
622
|
);
|
|
623
|
+
const rate = decodeThrowError(
|
|
624
|
+
this.poolInterface,
|
|
625
|
+
'getRate',
|
|
626
|
+
data[startIndex++],
|
|
627
|
+
pool.address,
|
|
628
|
+
)[0];
|
|
394
629
|
|
|
395
630
|
const bptIndex = pool.tokens.findIndex(
|
|
396
631
|
t => t.address.toLowerCase() === pool.address.toLowerCase(),
|
|
@@ -404,6 +639,7 @@ export class LinearPool extends BasePool {
|
|
|
404
639
|
|
|
405
640
|
const poolState: PoolState = {
|
|
406
641
|
swapFee: BigInt(swapFee.toString()),
|
|
642
|
+
rate: BigInt(rate.toString()),
|
|
407
643
|
mainIndex: Number(pool.mainIndex),
|
|
408
644
|
wrappedIndex: Number(pool.wrappedIndex),
|
|
409
645
|
bptIndex,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BI_POWS } from '
|
|
2
|
-
import { MathSol } from '
|
|
1
|
+
import { BI_POWS } from '../../../../bigint-constants';
|
|
2
|
+
import { MathSol } from '../../balancer-v2-math';
|
|
3
3
|
|
|
4
4
|
const AMP_PRECISION = BI_POWS[3];
|
|
5
5
|
|
|
@@ -9,15 +9,15 @@ export function _calculateInvariant(
|
|
|
9
9
|
roundUp: boolean,
|
|
10
10
|
): bigint {
|
|
11
11
|
/**********************************************************************************************
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
// invariant //
|
|
13
|
+
// D = invariant D^(n+1) //
|
|
14
|
+
// A = amplification coefficient A n^n S + D = A D n^n + ----------- //
|
|
15
|
+
// S = sum of balances n^n P //
|
|
16
|
+
// P = product of balances //
|
|
17
|
+
// n = number of tokens //
|
|
18
|
+
*********x************************************************************************************/
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
// We support rounding up or down.
|
|
21
21
|
|
|
22
22
|
let sum = 0n;
|
|
23
23
|
const numTokens = balances.length;
|
|
@@ -44,18 +44,18 @@ export function _calculateInvariant(
|
|
|
44
44
|
prevInvariant = invariant;
|
|
45
45
|
invariant = MathSol.div(
|
|
46
46
|
MathSol.mul(MathSol.mul(BigInt(numTokens), invariant), invariant) +
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
MathSol.div(
|
|
48
|
+
MathSol.mul(MathSol.mul(ampTimesTotal, sum), P_D),
|
|
49
|
+
AMP_PRECISION,
|
|
50
|
+
roundUp,
|
|
51
|
+
),
|
|
52
52
|
MathSol.mul(BigInt(numTokens + 1), invariant) +
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
// No need to use checked arithmetic for the amp precision, the amp is guaranteed to be at least 1
|
|
54
|
+
MathSol.div(
|
|
55
|
+
MathSol.mul(ampTimesTotal - AMP_PRECISION, P_D),
|
|
56
|
+
AMP_PRECISION,
|
|
57
|
+
!roundUp,
|
|
58
|
+
),
|
|
59
59
|
roundUp,
|
|
60
60
|
);
|
|
61
61
|
|
|
@@ -81,6 +81,17 @@ export function _calcOutGivenIn(
|
|
|
81
81
|
amountIn: bigint,
|
|
82
82
|
invariant?: bigint,
|
|
83
83
|
): bigint {
|
|
84
|
+
/**************************************************************************************************************
|
|
85
|
+
// outGivenIn token x for y - polynomial equation to solve //
|
|
86
|
+
// ay = amount out to calculate //
|
|
87
|
+
// by = balance token out //
|
|
88
|
+
// y = by - ay (finalBalanceOut) //
|
|
89
|
+
// D = invariant D D^(n+1) //
|
|
90
|
+
// A = amplification coefficient y^2 + ( S - ---------- - D) * y - ------------- = 0 //
|
|
91
|
+
// n = number of tokens (A * n^n) A * n^2n * P //
|
|
92
|
+
// S = sum of final balances but y //
|
|
93
|
+
// P = product of final balances but y //
|
|
94
|
+
**************************************************************************************************************/
|
|
84
95
|
balances = [...balances];
|
|
85
96
|
// Given that we need to have a greater final balance out, the invariant needs to be rounded up
|
|
86
97
|
if (!invariant) invariant = _calculateInvariant(amp, balances, true);
|
|
@@ -105,6 +116,19 @@ export function _calcInGivenOut(
|
|
|
105
116
|
fee: bigint,
|
|
106
117
|
invariant?: bigint,
|
|
107
118
|
): bigint {
|
|
119
|
+
/**************************************************************************************************************
|
|
120
|
+
// inGivenOut token x for y - polynomial equation to solve //
|
|
121
|
+
// ax = amount in to calculate //
|
|
122
|
+
// bx = balance token in //
|
|
123
|
+
// x = bx + ax (finalBalanceIn) //
|
|
124
|
+
// D = invariant D D^(n+1) //
|
|
125
|
+
// A = amplification coefficient x^2 + ( S - ---------- - D) * x - ------------- = 0 //
|
|
126
|
+
// n = number of tokens (A * n^n) A * n^2n * P //
|
|
127
|
+
// S = sum of final balances but x //
|
|
128
|
+
// P = product of final balances but x //
|
|
129
|
+
**************************************************************************************************************/
|
|
130
|
+
|
|
131
|
+
// Given that we need to have a greater final balance in, the invariant needs to be rounded up
|
|
108
132
|
balances = [...balances];
|
|
109
133
|
if (!invariant) invariant = _calculateInvariant(amp, balances, true);
|
|
110
134
|
balances[tokenIndexOut] = MathSol.sub(balances[tokenIndexOut], amountOut);
|
|
@@ -120,6 +144,7 @@ export function _calcInGivenOut(
|
|
|
120
144
|
MathSol.sub(finalBalanceIn, balances[tokenIndexIn]),
|
|
121
145
|
1n,
|
|
122
146
|
);
|
|
147
|
+
|
|
123
148
|
amountIn = addFee(amountIn, fee);
|
|
124
149
|
return amountIn;
|
|
125
150
|
}
|
|
@@ -195,6 +220,61 @@ export function _calcBptOutGivenExactTokensIn(
|
|
|
195
220
|
}
|
|
196
221
|
}
|
|
197
222
|
|
|
223
|
+
export function _calcTokenInGivenExactBptOut(
|
|
224
|
+
amp: bigint,
|
|
225
|
+
balances: bigint[],
|
|
226
|
+
tokenIndexIn: number,
|
|
227
|
+
bptAmountOut: bigint,
|
|
228
|
+
bptTotalSupply: bigint,
|
|
229
|
+
fee: bigint,
|
|
230
|
+
invariant?: bigint,
|
|
231
|
+
): bigint {
|
|
232
|
+
if (!invariant) invariant = _calculateInvariant(amp, balances, true);
|
|
233
|
+
|
|
234
|
+
const newInvariant = MathSol.mulUpFixed(
|
|
235
|
+
MathSol.divUpFixed(
|
|
236
|
+
MathSol.add(bptTotalSupply, bptAmountOut),
|
|
237
|
+
bptTotalSupply
|
|
238
|
+
),
|
|
239
|
+
invariant
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
const newBalanceTokenIndex =
|
|
243
|
+
_getTokenBalanceGivenInvariantAndAllOtherBalances(
|
|
244
|
+
amp,
|
|
245
|
+
balances,
|
|
246
|
+
newInvariant,
|
|
247
|
+
tokenIndexIn
|
|
248
|
+
);
|
|
249
|
+
const amountInWithoutFee = MathSol.sub(
|
|
250
|
+
newBalanceTokenIndex,
|
|
251
|
+
balances[tokenIndexIn]
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
let sumBalances = BigInt(0);
|
|
255
|
+
for (let i = 0; i < balances.length; i++) {
|
|
256
|
+
sumBalances = MathSol.add(sumBalances, balances[i]);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// We can now compute how much extra balance is being deposited
|
|
260
|
+
// and used in virtual swaps, and charge swap fees accordingly.
|
|
261
|
+
const currentWeight = MathSol.divDownFixed(
|
|
262
|
+
balances[tokenIndexIn],
|
|
263
|
+
sumBalances
|
|
264
|
+
);
|
|
265
|
+
const taxablePercentage = MathSol.complementFixed(currentWeight);
|
|
266
|
+
const taxableAmount = MathSol.mulUpFixed(
|
|
267
|
+
amountInWithoutFee,
|
|
268
|
+
taxablePercentage
|
|
269
|
+
);
|
|
270
|
+
const nonTaxableAmount = MathSol.sub(amountInWithoutFee, taxableAmount);
|
|
271
|
+
|
|
272
|
+
return MathSol.add(
|
|
273
|
+
nonTaxableAmount,
|
|
274
|
+
MathSol.divUpFixed(taxableAmount, MathSol.sub(MathSol.ONE, fee))
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
198
278
|
/*
|
|
199
279
|
Flow of calculations:
|
|
200
280
|
amountsTokenOut -> amountsOutProportional ->
|