@paraswap/dex-lib 2.16.8-pancakeswapv3.0 → 2.17.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/.idea/aws.xml +17 -0
- package/.idea/codeStyles/Project.xml +19 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -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/abi/woo-fi/WooFeeManager.abi.json +318 -0
- package/build/abi/woo-fi/WooPP.abi.json +548 -0
- package/build/abi/woo-fi/Wooracle.abi.json +260 -0
- package/build/config.js +4 -4
- package/build/dex/aave-v3/tokens/arbitrum.json +50 -0
- package/build/dex/aave-v3/tokens/avalanche.json +74 -0
- package/build/dex/aave-v3/tokens/fantom.json +62 -0
- package/build/dex/aave-v3/tokens/optimism.json +50 -0
- package/build/dex/aave-v3/tokens/polygon.json +116 -0
- package/build/dex/balancer-v2/balancer-v2.d.ts +14 -19
- package/build/dex/balancer-v2/balancer-v2.js +27 -22
- 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 +179 -0
- package/build/dex/balancer-v2/pools/linear/LinearMath.js.map +1 -0
- package/build/dex/balancer-v2/pools/linear/LinearPool.d.ts +50 -0
- package/build/dex/balancer-v2/pools/linear/LinearPool.js +458 -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/build/dex/balancer-v2/utils.d.ts +3 -2
- package/build/dex/balancer-v2/utils.js +6 -4
- package/build/dex/balancer-v2/utils.js.map +1 -1
- package/build/dex/index.js +1 -1
- package/build/dex/index.js.map +1 -1
- package/build/dex/quickswap-v3.d.ts +21 -0
- package/build/dex/quickswap-v3.js +40 -0
- package/build/dex/quickswap-v3.js.map +1 -0
- package/build/dex/uniswap-v3/config.js +28 -0
- package/build/dex/uniswap-v3/config.js.map +1 -1
- package/build/dex/uniswap-v3/uniswap-v3-pool.d.ts +2 -1
- package/build/dex/uniswap-v3/uniswap-v3-pool.js +3 -2
- package/build/dex/uniswap-v3/uniswap-v3-pool.js.map +1 -1
- package/build/dex/uniswap-v3/uniswap-v3.js +1 -1
- package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
- package/build/dex/{pancakeswap-v3 → woo-fi}/config.d.ts +2 -2
- package/build/dex/woo-fi/config.js +141 -0
- package/build/dex/woo-fi/config.js.map +1 -0
- package/build/dex/woo-fi/constants.d.ts +5 -0
- package/build/dex/woo-fi/constants.js +20 -0
- package/build/dex/woo-fi/constants.js.map +1 -0
- package/build/dex/woo-fi/types.d.ts +48 -0
- package/build/dex/woo-fi/types.js +3 -0
- package/build/dex/woo-fi/types.js.map +1 -0
- package/build/dex/woo-fi/woo-fi-decimal-math.d.ts +14 -0
- package/build/dex/woo-fi/woo-fi-decimal-math.js +42 -0
- package/build/dex/woo-fi/woo-fi-decimal-math.js.map +1 -0
- package/build/dex/woo-fi/woo-fi-math.d.ts +31 -0
- package/build/dex/woo-fi/woo-fi-math.js +300 -0
- package/build/dex/woo-fi/woo-fi-math.js.map +1 -0
- package/build/dex/woo-fi/woo-fi.d.ts +65 -0
- package/build/dex/woo-fi/woo-fi.js +480 -0
- package/build/dex/woo-fi/woo-fi.js.map +1 -0
- package/package.json +1 -1
- package/src/config.ts +4 -4
- package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +538 -225
- package/src/dex/balancer-v2/balancer-v2-integration.test.ts +305 -122
- package/src/dex/balancer-v2/balancer-v2.ts +60 -56
- 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} +11 -10
- package/src/dex/balancer-v2/{LinearPool.ts → pools/linear/LinearPool.ts} +210 -6
- 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} +167 -12
- 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/src/dex/balancer-v2/utils.ts +7 -1
- package/src/dex/index.ts +1 -1
- package/src/dex/uniswap-v3/config.ts +32 -0
- package/src/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.ts +28 -0
- package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +156 -0
- package/src/dex/uniswap-v3/uniswap-v3-events.test.ts +0 -4
- package/src/dex/uniswap-v3/uniswap-v3-pool.ts +2 -1
- package/src/dex/uniswap-v3/uniswap-v3.ts +1 -0
- package/tests/constants-e2e.ts +33 -8
- package/build/abi/pancakeswap-v3/PancakeV3StateMulticall.abi.json +0 -781
- package/build/abi/pancakeswap-v3/PancakeswapV3Pool.abi.json +0 -1039
- package/build/abi/pancakeswap-v3/PancakeswapV3Quoter.abi.json +0 -285
- package/build/abi/pancakeswap-v3/PancakeswapV3Router.abi.json +0 -583
- package/build/dex/pancakeswap-v3/config.js +0 -62
- package/build/dex/pancakeswap-v3/config.js.map +0 -1
- package/build/dex/pancakeswap-v3/constants.d.ts +0 -23
- package/build/dex/pancakeswap-v3/constants.js +0 -29
- package/build/dex/pancakeswap-v3/constants.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/BitMath.d.ts +0 -4
- package/build/dex/pancakeswap-v3/contract-math/BitMath.js +0 -93
- package/build/dex/pancakeswap-v3/contract-math/BitMath.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.d.ts +0 -3
- package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.js +0 -8
- package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.d.ts +0 -4
- package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.js +0 -9
- package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/FullMath.d.ts +0 -4
- package/build/dex/pancakeswap-v3/contract-math/FullMath.js +0 -19
- package/build/dex/pancakeswap-v3/contract-math/FullMath.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.d.ts +0 -3
- package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.js +0 -22
- package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/Oracle.d.ts +0 -10
- package/build/dex/pancakeswap-v3/contract-math/Oracle.js +0 -133
- package/build/dex/pancakeswap-v3/contract-math/Oracle.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.d.ts +0 -10
- package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.js +0 -91
- package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/SwapMath.d.ts +0 -8
- package/build/dex/pancakeswap-v3/contract-math/SwapMath.js +0 -70
- package/build/dex/pancakeswap-v3/contract-math/SwapMath.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/Tick.d.ts +0 -7
- package/build/dex/pancakeswap-v3/contract-math/Tick.js +0 -45
- package/build/dex/pancakeswap-v3/contract-math/Tick.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/TickBitMap.d.ts +0 -8
- package/build/dex/pancakeswap-v3/contract-math/TickBitMap.js +0 -87
- package/build/dex/pancakeswap-v3/contract-math/TickBitMap.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/TickMath.d.ts +0 -8
- package/build/dex/pancakeswap-v3/contract-math/TickMath.js +0 -162
- package/build/dex/pancakeswap-v3/contract-math/TickMath.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.d.ts +0 -3
- package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.js +0 -10
- package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.d.ts +0 -18
- package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.js +0 -407
- package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.js.map +0 -1
- package/build/dex/pancakeswap-v3/contract-math/utils.d.ts +0 -3
- package/build/dex/pancakeswap-v3/contract-math/utils.js +0 -16
- package/build/dex/pancakeswap-v3/contract-math/utils.js.map +0 -1
- package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.d.ts +0 -45
- package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js +0 -340
- package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js.map +0 -1
- package/build/dex/pancakeswap-v3/pancakeswap-v3.d.ts +0 -55
- package/build/dex/pancakeswap-v3/pancakeswap-v3.js +0 -605
- package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +0 -1
- package/build/dex/pancakeswap-v3/types.d.ts +0 -137
- package/build/dex/pancakeswap-v3/types.js +0 -9
- package/build/dex/pancakeswap-v3/types.js.map +0 -1
- package/build/dex/pancakeswap-v3/utils.d.ts +0 -6
- package/build/dex/pancakeswap-v3/utils.js +0 -65
- package/build/dex/pancakeswap-v3/utils.js.map +0 -1
- package/src/abi/pancakeswap-v3/PancakeV3StateMulticall.abi.json +0 -781
- package/src/abi/pancakeswap-v3/PancakeswapV3Pool.abi.json +0 -1039
- package/src/dex/balancer-v2/balancer-v2-pool.ts +0 -744
- package/src/dex/pancakeswap-v3/config.ts +0 -68
- package/src/dex/pancakeswap-v3/constants.ts +0 -35
- package/src/dex/pancakeswap-v3/contract-math/BitMath.ts +0 -90
- package/src/dex/pancakeswap-v3/contract-math/FixedPoint128.ts +0 -3
- package/src/dex/pancakeswap-v3/contract-math/FixedPoint96.ts +0 -4
- package/src/dex/pancakeswap-v3/contract-math/FullMath.ts +0 -30
- package/src/dex/pancakeswap-v3/contract-math/LiquidityMath.ts +0 -17
- package/src/dex/pancakeswap-v3/contract-math/Oracle.ts +0 -226
- package/src/dex/pancakeswap-v3/contract-math/SqrtPriceMath.ts +0 -226
- package/src/dex/pancakeswap-v3/contract-math/SwapMath.ts +0 -139
- package/src/dex/pancakeswap-v3/contract-math/Tick.ts +0 -82
- package/src/dex/pancakeswap-v3/contract-math/TickBitMap.ts +0 -128
- package/src/dex/pancakeswap-v3/contract-math/TickMath.ts +0 -211
- package/src/dex/pancakeswap-v3/contract-math/UnsafeMath.ts +0 -5
- package/src/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.ts +0 -691
- package/src/dex/pancakeswap-v3/contract-math/utils.ts +0 -11
- package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +0 -168
- package/src/dex/pancakeswap-v3/pancakeswap-v3-events.test.ts +0 -124
- package/src/dex/pancakeswap-v3/pancakeswap-v3-integration.test.ts +0 -338
- package/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts +0 -554
- package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +0 -1000
- /package/src/abi/{pancakeswap-v3/PancakeswapV3Quoter.abi.json → uniswap-v3/pancakeswap-v3/PancakeswapV3QuoterV2.abi.json} +0 -0
- /package/src/abi/{pancakeswap-v3 → uniswap-v3/pancakeswap-v3}/PancakeswapV3Router.abi.json +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { BI_POWS } from '../../../../bigint-constants';
|
|
2
|
+
import { MathSol } from '../../balancer-v2-math';
|
|
3
|
+
|
|
4
|
+
export class StableMath {
|
|
5
|
+
static _AMP_PRECISION = BI_POWS[3];
|
|
6
|
+
|
|
7
|
+
static _calculateInvariant(
|
|
8
|
+
amplificationParameter: bigint,
|
|
9
|
+
balances: bigint[],
|
|
10
|
+
roundUp: boolean,
|
|
11
|
+
): bigint {
|
|
12
|
+
/**********************************************************************************************
|
|
13
|
+
// invariant //
|
|
14
|
+
// D = invariant D^(n+1) //
|
|
15
|
+
// A = amplification coefficient A n^n S + D = A D n^n + ----------- //
|
|
16
|
+
// S = sum of balances n^n P //
|
|
17
|
+
// P = product of balances //
|
|
18
|
+
// n = number of tokens //
|
|
19
|
+
*********x************************************************************************************/
|
|
20
|
+
|
|
21
|
+
// We support rounding up or down.
|
|
22
|
+
let sum = 0n;
|
|
23
|
+
const numTokens = balances.length;
|
|
24
|
+
for (let i = 0; i < numTokens; i++) {
|
|
25
|
+
sum = sum + balances[i];
|
|
26
|
+
}
|
|
27
|
+
if (sum == 0n) {
|
|
28
|
+
return 0n;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let prevInvariant = 0n;
|
|
32
|
+
let invariant = sum;
|
|
33
|
+
const ampTimesTotal = amplificationParameter * BigInt(numTokens);
|
|
34
|
+
|
|
35
|
+
for (let i = 0; i < 255; i++) {
|
|
36
|
+
let P_D = balances[0] * BigInt(numTokens);
|
|
37
|
+
for (let j = 1; j < numTokens; j++) {
|
|
38
|
+
P_D = MathSol.div(
|
|
39
|
+
MathSol.mul(MathSol.mul(P_D, balances[j]), BigInt(numTokens)),
|
|
40
|
+
invariant,
|
|
41
|
+
roundUp,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
prevInvariant = invariant;
|
|
45
|
+
invariant = MathSol.div(
|
|
46
|
+
MathSol.mul(MathSol.mul(BigInt(numTokens), invariant), invariant) +
|
|
47
|
+
MathSol.div(
|
|
48
|
+
MathSol.mul(MathSol.mul(ampTimesTotal, sum), P_D),
|
|
49
|
+
this._AMP_PRECISION,
|
|
50
|
+
roundUp,
|
|
51
|
+
),
|
|
52
|
+
MathSol.mul(BigInt(numTokens + 1), invariant) +
|
|
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 - this._AMP_PRECISION, P_D),
|
|
56
|
+
this._AMP_PRECISION,
|
|
57
|
+
!roundUp,
|
|
58
|
+
),
|
|
59
|
+
roundUp,
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (invariant > prevInvariant) {
|
|
63
|
+
if (invariant - prevInvariant <= 1) {
|
|
64
|
+
return invariant;
|
|
65
|
+
}
|
|
66
|
+
} else if (prevInvariant - invariant <= 1) {
|
|
67
|
+
return invariant;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
throw new Error('Errors.STABLE_INVARIANT_DIDNT_CONVERGE');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
static _calcInGivenOut(
|
|
76
|
+
amplificationParameter: bigint,
|
|
77
|
+
balances: bigint[],
|
|
78
|
+
tokenIndexIn: number,
|
|
79
|
+
tokenIndexOut: number,
|
|
80
|
+
tokenAmountsOut: bigint[],
|
|
81
|
+
): bigint[] {
|
|
82
|
+
const invariant = this._calculateInvariant(
|
|
83
|
+
amplificationParameter,
|
|
84
|
+
balances,
|
|
85
|
+
false,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
return tokenAmountsOut.map(a => {
|
|
89
|
+
balances[tokenIndexOut] = MathSol.sub(balances[tokenIndexOut], a);
|
|
90
|
+
|
|
91
|
+
const finalBalanceIn =
|
|
92
|
+
this._getTokenBalanceGivenInvariantAndAllOtherBalances(
|
|
93
|
+
amplificationParameter,
|
|
94
|
+
balances,
|
|
95
|
+
invariant,
|
|
96
|
+
tokenIndexIn,
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
return MathSol.add(
|
|
100
|
+
MathSol.sub(finalBalanceIn, balances[tokenIndexIn]),
|
|
101
|
+
1n,
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
static _calcOutGivenIn(
|
|
107
|
+
amplificationParameter: bigint,
|
|
108
|
+
balances: bigint[],
|
|
109
|
+
tokenIndexIn: number,
|
|
110
|
+
tokenIndexOut: number,
|
|
111
|
+
tokenAmountsIn: bigint[],
|
|
112
|
+
): bigint[] {
|
|
113
|
+
// Amount out, so we round down overall.
|
|
114
|
+
|
|
115
|
+
// Given that we need to have a greater final balance out, the invariant needs to be rounded up
|
|
116
|
+
const invariant = this._calculateInvariant(
|
|
117
|
+
amplificationParameter,
|
|
118
|
+
balances,
|
|
119
|
+
true,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const initBalance = balances[tokenIndexIn];
|
|
123
|
+
// Modification: The original code was implemented for a single tokenAmountsIn
|
|
124
|
+
return tokenAmountsIn.map(a => {
|
|
125
|
+
balances[tokenIndexIn] = initBalance + a;
|
|
126
|
+
|
|
127
|
+
const finalBalanceOut =
|
|
128
|
+
this._getTokenBalanceGivenInvariantAndAllOtherBalances(
|
|
129
|
+
amplificationParameter,
|
|
130
|
+
balances,
|
|
131
|
+
invariant,
|
|
132
|
+
tokenIndexOut,
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// No need to use checked arithmetic since `tokenAmountIn` was actually added to the same balance right before
|
|
136
|
+
// calling `_getTokenBalanceGivenInvariantAndAllOtherBalances` which doesn't alter the balances array.
|
|
137
|
+
// balances[tokenIndexIn] = balances[tokenIndexIn] - tokenAmountIn;
|
|
138
|
+
return balances[tokenIndexOut] - finalBalanceOut - 1n;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
static _getTokenBalanceGivenInvariantAndAllOtherBalances(
|
|
143
|
+
amplificationParameter: bigint,
|
|
144
|
+
balances: bigint[],
|
|
145
|
+
invariant: bigint,
|
|
146
|
+
tokenIndex: number,
|
|
147
|
+
): bigint {
|
|
148
|
+
// Rounds result up overall
|
|
149
|
+
|
|
150
|
+
const ampTimesTotal = amplificationParameter * BigInt(balances.length);
|
|
151
|
+
let sum = balances[0];
|
|
152
|
+
let P_D = balances[0] * BigInt(balances.length);
|
|
153
|
+
for (let j = 1; j < balances.length; j++) {
|
|
154
|
+
P_D = MathSol.divDown(
|
|
155
|
+
MathSol.mul(MathSol.mul(P_D, balances[j]), BigInt(balances.length)),
|
|
156
|
+
invariant,
|
|
157
|
+
);
|
|
158
|
+
sum = sum + balances[j];
|
|
159
|
+
}
|
|
160
|
+
// No need to use safe math, based on the loop above `sum` is greater than or equal to `balances[tokenIndex]`
|
|
161
|
+
sum = sum - balances[tokenIndex];
|
|
162
|
+
|
|
163
|
+
const inv2 = MathSol.mul(invariant, invariant);
|
|
164
|
+
// We remove the balance fromm c by multiplying it
|
|
165
|
+
const c = MathSol.mul(
|
|
166
|
+
MathSol.mul(
|
|
167
|
+
MathSol.divUp(inv2, MathSol.mul(ampTimesTotal, P_D)),
|
|
168
|
+
this._AMP_PRECISION,
|
|
169
|
+
),
|
|
170
|
+
balances[tokenIndex],
|
|
171
|
+
);
|
|
172
|
+
const b =
|
|
173
|
+
sum +
|
|
174
|
+
MathSol.mul(
|
|
175
|
+
MathSol.divDown(invariant, ampTimesTotal),
|
|
176
|
+
this._AMP_PRECISION,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// We iterate to find the balance
|
|
180
|
+
let prevTokenBalance = 0n;
|
|
181
|
+
// We multiply the first iteration outside the loop with the invariant to set the value of the
|
|
182
|
+
// initial approximation.
|
|
183
|
+
let tokenBalance = MathSol.divUp(inv2 + c, invariant + b);
|
|
184
|
+
|
|
185
|
+
for (let i = 0; i < 255; i++) {
|
|
186
|
+
prevTokenBalance = tokenBalance;
|
|
187
|
+
|
|
188
|
+
tokenBalance = MathSol.divUp(
|
|
189
|
+
MathSol.mul(tokenBalance, tokenBalance) + c,
|
|
190
|
+
MathSol.mul(tokenBalance, 2n) + b - invariant,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
if (tokenBalance > prevTokenBalance) {
|
|
194
|
+
if (tokenBalance - prevTokenBalance <= 1) {
|
|
195
|
+
return tokenBalance;
|
|
196
|
+
}
|
|
197
|
+
} else if (prevTokenBalance - tokenBalance <= 1) {
|
|
198
|
+
return tokenBalance;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
throw new Error('Errors.STABLE_GET_BALANCE_DIDNT_CONVERGE');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
2
|
+
import StablePoolABI from '../../../../abi/balancer-v2/stable-pool.json';
|
|
3
|
+
import MetaStablePoolABI from '../../../../abi/balancer-v2/meta-stable-pool.json';
|
|
4
|
+
import { callData, PoolState, SubgraphPoolBase, TokenState } from '../../types';
|
|
5
|
+
import { decodeThrowError, getTokenScalingFactor } from '../../utils';
|
|
6
|
+
import { BigNumber } from '@ethersproject/bignumber';
|
|
7
|
+
import { SwapSide } from '../../../../constants';
|
|
8
|
+
import { BaseGeneralPool } from '../balancer-v2-pool';
|
|
9
|
+
import { StableMath } from './StableMath';
|
|
10
|
+
|
|
11
|
+
export type StablePoolPairData = {
|
|
12
|
+
balances: bigint[];
|
|
13
|
+
indexIn: number;
|
|
14
|
+
indexOut: number;
|
|
15
|
+
scalingFactors: bigint[];
|
|
16
|
+
swapFee: bigint;
|
|
17
|
+
amp: bigint;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export class StablePool extends BaseGeneralPool {
|
|
21
|
+
vaultAddress: string;
|
|
22
|
+
vaultInterface: Interface;
|
|
23
|
+
poolInterface: Interface;
|
|
24
|
+
metaPoolInterface: Interface;
|
|
25
|
+
|
|
26
|
+
constructor(vaultAddress: string, vaultInterface: Interface) {
|
|
27
|
+
super();
|
|
28
|
+
this.vaultAddress = vaultAddress;
|
|
29
|
+
this.vaultInterface = vaultInterface;
|
|
30
|
+
this.poolInterface = new Interface(StablePoolABI);
|
|
31
|
+
this.metaPoolInterface = new Interface(MetaStablePoolABI);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
_onSwapGivenOut(
|
|
35
|
+
tokenAmountsOut: bigint[],
|
|
36
|
+
balances: bigint[],
|
|
37
|
+
indexIn: number,
|
|
38
|
+
indexOut: number,
|
|
39
|
+
_amplificationParameter: bigint,
|
|
40
|
+
): bigint[] {
|
|
41
|
+
return StableMath._calcInGivenOut(
|
|
42
|
+
_amplificationParameter,
|
|
43
|
+
balances,
|
|
44
|
+
indexIn,
|
|
45
|
+
indexOut,
|
|
46
|
+
tokenAmountsOut,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
_onSwapGivenIn(
|
|
51
|
+
tokenAmountsIn: bigint[],
|
|
52
|
+
balances: bigint[],
|
|
53
|
+
indexIn: number,
|
|
54
|
+
indexOut: number,
|
|
55
|
+
_amplificationParameter: bigint,
|
|
56
|
+
): bigint[] {
|
|
57
|
+
return StableMath._calcOutGivenIn(
|
|
58
|
+
_amplificationParameter,
|
|
59
|
+
balances,
|
|
60
|
+
indexIn,
|
|
61
|
+
indexOut,
|
|
62
|
+
tokenAmountsIn,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
Helper function to parse pool data into params for onSell/onBuy functions.
|
|
68
|
+
*/
|
|
69
|
+
parsePoolPairData(
|
|
70
|
+
pool: SubgraphPoolBase,
|
|
71
|
+
poolState: PoolState,
|
|
72
|
+
tokenIn: string,
|
|
73
|
+
tokenOut: string,
|
|
74
|
+
): StablePoolPairData {
|
|
75
|
+
let indexIn = 0,
|
|
76
|
+
indexOut = 0;
|
|
77
|
+
|
|
78
|
+
const scalingFactors: bigint[] = [];
|
|
79
|
+
const balances = poolState.orderedTokens.map((tokenAddress, i) => {
|
|
80
|
+
const t = pool.tokensMap[tokenAddress.toLowerCase()] || poolState.tokens[tokenAddress.toLowerCase()];
|
|
81
|
+
|
|
82
|
+
if (t.address.toLowerCase() === tokenIn.toLowerCase()) {
|
|
83
|
+
indexIn = i;
|
|
84
|
+
}
|
|
85
|
+
if (t.address.toLowerCase() === tokenOut.toLowerCase()) {
|
|
86
|
+
indexOut = i;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (pool.poolType === 'MetaStable') {
|
|
90
|
+
scalingFactors.push(
|
|
91
|
+
poolState.tokens[t.address.toLowerCase()].scalingFactor || 0n,
|
|
92
|
+
);
|
|
93
|
+
} else scalingFactors.push(getTokenScalingFactor(t.decimals));
|
|
94
|
+
return poolState.tokens[t.address.toLowerCase()].balance;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const poolPairData: StablePoolPairData = {
|
|
98
|
+
balances,
|
|
99
|
+
indexIn,
|
|
100
|
+
indexOut,
|
|
101
|
+
scalingFactors,
|
|
102
|
+
swapFee: poolState.swapFee,
|
|
103
|
+
amp: poolState.amp ? poolState.amp : 0n,
|
|
104
|
+
};
|
|
105
|
+
return poolPairData;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/*
|
|
109
|
+
Helper function to construct onchain multicall data for StablePool.
|
|
110
|
+
*/
|
|
111
|
+
getOnChainCalls(pool: SubgraphPoolBase): callData[] {
|
|
112
|
+
const poolCallData: callData[] = [
|
|
113
|
+
{
|
|
114
|
+
target: this.vaultAddress,
|
|
115
|
+
callData: this.vaultInterface.encodeFunctionData('getPoolTokens', [
|
|
116
|
+
pool.id,
|
|
117
|
+
]),
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
target: pool.address,
|
|
121
|
+
callData: this.poolInterface.encodeFunctionData('getSwapFeePercentage'),
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
target: pool.address,
|
|
125
|
+
callData: this.poolInterface.encodeFunctionData(
|
|
126
|
+
'getAmplificationParameter',
|
|
127
|
+
),
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
if (pool.poolType === 'MetaStable') {
|
|
131
|
+
poolCallData.push({
|
|
132
|
+
target: pool.address,
|
|
133
|
+
callData:
|
|
134
|
+
this.metaPoolInterface.encodeFunctionData('getScalingFactors'),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return poolCallData;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/*
|
|
141
|
+
Helper function to decodes multicall data for a Stable Pool.
|
|
142
|
+
data must contain returnData
|
|
143
|
+
startIndex is where to start in returnData. Allows this decode function to be called along with other pool types.
|
|
144
|
+
*/
|
|
145
|
+
decodeOnChainCalls(
|
|
146
|
+
pool: SubgraphPoolBase,
|
|
147
|
+
data: { success: boolean; returnData: any }[],
|
|
148
|
+
startIndex: number,
|
|
149
|
+
): [{ [address: string]: PoolState }, number] {
|
|
150
|
+
const pools = {} as { [address: string]: PoolState };
|
|
151
|
+
|
|
152
|
+
const poolTokens = decodeThrowError(
|
|
153
|
+
this.vaultInterface,
|
|
154
|
+
'getPoolTokens',
|
|
155
|
+
data[startIndex++],
|
|
156
|
+
pool.address,
|
|
157
|
+
);
|
|
158
|
+
const swapFee = decodeThrowError(
|
|
159
|
+
this.poolInterface,
|
|
160
|
+
'getSwapFeePercentage',
|
|
161
|
+
data[startIndex++],
|
|
162
|
+
pool.address,
|
|
163
|
+
)[0];
|
|
164
|
+
const amp = decodeThrowError(
|
|
165
|
+
this.poolInterface,
|
|
166
|
+
'getAmplificationParameter',
|
|
167
|
+
data[startIndex++],
|
|
168
|
+
pool.address,
|
|
169
|
+
);
|
|
170
|
+
let scalingFactors: BigNumber[] | undefined;
|
|
171
|
+
if (pool.poolType === 'MetaStable') {
|
|
172
|
+
scalingFactors = decodeThrowError(
|
|
173
|
+
this.metaPoolInterface,
|
|
174
|
+
'getScalingFactors',
|
|
175
|
+
data[startIndex++],
|
|
176
|
+
pool.address,
|
|
177
|
+
)[0];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const poolState: PoolState = {
|
|
181
|
+
swapFee: BigInt(swapFee.toString()),
|
|
182
|
+
tokens: poolTokens.tokens.reduce(
|
|
183
|
+
(ptAcc: { [address: string]: TokenState }, pt: string, j: number) => {
|
|
184
|
+
const tokenState: TokenState = {
|
|
185
|
+
balance: BigInt(poolTokens.balances[j].toString()),
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
if (scalingFactors)
|
|
189
|
+
tokenState.scalingFactor = BigInt(scalingFactors[j].toString());
|
|
190
|
+
|
|
191
|
+
ptAcc[pt.toLowerCase()] = tokenState;
|
|
192
|
+
return ptAcc;
|
|
193
|
+
},
|
|
194
|
+
{},
|
|
195
|
+
),
|
|
196
|
+
orderedTokens: poolTokens.tokens,
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
if (amp) {
|
|
200
|
+
poolState.amp = BigInt(amp.value.toString());
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
pools[pool.address] = poolState;
|
|
204
|
+
|
|
205
|
+
return [pools, startIndex];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/*
|
|
209
|
+
For stable pools there is no Swap limit. As an approx - use almost the total balance of token out as we can add any amount of tokenIn and expect some back.
|
|
210
|
+
*/
|
|
211
|
+
getSwapMaxAmount(poolPairData: StablePoolPairData, side: SwapSide): bigint {
|
|
212
|
+
return (
|
|
213
|
+
(this._upscale(
|
|
214
|
+
poolPairData.balances[poolPairData.indexOut],
|
|
215
|
+
poolPairData.scalingFactors[poolPairData.indexOut],
|
|
216
|
+
) *
|
|
217
|
+
99n) /
|
|
218
|
+
100n
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { MathSol } from '../../balancer-v2-math';
|
|
2
|
+
|
|
3
|
+
const _require = (b: boolean, message: string) => {
|
|
4
|
+
if (!b) throw new Error(message);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export class WeightedMath {
|
|
8
|
+
static _MAX_IN_RATIO = 300000000000000000n;
|
|
9
|
+
static _MAX_OUT_RATIO = 300000000000000000n;
|
|
10
|
+
|
|
11
|
+
static _calcInGivenOut(
|
|
12
|
+
balanceIn: bigint,
|
|
13
|
+
weightIn: bigint,
|
|
14
|
+
balanceOut: bigint,
|
|
15
|
+
weightOut: bigint,
|
|
16
|
+
amountsOut: bigint[],
|
|
17
|
+
): bigint[] {
|
|
18
|
+
/* https://docs.balancer.fi/reference/math/weighted-math.html#ingivenout */
|
|
19
|
+
/**********************************************************************************************
|
|
20
|
+
// outGivenOut //
|
|
21
|
+
// aI = amountIn //
|
|
22
|
+
// bI = balanceIn //
|
|
23
|
+
// bO = balanceOut / / bO \ (wO / wI) \ //
|
|
24
|
+
// aO = amountOut aI = bI * | | -------------------------- | ^ - 1 | //
|
|
25
|
+
// wI = weightIn \ \ ( bO - aO ) / / //
|
|
26
|
+
// wO = weightOut //
|
|
27
|
+
*********************************************************************************************/
|
|
28
|
+
const exponent = MathSol.divUpFixed(weightOut, weightIn);
|
|
29
|
+
return amountsOut.map(amountOut => {
|
|
30
|
+
_require(
|
|
31
|
+
amountOut <= MathSol.mulDownFixed(balanceOut, this._MAX_OUT_RATIO),
|
|
32
|
+
'Errors.MAX_OUT_RATIO',
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const denominator = balanceOut - amountOut;
|
|
36
|
+
const base = MathSol.divUpFixed(balanceOut, denominator);
|
|
37
|
+
const power = MathSol.powUpFixed(base, exponent);
|
|
38
|
+
const ratio = MathSol.sub(power, MathSol.ONE);
|
|
39
|
+
|
|
40
|
+
return MathSol.mulUpFixed(balanceIn, ratio);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Computes how many tokens can be taken out of a pool if `amountIn` are sent, given the
|
|
45
|
+
// current balances and weights.
|
|
46
|
+
static _calcOutGivenIn(
|
|
47
|
+
balanceIn: bigint,
|
|
48
|
+
weightIn: bigint,
|
|
49
|
+
balanceOut: bigint,
|
|
50
|
+
weightOut: bigint,
|
|
51
|
+
amountsIn: bigint[],
|
|
52
|
+
): bigint[] {
|
|
53
|
+
/* https://docs.balancer.fi/reference/math/weighted-math.html#outgivenin */
|
|
54
|
+
/**********************************************************************************************
|
|
55
|
+
// outGivenIn //
|
|
56
|
+
// aO = amountOut //
|
|
57
|
+
// bO = balanceOut //
|
|
58
|
+
// bI = balanceIn / / bI \ (wI / wO) \ //
|
|
59
|
+
// aI = amountIn aO = bO * | 1 - | -------------------------- | ^ | //
|
|
60
|
+
// wI = weightIn \ \ ( bI + aI ) / / //
|
|
61
|
+
// wO = weightOut //
|
|
62
|
+
**********************************************************************************************/
|
|
63
|
+
|
|
64
|
+
// Amount out, so we round down overall.
|
|
65
|
+
|
|
66
|
+
// The multiplication rounds down, and the subtrahend (power) rounds up (so the base rounds up too).
|
|
67
|
+
// Because bI / (bI + aI) <= 1, the exponent rounds down.
|
|
68
|
+
|
|
69
|
+
// Cannot exceed maximum in ratio
|
|
70
|
+
|
|
71
|
+
const exponent = MathSol.divDownFixed(weightIn, weightOut);
|
|
72
|
+
return amountsIn.map(amountIn => {
|
|
73
|
+
_require(
|
|
74
|
+
amountIn <= MathSol.mulDownFixed(balanceIn, this._MAX_IN_RATIO),
|
|
75
|
+
'Errors.MAX_IN_RATIO',
|
|
76
|
+
);
|
|
77
|
+
const denominator = balanceIn + amountIn;
|
|
78
|
+
const base = MathSol.divUpFixed(balanceIn, denominator);
|
|
79
|
+
const power = MathSol.powUpFixed(base, exponent);
|
|
80
|
+
|
|
81
|
+
return MathSol.mulDownFixed(balanceOut, MathSol.complementFixed(power));
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
2
|
+
import WeightedPoolABI from '../../../../abi/balancer-v2/weighted-pool.json';
|
|
3
|
+
import { callData, PoolState, SubgraphPoolBase, TokenState } from '../../types';
|
|
4
|
+
import { decodeThrowError, getTokenScalingFactor } from '../../utils';
|
|
5
|
+
import { SwapSide } from '../../../../constants';
|
|
6
|
+
import { BaseMinimalSwapInfoPool } from '../balancer-v2-pool';
|
|
7
|
+
import { WeightedMath } from './WeightedMath';
|
|
8
|
+
|
|
9
|
+
export type WeightedPoolPairData = {
|
|
10
|
+
tokenInBalance: bigint;
|
|
11
|
+
tokenOutBalance: bigint;
|
|
12
|
+
tokenInScalingFactor: bigint;
|
|
13
|
+
tokenOutScalingFactor: bigint;
|
|
14
|
+
tokenInWeight: bigint;
|
|
15
|
+
tokenOutWeight: bigint;
|
|
16
|
+
swapFee: bigint;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export class WeightedPool extends BaseMinimalSwapInfoPool {
|
|
21
|
+
vaultAddress: string;
|
|
22
|
+
vaultInterface: Interface;
|
|
23
|
+
poolInterface: Interface;
|
|
24
|
+
|
|
25
|
+
constructor(vaultAddress: string, vaultInterface: Interface) {
|
|
26
|
+
super();
|
|
27
|
+
this.vaultAddress = vaultAddress;
|
|
28
|
+
this.vaultInterface = vaultInterface;
|
|
29
|
+
this.poolInterface = new Interface(WeightedPoolABI);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
_onSwapGivenOut(
|
|
33
|
+
tokenAmountsOut: bigint[],
|
|
34
|
+
currentBalanceTokenIn: bigint,
|
|
35
|
+
currentBalanceTokenOut: bigint,
|
|
36
|
+
_weightIn: bigint,
|
|
37
|
+
_weightOut: bigint,
|
|
38
|
+
): bigint[] {
|
|
39
|
+
return WeightedMath._calcInGivenOut(
|
|
40
|
+
currentBalanceTokenIn,
|
|
41
|
+
_weightIn,
|
|
42
|
+
currentBalanceTokenOut,
|
|
43
|
+
_weightOut,
|
|
44
|
+
tokenAmountsOut,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
_onSwapGivenIn(
|
|
49
|
+
tokenAmountsIn: bigint[],
|
|
50
|
+
currentBalanceTokenIn: bigint,
|
|
51
|
+
currentBalanceTokenOut: bigint,
|
|
52
|
+
_weightIn: bigint,
|
|
53
|
+
_weightOut: bigint,
|
|
54
|
+
): bigint[] {
|
|
55
|
+
return WeightedMath._calcOutGivenIn(
|
|
56
|
+
currentBalanceTokenIn,
|
|
57
|
+
_weightIn,
|
|
58
|
+
currentBalanceTokenOut,
|
|
59
|
+
_weightOut,
|
|
60
|
+
tokenAmountsIn,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
Helper function to parse pool data into params for onSell function.
|
|
66
|
+
*/
|
|
67
|
+
parsePoolPairData(
|
|
68
|
+
pool: SubgraphPoolBase,
|
|
69
|
+
poolState: PoolState,
|
|
70
|
+
tokenIn: string,
|
|
71
|
+
tokenOut: string,
|
|
72
|
+
): WeightedPoolPairData {
|
|
73
|
+
const inAddress = tokenIn.toLowerCase();
|
|
74
|
+
const outAddress = tokenOut.toLowerCase();
|
|
75
|
+
|
|
76
|
+
const tIn = pool.tokens.find(t => t.address.toLowerCase() === inAddress);
|
|
77
|
+
const tOut = pool.tokens.find(t => t.address.toLowerCase() === outAddress);
|
|
78
|
+
|
|
79
|
+
if (!tIn || !tOut) return {} as WeightedPoolPairData;
|
|
80
|
+
|
|
81
|
+
const tokenInBalance = poolState.tokens[inAddress].balance;
|
|
82
|
+
const tokenOutBalance = poolState.tokens[outAddress].balance;
|
|
83
|
+
const tokenInWeight = poolState.tokens[inAddress].weight || 0n;
|
|
84
|
+
const tokenOutWeight = poolState.tokens[outAddress].weight || 0n;
|
|
85
|
+
const tokenInScalingFactor = getTokenScalingFactor(tIn.decimals);
|
|
86
|
+
const tokenOutScalingFactor = getTokenScalingFactor(tOut.decimals);
|
|
87
|
+
|
|
88
|
+
const poolPairData: WeightedPoolPairData = {
|
|
89
|
+
tokenInBalance,
|
|
90
|
+
tokenOutBalance,
|
|
91
|
+
tokenInScalingFactor,
|
|
92
|
+
tokenOutScalingFactor,
|
|
93
|
+
tokenInWeight,
|
|
94
|
+
tokenOutWeight,
|
|
95
|
+
swapFee: poolState.swapFee,
|
|
96
|
+
};
|
|
97
|
+
return poolPairData;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
Helper function to construct onchain multicall data for WeightedPool (also 'LiquidityBootstrapping' and 'Investment' pool types).
|
|
102
|
+
*/
|
|
103
|
+
getOnChainCalls(pool: SubgraphPoolBase): callData[] {
|
|
104
|
+
return [
|
|
105
|
+
{
|
|
106
|
+
target: this.vaultAddress,
|
|
107
|
+
callData: this.vaultInterface.encodeFunctionData('getPoolTokens', [
|
|
108
|
+
pool.id,
|
|
109
|
+
]),
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
target: pool.address,
|
|
113
|
+
callData: this.poolInterface.encodeFunctionData('getSwapFeePercentage'),
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
target: pool.address,
|
|
117
|
+
callData: this.poolInterface.encodeFunctionData('getNormalizedWeights'),
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/*
|
|
123
|
+
Helper function to decodes multicall data for a Weighted Pool.
|
|
124
|
+
data must contain returnData
|
|
125
|
+
startIndex is where to start in returnData. Allows this decode function to be called along with other pool types.
|
|
126
|
+
*/
|
|
127
|
+
decodeOnChainCalls(
|
|
128
|
+
pool: SubgraphPoolBase,
|
|
129
|
+
data: { success: boolean; returnData: any }[],
|
|
130
|
+
startIndex: number,
|
|
131
|
+
): [{ [address: string]: PoolState }, number] {
|
|
132
|
+
const pools = {} as { [address: string]: PoolState };
|
|
133
|
+
|
|
134
|
+
const poolTokens = decodeThrowError(
|
|
135
|
+
this.vaultInterface,
|
|
136
|
+
'getPoolTokens',
|
|
137
|
+
data[startIndex++],
|
|
138
|
+
pool.address,
|
|
139
|
+
);
|
|
140
|
+
const swapFee = decodeThrowError(
|
|
141
|
+
this.poolInterface,
|
|
142
|
+
'getSwapFeePercentage',
|
|
143
|
+
data[startIndex++],
|
|
144
|
+
pool.address,
|
|
145
|
+
)[0];
|
|
146
|
+
const normalisedWeights = decodeThrowError(
|
|
147
|
+
this.poolInterface,
|
|
148
|
+
'getNormalizedWeights',
|
|
149
|
+
data[startIndex++],
|
|
150
|
+
pool.address,
|
|
151
|
+
)[0];
|
|
152
|
+
|
|
153
|
+
const poolState: PoolState = {
|
|
154
|
+
swapFee: BigInt(swapFee.toString()),
|
|
155
|
+
tokens: poolTokens.tokens.reduce(
|
|
156
|
+
(ptAcc: { [address: string]: TokenState }, pt: string, j: number) => {
|
|
157
|
+
const tokenState: TokenState = {
|
|
158
|
+
balance: BigInt(poolTokens.balances[j].toString()),
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
if (normalisedWeights)
|
|
162
|
+
tokenState.weight = BigInt(normalisedWeights[j].toString());
|
|
163
|
+
|
|
164
|
+
ptAcc[pt.toLowerCase()] = tokenState;
|
|
165
|
+
return ptAcc;
|
|
166
|
+
},
|
|
167
|
+
{},
|
|
168
|
+
),
|
|
169
|
+
orderedTokens: poolTokens.tokens,
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
pools[pool.address] = poolState;
|
|
173
|
+
|
|
174
|
+
return [pools, startIndex];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/*
|
|
178
|
+
For weighted pools there is a Swap limit of 30%: amounts swapped may not be larger than this percentage of total balance.
|
|
179
|
+
*/
|
|
180
|
+
getSwapMaxAmount(poolPairData: WeightedPoolPairData, side: SwapSide): bigint {
|
|
181
|
+
return (
|
|
182
|
+
((side === SwapSide.SELL
|
|
183
|
+
? poolPairData.tokenInBalance
|
|
184
|
+
: poolPairData.tokenOutBalance) *
|
|
185
|
+
3n) /
|
|
186
|
+
10n
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
}
|