@paraswap/dex-lib 4.1.1 → 4.1.2-fluid
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/build/abi/fluid-dex/resolver.abi.json +30 -0
- package/build/dex/balancer-v3/balancer-v3-pool.d.ts +2 -0
- package/build/dex/balancer-v3/balancer-v3-pool.js +14 -4
- package/build/dex/balancer-v3/balancer-v3-pool.js.map +1 -1
- package/build/dex/balancer-v3/balancer-v3.js +1 -1
- package/build/dex/balancer-v3/balancer-v3.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 +2 -1
- package/build/dex/fluid-dex/constants.js.map +1 -1
- package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.js +3 -1
- package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.js.map +1 -1
- package/build/dex/fluid-dex/fluid-dex.d.ts +4 -5
- package/build/dex/fluid-dex/fluid-dex.js +63 -57
- package/build/dex/fluid-dex/fluid-dex.js.map +1 -1
- package/build/dex/fluid-dex/types.d.ts +3 -0
- package/package.json +1 -1
- package/src/abi/fluid-dex/resolver.abi.json +30 -0
- package/src/dex/balancer-v3/balancer-v3-events.test.ts +157 -84
- package/src/dex/balancer-v3/balancer-v3-pool.ts +33 -13
- package/src/dex/balancer-v3/balancer-v3.ts +1 -1
- package/src/dex/fluid-dex/config.ts +2 -2
- package/src/dex/fluid-dex/constants.ts +2 -1
- package/src/dex/fluid-dex/fluid-dex-e2e.test.ts +31 -71
- package/src/dex/fluid-dex/fluid-dex-liquidity-proxy.ts +3 -0
- package/src/dex/fluid-dex/fluid-dex.ts +98 -91
- package/src/dex/fluid-dex/types.ts +3 -0
- package/tests/constants-e2e.ts +1 -1
- package/tests/tenderly-simulation.ts +1 -0
|
@@ -129,95 +129,168 @@ type EventData = { blockNumbers: number[]; poolAddress: string[] };
|
|
|
129
129
|
|
|
130
130
|
describe('BalancerV3 EventPool', function () {
|
|
131
131
|
const dexKey = 'BalancerV3';
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
132
|
+
|
|
133
|
+
describe('Sepolia', function () {
|
|
134
|
+
const network = Network.SEPOLIA;
|
|
135
|
+
const dexHelper = new DummyDexHelper(network);
|
|
136
|
+
const logger = dexHelper.getLogger(dexKey);
|
|
137
|
+
let balancerV3Pool: BalancerV3EventPool;
|
|
138
|
+
|
|
139
|
+
// vault -> EventMappings
|
|
140
|
+
// TODO once we have a new test deployment add tests for: AggregateSwapFeePercentageChanged, SwapFeePercentageChanged, PoolPausedStateChanged
|
|
141
|
+
const eventsToTest: Record<Address, EventMappings> = {
|
|
142
|
+
[BalancerV3Config.BalancerV3[network].vaultAddress]: {
|
|
143
|
+
// https://eth-sepolia.blockscout.com/tx/0xc417d38ad6e21250c9ddded37680b40f0991cfd3f8ae2d8b5800507a58d48c44
|
|
144
|
+
LiquidityAdded: {
|
|
145
|
+
blockNumbers: [7170937],
|
|
146
|
+
poolAddress: ['0x2ff3b96e0057a1f25f1d62ab800554ccdb268ab8'],
|
|
147
|
+
},
|
|
148
|
+
// https://sepolia.etherscan.io/tx/0xc1596e26d51104b9236a0debc3e1946b30b82f92b8331639ad6f6aea2ff2decc
|
|
149
|
+
LiquidityRemoved: {
|
|
150
|
+
blockNumbers: [7170957],
|
|
151
|
+
poolAddress: ['0x2ff3b96e0057a1f25f1d62ab800554ccdb268ab8'],
|
|
152
|
+
},
|
|
153
|
+
// https://sepolia.etherscan.io/tx/0x78d18503c2dd4458c94ec916b10c088bb4e8b90059676d00dbcec83f763d8c0e
|
|
154
|
+
Swap: {
|
|
155
|
+
blockNumbers: [7175721],
|
|
156
|
+
poolAddress: ['0x2ff3b96e0057a1f25f1d62ab800554ccdb268ab8'],
|
|
157
|
+
},
|
|
158
|
+
// 7170034, AmpUpdateStarted, https://eth-sepolia.blockscout.com/tx/0xfbe2e53d9cede1dc900100a1d6e809a89d909746ac7b8cc011e93227af8dda8b?tab=logs
|
|
159
|
+
// 7170069, AmpUpdateStopped, https://eth-sepolia.blockscout.com/tx/0x2ee2e1d5980013fdf1cf9c3789e0321fb598c2412db8ee8057fcfaffd1c792ab?tab=logs
|
|
160
|
+
VaultAuxiliary: {
|
|
161
|
+
blockNumbers: [7170034, 7170069],
|
|
162
|
+
poolAddress: [
|
|
163
|
+
'0xD63dB0B88dca565633fB8d70a70b9b8093d34A7E',
|
|
164
|
+
'0xD63dB0B88dca565633fB8d70a70b9b8093d34A7E',
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
// https://sepolia.etherscan.io/tx/0x71f9879485f4e4cf97aa42381988ffe277f05a872d6b507cfa007cec1239a3f8#eventlog
|
|
168
|
+
SwapFeePercentageChanged: {
|
|
169
|
+
blockNumbers: [7206571],
|
|
170
|
+
poolAddress: ['0xe69b70a86A4e1fD33dA95693A1aE12Be1c26C8ea'],
|
|
171
|
+
},
|
|
172
|
+
// https://sepolia.etherscan.io/tx/0xaf232ca2df59ba5fad38d74e9b54ec2ae1ad2e6abca8348f107cf3fd94c787c7#eventlog
|
|
173
|
+
// Should remove pool from state as its paused and no longer supports swaps
|
|
174
|
+
PoolPausedStateChanged: {
|
|
175
|
+
blockNumbers: [7206586],
|
|
176
|
+
poolAddress: ['0xe69b70a86A4e1fD33dA95693A1aE12Be1c26C8ea'],
|
|
177
|
+
},
|
|
178
|
+
// https://sepolia.etherscan.io/tx/0xa23dc10bd0fbed7ffffe867766d9b0d7670ca4a0bc352669f547bc7775644349#eventlog
|
|
179
|
+
AggregateSwapFeePercentageChanged: {
|
|
180
|
+
blockNumbers: [7206701],
|
|
181
|
+
poolAddress: ['0xe69b70a86A4e1fD33dA95693A1aE12Be1c26C8ea'],
|
|
182
|
+
},
|
|
180
183
|
},
|
|
181
|
-
}
|
|
182
|
-
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
beforeEach(async () => {
|
|
187
|
+
balancerV3Pool = new BalancerV3EventPool(
|
|
188
|
+
dexKey,
|
|
189
|
+
network,
|
|
190
|
+
dexHelper,
|
|
191
|
+
logger,
|
|
192
|
+
);
|
|
193
|
+
});
|
|
183
194
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
195
|
+
Object.entries(eventsToTest).forEach(
|
|
196
|
+
([vaultAddress, events]: [string, EventMappings]) => {
|
|
197
|
+
describe(`Events for Vault: ${vaultAddress}`, () => {
|
|
198
|
+
Object.entries(events).forEach(
|
|
199
|
+
([eventName, eventData]: [string, EventData]) => {
|
|
200
|
+
describe(`${eventName}`, () => {
|
|
201
|
+
eventData.blockNumbers.forEach((blockNumber: number, i) => {
|
|
202
|
+
it(`Pool: ${eventData.poolAddress[i]} State after ${blockNumber}`, async function () {
|
|
203
|
+
await testEventSubscriber(
|
|
204
|
+
balancerV3Pool,
|
|
205
|
+
balancerV3Pool.addressesSubscribed,
|
|
206
|
+
(_blockNumber: number) =>
|
|
207
|
+
fetchPoolState(
|
|
208
|
+
balancerV3Pool,
|
|
209
|
+
_blockNumber,
|
|
210
|
+
eventData.poolAddress[i],
|
|
211
|
+
),
|
|
212
|
+
blockNumber,
|
|
213
|
+
`${dexKey}_${vaultAddress}`,
|
|
214
|
+
dexHelper.provider,
|
|
215
|
+
stateCompare,
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
},
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
},
|
|
190
224
|
);
|
|
191
225
|
});
|
|
192
226
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
227
|
+
describe('Mainnet', function () {
|
|
228
|
+
const network = Network.MAINNET;
|
|
229
|
+
const dexHelper = new DummyDexHelper(network);
|
|
230
|
+
const logger = dexHelper.getLogger(dexKey);
|
|
231
|
+
let balancerV3Pool: BalancerV3EventPool;
|
|
232
|
+
|
|
233
|
+
// vault -> EventMappings
|
|
234
|
+
// TODO once we have a new test deployment add tests for: AggregateSwapFeePercentageChanged, SwapFeePercentageChanged, PoolPausedStateChanged
|
|
235
|
+
const eventsToTest: Record<Address, EventMappings> = {
|
|
236
|
+
[BalancerV3Config.BalancerV3[network].vaultAddress]: {
|
|
237
|
+
LiquidityAdded: {
|
|
238
|
+
blockNumbers: [21774068],
|
|
239
|
+
poolAddress: ['0x8523bcadcda4bd329435940dcc49a7c4c0a14d94'],
|
|
240
|
+
},
|
|
241
|
+
LiquidityRemoved: {
|
|
242
|
+
blockNumbers: [21788910],
|
|
243
|
+
poolAddress: ['0x8523bcadcda4bd329435940dcc49a7c4c0a14d94'],
|
|
244
|
+
},
|
|
245
|
+
Swap: {
|
|
246
|
+
blockNumbers: [21788638, 21791514, 21791514],
|
|
247
|
+
poolAddress: [
|
|
248
|
+
'0x8523bcadcda4bd329435940dcc49a7c4c0a14d94',
|
|
249
|
+
'0x8523bcadcda4bd329435940dcc49a7c4c0a14d94',
|
|
250
|
+
'0x8523bcadcda4bd329435940dcc49a7c4c0a14d94',
|
|
251
|
+
],
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
beforeEach(async () => {
|
|
257
|
+
balancerV3Pool = new BalancerV3EventPool(
|
|
258
|
+
dexKey,
|
|
259
|
+
network,
|
|
260
|
+
dexHelper,
|
|
261
|
+
logger,
|
|
262
|
+
);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
Object.entries(eventsToTest).forEach(
|
|
266
|
+
([vaultAddress, events]: [string, EventMappings]) => {
|
|
267
|
+
describe(`Events for Vault: ${vaultAddress}`, () => {
|
|
268
|
+
Object.entries(events).forEach(
|
|
269
|
+
([eventName, eventData]: [string, EventData]) => {
|
|
270
|
+
describe(`${eventName}`, () => {
|
|
271
|
+
eventData.blockNumbers.forEach((blockNumber: number, i) => {
|
|
272
|
+
it(`Pool: ${eventData.poolAddress[i]} State after ${blockNumber}`, async function () {
|
|
273
|
+
await testEventSubscriber(
|
|
274
|
+
balancerV3Pool,
|
|
275
|
+
balancerV3Pool.addressesSubscribed,
|
|
276
|
+
(_blockNumber: number) =>
|
|
277
|
+
fetchPoolState(
|
|
278
|
+
balancerV3Pool,
|
|
279
|
+
_blockNumber,
|
|
280
|
+
eventData.poolAddress[i],
|
|
281
|
+
),
|
|
282
|
+
blockNumber,
|
|
283
|
+
`${dexKey}_${vaultAddress}`,
|
|
284
|
+
dexHelper.provider,
|
|
285
|
+
stateCompare,
|
|
286
|
+
);
|
|
287
|
+
});
|
|
215
288
|
});
|
|
216
289
|
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
);
|
|
290
|
+
},
|
|
291
|
+
);
|
|
292
|
+
});
|
|
293
|
+
},
|
|
294
|
+
);
|
|
295
|
+
});
|
|
223
296
|
});
|
|
@@ -218,10 +218,12 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
218
218
|
i < newState[poolAddress].balancesLiveScaled18.length;
|
|
219
219
|
i++
|
|
220
220
|
) {
|
|
221
|
-
newState[poolAddress].balancesLiveScaled18[i] +=
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
221
|
+
newState[poolAddress].balancesLiveScaled18[i] +=
|
|
222
|
+
this.toScaled18ApplyRateRoundDown(
|
|
223
|
+
BigInt(event.args.amountsAddedRaw[i]),
|
|
224
|
+
newState[poolAddress].scalingFactors[i],
|
|
225
|
+
newState[poolAddress].tokenRates[i] || WAD,
|
|
226
|
+
);
|
|
225
227
|
}
|
|
226
228
|
newState[poolAddress].totalSupply = BigInt(event.args.totalSupply);
|
|
227
229
|
|
|
@@ -244,10 +246,12 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
244
246
|
i < newState[poolAddress].balancesLiveScaled18.length;
|
|
245
247
|
i++
|
|
246
248
|
) {
|
|
247
|
-
newState[poolAddress].balancesLiveScaled18[i] -=
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
newState[poolAddress].balancesLiveScaled18[i] -=
|
|
250
|
+
this.toScaled18ApplyRateRoundDown(
|
|
251
|
+
BigInt(event.args.amountsRemovedRaw[i]),
|
|
252
|
+
newState[poolAddress].scalingFactors[i],
|
|
253
|
+
newState[poolAddress].tokenRates[i] || WAD,
|
|
254
|
+
);
|
|
251
255
|
}
|
|
252
256
|
newState[poolAddress].totalSupply = BigInt(event.args.totalSupply);
|
|
253
257
|
|
|
@@ -275,14 +279,17 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
275
279
|
this.logger.error(`swapEvent - token index not found in pool state`);
|
|
276
280
|
return null;
|
|
277
281
|
}
|
|
278
|
-
newState[poolAddress].balancesLiveScaled18[tokenInIndex] +=
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
+
newState[poolAddress].balancesLiveScaled18[tokenInIndex] +=
|
|
283
|
+
this.toScaled18ApplyRateRoundDown(
|
|
284
|
+
BigInt(event.args.amountIn),
|
|
285
|
+
newState[poolAddress].scalingFactors[tokenInIndex],
|
|
286
|
+
newState[poolAddress].tokenRates[tokenInIndex] || WAD,
|
|
287
|
+
);
|
|
282
288
|
newState[poolAddress].balancesLiveScaled18[tokenOutIndex] -=
|
|
283
|
-
this.
|
|
289
|
+
this.toScaled18ApplyRateRoundDown(
|
|
284
290
|
BigInt(event.args.amountOut),
|
|
285
291
|
newState[poolAddress].scalingFactors[tokenOutIndex],
|
|
292
|
+
newState[poolAddress].tokenRates[tokenOutIndex] || WAD,
|
|
286
293
|
);
|
|
287
294
|
|
|
288
295
|
return newState;
|
|
@@ -697,6 +704,19 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
697
704
|
}
|
|
698
705
|
|
|
699
706
|
toScaled18(amount: bigint, scalingFactor: bigint): bigint {
|
|
707
|
+
// (amount * scalingFactor).mulUp(tokenRate);
|
|
700
708
|
return (amount * scalingFactor * WAD) / WAD;
|
|
701
709
|
}
|
|
710
|
+
|
|
711
|
+
toScaled18ApplyRateRoundDown(
|
|
712
|
+
amount: bigint,
|
|
713
|
+
scalingFactor: bigint,
|
|
714
|
+
tokenRate: bigint,
|
|
715
|
+
): bigint {
|
|
716
|
+
return this.mulDown(amount * scalingFactor, tokenRate);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
mulDown(a: bigint, b: bigint): bigint {
|
|
720
|
+
return (a * b) / WAD;
|
|
721
|
+
}
|
|
702
722
|
}
|
|
@@ -30,7 +30,7 @@ import { Block } from '@ethersproject/abstract-provider';
|
|
|
30
30
|
|
|
31
31
|
const MAX_UINT256 =
|
|
32
32
|
'115792089237316195423570985008687907853269984665640564039457584007913129639935';
|
|
33
|
-
const POOL_UPDATE_TTL =
|
|
33
|
+
const POOL_UPDATE_TTL = 1 * 60; // 1min
|
|
34
34
|
const RATE_UPDATE_TTL = 1 * 60; // 1min
|
|
35
35
|
|
|
36
36
|
type DeepMutable<T> = {
|
|
@@ -7,14 +7,14 @@ export const FluidDexConfig: DexConfigMap<DexParams> = {
|
|
|
7
7
|
[Network.MAINNET]: {
|
|
8
8
|
commonAddresses: {
|
|
9
9
|
liquidityProxy: '0x52aa899454998be5b000ad077a46bbe360f4e497',
|
|
10
|
-
resolver: '
|
|
10
|
+
resolver: '0xb387f9C2092cF7c4943F97842887eBff7AE96EB3',
|
|
11
11
|
dexFactory: '0x91716C4EDA1Fb55e84Bf8b4c7085f84285c19085',
|
|
12
12
|
},
|
|
13
13
|
},
|
|
14
14
|
[Network.ARBITRUM]: {
|
|
15
15
|
commonAddresses: {
|
|
16
16
|
liquidityProxy: '0x52Aa899454998Be5b000Ad077a46Bbe360F4e497',
|
|
17
|
-
resolver: '
|
|
17
|
+
resolver: '0xCe6F4E40152a1DF97ae95a7e4F60D944871A4060',
|
|
18
18
|
dexFactory: '0x91716C4EDA1Fb55e84Bf8b4c7085f84285c19085',
|
|
19
19
|
},
|
|
20
20
|
},
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
// on-chain we use 1e4 but use extra buffer to avoid reverts
|
|
2
|
+
export const MIN_SWAP_LIQUIDITY = 8500n;
|
|
@@ -4,46 +4,13 @@ dotenv.config();
|
|
|
4
4
|
|
|
5
5
|
import { StaticJsonRpcProvider } from '@ethersproject/providers';
|
|
6
6
|
import { testE2E } from '../../../tests/utils-e2e';
|
|
7
|
-
import {
|
|
8
|
-
Tokens,
|
|
9
|
-
Holders,
|
|
10
|
-
NativeTokenSymbols,
|
|
11
|
-
} from '../../../tests/constants-e2e';
|
|
7
|
+
import { Tokens, Holders } from '../../../tests/constants-e2e';
|
|
12
8
|
import { Network, ContractMethod, SwapSide } from '../../constants';
|
|
13
9
|
import { generateConfig } from '../../config';
|
|
14
10
|
import { CollateralReserves, DebtReserves, DexLimits } from './types';
|
|
15
11
|
import { DummyDexHelper } from '../../dex-helper/index';
|
|
16
12
|
import { FluidDex } from './fluid-dex';
|
|
17
13
|
|
|
18
|
-
/*
|
|
19
|
-
README
|
|
20
|
-
======
|
|
21
|
-
|
|
22
|
-
The template already enumerates the basic structure which involves
|
|
23
|
-
testing simpleSwap, multiSwap, megaSwap contract methods for
|
|
24
|
-
ETH <> TOKEN and TOKEN <> TOKEN swaps. You should replace tokenA and
|
|
25
|
-
tokenB with any two highly liquid tokens on FluidDex for the tests
|
|
26
|
-
to work. If the tokens that you would like to use are not defined in
|
|
27
|
-
Tokens or Holders map, you can update the './tests/constants-e2e'
|
|
28
|
-
|
|
29
|
-
Other than the standard cases that are already added by the template
|
|
30
|
-
it is highly recommended to add test cases which could be specific
|
|
31
|
-
to testing FluidDex (Eg. Tests based on poolType, special tokens,
|
|
32
|
-
etc).
|
|
33
|
-
|
|
34
|
-
You can run this individual test script by running:
|
|
35
|
-
`npx jest src/dex/<dex-name>/<dex-name>-e2e.test.ts`
|
|
36
|
-
|
|
37
|
-
e2e tests use the Tenderly fork api. Please add the following to your
|
|
38
|
-
.env file:
|
|
39
|
-
TENDERLY_TOKEN=Find this under Account>Settings>Authorization.
|
|
40
|
-
TENDERLY_ACCOUNT_ID=Your Tenderly account name.
|
|
41
|
-
TENDERLY_PROJECT=Name of a Tenderly project you have created in your
|
|
42
|
-
dashboard.
|
|
43
|
-
|
|
44
|
-
(This comment should be removed from the final implementation)
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
14
|
function testForNetwork(
|
|
48
15
|
network: Network,
|
|
49
16
|
dexKey: string,
|
|
@@ -56,9 +23,14 @@ function testForNetwork(
|
|
|
56
23
|
generateConfig(network).privateHttpProvider,
|
|
57
24
|
network,
|
|
58
25
|
);
|
|
26
|
+
|
|
59
27
|
const tokens = Tokens[network];
|
|
60
28
|
const holders = Holders[network];
|
|
61
29
|
|
|
30
|
+
// Create FluidDex instance to check reserves
|
|
31
|
+
const dexHelper = new DummyDexHelper(network);
|
|
32
|
+
const fluidDex = new FluidDex(network, dexKey, dexHelper);
|
|
33
|
+
|
|
62
34
|
const sideToContractMethods = new Map([
|
|
63
35
|
[SwapSide.SELL, [ContractMethod.swapExactAmountIn]],
|
|
64
36
|
[SwapSide.BUY, [ContractMethod.swapExactAmountOut]],
|
|
@@ -69,11 +41,11 @@ function testForNetwork(
|
|
|
69
41
|
describe(`${side}`, () => {
|
|
70
42
|
contractMethods.forEach((contractMethod: string) => {
|
|
71
43
|
describe(`${contractMethod}`, () => {
|
|
72
|
-
it(`${
|
|
44
|
+
it(`${tokenBSymbol} -> ${tokenASymbol}`, async () => {
|
|
73
45
|
await testE2E(
|
|
74
|
-
tokens[tokenASymbol],
|
|
75
46
|
tokens[tokenBSymbol],
|
|
76
|
-
|
|
47
|
+
tokens[tokenASymbol],
|
|
48
|
+
holders[tokenBSymbol],
|
|
77
49
|
tokenBAmount,
|
|
78
50
|
side,
|
|
79
51
|
dexKey,
|
|
@@ -82,12 +54,13 @@ function testForNetwork(
|
|
|
82
54
|
provider,
|
|
83
55
|
);
|
|
84
56
|
});
|
|
85
|
-
|
|
57
|
+
|
|
58
|
+
it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => {
|
|
86
59
|
await testE2E(
|
|
87
|
-
tokens[tokenBSymbol],
|
|
88
60
|
tokens[tokenASymbol],
|
|
89
|
-
|
|
90
|
-
|
|
61
|
+
tokens[tokenBSymbol],
|
|
62
|
+
holders[tokenASymbol],
|
|
63
|
+
tokenAAmount,
|
|
91
64
|
side,
|
|
92
65
|
dexKey,
|
|
93
66
|
contractMethod as ContractMethod,
|
|
@@ -108,30 +81,11 @@ describe('FluidDex E2E', () => {
|
|
|
108
81
|
describe('Mainnet', () => {
|
|
109
82
|
const network = Network.MAINNET;
|
|
110
83
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// const tokenAAmount: string = '160097047322810379';
|
|
117
|
-
// const tokenBAmount: string = '79923068733005505624';
|
|
118
|
-
//
|
|
119
|
-
// testForNetwork(
|
|
120
|
-
// network,
|
|
121
|
-
// dexKey,
|
|
122
|
-
// tokenASymbol,
|
|
123
|
-
// tokenBSymbol,
|
|
124
|
-
// tokenAAmount,
|
|
125
|
-
// tokenBAmount,
|
|
126
|
-
// );
|
|
127
|
-
// });
|
|
128
|
-
|
|
129
|
-
describe('ETH -> INST', () => {
|
|
130
|
-
const tokenASymbol: string = 'ETH';
|
|
131
|
-
const tokenBSymbol: string = 'INST';
|
|
132
|
-
|
|
133
|
-
const tokenAAmount: string = '100000000000000';
|
|
134
|
-
const tokenBAmount: string = '100000000000000';
|
|
84
|
+
describe('limit:FLUID -> ETH', () => {
|
|
85
|
+
const tokenASymbol: string = 'FLUID';
|
|
86
|
+
const tokenBSymbol: string = 'ETH';
|
|
87
|
+
const tokenAAmount: string = '16009704732281037900';
|
|
88
|
+
const tokenBAmount: string = '7992306873300550562400';
|
|
135
89
|
|
|
136
90
|
testForNetwork(
|
|
137
91
|
network,
|
|
@@ -148,7 +102,7 @@ describe('FluidDex E2E', () => {
|
|
|
148
102
|
const tokenBSymbol: string = 'ETH';
|
|
149
103
|
|
|
150
104
|
const tokenAAmount: string = '100000000000000';
|
|
151
|
-
const tokenBAmount: string = '
|
|
105
|
+
const tokenBAmount: string = '3500000000000000000';
|
|
152
106
|
|
|
153
107
|
testForNetwork(
|
|
154
108
|
network,
|
|
@@ -237,6 +191,9 @@ function NewDebtReservesOne(): DebtReserves {
|
|
|
237
191
|
};
|
|
238
192
|
}
|
|
239
193
|
|
|
194
|
+
const centerPriceTight: bigint = 3401944443797854601871360n;
|
|
195
|
+
const centerPriceWide: bigint = 1190081051944310368000000000n;
|
|
196
|
+
|
|
240
197
|
const limitsTight: DexLimits = {
|
|
241
198
|
withdrawableToken0: {
|
|
242
199
|
available: 456740438880263n,
|
|
@@ -283,9 +240,9 @@ const limitsWide: DexLimits = {
|
|
|
283
240
|
},
|
|
284
241
|
};
|
|
285
242
|
|
|
286
|
-
const ErrInsufficientBorrowable = new Error('
|
|
287
|
-
const ErrInsufficientMaxPrice = new Error('
|
|
288
|
-
const ErrInsufficientReserve = new Error('
|
|
243
|
+
const ErrInsufficientBorrowable = new Error('DebtLimitReached');
|
|
244
|
+
const ErrInsufficientMaxPrice = new Error('OracleUpdateHugeSwapDiff');
|
|
245
|
+
const ErrInsufficientReserve = new Error('DebtReservesTooLow');
|
|
289
246
|
|
|
290
247
|
describe('TestPoolSimulator_SwapInLimits', () => {
|
|
291
248
|
const network = Network.MAINNET;
|
|
@@ -304,6 +261,7 @@ describe('TestPoolSimulator_SwapInLimits', () => {
|
|
|
304
261
|
100n,
|
|
305
262
|
18,
|
|
306
263
|
limitsTight,
|
|
264
|
+
BigInt(centerPriceTight),
|
|
307
265
|
Math.floor(Date.now() / 1000) - 10,
|
|
308
266
|
);
|
|
309
267
|
expect(outAmt).toEqual(0n);
|
|
@@ -321,10 +279,10 @@ describe('TestPoolSimulator_SwapInLimits', () => {
|
|
|
321
279
|
100n,
|
|
322
280
|
18,
|
|
323
281
|
limitsTight,
|
|
282
|
+
BigInt(centerPriceTight),
|
|
324
283
|
Math.floor(Date.now() / 1000) - 6000,
|
|
325
284
|
);
|
|
326
|
-
|
|
327
|
-
expect(outAmt?.toString()).toEqual('998262697204710');
|
|
285
|
+
expect(outAmt?.toString()).toEqual('998163044346107');
|
|
328
286
|
});
|
|
329
287
|
|
|
330
288
|
it('when price diff hit', () => {
|
|
@@ -338,6 +296,7 @@ describe('TestPoolSimulator_SwapInLimits', () => {
|
|
|
338
296
|
100n,
|
|
339
297
|
18,
|
|
340
298
|
limitsWide,
|
|
299
|
+
BigInt(centerPriceWide),
|
|
341
300
|
Math.floor(Date.now() / 1000) - 10,
|
|
342
301
|
);
|
|
343
302
|
expect(outAmt).toEqual(0n);
|
|
@@ -357,6 +316,7 @@ describe('TestPoolSimulator_SwapInLimits', () => {
|
|
|
357
316
|
100n,
|
|
358
317
|
18,
|
|
359
318
|
limitsWide,
|
|
319
|
+
BigInt(centerPriceWide),
|
|
360
320
|
Math.floor(Date.now() / 1000) - 10,
|
|
361
321
|
);
|
|
362
322
|
expect(outAmt).toEqual(0n);
|
|
@@ -137,12 +137,14 @@ export class FluidDexLiquidityProxy extends StatefulEventSubscriber<FluidDexLiqu
|
|
|
137
137
|
token0,
|
|
138
138
|
token1,
|
|
139
139
|
feeHex,
|
|
140
|
+
centerPriceHex,
|
|
140
141
|
collateralReservesHex,
|
|
141
142
|
debtReservesHex,
|
|
142
143
|
dexLimitsHex,
|
|
143
144
|
] = poolReserve;
|
|
144
145
|
|
|
145
146
|
const fee = Number(feeHex.toString());
|
|
147
|
+
const centerPrice = Number(centerPriceHex.toString());
|
|
146
148
|
|
|
147
149
|
const collateralReserves = {
|
|
148
150
|
token0RealReserves: bigIntify(collateralReservesHex[0]),
|
|
@@ -196,6 +198,7 @@ export class FluidDexLiquidityProxy extends StatefulEventSubscriber<FluidDexLiqu
|
|
|
196
198
|
token0,
|
|
197
199
|
token1,
|
|
198
200
|
fee,
|
|
201
|
+
centerPrice,
|
|
199
202
|
collateralReserves,
|
|
200
203
|
debtReserves,
|
|
201
204
|
dexLimits,
|