@paraswap/dex-lib 3.8.24 → 3.8.26
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/.vscode/launch.json +16 -0
- package/.vscode/settings.json +3 -0
- package/build/abi/Uncompressor.json +250 -0
- 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/integral/relayer.json +1536 -0
- package/build/dex/aave-v1/aave-v1.d.ts +1 -2
- package/build/dex/aave-v1/aave-v1.js +0 -22
- package/build/dex/aave-v1/aave-v1.js.map +1 -1
- package/build/dex/bProtocol.d.ts +18 -0
- package/build/dex/bProtocol.js +39 -0
- package/build/dex/bProtocol.js.map +1 -0
- package/build/dex/bancor.d.ts +26 -0
- package/build/dex/bancor.js +58 -0
- package/build/dex/bancor.js.map +1 -0
- package/build/dex/compound.d.ts +18 -0
- package/build/dex/compound.js +46 -0
- package/build/dex/compound.js.map +1 -0
- package/build/dex/curve-v2.d.ts +58 -0
- package/build/dex/curve-v2.js +180 -0
- package/build/dex/curve-v2.js.map +1 -0
- package/build/dex/dodo-v1.d.ts +33 -0
- package/build/dex/dodo-v1.js +63 -0
- package/build/dex/dodo-v1.js.map +1 -0
- package/build/dex/etherfi/etherfi.d.ts +26 -0
- package/build/dex/etherfi/etherfi.js +96 -0
- package/build/dex/etherfi/etherfi.js.map +1 -0
- package/build/dex/generic-rfq/rate-fetcher.js +1 -1
- package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
- package/build/dex/index.js +2 -0
- package/build/dex/index.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/helpers.d.ts +17 -0
- package/build/dex/integral/helpers.js +157 -0
- package/build/dex/integral/helpers.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/{inception/inception-native.d.ts → integral/integral.d.ts} +19 -21
- 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/lido.d.ts +19 -0
- package/build/dex/lido.js +42 -0
- package/build/dex/lido.js.map +1 -0
- package/build/dex/onebit.d.ts +25 -0
- package/build/dex/onebit.js +42 -0
- package/build/dex/onebit.js.map +1 -0
- package/build/dex/oswap/oswap-pool.js +8 -8
- package/build/dex/oswap/oswap-pool.js.map +1 -1
- package/build/dex/oswap/oswap.d.ts +3 -3
- package/build/dex/oswap/oswap.js +21 -12
- package/build/dex/oswap/oswap.js.map +1 -1
- package/build/dex/oswap/types.d.ts +4 -4
- package/build/dex/platypus/platypus.d.ts +1 -2
- package/build/dex/platypus/platypus.js +0 -31
- package/build/dex/platypus/platypus.js.map +1 -1
- package/build/dex/sdai/config.d.ts +11 -0
- package/build/dex/sdai/config.js +21 -0
- package/build/dex/sdai/config.js.map +1 -0
- package/build/dex/sdai/constants.d.ts +2 -0
- package/build/dex/sdai/constants.js +6 -0
- package/build/dex/sdai/constants.js.map +1 -0
- package/build/dex/sdai/scripts/validate-state.d.ts +1 -0
- package/build/dex/sdai/scripts/validate-state.js +102 -0
- package/build/dex/sdai/scripts/validate-state.js.map +1 -0
- package/build/dex/sdai/sdai-pool.d.ts +16 -0
- package/build/dex/sdai/sdai-pool.js +85 -0
- package/build/dex/sdai/sdai-pool.js.map +1 -0
- package/build/dex/sdai/sdai.d.ts +51 -0
- package/build/dex/sdai/sdai.js +172 -0
- package/build/dex/sdai/sdai.js.map +1 -0
- package/build/dex/sdai/types.d.ts +21 -0
- package/build/dex/sdai/types.js +11 -0
- package/build/dex/sdai/types.js.map +1 -0
- package/build/dex/sdai/utils.d.ts +4 -0
- package/build/dex/sdai/utils.js +39 -0
- package/build/dex/sdai/utils.js.map +1 -0
- package/build/dex/smoothy.d.ts +26 -0
- package/build/dex/smoothy.js +48 -0
- package/build/dex/smoothy.js.map +1 -0
- package/build/dex/stable-pool.d.ts +28 -0
- package/build/dex/stable-pool.js +62 -0
- package/build/dex/stable-pool.js.map +1 -0
- package/build/dex/swaap-v1/swaap-v1.d.ts +1 -2
- package/build/dex/swaap-v1/swaap-v1.js +0 -10
- 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 +44 -0
- package/build/dex/trader-joe-v2.1/optimizer.js.map +1 -0
- package/build/dex/trader-joe-v2.1.d.ts +43 -0
- package/build/dex/trader-joe-v2.1.js +79 -0
- package/build/dex/trader-joe-v2.1.js.map +1 -0
- package/build/executor/compressor/Compressor.d.ts +23 -0
- package/build/executor/compressor/Compressor.js +144 -0
- package/build/executor/compressor/Compressor.js.map +1 -0
- package/build/executor/compressor/compress.d.ts +17 -0
- package/build/executor/compressor/compress.js +187 -0
- package/build/executor/compressor/compress.js.map +1 -0
- package/build/executor/compressor/compress_functions/addressSubstitution.d.ts +6 -0
- package/build/executor/compressor/compress_functions/addressSubstitution.js +29 -0
- package/build/executor/compressor/compress_functions/addressSubstitution.js.map +1 -0
- package/build/executor/compressor/compress_functions/addressSubstitutionFromObject.d.ts +10 -0
- package/build/executor/compressor/compress_functions/addressSubstitutionFromObject.js +40 -0
- package/build/executor/compressor/compress_functions/addressSubstitutionFromObject.js.map +1 -0
- package/build/executor/compressor/compress_functions/byteSubstitution.d.ts +11 -0
- package/build/executor/compressor/compress_functions/byteSubstitution.js +64 -0
- package/build/executor/compressor/compress_functions/byteSubstitution.js.map +1 -0
- package/build/executor/compressor/compress_functions/ffSubstitution.d.ts +7 -0
- package/build/executor/compressor/compress_functions/ffSubstitution.js +54 -0
- package/build/executor/compressor/compress_functions/ffSubstitution.js.map +1 -0
- package/build/executor/compressor/compress_functions/findLongestAndSubstitute.d.ts +8 -0
- package/build/executor/compressor/compress_functions/findLongestAndSubstitute.js +67 -0
- package/build/executor/compressor/compress_functions/findLongestAndSubstitute.js.map +1 -0
- package/build/executor/compressor/compress_functions/findLongestAndSubstitute_old.d.ts +8 -0
- package/build/executor/compressor/compress_functions/findLongestAndSubstitute_old.js +61 -0
- package/build/executor/compressor/compress_functions/findLongestAndSubstitute_old.js.map +1 -0
- package/build/executor/compressor/compress_functions/reverseAddressSubstitution.d.ts +6 -0
- package/build/executor/compressor/compress_functions/reverseAddressSubstitution.js +37 -0
- package/build/executor/compressor/compress_functions/reverseAddressSubstitution.js.map +1 -0
- package/build/executor/compressor/compress_functions/searchUnusedBytes.d.ts +9 -0
- package/build/executor/compressor/compress_functions/searchUnusedBytes.js +33 -0
- package/build/executor/compressor/compress_functions/searchUnusedBytes.js.map +1 -0
- package/build/executor/compressor/fetchSaved.d.ts +0 -0
- package/build/executor/compressor/fetchSaved.js +17 -0
- package/build/executor/compressor/fetchSaved.js.map +1 -0
- package/build/executor/compressor/utils/computeCostL2.d.ts +2 -0
- package/build/executor/compressor/utils/computeCostL2.js +14 -0
- package/build/executor/compressor/utils/computeCostL2.js.map +1 -0
- package/build/executor/compressor/utils/findLongestDuplicatedString.d.ts +2 -0
- package/build/executor/compressor/utils/findLongestDuplicatedString.js +30 -0
- package/build/executor/compressor/utils/findLongestDuplicatedString.js.map +1 -0
- package/build/executor/compressor/utils/getAllIndexes.d.ts +2 -0
- package/build/executor/compressor/utils/getAllIndexes.js +12 -0
- package/build/executor/compressor/utils/getAllIndexes.js.map +1 -0
- package/build/executor/compressor/utils/getByteForAddress.d.ts +2 -0
- package/build/executor/compressor/utils/getByteForAddress.js +14 -0
- package/build/executor/compressor/utils/getByteForAddress.js.map +1 -0
- package/build/executor/compressor/utils/intTo2Bytes.d.ts +2 -0
- package/build/executor/compressor/utils/intTo2Bytes.js +14 -0
- package/build/executor/compressor/utils/intTo2Bytes.js.map +1 -0
- package/build/executor/compressor/utils/intTo3Bytes.d.ts +2 -0
- package/build/executor/compressor/utils/intTo3Bytes.js +18 -0
- package/build/executor/compressor/utils/intTo3Bytes.js.map +1 -0
- package/build/executor/compressor/utils/intToByte.d.ts +2 -0
- package/build/executor/compressor/utils/intToByte.js +10 -0
- package/build/executor/compressor/utils/intToByte.js.map +1 -0
- package/package.json +1 -1
- package/src/abi/oswap/oswap.abi.json +452 -0
- package/src/dex/generic-rfq/rate-fetcher.ts +6 -5
- package/src/dex/index.ts +2 -0
- package/src/dex/oswap/config.ts +32 -0
- package/src/dex/oswap/oswap-e2e.test.ts +91 -0
- package/src/dex/oswap/oswap-events.test.ts +88 -0
- package/src/dex/oswap/oswap-integration.test.ts +291 -0
- package/src/dex/oswap/oswap-pool.ts +190 -0
- package/src/dex/oswap/oswap.ts +414 -0
- package/src/dex/oswap/types.ts +29 -0
- package/build/abi/inception/inception-ineth.json +0 -609
- package/build/abi/inception/inception-ratio-feed.json +0 -93
- package/build/abi/inception/inception-vault.json +0 -991
- package/build/dex/idle-dao/idle-dao-pool.d.ts +0 -56
- package/build/dex/idle-dao/idle-dao-pool.js +0 -176
- package/build/dex/idle-dao/idle-dao-pool.js.map +0 -1
- package/build/dex/idle-dao/idle-dao-pooling-pool.d.ts +0 -16
- package/build/dex/idle-dao/idle-dao-pooling-pool.js +0 -57
- package/build/dex/idle-dao/idle-dao-pooling-pool.js.map +0 -1
- package/build/dex/idle-dao/scripts.d.ts +0 -9
- package/build/dex/idle-dao/scripts.js +0 -552
- package/build/dex/idle-dao/scripts.js.map +0 -1
- package/build/dex/inception/config.d.ts +0 -5
- package/build/dex/inception/config.js +0 -112
- package/build/dex/inception/config.js.map +0 -1
- package/build/dex/inception/inception-event-pool.d.ts +0 -23
- package/build/dex/inception/inception-event-pool.js +0 -34
- package/build/dex/inception/inception-event-pool.js.map +0 -1
- package/build/dex/inception/inception-native.js +0 -131
- package/build/dex/inception/inception-native.js.map +0 -1
- package/build/dex/inception/inception-pool.d.ts +0 -18
- package/build/dex/inception/inception-pool.js +0 -32
- package/build/dex/inception/inception-pool.js.map +0 -1
- package/build/dex/inception/inception-price-feed.d.ts +0 -19
- package/build/dex/inception/inception-price-feed.js +0 -51
- package/build/dex/inception/inception-price-feed.js.map +0 -1
- package/build/dex/inception/inception.d.ts +0 -44
- package/build/dex/inception/inception.js +0 -162
- 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
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
dotenv.config();
|
|
4
|
+
|
|
5
|
+
import { DummyDexHelper } from '../../dex-helper/index';
|
|
6
|
+
import { Network, SwapSide } from '../../constants';
|
|
7
|
+
import { BI_POWS } from '../../bigint-constants';
|
|
8
|
+
import { MultiCallParams } from '../../lib/multi-wrapper';
|
|
9
|
+
import { uint256ToBigInt } from '../../lib/decoders';
|
|
10
|
+
import { getBigIntPow } from '../../utils';
|
|
11
|
+
import {
|
|
12
|
+
checkPoolPrices,
|
|
13
|
+
checkPoolsLiquidity,
|
|
14
|
+
checkConstantPoolPrices,
|
|
15
|
+
} from '../../../tests/utils';
|
|
16
|
+
import { Tokens } from '../../../tests/constants-e2e';
|
|
17
|
+
import { Address } from '../../types';
|
|
18
|
+
import { OSwap } from './oswap';
|
|
19
|
+
import { OSwapPool } from './types';
|
|
20
|
+
|
|
21
|
+
async function getOnchainTraderates(
|
|
22
|
+
oswap: OSwap,
|
|
23
|
+
pool: OSwapPool,
|
|
24
|
+
blockNumber: number,
|
|
25
|
+
): Promise<{ traderate0: bigint; traderate1: bigint }> {
|
|
26
|
+
const callData: MultiCallParams<bigint>[] = [
|
|
27
|
+
{
|
|
28
|
+
target: pool.address,
|
|
29
|
+
callData: oswap.iOSwap.encodeFunctionData('traderate0', []),
|
|
30
|
+
decodeFunction: uint256ToBigInt,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
target: pool.address,
|
|
34
|
+
callData: oswap.iOSwap.encodeFunctionData('traderate1', []),
|
|
35
|
+
decodeFunction: uint256ToBigInt,
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const results = await oswap.dexHelper.multiWrapper.aggregate<bigint>(
|
|
40
|
+
callData,
|
|
41
|
+
blockNumber,
|
|
42
|
+
oswap.dexHelper.multiWrapper.defaultBatchSize,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return { traderate0: results[0], traderate1: results[1] };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Check prices passed as arguments against prices calculated from on-chain data.
|
|
49
|
+
async function checkOnChainPricing(
|
|
50
|
+
oswap: OSwap,
|
|
51
|
+
pool: OSwapPool,
|
|
52
|
+
blockNumber: number,
|
|
53
|
+
prices: bigint[],
|
|
54
|
+
side: SwapSide,
|
|
55
|
+
srcAddress: Address,
|
|
56
|
+
destAddress: Address,
|
|
57
|
+
amounts: bigint[],
|
|
58
|
+
) {
|
|
59
|
+
// Get the onchain trade rates from the pool and calculate the prices.
|
|
60
|
+
const data = await getOnchainTraderates(oswap, pool, blockNumber);
|
|
61
|
+
let expectedPrices: bigint[] = [];
|
|
62
|
+
for (const amount of amounts) {
|
|
63
|
+
const rate =
|
|
64
|
+
srcAddress.toLowerCase() === pool.token0
|
|
65
|
+
? data.traderate0
|
|
66
|
+
: data.traderate1;
|
|
67
|
+
if (side === SwapSide.SELL) {
|
|
68
|
+
expectedPrices.push((amount * rate) / getBigIntPow(36));
|
|
69
|
+
} else {
|
|
70
|
+
// SwapSide.BUY
|
|
71
|
+
expectedPrices.push((amount * getBigIntPow(36)) / rate);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
expect(prices).toEqual(expectedPrices);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function testPricingOnNetwork(
|
|
78
|
+
oswap: OSwap,
|
|
79
|
+
network: Network,
|
|
80
|
+
dexKey: string,
|
|
81
|
+
blockNumber: number,
|
|
82
|
+
srcTokenSymbol: string,
|
|
83
|
+
destTokenSymbol: string,
|
|
84
|
+
side: SwapSide,
|
|
85
|
+
amounts: bigint[],
|
|
86
|
+
) {
|
|
87
|
+
const networkTokens = Tokens[network];
|
|
88
|
+
const srcToken = networkTokens[srcTokenSymbol];
|
|
89
|
+
const destToken = networkTokens[destTokenSymbol];
|
|
90
|
+
|
|
91
|
+
const poolIds = await oswap.getPoolIdentifiers(
|
|
92
|
+
srcToken,
|
|
93
|
+
destToken,
|
|
94
|
+
side,
|
|
95
|
+
blockNumber,
|
|
96
|
+
);
|
|
97
|
+
console.log(
|
|
98
|
+
`${srcTokenSymbol} <> ${destTokenSymbol} Pool Identifiers: ${poolIds}`,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
expect(poolIds.length).toBeGreaterThan(0);
|
|
102
|
+
|
|
103
|
+
// Get calculated prices based on the stored state.
|
|
104
|
+
const poolPrices = await oswap.getPricesVolume(
|
|
105
|
+
srcToken,
|
|
106
|
+
destToken,
|
|
107
|
+
amounts,
|
|
108
|
+
side,
|
|
109
|
+
blockNumber,
|
|
110
|
+
poolIds,
|
|
111
|
+
);
|
|
112
|
+
console.log(
|
|
113
|
+
`${side} ${srcTokenSymbol} <> ${destTokenSymbol} Pool Prices: `,
|
|
114
|
+
poolPrices,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
expect(poolPrices).not.toBeNull();
|
|
118
|
+
if (oswap.hasConstantPriceLargeAmounts) {
|
|
119
|
+
checkConstantPoolPrices(poolPrices!, amounts, dexKey);
|
|
120
|
+
} else {
|
|
121
|
+
checkPoolPrices(poolPrices!, amounts, side, dexKey);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Check that the prices calculated from onchain data match with the ones calculated from the stored state.
|
|
125
|
+
const pool = oswap.getPoolById(poolIds[0]);
|
|
126
|
+
expect(pool).not.toBeNull();
|
|
127
|
+
await checkOnChainPricing(
|
|
128
|
+
oswap,
|
|
129
|
+
pool as OSwapPool,
|
|
130
|
+
blockNumber,
|
|
131
|
+
poolPrices![0].prices,
|
|
132
|
+
side,
|
|
133
|
+
srcToken.address,
|
|
134
|
+
destToken.address,
|
|
135
|
+
amounts,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
describe('OSwap', function () {
|
|
140
|
+
const dexKey = 'OSwap';
|
|
141
|
+
let blockNumber: number;
|
|
142
|
+
let oswap: OSwap;
|
|
143
|
+
|
|
144
|
+
describe('Mainnet', () => {
|
|
145
|
+
const network = Network.MAINNET;
|
|
146
|
+
const dexHelper = new DummyDexHelper(network);
|
|
147
|
+
|
|
148
|
+
const tokens = Tokens[network];
|
|
149
|
+
|
|
150
|
+
const srcTokenSymbol = 'WETH';
|
|
151
|
+
const destTokenSymbol = 'STETH';
|
|
152
|
+
|
|
153
|
+
const amountsForSell = [
|
|
154
|
+
0n,
|
|
155
|
+
1n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
156
|
+
2n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
157
|
+
3n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
158
|
+
4n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
159
|
+
5n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
160
|
+
6n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
161
|
+
7n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
162
|
+
8n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
163
|
+
9n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
164
|
+
10n * BI_POWS[tokens[srcTokenSymbol].decimals],
|
|
165
|
+
];
|
|
166
|
+
|
|
167
|
+
const amountsForBuy = [
|
|
168
|
+
0n,
|
|
169
|
+
1n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
170
|
+
2n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
171
|
+
3n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
172
|
+
4n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
173
|
+
5n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
174
|
+
6n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
175
|
+
7n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
176
|
+
8n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
177
|
+
9n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
178
|
+
10n * BI_POWS[tokens[destTokenSymbol].decimals],
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
// Return a blockNumber to use for the tests.
|
|
182
|
+
// Check that the pool has enough liquidity to run the tests at the current blockNumber.
|
|
183
|
+
// If not, fallback to a known blockNumber in the past with
|
|
184
|
+
// high enough liquidity - the on-chain queries will just be a bit slower to execute.
|
|
185
|
+
async function getBlockNumberForTesting(oswap: OSwap): Promise<number> {
|
|
186
|
+
const DEFAULT_BLOCK_NUMBER = 18888241;
|
|
187
|
+
|
|
188
|
+
blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
|
|
189
|
+
const srcToken = Tokens[network][srcTokenSymbol];
|
|
190
|
+
const destToken = Tokens[network][destTokenSymbol];
|
|
191
|
+
|
|
192
|
+
// Get the pool and its state for the given test pair.
|
|
193
|
+
const pool = oswap.getPoolByTokenPair(srcToken, destToken);
|
|
194
|
+
if (!pool)
|
|
195
|
+
throw new Error(
|
|
196
|
+
`No pool found for pair ${srcTokenSymbol}-${destTokenSymbol}`,
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
const eventPool = oswap.eventPools[pool.id];
|
|
200
|
+
const state = await eventPool.getStateOrGenerate(blockNumber, true);
|
|
201
|
+
|
|
202
|
+
const minBalance =
|
|
203
|
+
state.balance0 < state.balance1 ? state.balance0 : state.balance1;
|
|
204
|
+
const maxAmount = [...amountsForSell, ...amountsForBuy].reduce(
|
|
205
|
+
(max, amount) => (amount > max ? amount : max),
|
|
206
|
+
);
|
|
207
|
+
const hasEnoughLiquidity = BigInt(minBalance) > maxAmount;
|
|
208
|
+
|
|
209
|
+
if (!hasEnoughLiquidity) {
|
|
210
|
+
return DEFAULT_BLOCK_NUMBER;
|
|
211
|
+
}
|
|
212
|
+
return blockNumber;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
beforeAll(async () => {
|
|
216
|
+
oswap = new OSwap(network, dexKey, dexHelper);
|
|
217
|
+
|
|
218
|
+
blockNumber = await getBlockNumberForTesting(oswap);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('getPoolIdentifiers and getPricesVolume SELL', async function () {
|
|
222
|
+
await testPricingOnNetwork(
|
|
223
|
+
oswap,
|
|
224
|
+
network,
|
|
225
|
+
dexKey,
|
|
226
|
+
blockNumber,
|
|
227
|
+
srcTokenSymbol,
|
|
228
|
+
destTokenSymbol,
|
|
229
|
+
SwapSide.SELL,
|
|
230
|
+
amountsForSell,
|
|
231
|
+
);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('getPoolIdentifiers and getPricesVolume BUY', async function () {
|
|
235
|
+
await testPricingOnNetwork(
|
|
236
|
+
oswap,
|
|
237
|
+
network,
|
|
238
|
+
dexKey,
|
|
239
|
+
blockNumber,
|
|
240
|
+
srcTokenSymbol,
|
|
241
|
+
destTokenSymbol,
|
|
242
|
+
SwapSide.BUY,
|
|
243
|
+
amountsForBuy,
|
|
244
|
+
);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it(`getTopPoolsForToken ${srcTokenSymbol}`, async function () {
|
|
248
|
+
// We have to check without calling initializePricing, because
|
|
249
|
+
// pool-tracker is not calling that function
|
|
250
|
+
const newOSwap = new OSwap(network, dexKey, dexHelper);
|
|
251
|
+
await newOSwap.updatePoolState?.();
|
|
252
|
+
|
|
253
|
+
const poolLiquidity = await newOSwap.getTopPoolsForToken(
|
|
254
|
+
tokens[srcTokenSymbol].address,
|
|
255
|
+
10,
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
console.log(`${srcTokenSymbol} top pools:`, poolLiquidity);
|
|
259
|
+
|
|
260
|
+
if (!newOSwap.hasConstantPriceLargeAmounts) {
|
|
261
|
+
checkPoolsLiquidity(
|
|
262
|
+
poolLiquidity,
|
|
263
|
+
Tokens[network][srcTokenSymbol].address,
|
|
264
|
+
dexKey,
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it(`getTopPoolsForToken ${destTokenSymbol}`, async function () {
|
|
270
|
+
// We have to check without calling initializePricing, because
|
|
271
|
+
// pool-tracker is not calling that function
|
|
272
|
+
const newOSwap = new OSwap(network, dexKey, dexHelper);
|
|
273
|
+
await newOSwap.updatePoolState?.();
|
|
274
|
+
|
|
275
|
+
const poolLiquidity = await newOSwap.getTopPoolsForToken(
|
|
276
|
+
tokens[destTokenSymbol].address,
|
|
277
|
+
10,
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
console.log(`${destTokenSymbol} top pools:`, poolLiquidity);
|
|
281
|
+
|
|
282
|
+
if (!newOSwap.hasConstantPriceLargeAmounts) {
|
|
283
|
+
checkPoolsLiquidity(
|
|
284
|
+
poolLiquidity,
|
|
285
|
+
Tokens[network][destTokenSymbol].address,
|
|
286
|
+
dexKey,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
});
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { Interface } from '@ethersproject/abi';
|
|
2
|
+
import { DeepReadonly } from 'ts-essentials';
|
|
3
|
+
import { Log, Logger, Token } from '../../types';
|
|
4
|
+
import { catchParseLogError } from '../../utils';
|
|
5
|
+
import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
|
|
6
|
+
import { IDexHelper } from '../../dex-helper/idex-helper';
|
|
7
|
+
import { MultiCallParams } from '../../lib/multi-wrapper';
|
|
8
|
+
import { uint256ToBigInt } from '../../lib/decoders';
|
|
9
|
+
import { OSwapPool, OSwapPoolState } from './types';
|
|
10
|
+
import OSwapABI from '../../abi/oswap/oswap.abi.json';
|
|
11
|
+
import ERC20ABI from '../../abi/ERC20.abi.json';
|
|
12
|
+
|
|
13
|
+
export class OSwapEventPool extends StatefulEventSubscriber<OSwapPoolState> {
|
|
14
|
+
handlers: {
|
|
15
|
+
[event: string]: (
|
|
16
|
+
event: any,
|
|
17
|
+
state: DeepReadonly<OSwapPoolState>,
|
|
18
|
+
log: Readonly<Log>,
|
|
19
|
+
) => DeepReadonly<OSwapPoolState> | null;
|
|
20
|
+
} = {};
|
|
21
|
+
|
|
22
|
+
logDecoder: (log: Log) => any;
|
|
23
|
+
|
|
24
|
+
addressesSubscribed: string[];
|
|
25
|
+
|
|
26
|
+
constructor(
|
|
27
|
+
readonly parentName: string,
|
|
28
|
+
readonly pool: OSwapPool,
|
|
29
|
+
protected network: number,
|
|
30
|
+
protected dexHelper: IDexHelper,
|
|
31
|
+
logger: Logger,
|
|
32
|
+
protected iOSwap = new Interface(OSwapABI),
|
|
33
|
+
protected iERC20 = new Interface(ERC20ABI),
|
|
34
|
+
) {
|
|
35
|
+
super(parentName, pool.id, dexHelper, logger);
|
|
36
|
+
|
|
37
|
+
this.logDecoder = (log: Log) => this.parseLog(log);
|
|
38
|
+
|
|
39
|
+
this.addressesSubscribed = [pool.address, pool.token0, pool.token1];
|
|
40
|
+
this.handlers['TraderateChanged'] = this.handleTraderateChanged.bind(this);
|
|
41
|
+
this.handlers['Transfer'] = this.handleTransfer.bind(this);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected parseLog(log: Log) {
|
|
45
|
+
if (log.address.toLowerCase() === this.pool.address) {
|
|
46
|
+
return this.iOSwap.parseLog(log);
|
|
47
|
+
}
|
|
48
|
+
return this.iERC20.parseLog(log);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The function is called every time any of the subscribed
|
|
53
|
+
* addresses release log. The function accepts the current
|
|
54
|
+
* state, updates the state according to the log, and returns
|
|
55
|
+
* the updated state.
|
|
56
|
+
* @param state - Current state of event subscriber
|
|
57
|
+
* @param log - Log released by one of the subscribed addresses
|
|
58
|
+
* @returns Updates state of the event subscriber after the log
|
|
59
|
+
*/
|
|
60
|
+
protected processLog(
|
|
61
|
+
state: DeepReadonly<OSwapPoolState>,
|
|
62
|
+
log: Readonly<Log>,
|
|
63
|
+
): DeepReadonly<OSwapPoolState> | null {
|
|
64
|
+
try {
|
|
65
|
+
const event = this.logDecoder(log);
|
|
66
|
+
if (event.name in this.handlers) {
|
|
67
|
+
return this.handlers[event.name](event, state, log);
|
|
68
|
+
}
|
|
69
|
+
} catch (e) {
|
|
70
|
+
catchParseLogError(e, this.logger);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The function generates state using on-chain calls. This
|
|
78
|
+
* function is called to regenerate state if the event based
|
|
79
|
+
* system fails to fetch events and the local state is no
|
|
80
|
+
* more correct.
|
|
81
|
+
* @param blockNumber - Blocknumber for which the state should
|
|
82
|
+
* should be generated
|
|
83
|
+
* @returns state of the event subscriber at blocknumber
|
|
84
|
+
*/
|
|
85
|
+
async generateState(
|
|
86
|
+
blockNumber: number,
|
|
87
|
+
): Promise<DeepReadonly<OSwapPoolState>> {
|
|
88
|
+
const iERC20 = new Interface(ERC20ABI);
|
|
89
|
+
const callData: MultiCallParams<bigint>[] = [
|
|
90
|
+
{
|
|
91
|
+
target: this.pool.token0,
|
|
92
|
+
callData: iERC20.encodeFunctionData('balanceOf', [this.pool.address]),
|
|
93
|
+
decodeFunction: uint256ToBigInt,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
target: this.pool.token1,
|
|
97
|
+
callData: iERC20.encodeFunctionData('balanceOf', [this.pool.address]),
|
|
98
|
+
decodeFunction: uint256ToBigInt,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
target: this.pool.address,
|
|
102
|
+
callData: this.iOSwap.encodeFunctionData('traderate0', []),
|
|
103
|
+
decodeFunction: uint256ToBigInt,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
target: this.pool.address,
|
|
107
|
+
callData: this.iOSwap.encodeFunctionData('traderate1', []),
|
|
108
|
+
decodeFunction: uint256ToBigInt,
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
const results = await this.dexHelper.multiWrapper.aggregate<bigint>(
|
|
113
|
+
callData,
|
|
114
|
+
blockNumber,
|
|
115
|
+
this.dexHelper.multiWrapper.defaultBatchSize,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
balance0: results[0].toString(),
|
|
120
|
+
balance1: results[1].toString(),
|
|
121
|
+
traderate0: results[2].toString(),
|
|
122
|
+
traderate1: results[3].toString(),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async getStateOrGenerate(
|
|
127
|
+
blockNumber: number,
|
|
128
|
+
readonly: boolean = true,
|
|
129
|
+
): Promise<OSwapPoolState> {
|
|
130
|
+
let state = this.getState(blockNumber);
|
|
131
|
+
if (!state) {
|
|
132
|
+
state = await this.generateState(blockNumber);
|
|
133
|
+
if (!readonly) this.setState(state, blockNumber);
|
|
134
|
+
}
|
|
135
|
+
return state;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Handle a trade rate change on the pool.
|
|
140
|
+
*/
|
|
141
|
+
handleTraderateChanged(
|
|
142
|
+
event: any,
|
|
143
|
+
state: DeepReadonly<OSwapPoolState>,
|
|
144
|
+
log: Readonly<Log>,
|
|
145
|
+
): DeepReadonly<OSwapPoolState> | null {
|
|
146
|
+
return {
|
|
147
|
+
...state,
|
|
148
|
+
traderate0: event.args.traderate0.toBigInt(),
|
|
149
|
+
traderate1: event.args.traderate1.toBigInt(),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Process the transfer events for tokens in/out of the pool
|
|
155
|
+
* to keep the state's token balances up to date.
|
|
156
|
+
*/
|
|
157
|
+
handleTransfer(
|
|
158
|
+
event: any,
|
|
159
|
+
state: DeepReadonly<OSwapPoolState>,
|
|
160
|
+
log: Readonly<Log>,
|
|
161
|
+
): DeepReadonly<OSwapPoolState> | null {
|
|
162
|
+
let balance0: bigint = BigInt(state.balance0);
|
|
163
|
+
let balance1: bigint = BigInt(state.balance1);
|
|
164
|
+
|
|
165
|
+
const tokenAddress = log.address.toLowerCase();
|
|
166
|
+
const fromAddress = event.args.from.toLowerCase();
|
|
167
|
+
const toAddress = event.args.to.toLowerCase();
|
|
168
|
+
const amount = event.args.value.toBigInt();
|
|
169
|
+
|
|
170
|
+
if (fromAddress == this.pool.address) {
|
|
171
|
+
if (tokenAddress === this.pool.token0) {
|
|
172
|
+
balance0 -= amount;
|
|
173
|
+
} else if (tokenAddress === this.pool.token1) {
|
|
174
|
+
balance1 -= amount;
|
|
175
|
+
}
|
|
176
|
+
} else if (toAddress == this.pool.address) {
|
|
177
|
+
if (tokenAddress === this.pool.token0) {
|
|
178
|
+
balance0 += amount;
|
|
179
|
+
} else if (tokenAddress === this.pool.token1) {
|
|
180
|
+
balance1 += amount;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
...state,
|
|
186
|
+
balance0: balance0.toString(),
|
|
187
|
+
balance1: balance1.toString(),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|