@paraswap/dex-lib 2.16.7 → 2.16.8-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 +4 -4
- 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/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/tests/constants-e2e.ts +33 -8
- 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
|
@@ -2,60 +2,44 @@ import { Interface } from '@ethersproject/abi';
|
|
|
2
2
|
import { assert, DeepReadonly } from 'ts-essentials';
|
|
3
3
|
import _, { keyBy } from 'lodash';
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
AdapterExchangeParam,
|
|
6
6
|
Address,
|
|
7
7
|
ExchangePrices,
|
|
8
|
-
PoolPrices,
|
|
9
8
|
Log,
|
|
10
|
-
AdapterExchangeParam,
|
|
11
|
-
SimpleExchangeParam,
|
|
12
|
-
PoolLiquidity,
|
|
13
9
|
Logger,
|
|
10
|
+
PoolLiquidity,
|
|
11
|
+
PoolPrices,
|
|
12
|
+
SimpleExchangeParam,
|
|
13
|
+
Token,
|
|
14
14
|
} from '../../types';
|
|
15
|
-
import {
|
|
16
|
-
SwapSide,
|
|
17
|
-
ETHER_ADDRESS,
|
|
18
|
-
NULL_ADDRESS,
|
|
19
|
-
MAX_INT,
|
|
20
|
-
MAX_UINT,
|
|
21
|
-
Network,
|
|
22
|
-
SUBGRAPH_TIMEOUT,
|
|
23
|
-
} from '../../constants';
|
|
15
|
+
import { ETHER_ADDRESS, MAX_INT, MAX_UINT, Network, NULL_ADDRESS, SUBGRAPH_TIMEOUT, SwapSide, } from '../../constants';
|
|
24
16
|
import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
|
|
25
|
-
import { StablePool
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
17
|
+
import { StablePool } from './pools/stable/StablePool';
|
|
18
|
+
import { WeightedPool } from './pools/weighted/WeightedPool';
|
|
19
|
+
import { PhantomStablePool } from './pools/phantom-stable/PhantomStablePool';
|
|
20
|
+
import { LinearPool } from './pools/linear/LinearPool';
|
|
28
21
|
import VaultABI from '../../abi/balancer-v2/vault.json';
|
|
29
22
|
import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
|
|
30
|
-
import {
|
|
23
|
+
import { getBigIntPow, getDexKeysWithNetwork } from '../../utils';
|
|
31
24
|
import { IDex } from '../../dex/idex';
|
|
32
25
|
import { IDexHelper } from '../../dex-helper';
|
|
33
26
|
import {
|
|
34
|
-
PoolState,
|
|
35
|
-
SubgraphPoolBase,
|
|
36
|
-
BalancerV2Data,
|
|
37
27
|
BalancerParam,
|
|
28
|
+
BalancerPoolTypes,
|
|
38
29
|
BalancerSwap,
|
|
30
|
+
BalancerV2Data,
|
|
39
31
|
OptimizedBalancerV2Data,
|
|
40
|
-
|
|
41
|
-
PoolStateMap,
|
|
32
|
+
PoolState,
|
|
42
33
|
PoolStateCache,
|
|
43
|
-
|
|
34
|
+
PoolStateMap,
|
|
44
35
|
SubgraphPoolAddressDictionary,
|
|
36
|
+
SubgraphPoolBase,
|
|
37
|
+
SwapTypes,
|
|
45
38
|
} from './types';
|
|
46
39
|
import { SimpleExchange } from '../simple-exchange';
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
49
|
-
|
|
50
|
-
isSameAddress,
|
|
51
|
-
poolGetMainTokens,
|
|
52
|
-
poolGetPathForTokenInOut,
|
|
53
|
-
} from './utils';
|
|
54
|
-
import {
|
|
55
|
-
MIN_USD_LIQUIDITY_TO_FETCH,
|
|
56
|
-
STABLE_GAS_COST,
|
|
57
|
-
VARIABLE_GAS_COST_PER_CYCLE,
|
|
58
|
-
} from './constants';
|
|
40
|
+
import { Adapters, BalancerConfig } from './config';
|
|
41
|
+
import { getAllPoolsUsedInPaths, isSameAddress, poolGetMainTokens, poolGetPathForTokenInOut, } from './utils';
|
|
42
|
+
import { MIN_USD_LIQUIDITY_TO_FETCH, STABLE_GAS_COST, VARIABLE_GAS_COST_PER_CYCLE } from './constants';
|
|
59
43
|
|
|
60
44
|
const fetchAllPools = `query ($count: Int) {
|
|
61
45
|
pools: pools(
|
|
@@ -160,7 +144,7 @@ export class BalancerV2EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
160
144
|
constructor(
|
|
161
145
|
parentName: string,
|
|
162
146
|
protected network: number,
|
|
163
|
-
|
|
147
|
+
public vaultAddress: Address,
|
|
164
148
|
protected subgraphURL: string,
|
|
165
149
|
protected dexHelper: IDexHelper,
|
|
166
150
|
logger: Logger,
|
|
@@ -308,6 +292,7 @@ export class BalancerV2EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
308
292
|
async generateState(blockNumber: number): Promise<Readonly<PoolStateMap>> {
|
|
309
293
|
const allPools = await this.fetchAllSubgraphPools();
|
|
310
294
|
this.allPools = allPools;
|
|
295
|
+
|
|
311
296
|
const eventSupportedPools = allPools.filter(
|
|
312
297
|
pool =>
|
|
313
298
|
this.eventSupportedPoolTypes.includes(pool.poolType) &&
|
|
@@ -317,6 +302,7 @@ export class BalancerV2EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
317
302
|
eventSupportedPools,
|
|
318
303
|
blockNumber,
|
|
319
304
|
);
|
|
305
|
+
|
|
320
306
|
return allPoolsLatestState;
|
|
321
307
|
}
|
|
322
308
|
|
|
@@ -362,6 +348,10 @@ export class BalancerV2EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
362
348
|
return null;
|
|
363
349
|
}
|
|
364
350
|
|
|
351
|
+
if(subgraphPool.poolType !== BalancerPoolTypes.Weighted && side === SwapSide.BUY) {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
|
|
365
355
|
const amountWithoutZero = amounts.slice(1);
|
|
366
356
|
const pool = this.pools[subgraphPool.poolType];
|
|
367
357
|
|
|
@@ -407,13 +397,22 @@ export class BalancerV2EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
407
397
|
const unitResult =
|
|
408
398
|
checkedUnitVolume === 0n
|
|
409
399
|
? 0n
|
|
410
|
-
:
|
|
400
|
+
: side === SwapSide.SELL
|
|
401
|
+
? pool.onSell([checkedUnitVolume], poolPairData as any)[0]
|
|
402
|
+
: pool.onBuy([checkedUnitVolume], poolPairData as any)[0];
|
|
411
403
|
|
|
412
404
|
const prices: bigint[] = new Array(amounts.length).fill(0n);
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
405
|
+
|
|
406
|
+
const outputs =
|
|
407
|
+
side === SwapSide.SELL
|
|
408
|
+
? pool.onSell(
|
|
409
|
+
amountWithoutZero.slice(0, nonZeroAmountIndex),
|
|
410
|
+
poolPairData as any,
|
|
411
|
+
)
|
|
412
|
+
: pool.onBuy(
|
|
413
|
+
amountWithoutZero.slice(0, nonZeroAmountIndex),
|
|
414
|
+
poolPairData as any,
|
|
415
|
+
);
|
|
417
416
|
|
|
418
417
|
assert(
|
|
419
418
|
outputs.length <= prices.length,
|
|
@@ -476,7 +475,7 @@ export class BalancerV2
|
|
|
476
475
|
extends SimpleExchange
|
|
477
476
|
implements IDex<BalancerV2Data, BalancerParam, OptimizedBalancerV2Data>
|
|
478
477
|
{
|
|
479
|
-
|
|
478
|
+
public eventPools: BalancerV2EventPool;
|
|
480
479
|
|
|
481
480
|
readonly hasConstantPriceLargeAmounts = false;
|
|
482
481
|
readonly isFeeOnTransferSupported = false;
|
|
@@ -495,8 +494,8 @@ export class BalancerV2
|
|
|
495
494
|
constructor(
|
|
496
495
|
protected network: Network,
|
|
497
496
|
dexKey: string,
|
|
498
|
-
|
|
499
|
-
|
|
497
|
+
public dexHelper: IDexHelper,
|
|
498
|
+
public vaultAddress: Address = BalancerConfig[dexKey][network]
|
|
500
499
|
.vaultAddress,
|
|
501
500
|
protected subgraphURL: string = BalancerConfig[dexKey][network].subgraphURL,
|
|
502
501
|
protected adapters = Adapters[network],
|
|
@@ -597,7 +596,7 @@ export class BalancerV2
|
|
|
597
596
|
}
|
|
598
597
|
|
|
599
598
|
getPoolsWithTokenPair(from: Token, to: Token): SubgraphPoolBase[] {
|
|
600
|
-
|
|
599
|
+
const pools = this.eventPools.allPools
|
|
601
600
|
.filter(p => {
|
|
602
601
|
const fromMain = p.mainTokens.find(
|
|
603
602
|
token => token.address.toLowerCase() === from.address.toLowerCase(),
|
|
@@ -613,13 +612,13 @@ export class BalancerV2
|
|
|
613
612
|
// USDC -> DAI in a pool where bbaUSD is nested (ie: MAI / bbaUSD)
|
|
614
613
|
!(fromMain.isDeeplyNested && toMain.isDeeplyNested)
|
|
615
614
|
);
|
|
616
|
-
})
|
|
617
|
-
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
return pools.slice(0, 10);
|
|
618
618
|
}
|
|
619
619
|
|
|
620
620
|
getAdapters(side: SwapSide): { name: string; index: number }[] | null {
|
|
621
|
-
|
|
622
|
-
return this.adapters;
|
|
621
|
+
return this.adapters[side] ? this.adapters[side] : null;
|
|
623
622
|
}
|
|
624
623
|
|
|
625
624
|
async getPoolIdentifiers(
|
|
@@ -628,7 +627,6 @@ export class BalancerV2
|
|
|
628
627
|
side: SwapSide,
|
|
629
628
|
blockNumber: number,
|
|
630
629
|
): Promise<string[]> {
|
|
631
|
-
if (side === SwapSide.BUY) return [];
|
|
632
630
|
const _from = this.dexHelper.config.wrapETH(from);
|
|
633
631
|
const _to = this.dexHelper.config.wrapETH(to);
|
|
634
632
|
|
|
@@ -676,7 +674,6 @@ export class BalancerV2
|
|
|
676
674
|
blockNumber: number,
|
|
677
675
|
limitPools?: string[],
|
|
678
676
|
): Promise<null | ExchangePrices<BalancerV2Data>> {
|
|
679
|
-
if (side === SwapSide.BUY) return null;
|
|
680
677
|
try {
|
|
681
678
|
const _from = this.dexHelper.config.wrapETH(from);
|
|
682
679
|
const _to = this.dexHelper.config.wrapETH(to);
|
|
@@ -710,6 +707,7 @@ export class BalancerV2
|
|
|
710
707
|
_to.address,
|
|
711
708
|
allowedPools,
|
|
712
709
|
this.poolAddressMap,
|
|
710
|
+
side,
|
|
713
711
|
);
|
|
714
712
|
|
|
715
713
|
// Missing pools are pools that don't already exist in event or non-event
|
|
@@ -743,6 +741,7 @@ export class BalancerV2
|
|
|
743
741
|
_to.address,
|
|
744
742
|
pool,
|
|
745
743
|
this.poolAddressMap,
|
|
744
|
+
side,
|
|
746
745
|
);
|
|
747
746
|
|
|
748
747
|
let pathAmounts = amounts;
|
|
@@ -918,7 +917,7 @@ export class BalancerV2
|
|
|
918
917
|
};
|
|
919
918
|
}
|
|
920
919
|
|
|
921
|
-
|
|
920
|
+
public getBalancerParam(
|
|
922
921
|
srcToken: string,
|
|
923
922
|
destToken: string,
|
|
924
923
|
srcAmount: string,
|
|
@@ -945,18 +944,23 @@ export class BalancerV2
|
|
|
945
944
|
decimals: 18,
|
|
946
945
|
}).address;
|
|
947
946
|
|
|
948
|
-
|
|
947
|
+
let path = poolGetPathForTokenInOut(
|
|
949
948
|
_srcToken,
|
|
950
949
|
_destToken,
|
|
951
950
|
pool,
|
|
952
951
|
this.poolAddressMap,
|
|
952
|
+
side,
|
|
953
953
|
);
|
|
954
954
|
|
|
955
|
+
if(side === SwapSide.BUY) {
|
|
956
|
+
path = path.reverse();
|
|
957
|
+
}
|
|
958
|
+
|
|
955
959
|
const _swaps = path.map((hop, index) => ({
|
|
956
960
|
poolId: hop.pool.id,
|
|
957
961
|
assetInIndex: swapOffset + index,
|
|
958
962
|
assetOutIndex: swapOffset + index + 1,
|
|
959
|
-
amount: index === 0 ? swapData.amount
|
|
963
|
+
amount: (side === SwapSide.SELL && index === 0 || side === SwapSide.BUY && index === path.length - 1) ? swapData.amount : '0',
|
|
960
964
|
userData: '0x',
|
|
961
965
|
}));
|
|
962
966
|
|
|
@@ -983,7 +987,7 @@ export class BalancerV2
|
|
|
983
987
|
|
|
984
988
|
const params: BalancerParam = [
|
|
985
989
|
side === SwapSide.SELL ? SwapTypes.SwapExactIn : SwapTypes.SwapExactOut,
|
|
986
|
-
swaps,
|
|
990
|
+
side === SwapSide.SELL ? swaps : swaps.reverse(),
|
|
987
991
|
assets,
|
|
988
992
|
funds,
|
|
989
993
|
limits,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DexParams } from './types';
|
|
2
|
-
import { DexConfigMap } from '../../types';
|
|
3
|
-
import { Network } from '../../constants';
|
|
2
|
+
import { AdapterMappings, DexConfigMap } from '../../types';
|
|
3
|
+
import { Network, SwapSide } from '../../constants';
|
|
4
4
|
|
|
5
5
|
export const BalancerConfig: DexConfigMap<DexParams> = {
|
|
6
6
|
BalancerV2: {
|
|
@@ -42,37 +42,25 @@ export const BalancerConfig: DexConfigMap<DexParams> = {
|
|
|
42
42
|
// },
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
export const Adapters: {
|
|
46
|
-
[
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
[Network.
|
|
55
|
-
{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
|
|
66
|
-
[Network.ARBITRUM]: [
|
|
67
|
-
{
|
|
68
|
-
name: 'ArbitrumAdapter01',
|
|
69
|
-
index: 5,
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
[Network.OPTIMISM]: [
|
|
73
|
-
{
|
|
74
|
-
name: 'OptimismAdapter01',
|
|
75
|
-
index: 4,
|
|
76
|
-
},
|
|
77
|
-
],
|
|
45
|
+
export const Adapters: Record<number, AdapterMappings> = {
|
|
46
|
+
[Network.MAINNET]: {
|
|
47
|
+
[SwapSide.SELL]: [{ name: 'Adapter02', index: 9 }],
|
|
48
|
+
[SwapSide.BUY]: [{ name: 'BuyAdapter', index: 9 }],
|
|
49
|
+
},
|
|
50
|
+
[Network.POLYGON]: {
|
|
51
|
+
[SwapSide.SELL]: [{ name: 'PolygonAdapter01', index: 9 }],
|
|
52
|
+
[SwapSide.BUY]: [{ name: 'PolygonBuyAdapter', index: 6 }],
|
|
53
|
+
},
|
|
54
|
+
[Network.FANTOM]:{
|
|
55
|
+
[SwapSide.SELL]: [{ name: 'FantomAdapter01', index: 5 }],
|
|
56
|
+
[SwapSide.BUY]: [{ name: 'FantomBuyAdapter', index: 4 }],
|
|
57
|
+
},
|
|
58
|
+
[Network.ARBITRUM]: {
|
|
59
|
+
[SwapSide.SELL]: [{ name: 'ArbitrumAdapter01', index: 5 }],
|
|
60
|
+
[SwapSide.BUY]: [{ name: 'ArbitrumBuyAdapter', index: 6 }],
|
|
61
|
+
},
|
|
62
|
+
[Network.OPTIMISM]: {
|
|
63
|
+
[SwapSide.SELL]: [{ name: 'OptimismAdapter01', index: 4 }],
|
|
64
|
+
[SwapSide.BUY]: [{ name: 'OptimismBuyAdapter', index: 5 }],
|
|
65
|
+
},
|
|
78
66
|
};
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { MathSol } from '../balancer-v2-math';
|
|
2
|
+
import { WeightedPoolPairData } from './weighted/WeightedPool';
|
|
3
|
+
import { StablePoolPairData } from './stable/StablePool';
|
|
4
|
+
|
|
5
|
+
export class BasePool {
|
|
6
|
+
_subtractSwapFeeAmount(amount: bigint, _swapFeePercentage: bigint): bigint {
|
|
7
|
+
// This returns amount - fee amount, so we round up (favoring a higher fee amount).
|
|
8
|
+
const feeAmount = MathSol.mulUpFixed(amount, _swapFeePercentage);
|
|
9
|
+
return amount - feeAmount;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
_addFeeAmount(amount: bigint, _swapFeePercentage: bigint): bigint {
|
|
13
|
+
return MathSol.divUpFixed(
|
|
14
|
+
amount,
|
|
15
|
+
MathSol.complementFixed(_swapFeePercentage),
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// These methods use fixed versions to match SC scaling
|
|
20
|
+
_upscaleArray(amounts: bigint[], scalingFactors: bigint[]): bigint[] {
|
|
21
|
+
return amounts.map((a, i) => MathSol.mulUpFixed(a, scalingFactors[i]));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
_upscale(amount: bigint, scalingFactor: bigint): bigint {
|
|
25
|
+
return MathSol.mulUpFixed(amount, scalingFactor);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
_downscaleDown(amount: bigint, scalingFactor: bigint): bigint {
|
|
29
|
+
return MathSol.divDownFixed(amount, scalingFactor);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
_downscaleUp(amount: bigint, scalingFactor: bigint): bigint {
|
|
33
|
+
return MathSol.divUpFixed(amount, scalingFactor);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
_nullifyIfMaxAmountExceeded(amountToTrade: bigint, swapMax: bigint): bigint {
|
|
37
|
+
return swapMax >= amountToTrade ? amountToTrade : 0n;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export abstract class BaseGeneralPool extends BasePool {
|
|
42
|
+
// Swap Hooks
|
|
43
|
+
onBuy(amounts: bigint[], poolPairData: StablePoolPairData): bigint[] {
|
|
44
|
+
return this._swapGivenOut(
|
|
45
|
+
amounts,
|
|
46
|
+
poolPairData.balances,
|
|
47
|
+
poolPairData.indexIn,
|
|
48
|
+
poolPairData.indexOut,
|
|
49
|
+
poolPairData.scalingFactors,
|
|
50
|
+
poolPairData.swapFee,
|
|
51
|
+
poolPairData.amp,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Modification: this is inspired from the function onSwap which is in the original contract
|
|
56
|
+
onSell(amounts: bigint[], poolPairData: StablePoolPairData): bigint[] {
|
|
57
|
+
// _validateIndexes(indexIn, indexOut, _getTotalTokens());
|
|
58
|
+
// uint256[] memory scalingFactors = _scalingFactors();
|
|
59
|
+
return this._swapGivenIn(
|
|
60
|
+
amounts,
|
|
61
|
+
poolPairData.balances,
|
|
62
|
+
poolPairData.indexIn,
|
|
63
|
+
poolPairData.indexOut,
|
|
64
|
+
poolPairData.scalingFactors,
|
|
65
|
+
poolPairData.swapFee,
|
|
66
|
+
poolPairData.amp,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
_swapGivenIn(
|
|
71
|
+
tokenAmountsIn: bigint[],
|
|
72
|
+
balances: bigint[],
|
|
73
|
+
indexIn: number,
|
|
74
|
+
indexOut: number,
|
|
75
|
+
scalingFactors: bigint[],
|
|
76
|
+
_swapFeePercentage: bigint,
|
|
77
|
+
_amplificationParameter: bigint,
|
|
78
|
+
): bigint[] {
|
|
79
|
+
// Fees are subtracted before scaling, to reduce the complexity of the rounding direction analysis.
|
|
80
|
+
const tokenAmountsInWithFee = tokenAmountsIn.map(a =>
|
|
81
|
+
this._subtractSwapFeeAmount(a, _swapFeePercentage),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const balancesUpscaled = this._upscaleArray(balances, scalingFactors);
|
|
85
|
+
const tokenAmountsInScaled = tokenAmountsInWithFee.map(a =>
|
|
86
|
+
this._upscale(a, scalingFactors[indexIn]),
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const amountsOut = this._onSwapGivenIn(
|
|
90
|
+
tokenAmountsInScaled,
|
|
91
|
+
balancesUpscaled,
|
|
92
|
+
indexIn,
|
|
93
|
+
indexOut,
|
|
94
|
+
_amplificationParameter,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// amountOut tokens are exiting the Pool, so we round down.
|
|
98
|
+
return amountsOut.map(a =>
|
|
99
|
+
this._downscaleDown(a, scalingFactors[indexOut]),
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
_swapGivenOut(
|
|
104
|
+
tokenAmountsOut: bigint[],
|
|
105
|
+
balances: bigint[],
|
|
106
|
+
indexIn: number,
|
|
107
|
+
indexOut: number,
|
|
108
|
+
scalingFactors: bigint[],
|
|
109
|
+
_swapFeePercentage: bigint,
|
|
110
|
+
_amplificationParameter: bigint,
|
|
111
|
+
): bigint[] {
|
|
112
|
+
const balancesUpscaled = this._upscaleArray(balances, scalingFactors);
|
|
113
|
+
const tokenAmountsOutScaled = tokenAmountsOut.map(a =>
|
|
114
|
+
this._upscale(a, scalingFactors[indexOut]),
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
let amountsIn: bigint[];
|
|
118
|
+
try {
|
|
119
|
+
amountsIn = this._onSwapGivenOut(
|
|
120
|
+
tokenAmountsOutScaled,
|
|
121
|
+
balancesUpscaled,
|
|
122
|
+
indexIn,
|
|
123
|
+
indexOut,
|
|
124
|
+
_amplificationParameter,
|
|
125
|
+
);
|
|
126
|
+
} catch (e) {
|
|
127
|
+
amountsIn = new Array(tokenAmountsOut.length).fill(0n);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// amountIn tokens are entering the Pool, so we round up.
|
|
131
|
+
const amountsInDownscaled = amountsIn.map(a =>
|
|
132
|
+
this._downscaleUp(a, scalingFactors[indexIn]),
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// Fees are added after scaling happens, to reduce the complexity of the rounding direction analysis.
|
|
136
|
+
return amountsInDownscaled.map(a =>
|
|
137
|
+
this._subtractSwapFeeAmount(a, _swapFeePercentage),
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/*
|
|
142
|
+
* @dev Called when a swap with the Pool occurs, where the amount of tokens entering the Pool is known.
|
|
143
|
+
*
|
|
144
|
+
* Returns the amount of tokens that will be taken from the Pool in return.
|
|
145
|
+
*
|
|
146
|
+
* All amounts inside `swapRequest` and `balances` are upscaled. The swap fee has already been deducted from
|
|
147
|
+
* `swapRequest.amount`.
|
|
148
|
+
*
|
|
149
|
+
* The return value is also considered upscaled, and will be downscaled (rounding down) before returning it to the
|
|
150
|
+
* Vault.
|
|
151
|
+
*/
|
|
152
|
+
abstract _onSwapGivenIn(
|
|
153
|
+
tokenAmountsIn: bigint[],
|
|
154
|
+
balances: bigint[],
|
|
155
|
+
indexIn: number,
|
|
156
|
+
indexOut: number,
|
|
157
|
+
_amplificationParameter: bigint,
|
|
158
|
+
): bigint[];
|
|
159
|
+
|
|
160
|
+
abstract _onSwapGivenOut(
|
|
161
|
+
tokenAmountsOut: bigint[],
|
|
162
|
+
balances: bigint[],
|
|
163
|
+
indexIn: number,
|
|
164
|
+
indexOut: number,
|
|
165
|
+
_amplificationParameter: bigint,
|
|
166
|
+
): bigint[];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export abstract class BaseMinimalSwapInfoPool extends BasePool {
|
|
170
|
+
// Swap Hooks
|
|
171
|
+
|
|
172
|
+
// This is inspired from the function onSwap which is in the original contract
|
|
173
|
+
onBuy(
|
|
174
|
+
tokenAmountsOut: bigint[],
|
|
175
|
+
poolPairData: WeightedPoolPairData,
|
|
176
|
+
): bigint[] {
|
|
177
|
+
// uint256 scalingFactorTokenIn = _scalingFactor(request.tokenIn);
|
|
178
|
+
// uint256 scalingFactorTokenOut = _scalingFactor(request.tokenOut);
|
|
179
|
+
|
|
180
|
+
// All token amounts are upscaled.
|
|
181
|
+
const balanceTokenIn = this._upscale(
|
|
182
|
+
poolPairData.tokenInBalance,
|
|
183
|
+
poolPairData.tokenInScalingFactor,
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
const balanceTokenOut = this._upscale(
|
|
187
|
+
poolPairData.tokenOutBalance,
|
|
188
|
+
poolPairData.tokenOutScalingFactor,
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const tokenAmountsOutScaled = tokenAmountsOut.map(a =>
|
|
192
|
+
this._upscale(a, poolPairData.tokenOutScalingFactor),
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
let amountsIn: bigint[];
|
|
196
|
+
try {
|
|
197
|
+
amountsIn = this._onSwapGivenOut(
|
|
198
|
+
tokenAmountsOutScaled,
|
|
199
|
+
balanceTokenIn,
|
|
200
|
+
balanceTokenOut,
|
|
201
|
+
poolPairData.tokenInWeight,
|
|
202
|
+
poolPairData.tokenOutWeight,
|
|
203
|
+
);
|
|
204
|
+
} catch (e) {
|
|
205
|
+
amountsIn = new Array(tokenAmountsOut.length).fill(0n);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// amountIn tokens are entering the Pool, so we round up.
|
|
209
|
+
const amountsInDownscaled = amountsIn.map(a =>
|
|
210
|
+
this._downscaleUp(a, poolPairData.tokenInScalingFactor),
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
// Fees are added after scaling happens, to reduce the complexity of the rounding direction analysis.
|
|
214
|
+
return amountsInDownscaled.map(a =>
|
|
215
|
+
this._addFeeAmount(a, poolPairData.swapFee),
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Modification: this is inspired from the function onSwap which is in the original contract
|
|
220
|
+
onSell(
|
|
221
|
+
tokenAmountsIn: bigint[],
|
|
222
|
+
poolPairData: WeightedPoolPairData,
|
|
223
|
+
): bigint[] {
|
|
224
|
+
// uint256 _scalingFactorTokenIn = _scalingFactor(request.tokenIn);
|
|
225
|
+
// uint256 _scalingFactorTokenOut = _scalingFactor(request.tokenOut);
|
|
226
|
+
|
|
227
|
+
// Fees are subtracted before scaling, to reduce the complexity of the rounding direction analysis.
|
|
228
|
+
const tokenAmountsInWithFee = tokenAmountsIn.map(a =>
|
|
229
|
+
this._subtractSwapFeeAmount(a, poolPairData.swapFee),
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// All token amounts are upscaled.
|
|
233
|
+
const balanceTokenIn = this._upscale(
|
|
234
|
+
poolPairData.tokenInBalance,
|
|
235
|
+
poolPairData.tokenInScalingFactor,
|
|
236
|
+
);
|
|
237
|
+
const balanceTokenOut = this._upscale(
|
|
238
|
+
poolPairData.tokenOutBalance,
|
|
239
|
+
poolPairData.tokenOutScalingFactor,
|
|
240
|
+
);
|
|
241
|
+
const tokenAmountsInScaled = tokenAmountsInWithFee.map(a =>
|
|
242
|
+
this._upscale(a, poolPairData.tokenInScalingFactor),
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
const amountsOut = this._onSwapGivenIn(
|
|
246
|
+
tokenAmountsInScaled,
|
|
247
|
+
balanceTokenIn,
|
|
248
|
+
balanceTokenOut,
|
|
249
|
+
poolPairData.tokenInWeight,
|
|
250
|
+
poolPairData.tokenOutWeight,
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
// amountOut tokens are exiting the Pool, so we round down.
|
|
254
|
+
return amountsOut.map(a =>
|
|
255
|
+
this._downscaleDown(a, poolPairData.tokenOutScalingFactor),
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
abstract _onSwapGivenIn(
|
|
260
|
+
tokenAmountsIn: bigint[],
|
|
261
|
+
currentBalanceTokenIn: bigint,
|
|
262
|
+
currentBalanceTokenOut: bigint,
|
|
263
|
+
_weightIn: bigint,
|
|
264
|
+
_weightOut: bigint,
|
|
265
|
+
): bigint[];
|
|
266
|
+
|
|
267
|
+
abstract _onSwapGivenOut(
|
|
268
|
+
tokenAmountsOut: bigint[],
|
|
269
|
+
currentBalanceTokenIn: bigint,
|
|
270
|
+
currentBalanceTokenOut: bigint,
|
|
271
|
+
_weightIn: bigint,
|
|
272
|
+
_weightOut: bigint,
|
|
273
|
+
): bigint[];
|
|
274
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MathSol } from '
|
|
1
|
+
import { MathSol } from '../../balancer-v2-math';
|
|
2
2
|
|
|
3
3
|
/*
|
|
4
4
|
Note when comparing vs smart contract:
|
|
@@ -11,6 +11,7 @@ type Params = {
|
|
|
11
11
|
fee: bigint;
|
|
12
12
|
lowerTarget: bigint;
|
|
13
13
|
upperTarget: bigint;
|
|
14
|
+
rate?: bigint;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
export function _calcBptOutPerMainIn(
|
|
@@ -262,16 +263,16 @@ export function _calcTokensOutGivenExactBptIn(
|
|
|
262
263
|
bptIndex: number,
|
|
263
264
|
): bigint[] {
|
|
264
265
|
/**********************************************************************************************
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
266
|
+
// exactBPTInForTokensOut //
|
|
267
|
+
// (per token) //
|
|
268
|
+
// aO = tokenAmountOut / bptIn \ //
|
|
269
|
+
// b = tokenBalance a0 = b * | --------------------- | //
|
|
270
|
+
// bptIn = bptAmountIn \ bptTotalSupply / //
|
|
271
|
+
// bpt = bptTotalSupply //
|
|
272
|
+
**********************************************************************************************/
|
|
272
273
|
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
// Since we're computing an amount out, we round down overall. This means rounding down on both the
|
|
275
|
+
// multiplication and division.
|
|
275
276
|
|
|
276
277
|
const bptRatio = MathSol.divDownFixed(bptAmountIn, bptTotalSupply);
|
|
277
278
|
const amountsOut: bigint[] = new Array(balances.length);
|