@paraswap/dex-lib 4.0.6-rfq-pub-sub.3 → 4.0.6
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/prettier.xml +7 -0
- package/.idea/vcs.xml +6 -0
- package/build/abi/fluid-dex/fluid-dex.abi.json +579 -25
- package/build/abi/integral/factory.json +333 -0
- package/build/abi/integral/oracle.json +501 -0
- package/build/abi/{inception/inception-ineth-pool.json → integral/pool.json} +522 -543
- package/build/abi/{wombat/pool.json → integral/relayer.json} +720 -473
- package/build/dex/aave-v1/aave-v1.d.ts +1 -2
- package/build/dex/aave-v1/aave-v1.js +0 -23
- package/build/dex/aave-v1/aave-v1.js.map +1 -1
- package/build/dex/fluid-dex/fluid-dex-generate-pool.d.ts +49 -0
- package/build/dex/fluid-dex/fluid-dex-generate-pool.js +104 -0
- package/build/dex/fluid-dex/fluid-dex-generate-pool.js.map +1 -0
- package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.d.ts +1 -1
- package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.js.map +1 -1
- package/build/dex/fluid-dex/fluid-dex-pool.js +1 -2
- package/build/dex/fluid-dex/fluid-dex-pool.js.map +1 -1
- package/build/dex/fluid-dex/fluid-dex.d.ts +21 -2
- package/build/dex/fluid-dex/fluid-dex.js +108 -37
- package/build/dex/fluid-dex/fluid-dex.js.map +1 -1
- package/build/dex/fluid-dex/types.d.ts +3 -1
- package/build/dex/generic-rfq/generic-rfq.js +2 -1
- package/build/dex/generic-rfq/generic-rfq.js.map +1 -1
- package/build/dex/generic-rfq/rate-fetcher.d.ts +1 -4
- package/build/dex/generic-rfq/rate-fetcher.js +20 -52
- package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
- package/build/dex/integral/config.d.ts +4 -0
- package/build/dex/integral/config.js +20 -0
- package/build/dex/integral/config.js.map +1 -0
- package/build/dex/integral/context.d.ts +40 -0
- package/build/dex/integral/context.js +158 -0
- package/build/dex/integral/context.js.map +1 -0
- package/build/dex/integral/integral-factory.d.ts +24 -0
- package/build/dex/integral/integral-factory.js +95 -0
- package/build/dex/integral/integral-factory.js.map +1 -0
- package/build/dex/integral/integral-pool.d.ts +50 -0
- package/build/dex/integral/integral-pool.js +149 -0
- package/build/dex/integral/integral-pool.js.map +1 -0
- package/build/dex/integral/integral-pricing.d.ts +18 -0
- package/build/dex/integral/integral-pricing.js +114 -0
- package/build/dex/integral/integral-pricing.js.map +1 -0
- package/build/dex/integral/integral-relayer.d.ts +42 -0
- package/build/dex/integral/integral-relayer.js +192 -0
- package/build/dex/integral/integral-relayer.js.map +1 -0
- package/build/dex/integral/integral-token.d.ts +27 -0
- package/build/dex/integral/integral-token.js +59 -0
- package/build/dex/integral/integral-token.js.map +1 -0
- package/build/dex/integral/integral.d.ts +41 -0
- package/build/dex/integral/integral.js +376 -0
- package/build/dex/integral/integral.js.map +1 -0
- package/build/dex/integral/types.d.ts +85 -0
- package/build/dex/integral/types.js +9 -0
- package/build/dex/integral/types.js.map +1 -0
- package/build/dex/integral/utils-e2e.d.ts +9 -0
- package/build/dex/integral/utils-e2e.js +131 -0
- package/build/dex/integral/utils-e2e.js.map +1 -0
- package/build/dex/integral/utils.d.ts +17 -0
- package/build/dex/integral/utils.js +94 -0
- package/build/dex/integral/utils.js.map +1 -0
- package/build/dex/jarvis.d.ts +1 -2
- package/build/dex/jarvis.js +0 -58
- package/build/dex/jarvis.js.map +1 -1
- package/build/dex/platypus/platypus.d.ts +1 -2
- package/build/dex/platypus/platypus.js +0 -45
- package/build/dex/platypus/platypus.js.map +1 -1
- package/build/dex/stable-pool.js +8 -1
- package/build/dex/stable-pool.js.map +1 -1
- package/build/dex/swaap-v1/swaap-v1.d.ts +1 -2
- package/build/dex/swaap-v1/swaap-v1.js +0 -14
- package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
- package/build/dex/trader-joe-v2.1/optimizer.d.ts +2 -0
- package/build/dex/trader-joe-v2.1/optimizer.js +47 -0
- package/build/dex/trader-joe-v2.1/optimizer.js.map +1 -0
- package/build/dex/zerox/index.d.ts +26 -4
- package/build/dex/zerox/index.js +42 -50
- package/build/dex/zerox/index.js.map +1 -1
- package/build/dex/zerox/types.d.ts +0 -29
- package/build/dex/zerox/types.js +1 -8
- package/build/dex/zerox/types.js.map +1 -1
- package/build/dex-helper/dummy-dex-helper.js +0 -7
- package/build/dex-helper/dummy-dex-helper.js.map +1 -1
- package/build/dex-helper/icache.d.ts +0 -2
- package/package.json +1 -1
- package/src/abi/fluid-dex/fluid-dex.abi.json +581 -25
- package/src/dex/fluid-dex/constants.ts +1 -0
- package/src/dex/fluid-dex/fluid-dex-e2e.test.ts +17 -0
- package/src/dex/fluid-dex/fluid-dex-events.test.ts +55 -5
- package/src/dex/fluid-dex/fluid-dex-liquidity-proxy.ts +1 -2
- package/src/dex/fluid-dex/fluid-dex-pool.ts +138 -0
- package/src/dex/fluid-dex/fluid-dex.ts +221 -69
- package/src/dex/fluid-dex/types.ts +3 -1
- package/src/dex/generic-rfq/generic-rfq.ts +6 -1
- package/src/dex/generic-rfq/rate-fetcher.ts +42 -77
- package/src/dex-helper/dummy-dex-helper.ts +0 -13
- package/src/dex-helper/icache.ts +0 -4
- package/tests/constants-e2e.ts +5 -0
- package/.vscode/launch.json +0 -53
- package/.vscode/settings.json +0 -2
- package/.vscode/tasks.json +0 -15
- package/build/abi/inception/inception-ratio-feed.json +0 -329
- package/build/abi/inception/inception-vault.json +0 -991
- package/build/abi/uniswap-v3/AlienBaseV3Router.abi.json +0 -52
- package/build/abi/usual-m-smart-m/usualM.abi.json +0 -483
- package/build/abi/usual-m-usd0/usualCollateralDao.abi.json +0 -681
- package/build/abi/usual-m-wrapped-m/usualM.abi.json +0 -509
- package/build/dex/aave-v2/tokens-avalanche.json +0 -44
- package/build/dex/aave-v2/tokens-mainnet.json +0 -188
- package/build/dex/aave-v2/tokens-polygon.json +0 -44
- package/build/dex/balancer-v3/abi/balancerBatchRouter.d.ts +0 -729
- package/build/dex/balancer-v3/abi/balancerBatchRouter.js +0 -732
- package/build/dex/balancer-v3/abi/balancerBatchRouter.js.map +0 -1
- package/build/dex/balancer-v3/abi/balancerRouter.d.ts +0 -1406
- package/build/dex/balancer-v3/abi/balancerRouter.js +0 -1175
- package/build/dex/balancer-v3/abi/balancerRouter.js.map +0 -1
- package/build/dex/balancer-v3/abi/vaultExtension.V3.d.ts +0 -2081
- package/build/dex/balancer-v3/abi/vaultExtension.V3.js +0 -1851
- package/build/dex/balancer-v3/abi/vaultExtension.V3.js.map +0 -1
- package/build/dex/balancer-v3/balancer-v3-sepolia-pools.d.ts +0 -34
- package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js +0 -406
- package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js.map +0 -1
- package/build/dex/inception/config.d.ts +0 -4
- package/build/dex/inception/config.js +0 -109
- package/build/dex/inception/config.js.map +0 -1
- package/build/dex/inception/inception-event-pool.d.ts +0 -16
- package/build/dex/inception/inception-event-pool.js +0 -49
- package/build/dex/inception/inception-event-pool.js.map +0 -1
- package/build/dex/inception/inception.d.ts +0 -43
- package/build/dex/inception/inception.js +0 -180
- package/build/dex/inception/inception.js.map +0 -1
- package/build/dex/inception/tokens.d.ts +0 -9
- package/build/dex/inception/tokens.js +0 -28
- package/build/dex/inception/tokens.js.map +0 -1
- package/build/dex/inception/types.d.ts +0 -22
- package/build/dex/inception/types.js +0 -3
- package/build/dex/inception/types.js.map +0 -1
- package/build/dex/inception/utils.d.ts +0 -7
- package/build/dex/inception/utils.js +0 -58
- package/build/dex/inception/utils.js.map +0 -1
- package/build/dex/maker-psm/scripts/gem.abi.json +0 -136
- package/build/dex/maker-psm/scripts/validate-state.d.ts +0 -0
- package/build/dex/maker-psm/scripts/validate-state.js +0 -185
- package/build/dex/maker-psm/scripts/validate-state.js.map +0 -1
- package/build/dex/maker-psm/scripts/vat.abi.json +0 -243
- package/build/dex/solidly-v3/scripts/check-event-pool-event.d.ts +0 -1
- package/build/dex/solidly-v3/scripts/check-event-pool-event.js +0 -53
- package/build/dex/solidly-v3/scripts/check-event-pool-event.js.map +0 -1
- package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.d.ts +0 -17
- package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js +0 -64
- package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js.map +0 -1
- package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.d.ts +0 -17
- package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js +0 -79
- package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js.map +0 -1
- package/build/dex/uniswap-v3/uniswap-v3-pricing.d.ts +0 -4
- package/build/dex/uniswap-v3/uniswap-v3-pricing.js +0 -43
- package/build/dex/uniswap-v3/uniswap-v3-pricing.js.map +0 -1
- package/build/dex/uniswap-v3/uniswap-v3-worker.d.ts +0 -1
- package/build/dex/uniswap-v3/uniswap-v3-worker.js +0 -10
- package/build/dex/uniswap-v3/uniswap-v3-worker.js.map +0 -1
- package/build/dex/usual/types.d.ts +0 -13
- package/build/dex/usual/types.js +0 -3
- package/build/dex/usual/types.js.map +0 -1
- package/build/dex/usual/usual-bond.d.ts +0 -18
- package/build/dex/usual/usual-bond.js +0 -52
- package/build/dex/usual/usual-bond.js.map +0 -1
- package/build/dex/usual/usual-m-smart-m.d.ts +0 -17
- package/build/dex/usual/usual-m-smart-m.js +0 -50
- package/build/dex/usual/usual-m-smart-m.js.map +0 -1
- package/build/dex/usual/usual-m-usd0.d.ts +0 -17
- package/build/dex/usual/usual-m-usd0.js +0 -51
- package/build/dex/usual/usual-m-usd0.js.map +0 -1
- package/build/dex/usual/usual-m-wrapped-m.d.ts +0 -17
- package/build/dex/usual/usual-m-wrapped-m.js +0 -50
- package/build/dex/usual/usual-m-wrapped-m.js.map +0 -1
- package/build/dex/usual/usual.d.ts +0 -27
- package/build/dex/usual/usual.js +0 -125
- package/build/dex/usual/usual.js.map +0 -1
- package/build/dex/usual-m-smart-m/config.d.ts +0 -3
- package/build/dex/usual-m-smart-m/config.js +0 -13
- package/build/dex/usual-m-smart-m/config.js.map +0 -1
- package/build/dex/usual-m-smart-m/types.d.ts +0 -7
- package/build/dex/usual-m-smart-m/types.js +0 -3
- package/build/dex/usual-m-smart-m/types.js.map +0 -1
- package/build/dex/usual-m-smart-m/usual-m-smart-m.d.ts +0 -35
- package/build/dex/usual-m-smart-m/usual-m-smart-m.js +0 -161
- package/build/dex/usual-m-smart-m/usual-m-smart-m.js.map +0 -1
- package/build/dex/usual-m-usd0/config.d.ts +0 -3
- package/build/dex/usual-m-usd0/config.js +0 -14
- package/build/dex/usual-m-usd0/config.js.map +0 -1
- package/build/dex/usual-m-usd0/types.d.ts +0 -8
- package/build/dex/usual-m-usd0/types.js +0 -3
- package/build/dex/usual-m-usd0/types.js.map +0 -1
- package/build/dex/usual-m-usd0/usual-m-usd0.d.ts +0 -35
- package/build/dex/usual-m-usd0/usual-m-usd0.js +0 -159
- package/build/dex/usual-m-usd0/usual-m-usd0.js.map +0 -1
- package/build/lib/pub-sub.d.ts +0 -39
- package/build/lib/pub-sub.js +0 -133
- package/build/lib/pub-sub.js.map +0 -1
- package/src/lib/pub-sub.ts +0 -174
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const MIN_SWAP_LIQUIDITY = 10n ** 4n;
|
|
@@ -118,6 +118,23 @@ describe('FluidDex E2E', () => {
|
|
|
118
118
|
describe('Mainnet', () => {
|
|
119
119
|
const network = Network.MAINNET;
|
|
120
120
|
|
|
121
|
+
describe('ETH -> INST', () => {
|
|
122
|
+
const tokenASymbol: string = 'ETH';
|
|
123
|
+
const tokenBSymbol: string = 'INST';
|
|
124
|
+
|
|
125
|
+
const tokenAAmount: string = '100000000000000';
|
|
126
|
+
const tokenBAmount: string = '100000000000000';
|
|
127
|
+
|
|
128
|
+
testForNetwork(
|
|
129
|
+
network,
|
|
130
|
+
dexKey,
|
|
131
|
+
tokenASymbol,
|
|
132
|
+
tokenBSymbol,
|
|
133
|
+
tokenAAmount,
|
|
134
|
+
tokenBAmount,
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
|
|
121
138
|
describe('ETH -> wstETH', () => {
|
|
122
139
|
const tokenASymbol: string = 'wstETH';
|
|
123
140
|
const tokenBSymbol: string = 'ETH';
|
|
@@ -10,14 +10,16 @@ import { FluidDexLiquidityProxyState } from './types';
|
|
|
10
10
|
import { FluidDexConfig } from './config';
|
|
11
11
|
import { FluidDexLiquidityProxy } from './fluid-dex-liquidity-proxy';
|
|
12
12
|
import { FluidDexFactory } from './fluid-dex-factory';
|
|
13
|
+
import { FluidDexEventPool } from './fluid-dex-pool';
|
|
14
|
+
import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
|
|
13
15
|
|
|
14
16
|
jest.setTimeout(50 * 1000);
|
|
15
17
|
|
|
16
|
-
async function
|
|
17
|
-
|
|
18
|
+
async function fetchState(
|
|
19
|
+
statefulEventSubscriber: StatefulEventSubscriber<any>,
|
|
18
20
|
blockNumber: number,
|
|
19
|
-
): Promise<
|
|
20
|
-
return
|
|
21
|
+
): Promise<any> {
|
|
22
|
+
return statefulEventSubscriber.generateState(blockNumber);
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
// eventName -> blockNumbers
|
|
@@ -64,7 +66,7 @@ describe('FluidDex EventPool Mainnet', function () {
|
|
|
64
66
|
liquidityProxy,
|
|
65
67
|
liquidityProxy.addressesSubscribed,
|
|
66
68
|
(_blockNumber: number) =>
|
|
67
|
-
|
|
69
|
+
fetchState(liquidityProxy, _blockNumber),
|
|
68
70
|
blockNumber,
|
|
69
71
|
`${dexKey}_${poolAddress}`,
|
|
70
72
|
dexHelper.provider,
|
|
@@ -126,4 +128,52 @@ describe('FluidDex EventPool Mainnet', function () {
|
|
|
126
128
|
},
|
|
127
129
|
);
|
|
128
130
|
});
|
|
131
|
+
|
|
132
|
+
describe('Pool events', () => {
|
|
133
|
+
let dexPool: FluidDexEventPool;
|
|
134
|
+
|
|
135
|
+
const eventsToTest: Record<Address, EventMappings> = {
|
|
136
|
+
'0x8710039D5de6840EdE452A85672B32270a709aE2': {
|
|
137
|
+
LogPauseSwapAndArbitrage: [21337128],
|
|
138
|
+
},
|
|
139
|
+
'0x2886a01a0645390872a9eb99dae1283664b0c524': {
|
|
140
|
+
LogPauseSwapAndArbitrage: [21374547],
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
Object.entries(eventsToTest).forEach(
|
|
145
|
+
([poolAddress, events]: [string, EventMappings]) => {
|
|
146
|
+
describe(`Events for ${poolAddress}`, () => {
|
|
147
|
+
beforeEach(() => {
|
|
148
|
+
dexPool = new FluidDexEventPool(
|
|
149
|
+
dexKey,
|
|
150
|
+
poolAddress,
|
|
151
|
+
network,
|
|
152
|
+
dexHelper,
|
|
153
|
+
logger,
|
|
154
|
+
);
|
|
155
|
+
});
|
|
156
|
+
Object.entries(events).forEach(
|
|
157
|
+
([eventName, blockNumbers]: [string, number[]]) => {
|
|
158
|
+
describe(`${eventName}`, () => {
|
|
159
|
+
blockNumbers.forEach((blockNumber: number) => {
|
|
160
|
+
it(`State after ${blockNumber}`, async function () {
|
|
161
|
+
await testEventSubscriber(
|
|
162
|
+
dexPool,
|
|
163
|
+
dexPool.addressesSubscribed,
|
|
164
|
+
(_blockNumber: number) =>
|
|
165
|
+
fetchState(dexPool, _blockNumber),
|
|
166
|
+
blockNumber,
|
|
167
|
+
`${dexKey}_${poolAddress}`,
|
|
168
|
+
dexHelper.provider,
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
},
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
},
|
|
177
|
+
);
|
|
178
|
+
});
|
|
129
179
|
});
|
|
@@ -28,7 +28,7 @@ export class FluidDexLiquidityProxy extends StatefulEventSubscriber<FluidDexLiqu
|
|
|
28
28
|
|
|
29
29
|
addressesSubscribed: Address[];
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
readonly liquidityIface = new Interface(LiquidityABI);
|
|
32
32
|
|
|
33
33
|
readonly resolverIface = new Interface(ResolverABI);
|
|
34
34
|
|
|
@@ -123,7 +123,6 @@ export class FluidDexLiquidityProxy extends StatefulEventSubscriber<FluidDexLiqu
|
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
const convertedResult = this.convertToFluidDexPoolState(rawResult);
|
|
126
|
-
|
|
127
126
|
this.logger.info(`${this.parentName}: ${this.name}: generating state...`);
|
|
128
127
|
|
|
129
128
|
return convertedResult;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
|
|
2
|
+
import { DeepReadonly } from 'ts-essentials';
|
|
3
|
+
import { Address, Log, Logger } from '../../types';
|
|
4
|
+
import { IDexHelper } from '../../dex-helper';
|
|
5
|
+
import { Interface } from '@ethersproject/abi';
|
|
6
|
+
import FluidDexPoolABI from '../../abi/fluid-dex/fluid-dex.abi.json';
|
|
7
|
+
import { catchParseLogError } from '../../utils';
|
|
8
|
+
import { ethers } from 'ethers';
|
|
9
|
+
import { uint256ToBigInt } from '../../lib/decoders';
|
|
10
|
+
import { DecodedStateMultiCallResultWithRelativeBitmaps } from '../uniswap-v3/types';
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
utils: { hexlify, hexZeroPad },
|
|
14
|
+
} = ethers;
|
|
15
|
+
|
|
16
|
+
type PoolState = {
|
|
17
|
+
isSwapAndArbitragePaused: boolean;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export class FluidDexEventPool extends StatefulEventSubscriber<PoolState> {
|
|
21
|
+
handlers: {
|
|
22
|
+
[event: string]: (
|
|
23
|
+
event: any,
|
|
24
|
+
state: DeepReadonly<PoolState>,
|
|
25
|
+
log: Readonly<Log>,
|
|
26
|
+
) => DeepReadonly<PoolState> | null;
|
|
27
|
+
} = {};
|
|
28
|
+
|
|
29
|
+
logDecoder: (log: Log) => any;
|
|
30
|
+
addressesSubscribed: Address[];
|
|
31
|
+
protected poolIface = new Interface(FluidDexPoolABI);
|
|
32
|
+
|
|
33
|
+
constructor(
|
|
34
|
+
readonly parentName: string,
|
|
35
|
+
readonly poolAddress: string,
|
|
36
|
+
protected network: number,
|
|
37
|
+
protected dexHelper: IDexHelper,
|
|
38
|
+
logger: Logger,
|
|
39
|
+
) {
|
|
40
|
+
super(parentName, 'pool', dexHelper, logger);
|
|
41
|
+
|
|
42
|
+
this.logDecoder = (log: Log) => this.poolIface.parseLog(log);
|
|
43
|
+
this.addressesSubscribed = [poolAddress];
|
|
44
|
+
|
|
45
|
+
// Add handlers
|
|
46
|
+
this.handlers['LogPauseSwapAndArbitrage'] =
|
|
47
|
+
this.handleLogPauseSwapAndArbitrage.bind(this);
|
|
48
|
+
this.handlers['LogUnpauseSwapAndArbitrage'] =
|
|
49
|
+
this.handleLogUnpauseSwapAndArbitrage.bind(this);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The function is called every time any of the subscribed
|
|
54
|
+
* addresses release log. The function accepts the current
|
|
55
|
+
* state, updates the state according to the log, and returns
|
|
56
|
+
* the updated state.
|
|
57
|
+
* @param state - Current state of event subscriber
|
|
58
|
+
* @param log - Log released by one of the subscribed addresses
|
|
59
|
+
* @returns Updates state of the event subscriber after the log
|
|
60
|
+
*/
|
|
61
|
+
async processLog(
|
|
62
|
+
state: DeepReadonly<PoolState>,
|
|
63
|
+
log: Readonly<Log>,
|
|
64
|
+
): Promise<DeepReadonly<PoolState> | null> {
|
|
65
|
+
try {
|
|
66
|
+
let event;
|
|
67
|
+
try {
|
|
68
|
+
event = this.logDecoder(log);
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (event.name in this.handlers) {
|
|
74
|
+
return this.handlers[event.name](event, state, log);
|
|
75
|
+
}
|
|
76
|
+
} catch (e) {
|
|
77
|
+
catchParseLogError(e, this.logger);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
handleLogPauseSwapAndArbitrage(): PoolState {
|
|
84
|
+
return { isSwapAndArbitragePaused: true };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
handleLogUnpauseSwapAndArbitrage(): PoolState {
|
|
88
|
+
return { isSwapAndArbitragePaused: false };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async getStateOrGenerate(
|
|
92
|
+
blockNumber: number,
|
|
93
|
+
readonly: boolean = false,
|
|
94
|
+
): Promise<DeepReadonly<PoolState>> {
|
|
95
|
+
let state = this.getState(blockNumber);
|
|
96
|
+
if (!state) {
|
|
97
|
+
state = await this.generateState(blockNumber);
|
|
98
|
+
if (!readonly) this.setState(state, blockNumber);
|
|
99
|
+
}
|
|
100
|
+
return state;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The function generates state using on-chain calls. This
|
|
105
|
+
* function is called to regenerate state if the event based
|
|
106
|
+
* system fails to fetch events and the local state is no
|
|
107
|
+
* more correct.
|
|
108
|
+
* @param blockNumber - Blocknumber for which the state should
|
|
109
|
+
* should be generated
|
|
110
|
+
* @returns state of the event subscriber at blocknumber
|
|
111
|
+
*/
|
|
112
|
+
async generateState(blockNumber: number): Promise<DeepReadonly<PoolState>> {
|
|
113
|
+
const multicallData = [
|
|
114
|
+
{
|
|
115
|
+
target: this.addressesSubscribed[0],
|
|
116
|
+
callData: this.poolIface.encodeFunctionData('readFromStorage', [
|
|
117
|
+
hexZeroPad(hexlify(1), 32),
|
|
118
|
+
]),
|
|
119
|
+
decodeFunction: uint256ToBigInt,
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
const storageResults = await this.dexHelper.multiWrapper.tryAggregate<
|
|
124
|
+
bigint | DecodedStateMultiCallResultWithRelativeBitmaps
|
|
125
|
+
>(
|
|
126
|
+
false,
|
|
127
|
+
multicallData,
|
|
128
|
+
blockNumber,
|
|
129
|
+
this.dexHelper.multiWrapper.defaultBatchSize,
|
|
130
|
+
false,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const isSwapAndArbitragePaused =
|
|
134
|
+
BigInt(storageResults[0].returnData.toString()) >> 255n === 1n;
|
|
135
|
+
|
|
136
|
+
return { isSwapAndArbitragePaused };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -34,6 +34,8 @@ import { generalDecoder } from '../../lib/decoders';
|
|
|
34
34
|
import { BigNumber } from 'ethers';
|
|
35
35
|
import { sqrt } from './utils';
|
|
36
36
|
import { FluidDexLiquidityProxy } from './fluid-dex-liquidity-proxy';
|
|
37
|
+
import { FluidDexEventPool } from './fluid-dex-pool';
|
|
38
|
+
import { MIN_SWAP_LIQUIDITY } from './constants';
|
|
37
39
|
|
|
38
40
|
export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
39
41
|
readonly hasConstantPriceLargeAmounts = false;
|
|
@@ -46,14 +48,14 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
|
46
48
|
|
|
47
49
|
pools: FluidDexPool[] = [];
|
|
48
50
|
|
|
51
|
+
eventPools: FluidDexEventPool[] = [];
|
|
52
|
+
|
|
49
53
|
readonly factory: FluidDexFactory;
|
|
50
54
|
|
|
51
55
|
readonly liquidityProxy: FluidDexLiquidityProxy;
|
|
52
56
|
|
|
53
57
|
readonly fluidDexPoolIface: Interface;
|
|
54
58
|
|
|
55
|
-
FEE_100_PERCENT = BigInt(1000000);
|
|
56
|
-
|
|
57
59
|
constructor(
|
|
58
60
|
readonly network: Network,
|
|
59
61
|
readonly dexKey: string,
|
|
@@ -110,6 +112,20 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
|
110
112
|
await this.factory.initialize(blockNumber);
|
|
111
113
|
this.pools = await this.fetchFluidDexPools(blockNumber);
|
|
112
114
|
|
|
115
|
+
this.eventPools = await Promise.all(
|
|
116
|
+
this.pools.map(async pool => {
|
|
117
|
+
const eventPool = new FluidDexEventPool(
|
|
118
|
+
this.dexKey,
|
|
119
|
+
pool.address,
|
|
120
|
+
this.network,
|
|
121
|
+
this.dexHelper,
|
|
122
|
+
this.logger,
|
|
123
|
+
);
|
|
124
|
+
await eventPool.initialize(blockNumber);
|
|
125
|
+
return eventPool;
|
|
126
|
+
}),
|
|
127
|
+
);
|
|
128
|
+
|
|
113
129
|
await this.liquidityProxy.initialize(blockNumber);
|
|
114
130
|
}
|
|
115
131
|
|
|
@@ -147,29 +163,24 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
|
147
163
|
side: SwapSide,
|
|
148
164
|
blockNumber: number,
|
|
149
165
|
): Promise<string[]> {
|
|
150
|
-
const
|
|
151
|
-
return pool
|
|
166
|
+
const pools = this.getPoolsByTokenPair(srcToken.address, destToken.address);
|
|
167
|
+
return pools.map(pool => pool.id);
|
|
152
168
|
}
|
|
153
169
|
|
|
154
|
-
|
|
155
|
-
srcToken: Address,
|
|
156
|
-
destToken: Address,
|
|
157
|
-
): FluidDexPool | null {
|
|
170
|
+
getPoolsByTokenPair(srcToken: Address, destToken: Address): FluidDexPool[] {
|
|
158
171
|
const srcAddress = srcToken.toLowerCase();
|
|
159
172
|
const destAddress = destToken.toLowerCase();
|
|
160
173
|
|
|
161
174
|
// A pair must have 2 different tokens.
|
|
162
|
-
if (srcAddress === destAddress) return
|
|
175
|
+
if (srcAddress === destAddress) return [];
|
|
163
176
|
|
|
164
|
-
|
|
165
|
-
|
|
177
|
+
const pools = this.pools.filter(
|
|
178
|
+
pool =>
|
|
166
179
|
(srcAddress === pool.token0 && destAddress === pool.token1) ||
|
|
167
|
-
(srcAddress === pool.token1 && destAddress === pool.token0)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
return null;
|
|
180
|
+
(srcAddress === pool.token1 && destAddress === pool.token0),
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
return pools;
|
|
173
184
|
}
|
|
174
185
|
|
|
175
186
|
// Returns pool prices for amounts.
|
|
@@ -187,61 +198,93 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
|
187
198
|
try {
|
|
188
199
|
if (srcToken.address.toLowerCase() === destToken.address.toLowerCase())
|
|
189
200
|
return null;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (limitPools
|
|
201
|
+
|
|
202
|
+
// Get the pools to use.
|
|
203
|
+
let pools = this.getPoolsByTokenPair(srcToken.address, destToken.address);
|
|
204
|
+
|
|
205
|
+
if (limitPools) {
|
|
206
|
+
pools = pools.filter(pool => limitPools.includes(pool.id));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!pools.length) return null;
|
|
195
210
|
|
|
196
211
|
const liquidityProxyState = await this.liquidityProxy.getStateOrGenerate(
|
|
197
212
|
blockNumber,
|
|
198
213
|
);
|
|
199
214
|
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
const prices = amounts.map(amount => {
|
|
208
|
-
if (side === SwapSide.SELL) {
|
|
209
|
-
return this.swapIn(
|
|
210
|
-
srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
|
|
211
|
-
amount,
|
|
212
|
-
currentPoolReserves.collateralReserves,
|
|
213
|
-
currentPoolReserves.debtReserves,
|
|
214
|
-
srcToken.decimals,
|
|
215
|
-
destToken.decimals,
|
|
216
|
-
BigInt(currentPoolReserves.fee),
|
|
217
|
-
currentPoolReserves.dexLimits,
|
|
218
|
-
Math.floor(Date.now() / 1000),
|
|
215
|
+
const poolsPrices = await Promise.all(
|
|
216
|
+
pools.map(async pool => {
|
|
217
|
+
const currentPoolReserves = liquidityProxyState.poolsReserves.find(
|
|
218
|
+
poolReserve =>
|
|
219
|
+
poolReserve.pool.toLowerCase() === pool.address.toLowerCase(),
|
|
219
220
|
);
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
currentPoolReserves.debtReserves,
|
|
226
|
-
srcToken.decimals,
|
|
227
|
-
destToken.decimals,
|
|
228
|
-
BigInt(currentPoolReserves.fee),
|
|
229
|
-
currentPoolReserves.dexLimits,
|
|
230
|
-
Math.floor(Date.now() / 1000),
|
|
221
|
+
|
|
222
|
+
const eventPool = this.eventPools.find(
|
|
223
|
+
eventPool =>
|
|
224
|
+
eventPool.poolAddress.toLowerCase() ===
|
|
225
|
+
pool.address.toLowerCase(),
|
|
231
226
|
);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
227
|
+
|
|
228
|
+
if (!eventPool) {
|
|
229
|
+
this.logger.warn(
|
|
230
|
+
`${this.dexKey}-${this.network}: Event pool ${pool.address} was not found...`,
|
|
231
|
+
);
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const state = await eventPool.getStateOrGenerate(blockNumber);
|
|
236
|
+
|
|
237
|
+
if (!currentPoolReserves || state.isSwapAndArbitragePaused === true) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const prices = amounts.map(amount => {
|
|
242
|
+
if (side === SwapSide.SELL) {
|
|
243
|
+
return this.swapIn(
|
|
244
|
+
srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
|
|
245
|
+
amount,
|
|
246
|
+
currentPoolReserves.collateralReserves,
|
|
247
|
+
currentPoolReserves.debtReserves,
|
|
248
|
+
srcToken.decimals,
|
|
249
|
+
destToken.decimals,
|
|
250
|
+
BigInt(currentPoolReserves.fee),
|
|
251
|
+
currentPoolReserves.dexLimits,
|
|
252
|
+
Math.floor(Date.now() / 1000),
|
|
253
|
+
);
|
|
254
|
+
} else {
|
|
255
|
+
return this.swapOut(
|
|
256
|
+
srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
|
|
257
|
+
amount,
|
|
258
|
+
currentPoolReserves.collateralReserves,
|
|
259
|
+
currentPoolReserves.debtReserves,
|
|
260
|
+
srcToken.decimals,
|
|
261
|
+
destToken.decimals,
|
|
262
|
+
BigInt(currentPoolReserves.fee),
|
|
263
|
+
currentPoolReserves.dexLimits,
|
|
264
|
+
Math.floor(Date.now() / 1000),
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
prices: prices,
|
|
271
|
+
unit: getBigIntPow(destToken.decimals),
|
|
272
|
+
data: {
|
|
273
|
+
poolId: pool.id,
|
|
274
|
+
},
|
|
275
|
+
exchange: this.dexKey,
|
|
276
|
+
poolIdentifier: pool.id,
|
|
277
|
+
gasCost: FLUID_DEX_GAS_COST,
|
|
278
|
+
poolAddresses: [pool.address],
|
|
279
|
+
};
|
|
280
|
+
}),
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
const notNullResults = poolsPrices.filter(
|
|
284
|
+
res => res !== null,
|
|
285
|
+
) as ExchangePrices<FluidDexData>;
|
|
286
|
+
|
|
287
|
+
return notNullResults;
|
|
245
288
|
} catch (e) {
|
|
246
289
|
this.logger.error(
|
|
247
290
|
`Error_getPricesVolume ${srcToken.address || srcToken.symbol}, ${
|
|
@@ -272,10 +315,9 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
|
272
315
|
): AdapterExchangeParam {
|
|
273
316
|
// Encode here the payload for adapter
|
|
274
317
|
const payload = '';
|
|
275
|
-
const pool = this.getPoolByTokenPair(srcToken, destToken);
|
|
276
318
|
|
|
277
319
|
return {
|
|
278
|
-
targetExchange:
|
|
320
|
+
targetExchange: '0x',
|
|
279
321
|
payload,
|
|
280
322
|
networkFee: '0',
|
|
281
323
|
};
|
|
@@ -313,7 +355,11 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
|
313
355
|
side === SwapSide.SELL ? 'amountOut_' : 'amountIn_',
|
|
314
356
|
);
|
|
315
357
|
|
|
316
|
-
const pool = this.
|
|
358
|
+
const pool = this.pools.find(pool => pool.id === data.poolId);
|
|
359
|
+
if (!pool)
|
|
360
|
+
throw new Error(
|
|
361
|
+
`${this.dexKey}-${this.network}: Pool with id: ${data.poolId} was not found`,
|
|
362
|
+
);
|
|
317
363
|
|
|
318
364
|
if (side === SwapSide.SELL) {
|
|
319
365
|
if (pool!.token0.toLowerCase() !== srcToken.toLowerCase()) {
|
|
@@ -584,11 +630,84 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
|
584
630
|
if (priceDiff > maxAllowedDiff) {
|
|
585
631
|
return 0n;
|
|
586
632
|
}
|
|
633
|
+
|
|
634
|
+
if (amountInCollateral > 0) {
|
|
635
|
+
let reservesRatioValid = swap0To1
|
|
636
|
+
? this.verifyToken1Reserves(
|
|
637
|
+
colReserveIn + amountInCollateral,
|
|
638
|
+
colReserveOut - amountOutCollateral,
|
|
639
|
+
oldPrice,
|
|
640
|
+
)
|
|
641
|
+
: this.verifyToken0Reserves(
|
|
642
|
+
colReserveOut - amountOutCollateral,
|
|
643
|
+
colReserveIn + amountInCollateral,
|
|
644
|
+
oldPrice,
|
|
645
|
+
);
|
|
646
|
+
if (!reservesRatioValid) {
|
|
647
|
+
return 0n;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (amountInDebt > 0) {
|
|
652
|
+
let reservesRatioValid = swap0To1
|
|
653
|
+
? this.verifyToken1Reserves(
|
|
654
|
+
debtReserveIn + amountInDebt,
|
|
655
|
+
debtReserveOut - amountOutDebt,
|
|
656
|
+
oldPrice,
|
|
657
|
+
)
|
|
658
|
+
: this.verifyToken0Reserves(
|
|
659
|
+
debtReserveOut - amountOutDebt,
|
|
660
|
+
debtReserveIn + amountInDebt,
|
|
661
|
+
oldPrice,
|
|
662
|
+
);
|
|
663
|
+
if (!reservesRatioValid) {
|
|
664
|
+
return 0n;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
587
668
|
const totalAmountOut = amountOutCollateral + amountOutDebt;
|
|
588
669
|
|
|
589
670
|
return totalAmountOut;
|
|
590
671
|
}
|
|
591
672
|
|
|
673
|
+
/**
|
|
674
|
+
* Checks if token0 reserves are sufficient compared to token1 reserves.
|
|
675
|
+
* This helps prevent edge cases and ensures high precision in calculations.
|
|
676
|
+
* @param {number} token0Reserves - The reserves of token0.
|
|
677
|
+
* @param {number} token1Reserves - The reserves of token1.
|
|
678
|
+
* @param {number} price - The current price used for calculation.
|
|
679
|
+
* @returns {boolean} - Returns false if token0 reserves are too low, true otherwise.
|
|
680
|
+
*/
|
|
681
|
+
protected verifyToken0Reserves(
|
|
682
|
+
token0Reserves: bigint,
|
|
683
|
+
token1Reserves: bigint,
|
|
684
|
+
price: bigint,
|
|
685
|
+
): boolean {
|
|
686
|
+
return (
|
|
687
|
+
token0Reserves >=
|
|
688
|
+
(token1Reserves * 10n ** 27n) / (price * MIN_SWAP_LIQUIDITY)
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Checks if token1 reserves are sufficient compared to token0 reserves.
|
|
694
|
+
* This helps prevent edge cases and ensures high precision in calculations.
|
|
695
|
+
* @param {number} token0Reserves - The reserves of token0.
|
|
696
|
+
* @param {number} token1Reserves - The reserves of token1.
|
|
697
|
+
* @param {number} price - The current price used for calculation.
|
|
698
|
+
* @returns {boolean} - Returns false if token1 reserves are too low, true otherwise.
|
|
699
|
+
*/
|
|
700
|
+
protected verifyToken1Reserves(
|
|
701
|
+
token0Reserves: bigint,
|
|
702
|
+
token1Reserves: bigint,
|
|
703
|
+
price: bigint,
|
|
704
|
+
): boolean {
|
|
705
|
+
return (
|
|
706
|
+
token1Reserves >=
|
|
707
|
+
(token0Reserves * price) / (10n ** 27n * MIN_SWAP_LIQUIDITY)
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
|
|
592
711
|
/**
|
|
593
712
|
* Calculates the currently available swappable amount for a token limit considering expansion since last syncTime.
|
|
594
713
|
* @param syncTime - timestamp in seconds when the limits were synced
|
|
@@ -765,7 +884,7 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
|
765
884
|
syncTime,
|
|
766
885
|
);
|
|
767
886
|
|
|
768
|
-
if (amountIn
|
|
887
|
+
if (amountIn === 2n ** 256n - 1n) {
|
|
769
888
|
return amountIn;
|
|
770
889
|
}
|
|
771
890
|
const ans = (amountIn * BigInt(10 ** inDecimals)) / BigInt(10 ** 12);
|
|
@@ -985,6 +1104,39 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
|
|
|
985
1104
|
return 2n ** 256n - 1n;
|
|
986
1105
|
}
|
|
987
1106
|
|
|
1107
|
+
if (amountInCollateral > 0) {
|
|
1108
|
+
let reservesRatioValid = swap0to1
|
|
1109
|
+
? this.verifyToken1Reserves(
|
|
1110
|
+
colReserveIn + amountInCollateral,
|
|
1111
|
+
colReserveOut - amountOutCollateral,
|
|
1112
|
+
oldPrice,
|
|
1113
|
+
)
|
|
1114
|
+
: this.verifyToken0Reserves(
|
|
1115
|
+
colReserveOut - amountOutCollateral,
|
|
1116
|
+
colReserveIn + amountInCollateral,
|
|
1117
|
+
oldPrice,
|
|
1118
|
+
);
|
|
1119
|
+
if (!reservesRatioValid) {
|
|
1120
|
+
return 0n;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
if (amountInDebt > 0) {
|
|
1124
|
+
let reservesRatioValid = swap0to1
|
|
1125
|
+
? this.verifyToken1Reserves(
|
|
1126
|
+
debtReserveIn + amountInDebt,
|
|
1127
|
+
debtReserveOut - amountOutDebt,
|
|
1128
|
+
oldPrice,
|
|
1129
|
+
)
|
|
1130
|
+
: this.verifyToken0Reserves(
|
|
1131
|
+
debtReserveOut - amountOutDebt,
|
|
1132
|
+
debtReserveIn + amountInDebt,
|
|
1133
|
+
oldPrice,
|
|
1134
|
+
);
|
|
1135
|
+
if (!reservesRatioValid) {
|
|
1136
|
+
return 0n;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
|
|
988
1140
|
const totalAmountIn = amountInCollateral + amountInDebt;
|
|
989
1141
|
|
|
990
1142
|
return totalAmountIn;
|
|
@@ -72,7 +72,9 @@ export interface PoolWithReserves {
|
|
|
72
72
|
debtReserves: DebtReserves;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
export type FluidDexData = {
|
|
75
|
+
export type FluidDexData = {
|
|
76
|
+
poolId: string;
|
|
77
|
+
};
|
|
76
78
|
|
|
77
79
|
// Each pool has a contract address and token pairs.
|
|
78
80
|
export type FluidDexPool = {
|
|
@@ -447,7 +447,12 @@ export class GenericRFQ extends ParaSwapLimitOrders {
|
|
|
447
447
|
}
|
|
448
448
|
|
|
449
449
|
async setBlacklist(userAddress: string): Promise<boolean> {
|
|
450
|
-
|
|
450
|
+
await this.dexHelper.cache.hset(
|
|
451
|
+
this.rateFetcher.blackListCacheKey,
|
|
452
|
+
userAddress.toLowerCase(),
|
|
453
|
+
'true',
|
|
454
|
+
);
|
|
455
|
+
return true;
|
|
451
456
|
}
|
|
452
457
|
|
|
453
458
|
releaseResources(): void {
|