@paraswap/dex-lib 4.1.6 → 4.1.7-mwrappedm.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/README.md +1 -1
- package/build/abi/fluid-dex/resolver.abi.json +0 -30
- package/build/abi/m-token/WrappedM.abi.json +1708 -0
- package/build/dex/aave-v3-stata-v2/config.js +0 -13
- package/build/dex/aave-v3-stata-v2/config.js.map +1 -1
- package/build/dex/algebra/config.js +1 -1
- package/build/dex/algebra/config.js.map +1 -1
- package/build/dex/balancer-v2/pools/gyro/GyroEPool.js.map +1 -1
- package/build/dex/balancer-v3/balancer-v3-pool.d.ts +1 -6
- package/build/dex/balancer-v3/balancer-v3-pool.js +17 -45
- package/build/dex/balancer-v3/balancer-v3-pool.js.map +1 -1
- package/build/dex/balancer-v3/balancer-v3.d.ts +0 -4
- package/build/dex/balancer-v3/balancer-v3.js +4 -30
- package/build/dex/balancer-v3/balancer-v3.js.map +1 -1
- package/build/dex/balancer-v3/config.js +0 -51
- package/build/dex/balancer-v3/config.js.map +1 -1
- package/build/dex/balancer-v3/getOnChainState.d.ts +2 -1
- package/build/dex/balancer-v3/getOnChainState.js +2 -0
- package/build/dex/balancer-v3/getOnChainState.js.map +1 -1
- package/build/dex/balancer-v3/getPoolsApi.d.ts +1 -2
- package/build/dex/balancer-v3/getPoolsApi.js +10 -17
- package/build/dex/balancer-v3/getPoolsApi.js.map +1 -1
- package/build/dex/balancer-v3/getTopPoolsApi.d.ts +1 -5
- package/build/dex/balancer-v3/getTopPoolsApi.js +3 -6
- package/build/dex/balancer-v3/getTopPoolsApi.js.map +1 -1
- package/build/dex/balancer-v3/types.d.ts +1 -4
- package/build/dex/cables/cables.d.ts +1 -1
- package/build/dex/cables/cables.js +7 -26
- package/build/dex/cables/cables.js.map +1 -1
- package/build/dex/fluid-dex/config.js +2 -2
- package/build/dex/fluid-dex/constants.d.ts +1 -1
- package/build/dex/fluid-dex/constants.js +1 -2
- package/build/dex/fluid-dex/constants.js.map +1 -1
- package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.js +1 -3
- package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.js.map +1 -1
- package/build/dex/fluid-dex/fluid-dex.d.ts +5 -4
- package/build/dex/fluid-dex/fluid-dex.js +59 -61
- package/build/dex/fluid-dex/fluid-dex.js.map +1 -1
- package/build/dex/fluid-dex/types.d.ts +0 -3
- package/build/dex/index.js +2 -0
- package/build/dex/index.js.map +1 -1
- package/build/dex/m-token/config.d.ts +3 -0
- package/build/dex/m-token/config.js +19 -0
- package/build/dex/m-token/config.js.map +1 -0
- package/build/dex/m-token/m-token.d.ts +29 -0
- package/build/dex/m-token/m-token.js +145 -0
- package/build/dex/m-token/m-token.js.map +1 -0
- package/build/dex/m-token/m-wrapped-m.d.ts +17 -0
- package/build/dex/m-token/m-wrapped-m.js +50 -0
- package/build/dex/m-token/m-wrapped-m.js.map +1 -0
- package/build/dex/m-token/types.d.ts +12 -0
- package/build/dex/m-token/types.js +3 -0
- package/build/dex/m-token/types.js.map +1 -0
- package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js +0 -1
- package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js.map +1 -1
- package/build/dex/uniswap-v3/constants.d.ts +0 -2
- package/build/dex/uniswap-v3/constants.js +1 -8
- package/build/dex/uniswap-v3/constants.js.map +1 -1
- package/build/dex/uniswap-v3/contract-math/TickBitMap.d.ts +2 -2
- package/build/dex/uniswap-v3/contract-math/TickBitMap.js +8 -10
- package/build/dex/uniswap-v3/contract-math/TickBitMap.js.map +1 -1
- package/build/dex/uniswap-v3/contract-math/uniswap-v3-math.js +3 -3
- package/build/dex/uniswap-v3/contract-math/uniswap-v3-math.js.map +1 -1
- package/build/dex/uniswap-v3/forks/ramses-v2/ramses-v2-pool.js +0 -1
- package/build/dex/uniswap-v3/forks/ramses-v2/ramses-v2-pool.js.map +1 -1
- package/build/dex/uniswap-v3/forks/velodrome-slipstream/velodrome-slipstream-pool.js +0 -1
- package/build/dex/uniswap-v3/forks/velodrome-slipstream/velodrome-slipstream-pool.js.map +1 -1
- package/build/dex/uniswap-v3/types.d.ts +0 -1
- package/build/dex/uniswap-v3/types.js.map +1 -1
- package/build/dex/uniswap-v3/uniswap-v3-pool.js +1 -5
- package/build/dex/uniswap-v3/uniswap-v3-pool.js.map +1 -1
- package/build/dex/wusdm/config.js +0 -6
- package/build/dex/wusdm/config.js.map +1 -1
- package/build/generic-swap-transaction-builder.d.ts +1 -1
- package/build/generic-swap-transaction-builder.js +1 -6
- package/build/generic-swap-transaction-builder.js.map +1 -1
- package/build/implementations/local-paraswap-sdk.js +1 -1
- package/build/implementations/local-paraswap-sdk.js.map +1 -1
- package/package.json +3 -3
- package/scripts/run-dex-integration-v3.ts +4 -4
- package/src/abi/fluid-dex/resolver.abi.json +0 -30
- package/src/abi/m-token/WrappedM.abi.json +1708 -0
- package/src/dex/aave-v3-stata-v2/aave-v3-stata-v2-e2e.test.ts +32 -11
- package/src/dex/aave-v3-stata-v2/config.ts +0 -16
- package/src/dex/algebra/config.ts +1 -1
- package/src/dex/balancer-v2/balancer-v2-integration.test.ts +12 -11
- package/src/dex/balancer-v2/pools/gyro/GyroEPool.ts +1 -0
- package/src/dex/balancer-v3/balancer-v3-e2e.test.ts +0 -130
- package/src/dex/balancer-v3/balancer-v3-events.test.ts +84 -157
- package/src/dex/balancer-v3/balancer-v3-integration.test.ts +202 -103
- package/src/dex/balancer-v3/balancer-v3-pool.ts +26 -85
- package/src/dex/balancer-v3/balancer-v3.ts +2 -43
- package/src/dex/balancer-v3/config.ts +0 -51
- package/src/dex/balancer-v3/getOnChainState.ts +4 -1
- package/src/dex/balancer-v3/getPoolsApi.ts +23 -42
- package/src/dex/balancer-v3/getTopPoolsApi.ts +2 -13
- package/src/dex/balancer-v3/types.ts +2 -4
- package/src/dex/cables/cables-e2e.test.ts +40 -40
- package/src/dex/cables/cables.ts +10 -37
- package/src/dex/fluid-dex/config.ts +2 -2
- package/src/dex/fluid-dex/constants.ts +1 -2
- package/src/dex/fluid-dex/fluid-dex-e2e.test.ts +117 -61
- package/src/dex/fluid-dex/fluid-dex-liquidity-proxy.ts +0 -3
- package/src/dex/fluid-dex/fluid-dex.ts +94 -96
- package/src/dex/fluid-dex/types.ts +0 -3
- package/src/dex/index.ts +2 -0
- package/src/dex/m-token/config.ts +18 -0
- package/src/dex/m-token/m-token-e2e.test.ts +93 -0
- package/src/dex/m-token/m-token-integration.test.ts +199 -0
- package/src/dex/m-token/m-token.ts +167 -0
- package/src/dex/m-token/m-wrapped-m.ts +68 -0
- package/src/dex/m-token/types.ts +10 -0
- package/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts +0 -1
- package/src/dex/uniswap-v3/constants.ts +0 -10
- package/src/dex/uniswap-v3/contract-math/TickBitMap.ts +9 -29
- package/src/dex/uniswap-v3/contract-math/uniswap-v3-math.ts +1 -3
- package/src/dex/uniswap-v3/forks/ramses-v2/ramses-v2-pool.ts +0 -1
- package/src/dex/uniswap-v3/forks/velodrome-slipstream/velodrome-slipstream-pool.ts +0 -1
- package/src/dex/uniswap-v3/types.ts +0 -1
- package/src/dex/uniswap-v3/uniswap-v3-integration.test.ts +302 -647
- package/src/dex/uniswap-v3/uniswap-v3-pool.ts +1 -11
- package/src/dex/wusdm/config.ts +0 -7
- package/src/dex/wusdm/wusdm-e2e.test.ts +0 -20
- package/src/generic-swap-transaction-builder.ts +2 -10
- package/src/implementations/local-paraswap-sdk.ts +1 -1
- package/tests/constants-e2e.ts +8 -63
- package/tests/tenderly-simulation.ts +0 -3
- package/tests/utils-e2e.ts +7 -4
- package/src/abi/balancer-v3/directionalFeeHook.json +0 -684
- package/src/abi/balancer-v3/stableSurgeHook.json +0 -976
- package/src/dex/balancer-v3/balancer-hooks-events.test.ts +0 -166
- package/src/dex/balancer-v3/balancer-stableSurge.test.ts +0 -110
- package/src/dex/balancer-v3/balancer-test-helpers.ts +0 -199
- package/src/dex/balancer-v3/hooks/balancer-hook-event-subscriber.ts +0 -212
- package/src/dex/balancer-v3/hooks/directionalFeeHook.ts +0 -51
- package/src/dex/balancer-v3/hooks/loadHooksConfig.ts +0 -12
- package/src/dex/balancer-v3/hooks/stableSurgeHook.ts +0 -198
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import dotenv from 'dotenv';
|
|
3
3
|
dotenv.config();
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Interface, Result } from '@ethersproject/abi';
|
|
6
6
|
import { DummyDexHelper } from '../../dex-helper/index';
|
|
7
|
-
import { Network, SwapSide } from '../../constants';
|
|
7
|
+
import { Network, NULL_ADDRESS, SwapSide } from '../../constants';
|
|
8
8
|
import { BI_POWS } from '../../bigint-constants';
|
|
9
9
|
import { BalancerV3 } from './balancer-v3';
|
|
10
10
|
import {
|
|
@@ -13,6 +13,201 @@ import {
|
|
|
13
13
|
checkPoolsLiquidity,
|
|
14
14
|
} from '../../../tests/utils';
|
|
15
15
|
import { Tokens } from '../../../tests/constants-e2e';
|
|
16
|
+
import { BalancerV3Config } from './config';
|
|
17
|
+
import { BalancerV3Data, Step } from './types';
|
|
18
|
+
import { Address, ExchangePrices, PoolPrices } from '../../types';
|
|
19
|
+
import balancerBatchRouterAbi from '../../abi/balancer-v3/batch-router.json';
|
|
20
|
+
import balancerRouterAbi from '../../abi/balancer-v3/router.json';
|
|
21
|
+
|
|
22
|
+
function getQuerySwapSingleTokenCalldata(
|
|
23
|
+
routerAddress: Address,
|
|
24
|
+
routerInterface: Interface,
|
|
25
|
+
amounts: bigint[],
|
|
26
|
+
step: Step,
|
|
27
|
+
side: SwapSide,
|
|
28
|
+
) {
|
|
29
|
+
return amounts
|
|
30
|
+
.filter(amount => amount !== 0n)
|
|
31
|
+
.map(amount => {
|
|
32
|
+
return {
|
|
33
|
+
target: routerAddress,
|
|
34
|
+
callData: routerInterface.encodeFunctionData(
|
|
35
|
+
side === SwapSide.SELL
|
|
36
|
+
? `querySwapSingleTokenExactIn`
|
|
37
|
+
: `querySwapSingleTokenExactOut`,
|
|
38
|
+
[
|
|
39
|
+
step.pool,
|
|
40
|
+
step.swapInput.tokenIn,
|
|
41
|
+
step.swapInput.tokenOut,
|
|
42
|
+
amount,
|
|
43
|
+
NULL_ADDRESS,
|
|
44
|
+
'0x',
|
|
45
|
+
],
|
|
46
|
+
),
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getQuerySwapMultiTokenCalldata(
|
|
52
|
+
routerAddress: Address,
|
|
53
|
+
routerInterface: Interface,
|
|
54
|
+
amounts: bigint[],
|
|
55
|
+
steps: Step[],
|
|
56
|
+
side: SwapSide,
|
|
57
|
+
) {
|
|
58
|
+
const tokenIn = steps[0].swapInput.tokenIn;
|
|
59
|
+
const stepsNew = steps.map(s => ({
|
|
60
|
+
pool: s.pool,
|
|
61
|
+
tokenOut: s.swapInput.tokenOut,
|
|
62
|
+
isBuffer: s.isBuffer,
|
|
63
|
+
}));
|
|
64
|
+
return amounts
|
|
65
|
+
.filter(amount => amount !== 0n)
|
|
66
|
+
.map(amount => {
|
|
67
|
+
let args: any[] = [];
|
|
68
|
+
if (side === SwapSide.SELL)
|
|
69
|
+
args = [
|
|
70
|
+
{
|
|
71
|
+
tokenIn,
|
|
72
|
+
steps: stepsNew,
|
|
73
|
+
exactAmountIn: amount,
|
|
74
|
+
minAmountOut: 0n,
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
else
|
|
78
|
+
args = [
|
|
79
|
+
{
|
|
80
|
+
tokenIn,
|
|
81
|
+
steps: stepsNew,
|
|
82
|
+
exactAmountOut: amount,
|
|
83
|
+
maxAmountIn: 0n,
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
return {
|
|
87
|
+
target: routerAddress,
|
|
88
|
+
callData: routerInterface.encodeFunctionData(
|
|
89
|
+
side === SwapSide.SELL ? `querySwapExactIn` : `querySwapExactOut`,
|
|
90
|
+
[args, NULL_ADDRESS, '0x'],
|
|
91
|
+
),
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function querySinglePathPrices(
|
|
97
|
+
network: number,
|
|
98
|
+
side: SwapSide,
|
|
99
|
+
balancerV3: BalancerV3,
|
|
100
|
+
blockNumber: number,
|
|
101
|
+
price: PoolPrices<BalancerV3Data>,
|
|
102
|
+
amounts: bigint[],
|
|
103
|
+
) {
|
|
104
|
+
const balancerRouter = new Interface(balancerRouterAbi);
|
|
105
|
+
const readerCallData = getQuerySwapSingleTokenCalldata(
|
|
106
|
+
BalancerV3Config.BalancerV3[network].balancerRouterAddress,
|
|
107
|
+
balancerRouter,
|
|
108
|
+
amounts,
|
|
109
|
+
price.data.steps[0],
|
|
110
|
+
side,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const expectedPrices = [0n];
|
|
114
|
+
for (const call of readerCallData) {
|
|
115
|
+
try {
|
|
116
|
+
const result = await balancerV3.dexHelper.provider.call(
|
|
117
|
+
{
|
|
118
|
+
to: call.target,
|
|
119
|
+
data: call.callData,
|
|
120
|
+
},
|
|
121
|
+
blockNumber,
|
|
122
|
+
);
|
|
123
|
+
const parsed = balancerRouter.decodeFunctionResult(
|
|
124
|
+
side === SwapSide.SELL
|
|
125
|
+
? `querySwapSingleTokenExactIn`
|
|
126
|
+
: `querySwapSingleTokenExactOut`,
|
|
127
|
+
result,
|
|
128
|
+
);
|
|
129
|
+
expectedPrices.push(BigInt(parsed[0]._hex));
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.log('Error in querySinglePathPrices', error);
|
|
132
|
+
expectedPrices.push(0n);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return expectedPrices;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function queryMultiPathPrices(
|
|
139
|
+
network: number,
|
|
140
|
+
side: SwapSide,
|
|
141
|
+
balancerV3: BalancerV3,
|
|
142
|
+
blockNumber: number,
|
|
143
|
+
price: PoolPrices<BalancerV3Data>,
|
|
144
|
+
amounts: bigint[],
|
|
145
|
+
) {
|
|
146
|
+
const balancerBatchRouter = new Interface(balancerBatchRouterAbi);
|
|
147
|
+
const readerCallData = getQuerySwapMultiTokenCalldata(
|
|
148
|
+
BalancerV3Config.BalancerV3[network].balancerBatchRouterAddress,
|
|
149
|
+
balancerBatchRouter,
|
|
150
|
+
amounts,
|
|
151
|
+
price.data.steps,
|
|
152
|
+
side,
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
const expectedPrices = [0n];
|
|
156
|
+
for (const call of readerCallData) {
|
|
157
|
+
try {
|
|
158
|
+
const result = await balancerV3.dexHelper.provider.call(
|
|
159
|
+
{
|
|
160
|
+
to: call.target,
|
|
161
|
+
data: call.callData,
|
|
162
|
+
},
|
|
163
|
+
blockNumber,
|
|
164
|
+
);
|
|
165
|
+
const parsed = balancerBatchRouter.decodeFunctionResult(
|
|
166
|
+
side === SwapSide.SELL ? `querySwapExactIn` : `querySwapExactOut`,
|
|
167
|
+
result,
|
|
168
|
+
);
|
|
169
|
+
expectedPrices.push(BigInt(parsed[2][0]._hex));
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.log('Error in queryMultiPathPrices', error);
|
|
172
|
+
expectedPrices.push(0n);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return expectedPrices;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Note - this is currently needed because queries won't work with multicall but should be updated in future
|
|
179
|
+
async function checkOnChainPricingNonMulti(
|
|
180
|
+
network: number,
|
|
181
|
+
side: SwapSide,
|
|
182
|
+
balancerV3: BalancerV3,
|
|
183
|
+
blockNumber: number,
|
|
184
|
+
prices: ExchangePrices<BalancerV3Data>,
|
|
185
|
+
amounts: bigint[],
|
|
186
|
+
) {
|
|
187
|
+
// test match for each returned price
|
|
188
|
+
for (const price of prices) {
|
|
189
|
+
let expectedPrices: bigint[] = [];
|
|
190
|
+
if (price.data.steps.length === 1 && !price.data.steps[0].isBuffer)
|
|
191
|
+
expectedPrices = await querySinglePathPrices(
|
|
192
|
+
network,
|
|
193
|
+
side,
|
|
194
|
+
balancerV3,
|
|
195
|
+
blockNumber,
|
|
196
|
+
price,
|
|
197
|
+
amounts,
|
|
198
|
+
);
|
|
199
|
+
else
|
|
200
|
+
expectedPrices = await queryMultiPathPrices(
|
|
201
|
+
network,
|
|
202
|
+
side,
|
|
203
|
+
balancerV3,
|
|
204
|
+
blockNumber,
|
|
205
|
+
price,
|
|
206
|
+
amounts,
|
|
207
|
+
);
|
|
208
|
+
expect(price.prices).toEqual(expectedPrices);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
16
211
|
|
|
17
212
|
async function testPricingOnNetwork(
|
|
18
213
|
balancerV3: BalancerV3,
|
|
@@ -639,9 +834,9 @@ describe('BalancerV3', function () {
|
|
|
639
834
|
|
|
640
835
|
describe('Buffer, Nested Rate', () => {
|
|
641
836
|
/*
|
|
642
|
-
The Gnosis pool, 0x272d6be442e30d7c87390edeb9b96f1e84cecd8d uses a rate provider that is nested.
|
|
643
|
-
So unwrap rate does not equal rate between aave wsteth and eth.
|
|
644
|
-
This particular case the rate provider accounts for growth of wsteth in terms of weth and the additional aave yield.
|
|
837
|
+
The Gnosis pool, 0x272d6be442e30d7c87390edeb9b96f1e84cecd8d uses a rate provider that is nested.
|
|
838
|
+
So unwrap rate does not equal rate between aave wsteth and eth.
|
|
839
|
+
This particular case the rate provider accounts for growth of wsteth in terms of weth and the additional aave yield.
|
|
645
840
|
This highlighted that rateProvider can not be used for buffer wrap/unwrap which instead should use erc4626 rate.
|
|
646
841
|
*/
|
|
647
842
|
const dexHelper = new DummyDexHelper(network);
|
|
@@ -703,10 +898,10 @@ describe('BalancerV3', function () {
|
|
|
703
898
|
describe('Token/Underlying With Different Decimals', () => {
|
|
704
899
|
/*
|
|
705
900
|
Mainnet Pool, 0x5dd88b3aa3143173eb26552923922bdf33f50949 has an ERC4626 token with 18 decimals that uses a 6 decimal underlying.
|
|
706
|
-
Note for maths: Instead of manually adding support for each ERC4626 implementation (e.g. stata with Ray maths) we always use an
|
|
901
|
+
Note for maths: Instead of manually adding support for each ERC4626 implementation (e.g. stata with Ray maths) we always use an
|
|
707
902
|
18 decimal scaled rate and do 18 decimal maths to convert. We may end up loosing 100% accuracy but thats deemed acceptable.
|
|
708
903
|
*/
|
|
709
|
-
describe('Buffer wrap 6decimal>18decimal', () => {
|
|
904
|
+
describe.only('Buffer wrap 6decimal>18decimal', () => {
|
|
710
905
|
const dexHelper = new DummyDexHelper(network);
|
|
711
906
|
|
|
712
907
|
const tokens = Tokens[network];
|
|
@@ -865,102 +1060,6 @@ describe('BalancerV3', function () {
|
|
|
865
1060
|
});
|
|
866
1061
|
});
|
|
867
1062
|
});
|
|
868
|
-
|
|
869
|
-
describe('Base', () => {
|
|
870
|
-
const network = Network.BASE;
|
|
871
|
-
|
|
872
|
-
describe('Stable Pool', () => {
|
|
873
|
-
const dexHelper = new DummyDexHelper(network);
|
|
874
|
-
|
|
875
|
-
const tokens = Tokens[network];
|
|
876
|
-
const srcTokenSymbol = 'wstETH';
|
|
877
|
-
const destTokenSymbol = 'WETH';
|
|
878
|
-
|
|
879
|
-
const amountsForSell = [
|
|
880
|
-
0n,
|
|
881
|
-
1n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
882
|
-
2n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
883
|
-
3n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
884
|
-
4n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
885
|
-
5n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
886
|
-
6n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
887
|
-
7n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
888
|
-
8n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
889
|
-
9n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
890
|
-
10n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
891
|
-
];
|
|
892
|
-
|
|
893
|
-
const amountsForBuy = [
|
|
894
|
-
0n,
|
|
895
|
-
1n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
896
|
-
2n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
897
|
-
3n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
898
|
-
4n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
899
|
-
5n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
900
|
-
6n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
901
|
-
7n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
902
|
-
8n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
903
|
-
9n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
904
|
-
10n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
905
|
-
];
|
|
906
|
-
|
|
907
|
-
beforeAll(async () => {
|
|
908
|
-
blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
|
|
909
|
-
balancerV3 = new BalancerV3(network, dexKey, dexHelper);
|
|
910
|
-
if (balancerV3.initializePricing) {
|
|
911
|
-
await balancerV3.initializePricing(blockNumber);
|
|
912
|
-
}
|
|
913
|
-
});
|
|
914
|
-
|
|
915
|
-
it('getPoolIdentifiers and getPricesVolume SELL', async function () {
|
|
916
|
-
await testPricingOnNetwork(
|
|
917
|
-
balancerV3,
|
|
918
|
-
network,
|
|
919
|
-
dexKey,
|
|
920
|
-
blockNumber,
|
|
921
|
-
srcTokenSymbol,
|
|
922
|
-
destTokenSymbol,
|
|
923
|
-
SwapSide.SELL,
|
|
924
|
-
amountsForSell,
|
|
925
|
-
);
|
|
926
|
-
});
|
|
927
|
-
|
|
928
|
-
it('getPoolIdentifiers and getPricesVolume BUY', async function () {
|
|
929
|
-
await testPricingOnNetwork(
|
|
930
|
-
balancerV3,
|
|
931
|
-
network,
|
|
932
|
-
dexKey,
|
|
933
|
-
blockNumber,
|
|
934
|
-
srcTokenSymbol,
|
|
935
|
-
destTokenSymbol,
|
|
936
|
-
SwapSide.BUY,
|
|
937
|
-
amountsForBuy,
|
|
938
|
-
);
|
|
939
|
-
});
|
|
940
|
-
|
|
941
|
-
it('getTopPoolsForToken', async function () {
|
|
942
|
-
// We have to check without calling initializePricing, because
|
|
943
|
-
// pool-tracker is not calling that function
|
|
944
|
-
const newBalancerV3 = new BalancerV3(network, dexKey, dexHelper);
|
|
945
|
-
if (newBalancerV3.updatePoolState) {
|
|
946
|
-
await newBalancerV3.updatePoolState();
|
|
947
|
-
}
|
|
948
|
-
const poolLiquidity = await newBalancerV3.getTopPoolsForToken(
|
|
949
|
-
tokens[srcTokenSymbol].address,
|
|
950
|
-
10,
|
|
951
|
-
);
|
|
952
|
-
console.log(`${srcTokenSymbol} Top Pools:`, poolLiquidity);
|
|
953
|
-
|
|
954
|
-
if (!newBalancerV3.hasConstantPriceLargeAmounts) {
|
|
955
|
-
checkPoolsLiquidity(
|
|
956
|
-
poolLiquidity,
|
|
957
|
-
Tokens[network][srcTokenSymbol].address,
|
|
958
|
-
dexKey,
|
|
959
|
-
);
|
|
960
|
-
}
|
|
961
|
-
});
|
|
962
|
-
});
|
|
963
|
-
});
|
|
964
1063
|
});
|
|
965
1064
|
|
|
966
1065
|
// Add back once multicall queries are working
|
|
@@ -29,11 +29,6 @@ import {
|
|
|
29
29
|
isStableMutableState,
|
|
30
30
|
} from './stablePool';
|
|
31
31
|
import { BI_POWS } from '../../bigint-constants';
|
|
32
|
-
import {
|
|
33
|
-
HookStateMap,
|
|
34
|
-
HooksConfigMap,
|
|
35
|
-
} from './hooks/balancer-hook-event-subscriber';
|
|
36
|
-
import { StableSurge, StableSurgeHookState } from './hooks/stableSurgeHook';
|
|
37
32
|
|
|
38
33
|
export const WAD = BI_POWS[18];
|
|
39
34
|
|
|
@@ -53,8 +48,8 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
53
48
|
interfaces: {
|
|
54
49
|
[name: string]: Interface;
|
|
55
50
|
};
|
|
51
|
+
|
|
56
52
|
vault: Vault;
|
|
57
|
-
hooksConfigMap: HooksConfigMap = {};
|
|
58
53
|
|
|
59
54
|
constructor(
|
|
60
55
|
readonly parentName: string,
|
|
@@ -101,10 +96,6 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
101
96
|
this.vault = new Vault();
|
|
102
97
|
}
|
|
103
98
|
|
|
104
|
-
setHooksConfigMap(hooksConfigMap: HooksConfigMap) {
|
|
105
|
-
this.hooksConfigMap = hooksConfigMap;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
99
|
/**
|
|
109
100
|
* The function is called every time any of the subscribed
|
|
110
101
|
* addresses release log. The function accepts the current
|
|
@@ -143,11 +134,7 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
143
134
|
blockNumber: number,
|
|
144
135
|
): Promise<DeepReadonly<PoolStateMap>> {
|
|
145
136
|
const block = await this.dexHelper.provider.getBlock(blockNumber);
|
|
146
|
-
const apiPoolStateMap = await getPoolsApi(
|
|
147
|
-
this.network,
|
|
148
|
-
this.hooksConfigMap,
|
|
149
|
-
block.timestamp,
|
|
150
|
-
);
|
|
137
|
+
const apiPoolStateMap = await getPoolsApi(this.network, block.timestamp);
|
|
151
138
|
const allOnChainPools = await getOnChainState(
|
|
152
139
|
this.network,
|
|
153
140
|
apiPoolStateMap,
|
|
@@ -173,10 +160,7 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
173
160
|
existingPoolState: DeepReadonly<PoolStateMap>,
|
|
174
161
|
): Promise<DeepReadonly<PoolStateMap> | null> {
|
|
175
162
|
// Get all latest pools from API
|
|
176
|
-
const apiPoolStateMap = await getPoolsApi(
|
|
177
|
-
this.network,
|
|
178
|
-
this.hooksConfigMap,
|
|
179
|
-
);
|
|
163
|
+
const apiPoolStateMap = await getPoolsApi(this.network);
|
|
180
164
|
|
|
181
165
|
// Filter out pools that already exist in existing state
|
|
182
166
|
const newApiPools = Object.entries(apiPoolStateMap).reduce(
|
|
@@ -202,10 +186,19 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
202
186
|
this.interfaces,
|
|
203
187
|
);
|
|
204
188
|
|
|
189
|
+
// Filter out pools with hooks and paused pools from new state
|
|
190
|
+
// TODO this won't be necessary once API has this filter option
|
|
191
|
+
const filteredNewPools = Object.entries(newOnChainPools)
|
|
192
|
+
.filter(([_, pool]) => !(pool.hasHook || pool.isPoolPaused))
|
|
193
|
+
.reduce((acc, [address, pool]) => {
|
|
194
|
+
acc[address] = pool;
|
|
195
|
+
return acc;
|
|
196
|
+
}, {} as PoolStateMap);
|
|
197
|
+
|
|
205
198
|
// Merge existing pools with new pools
|
|
206
199
|
return {
|
|
207
200
|
...existingPoolState,
|
|
208
|
-
...
|
|
201
|
+
...filteredNewPools,
|
|
209
202
|
};
|
|
210
203
|
}
|
|
211
204
|
|
|
@@ -225,12 +218,10 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
225
218
|
i < newState[poolAddress].balancesLiveScaled18.length;
|
|
226
219
|
i++
|
|
227
220
|
) {
|
|
228
|
-
newState[poolAddress].balancesLiveScaled18[i] +=
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
newState[poolAddress].tokenRates[i] || WAD,
|
|
233
|
-
);
|
|
221
|
+
newState[poolAddress].balancesLiveScaled18[i] += this.toScaled18(
|
|
222
|
+
BigInt(event.args.amountsAddedRaw[i]),
|
|
223
|
+
newState[poolAddress].scalingFactors[i],
|
|
224
|
+
);
|
|
234
225
|
}
|
|
235
226
|
newState[poolAddress].totalSupply = BigInt(event.args.totalSupply);
|
|
236
227
|
|
|
@@ -253,12 +244,10 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
253
244
|
i < newState[poolAddress].balancesLiveScaled18.length;
|
|
254
245
|
i++
|
|
255
246
|
) {
|
|
256
|
-
newState[poolAddress].balancesLiveScaled18[i] -=
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
newState[poolAddress].tokenRates[i] || WAD,
|
|
261
|
-
);
|
|
247
|
+
newState[poolAddress].balancesLiveScaled18[i] -= this.toScaled18(
|
|
248
|
+
BigInt(event.args.amountsRemovedRaw[i]),
|
|
249
|
+
newState[poolAddress].scalingFactors[i],
|
|
250
|
+
);
|
|
262
251
|
}
|
|
263
252
|
newState[poolAddress].totalSupply = BigInt(event.args.totalSupply);
|
|
264
253
|
|
|
@@ -286,17 +275,14 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
286
275
|
this.logger.error(`swapEvent - token index not found in pool state`);
|
|
287
276
|
return null;
|
|
288
277
|
}
|
|
289
|
-
newState[poolAddress].balancesLiveScaled18[tokenInIndex] +=
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
newState[poolAddress].tokenRates[tokenInIndex] || WAD,
|
|
294
|
-
);
|
|
278
|
+
newState[poolAddress].balancesLiveScaled18[tokenInIndex] += this.toScaled18(
|
|
279
|
+
BigInt(event.args.amountIn),
|
|
280
|
+
newState[poolAddress].scalingFactors[tokenInIndex],
|
|
281
|
+
);
|
|
295
282
|
newState[poolAddress].balancesLiveScaled18[tokenOutIndex] -=
|
|
296
|
-
this.
|
|
283
|
+
this.toScaled18(
|
|
297
284
|
BigInt(event.args.amountOut),
|
|
298
285
|
newState[poolAddress].scalingFactors[tokenOutIndex],
|
|
299
|
-
newState[poolAddress].tokenRates[tokenOutIndex] || WAD,
|
|
300
286
|
);
|
|
301
287
|
|
|
302
288
|
return newState;
|
|
@@ -405,7 +391,6 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
405
391
|
amountRaw: bigint,
|
|
406
392
|
swapKind: SwapKind,
|
|
407
393
|
timestamp: number,
|
|
408
|
-
hookStateMap: HookStateMap,
|
|
409
394
|
): bigint {
|
|
410
395
|
if (amountRaw === 0n) return 0n;
|
|
411
396
|
|
|
@@ -419,19 +404,6 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
419
404
|
let outputAmountRaw = 0n;
|
|
420
405
|
for (const i of indices) {
|
|
421
406
|
const step = steps[i];
|
|
422
|
-
|
|
423
|
-
// If the pool has a hook we fetch latest hook state for use in maths
|
|
424
|
-
let hookState = undefined;
|
|
425
|
-
if ('hookAddress' in step.poolState && step.poolState.hookAddress) {
|
|
426
|
-
hookState = hookStateMap[step.poolState.hookAddress];
|
|
427
|
-
if (!hookState) {
|
|
428
|
-
this.logger.error(
|
|
429
|
-
`getSwapResult hookState not found ${step.poolState.hookAddress}`,
|
|
430
|
-
);
|
|
431
|
-
return 0n;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
407
|
// If its a Stable Pool with an updating Amp factor calculate current Amp value
|
|
436
408
|
if (
|
|
437
409
|
step.poolState.poolType === 'STABLE' &&
|
|
@@ -446,24 +418,7 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
446
418
|
BigInt(timestamp),
|
|
447
419
|
);
|
|
448
420
|
}
|
|
449
|
-
// StableSurge hook uses Amp as part of maths
|
|
450
|
-
if (step.poolState.hookType === StableSurge.type && hookState) {
|
|
451
|
-
const poolHookState = (hookState as StableSurgeHookState)[
|
|
452
|
-
step.poolState.poolAddress.toLowerCase()
|
|
453
|
-
];
|
|
454
|
-
if (!poolHookState) {
|
|
455
|
-
this.logger.error(
|
|
456
|
-
`getSwapResult StableSurge hookState not found ${step.poolState.hookAddress}`,
|
|
457
|
-
);
|
|
458
|
-
return 0n;
|
|
459
|
-
}
|
|
460
|
-
hookState = {
|
|
461
|
-
...poolHookState,
|
|
462
|
-
amp: step.poolState.amp,
|
|
463
|
-
};
|
|
464
|
-
}
|
|
465
421
|
}
|
|
466
|
-
|
|
467
422
|
outputAmountRaw = this.vault.swap(
|
|
468
423
|
{
|
|
469
424
|
...step.swapInput,
|
|
@@ -471,7 +426,6 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
471
426
|
swapKind,
|
|
472
427
|
},
|
|
473
428
|
step.poolState,
|
|
474
|
-
hookState,
|
|
475
429
|
);
|
|
476
430
|
// Next step uses output from previous step as input
|
|
477
431
|
amount = outputAmountRaw;
|
|
@@ -743,19 +697,6 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
743
697
|
}
|
|
744
698
|
|
|
745
699
|
toScaled18(amount: bigint, scalingFactor: bigint): bigint {
|
|
746
|
-
// (amount * scalingFactor).mulUp(tokenRate);
|
|
747
700
|
return (amount * scalingFactor * WAD) / WAD;
|
|
748
701
|
}
|
|
749
|
-
|
|
750
|
-
toScaled18ApplyRateRoundDown(
|
|
751
|
-
amount: bigint,
|
|
752
|
-
scalingFactor: bigint,
|
|
753
|
-
tokenRate: bigint,
|
|
754
|
-
): bigint {
|
|
755
|
-
return this.mulDown(amount * scalingFactor, tokenRate);
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
mulDown(a: bigint, b: bigint): bigint {
|
|
759
|
-
return (a * b) / WAD;
|
|
760
|
-
}
|
|
761
702
|
}
|
|
@@ -27,13 +27,11 @@ import balancerRouterAbi from '../../abi/balancer-v3/router.json';
|
|
|
27
27
|
import balancerBatchRouterAbi from '../../abi/balancer-v3/batch-router.json';
|
|
28
28
|
import { getGasCost } from './getGasCost';
|
|
29
29
|
import { Block } from '@ethersproject/abstract-provider';
|
|
30
|
-
import { BalancerEventHook } from './hooks/balancer-hook-event-subscriber';
|
|
31
30
|
|
|
32
31
|
const MAX_UINT256 =
|
|
33
32
|
'115792089237316195423570985008687907853269984665640564039457584007913129639935';
|
|
34
|
-
const POOL_UPDATE_TTL =
|
|
33
|
+
const POOL_UPDATE_TTL = 5 * 60; // 5mins
|
|
35
34
|
const RATE_UPDATE_TTL = 1 * 60; // 1min
|
|
36
|
-
const HOOK_UPDATE_TTL = 5 * 60; // 5min
|
|
37
35
|
|
|
38
36
|
type DeepMutable<T> = {
|
|
39
37
|
-readonly [P in keyof T]: T[P] extends object ? DeepMutable<T[P]> : T[P];
|
|
@@ -41,7 +39,6 @@ type DeepMutable<T> = {
|
|
|
41
39
|
|
|
42
40
|
export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
43
41
|
protected eventPools: BalancerV3EventPool;
|
|
44
|
-
protected eventHooks: BalancerEventHook;
|
|
45
42
|
|
|
46
43
|
readonly hasConstantPriceLargeAmounts = false;
|
|
47
44
|
// Vault can handle native
|
|
@@ -57,7 +54,6 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
57
54
|
balancerBatchRouter: Interface;
|
|
58
55
|
updateNewPoolsTimer?: NodeJS.Timeout;
|
|
59
56
|
updateRatesTimer?: NodeJS.Timeout;
|
|
60
|
-
updateHooksTimer?: NodeJS.Timeout;
|
|
61
57
|
|
|
62
58
|
latestBlock?: Block;
|
|
63
59
|
|
|
@@ -68,12 +64,6 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
68
64
|
) {
|
|
69
65
|
super(dexHelper, dexKey);
|
|
70
66
|
this.logger = dexHelper.getLogger(dexKey);
|
|
71
|
-
this.eventHooks = new BalancerEventHook(
|
|
72
|
-
dexKey,
|
|
73
|
-
network,
|
|
74
|
-
dexHelper,
|
|
75
|
-
this.logger,
|
|
76
|
-
);
|
|
77
67
|
this.eventPools = new BalancerV3EventPool(
|
|
78
68
|
dexKey,
|
|
79
69
|
network,
|
|
@@ -89,8 +79,6 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
89
79
|
// for pricing requests. It is optional for a DEX to
|
|
90
80
|
// implement this function
|
|
91
81
|
async initializePricing(blockNumber: number) {
|
|
92
|
-
await this.eventHooks.initialize(blockNumber);
|
|
93
|
-
this.eventPools.setHooksConfigMap(this.eventHooks.hooksConfigMap);
|
|
94
82
|
await this.eventPools.initialize(blockNumber);
|
|
95
83
|
|
|
96
84
|
// This will periodically query API and add any new pools to pool state
|
|
@@ -114,17 +102,6 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
114
102
|
}
|
|
115
103
|
}, RATE_UPDATE_TTL * 1000);
|
|
116
104
|
}
|
|
117
|
-
|
|
118
|
-
// This will periodically update any hook state that can't be tracked by events
|
|
119
|
-
if (!this.updateHooksTimer) {
|
|
120
|
-
this.updateHooksTimer = setInterval(async () => {
|
|
121
|
-
try {
|
|
122
|
-
await this.updateHooksState();
|
|
123
|
-
} catch (e) {
|
|
124
|
-
this.logger.error(`${this.dexKey}: Failed to update hook state:`, e);
|
|
125
|
-
}
|
|
126
|
-
}, HOOK_UPDATE_TTL * 1000);
|
|
127
|
-
}
|
|
128
105
|
}
|
|
129
106
|
|
|
130
107
|
getAdapters(side: SwapSide): null {
|
|
@@ -284,7 +261,6 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
284
261
|
unitAmount,
|
|
285
262
|
swapKind,
|
|
286
263
|
block.timestamp,
|
|
287
|
-
this.eventHooks.getState(blockNumber) || {},
|
|
288
264
|
);
|
|
289
265
|
|
|
290
266
|
const poolExchangePrice: PoolPrices<BalancerV3Data> = {
|
|
@@ -307,7 +283,6 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
307
283
|
amounts[j],
|
|
308
284
|
swapKind,
|
|
309
285
|
block.timestamp,
|
|
310
|
-
this.eventHooks.getState(blockNumber) || {},
|
|
311
286
|
);
|
|
312
287
|
}
|
|
313
288
|
}
|
|
@@ -584,10 +559,6 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
584
559
|
await this.eventPools.updateStatePools();
|
|
585
560
|
}
|
|
586
561
|
|
|
587
|
-
async updateHooksState(): Promise<void> {
|
|
588
|
-
await this.eventHooks.updateHookState();
|
|
589
|
-
}
|
|
590
|
-
|
|
591
562
|
// Returns list of top pools based on liquidity. Max
|
|
592
563
|
// limit number pools should be returned.
|
|
593
564
|
async getTopPoolsForToken(
|
|
@@ -600,12 +571,7 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
600
571
|
})
|
|
601
572
|
.map(([address]) => address);
|
|
602
573
|
|
|
603
|
-
const topPools = await getTopPoolsApi(
|
|
604
|
-
this.network,
|
|
605
|
-
poolsWithToken,
|
|
606
|
-
count,
|
|
607
|
-
this.eventHooks.hooksConfigMap,
|
|
608
|
-
);
|
|
574
|
+
const topPools = await getTopPoolsApi(this.network, poolsWithToken, count);
|
|
609
575
|
|
|
610
576
|
return topPools.map(pool => {
|
|
611
577
|
const tokens = pool.poolTokens
|
|
@@ -644,12 +610,5 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
644
610
|
`${this.dexKey}: cleared updateRatesTimer before shutting down`,
|
|
645
611
|
);
|
|
646
612
|
}
|
|
647
|
-
if (this.updateHooksTimer) {
|
|
648
|
-
clearInterval(this.updateHooksTimer);
|
|
649
|
-
this.updateHooksTimer = undefined;
|
|
650
|
-
this.logger.info(
|
|
651
|
-
`${this.dexKey}: cleared updateHooksTimer before shutting down`,
|
|
652
|
-
);
|
|
653
|
-
}
|
|
654
613
|
}
|
|
655
614
|
}
|