@paraswap/dex-lib 2.19.1 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/abi/DirectSwap.json +1018 -0
- package/build/dex/balancer-v2/balancer-v2.d.ts +9 -3
- package/build/dex/balancer-v2/balancer-v2.js +83 -0
- package/build/dex/balancer-v2/balancer-v2.js.map +1 -1
- package/build/dex/balancer-v2/constants.d.ts +4 -0
- package/build/dex/balancer-v2/constants.js +6 -1
- package/build/dex/balancer-v2/constants.js.map +1 -1
- package/build/dex/balancer-v2/types.d.ts +20 -1
- package/build/dex/balancer-v2/types.js.map +1 -1
- package/build/dex/curve-v1/constants.d.ts +1 -0
- package/build/dex/curve-v1/constants.js +2 -1
- package/build/dex/curve-v1/constants.js.map +1 -1
- package/build/dex/curve-v1/curve-v1.d.ts +9 -3
- package/build/dex/curve-v1/curve-v1.js +92 -4
- package/build/dex/curve-v1/curve-v1.js.map +1 -1
- package/build/dex/curve-v1/types.d.ts +24 -0
- package/build/dex/curve-v1/types.js +6 -1
- package/build/dex/curve-v1/types.js.map +1 -1
- package/build/dex/curve-v1-factory/constants.d.ts +1 -0
- package/build/dex/curve-v1-factory/constants.js +2 -1
- package/build/dex/curve-v1-factory/constants.js.map +1 -1
- package/build/dex/curve-v1-factory/curve-v1-factory.d.ts +11 -4
- package/build/dex/curve-v1-factory/curve-v1-factory.js +87 -0
- package/build/dex/curve-v1-factory/curve-v1-factory.js.map +1 -1
- package/build/dex/curve-v1-factory/types.d.ts +24 -0
- package/build/dex/curve-v1-factory/types.js +6 -1
- package/build/dex/curve-v1-factory/types.js.map +1 -1
- package/build/dex/curve-v2.d.ts +29 -7
- package/build/dex/curve-v2.js +91 -1
- package/build/dex/curve-v2.js.map +1 -1
- package/build/dex/idex.d.ts +1 -1
- package/build/dex/pancakeswap-v3/pancakeswap-v3.d.ts +2 -2
- package/build/dex/pancakeswap-v3/utils.js.map +1 -1
- package/build/dex/simple-exchange.d.ts +2 -0
- package/build/dex/simple-exchange.js +1 -0
- package/build/dex/simple-exchange.js.map +1 -1
- package/build/dex/swaap-v2/swaap-v2.js +5 -1
- package/build/dex/swaap-v2/swaap-v2.js.map +1 -1
- package/build/dex/swaap-v2/utils.js.map +1 -1
- package/build/dex/swaap-v2/validators.js +1 -2
- package/build/dex/swaap-v2/validators.js.map +1 -1
- package/build/dex/test-dex/config.d.ts +4 -0
- package/build/dex/test-dex/config.js +15 -0
- package/build/dex/test-dex/config.js.map +1 -0
- package/build/dex/test-dex/test-dex-pool.d.ts +39 -0
- package/build/dex/test-dex/test-dex-pool.js +63 -0
- package/build/dex/test-dex/test-dex-pool.js.map +1 -0
- package/build/dex/test-dex/test-dex.d.ts +37 -0
- package/build/dex/test-dex/test-dex.js +126 -0
- package/build/dex/test-dex/test-dex.js.map +1 -0
- package/build/dex/test-dex/types.d.ts +6 -0
- package/build/dex/{pancakeswap-v3 → test-dex}/types.js.map +1 -1
- package/build/dex/uniswap-v2/uniswap-v2.d.ts +1 -1
- package/build/dex/uniswap-v2/uniswap-v2.js +1 -1
- package/build/dex/uniswap-v2/uniswap-v2.js.map +1 -1
- package/build/dex/uniswap-v3/constants.d.ts +4 -0
- package/build/dex/uniswap-v3/constants.js +6 -1
- package/build/dex/uniswap-v3/constants.js.map +1 -1
- package/build/dex/uniswap-v3/types.d.ts +20 -3
- package/build/dex/uniswap-v3/types.js.map +1 -1
- package/build/dex/uniswap-v3/uniswap-v3.d.ts +7 -1
- package/build/dex/uniswap-v3/uniswap-v3.js +85 -1
- package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
- package/build/dex/woo-fi-v2/woo-fi-math.d.ts +16 -0
- package/build/dex/woo-fi-v2/woo-fi-math.js +137 -0
- package/build/dex/woo-fi-v2/woo-fi-math.js.map +1 -0
- package/build/dex/zerox/index.d.ts +1 -1
- package/build/dex/zerox/index.js +1 -1
- package/build/dex/zerox/index.js.map +1 -1
- package/build/implementations/local-paraswap-sdk.js +5 -1
- package/build/implementations/local-paraswap-sdk.js.map +1 -1
- package/build/router/directswap.js +7 -1
- package/build/router/directswap.js.map +1 -1
- package/build/router/index.js.map +1 -1
- package/build/router/payload-encoder.js +14 -3
- package/build/router/payload-encoder.js.map +1 -1
- package/build/types.d.ts +1 -0
- package/build/utils.js.map +1 -1
- package/package.json +5 -3
- package/src/abi/DirectSwap.json +1018 -0
- package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +79 -0
- package/src/dex/balancer-v2/balancer-v2.ts +153 -4
- package/src/dex/balancer-v2/constants.ts +5 -0
- package/src/dex/balancer-v2/types.ts +21 -1
- package/src/dex/curve-v1/constants.ts +2 -0
- package/src/dex/curve-v1/curve-v1-e2e.test.ts +57 -0
- package/src/dex/curve-v1/curve-v1.ts +144 -5
- package/src/dex/curve-v1/types.ts +26 -0
- package/src/dex/curve-v1-factory/constants.ts +2 -0
- package/src/dex/curve-v1-factory/curve-v1-factory-e2e.test.ts +1 -0
- package/src/dex/curve-v1-factory/curve-v1-factory.ts +140 -4
- package/src/dex/curve-v1-factory/types.ts +26 -0
- package/src/dex/curve-v2.ts +169 -8
- package/src/dex/idex.ts +6 -0
- package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +3 -6
- package/src/dex/pancakeswap-v3/pancakeswap-v3-integration.test.ts +3 -14
- package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +3 -3
- package/src/dex/pancakeswap-v3/utils.ts +1 -4
- package/src/dex/simple-exchange.ts +6 -0
- package/src/dex/solidly/solidly-e2e.test.ts +31 -32
- package/src/dex/swaap-v2/swaap-v2.ts +19 -11
- package/src/dex/swaap-v2/types.ts +4 -4
- package/src/dex/swaap-v2/utils.ts +4 -4
- package/src/dex/swaap-v2/validators.ts +4 -7
- package/src/dex/uniswap-v2/uniswap-v2.ts +6 -0
- package/src/dex/uniswap-v3/constants.ts +5 -0
- package/src/dex/uniswap-v3/types.ts +23 -3
- package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +100 -2
- package/src/dex/uniswap-v3/uniswap-v3.ts +138 -3
- package/src/dex/zerox/index.ts +7 -0
- package/src/implementations/local-paraswap-sdk.ts +8 -1
- package/src/router/directswap.ts +23 -0
- package/src/router/index.ts +0 -2
- package/src/router/payload-encoder.ts +19 -3
- package/src/types.ts +1 -0
- package/src/utils.ts +1 -1
- package/tests/constants-e2e.ts +3 -3
- package/tests/utils-e2e.ts +136 -21
- package/tests/utils.ts +52 -0
- package/.idea/aws.xml +0 -17
- package/.idea/codeStyles/Project.xml +0 -19
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/paraswap-dex-lib.iml +0 -9
- package/.idea/vcs.xml +0 -6
- package/build/dex/pancakeswap-v3/types.d.ts +0 -14
- package/build/dex/solidly/forks-override/chronos.d.ts +0 -20
- package/build/dex/solidly/forks-override/chronos.js +0 -44
- package/build/dex/solidly/forks-override/chronos.js.map +0 -1
- /package/build/dex/{pancakeswap-v3 → test-dex}/types.js +0 -0
|
@@ -905,39 +905,38 @@ describe('Solidly E2E', () => {
|
|
|
905
905
|
],
|
|
906
906
|
]);
|
|
907
907
|
|
|
908
|
-
const pairs: { name: string; sellAmount: string
|
|
908
|
+
const pairs: { name: string; sellAmount: string }[][] = [
|
|
909
909
|
[
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
];
|
|
910
|
+
{
|
|
911
|
+
name: 'BNB',
|
|
912
|
+
sellAmount: '1000000000000000000',
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
name: 'USDT',
|
|
916
|
+
sellAmount: '10000000000000000000',
|
|
917
|
+
},
|
|
918
|
+
],
|
|
919
|
+
[
|
|
920
|
+
{
|
|
921
|
+
name: 'USDT',
|
|
922
|
+
sellAmount: '10000000000000000000',
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
name: 'USDC',
|
|
926
|
+
sellAmount: '10000000000000000000',
|
|
927
|
+
},
|
|
928
|
+
],
|
|
929
|
+
[
|
|
930
|
+
{
|
|
931
|
+
name: 'ETH',
|
|
932
|
+
sellAmount: '5000000000000000000',
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
name: 'BNB',
|
|
936
|
+
sellAmount: '1000000000000000000',
|
|
937
|
+
},
|
|
938
|
+
],
|
|
939
|
+
];
|
|
941
940
|
|
|
942
941
|
sideToContractMethods.forEach((contractMethods, side) =>
|
|
943
942
|
describe(`${side}`, () => {
|
|
@@ -116,10 +116,13 @@ export class SwaapV2 extends SimpleExchange implements IDex<SwaapV2Data> {
|
|
|
116
116
|
getTokensResponseValidator,
|
|
117
117
|
);
|
|
118
118
|
|
|
119
|
-
this.tokensMap = Object.keys(tokensResp.tokens).reduce(
|
|
120
|
-
acc
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
this.tokensMap = Object.keys(tokensResp.tokens).reduce(
|
|
120
|
+
(acc, key: string) => {
|
|
121
|
+
acc[key.toLowerCase()] = tokensResp.tokens[key];
|
|
122
|
+
return acc;
|
|
123
|
+
},
|
|
124
|
+
{} as TokensMap,
|
|
125
|
+
);
|
|
123
126
|
|
|
124
127
|
if (!this.dexHelper.config.isSlave) {
|
|
125
128
|
await this.rateFetcher.start();
|
|
@@ -281,7 +284,7 @@ export class SwaapV2 extends SimpleExchange implements IDex<SwaapV2Data> {
|
|
|
281
284
|
limitPools?: string[],
|
|
282
285
|
): Promise<null | ExchangePrices<SwaapV2Data>> {
|
|
283
286
|
try {
|
|
284
|
-
if(await this.isRestricted()) {
|
|
287
|
+
if (await this.isRestricted()) {
|
|
285
288
|
return null;
|
|
286
289
|
}
|
|
287
290
|
|
|
@@ -332,7 +335,6 @@ export class SwaapV2 extends SimpleExchange implements IDex<SwaapV2Data> {
|
|
|
332
335
|
);
|
|
333
336
|
|
|
334
337
|
const prices = levelEntries.map((askAndBids: SwaapV2PriceLevels) => {
|
|
335
|
-
|
|
336
338
|
const unitPrice = this.computePricesFromLevelsBids(
|
|
337
339
|
[unitVolume],
|
|
338
340
|
askAndBids,
|
|
@@ -361,7 +363,8 @@ export class SwaapV2 extends SimpleExchange implements IDex<SwaapV2Data> {
|
|
|
361
363
|
return prices;
|
|
362
364
|
} catch (e) {
|
|
363
365
|
this.logger.error(
|
|
364
|
-
`Error_getPrices ${srcToken}, ${destToken}, ${side}:`,
|
|
366
|
+
`Error_getPrices ${srcToken}, ${destToken}, ${side}:`,
|
|
367
|
+
e,
|
|
365
368
|
);
|
|
366
369
|
return null;
|
|
367
370
|
}
|
|
@@ -459,7 +462,7 @@ export class SwaapV2 extends SimpleExchange implements IDex<SwaapV2Data> {
|
|
|
459
462
|
const quoteTokenAmount = BigInt(quote.amount);
|
|
460
463
|
const slippageFactor = options.slippageFactor;
|
|
461
464
|
|
|
462
|
-
if(side === SwapSide.SELL) {
|
|
465
|
+
if (side === SwapSide.SELL) {
|
|
463
466
|
if (
|
|
464
467
|
quoteTokenAmount <
|
|
465
468
|
BigInt(
|
|
@@ -798,8 +801,7 @@ export class SwaapV2 extends SimpleExchange implements IDex<SwaapV2Data> {
|
|
|
798
801
|
tokenAddress: Address,
|
|
799
802
|
limit: number,
|
|
800
803
|
): Promise<PoolLiquidity[]> {
|
|
801
|
-
|
|
802
|
-
if(await this.isRestricted()) {
|
|
804
|
+
if (await this.isRestricted()) {
|
|
803
805
|
return [];
|
|
804
806
|
}
|
|
805
807
|
|
|
@@ -821,7 +823,13 @@ export class SwaapV2 extends SimpleExchange implements IDex<SwaapV2Data> {
|
|
|
821
823
|
.map((pair: string) => {
|
|
822
824
|
return {
|
|
823
825
|
exchange: this.dexKey,
|
|
824
|
-
connectorTokens: [
|
|
826
|
+
connectorTokens: [
|
|
827
|
+
this.getTokenFromAddress(
|
|
828
|
+
normalizedTokenAddress === pLevels[pair].base
|
|
829
|
+
? pLevels[pair].quote
|
|
830
|
+
: pLevels[pair].base,
|
|
831
|
+
),
|
|
832
|
+
],
|
|
825
833
|
liquidityUSD: this.computeMaxLiquidity(pLevels[pair], tokenAddress),
|
|
826
834
|
} as PoolLiquidity;
|
|
827
835
|
})
|
|
@@ -42,10 +42,10 @@ export type SwaapV2TokensResponse = {
|
|
|
42
42
|
symbol: string;
|
|
43
43
|
address: string;
|
|
44
44
|
decimals: number;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
47
|
success: boolean;
|
|
48
|
-
}
|
|
48
|
+
};
|
|
49
49
|
|
|
50
50
|
export type SwaapV2QuoteResponse = {
|
|
51
51
|
id: string;
|
|
@@ -84,5 +84,5 @@ export type SwaapV2APIParameters = {
|
|
|
84
84
|
};
|
|
85
85
|
|
|
86
86
|
export type TokensMap = {
|
|
87
|
-
[address: string]: Token
|
|
87
|
+
[address: string]: Token;
|
|
88
88
|
};
|
|
@@ -11,11 +11,11 @@ export const getIdentifierPrefix = (
|
|
|
11
11
|
|
|
12
12
|
export const getPairName = (srcAddress: Address, destAddress: Address) => {
|
|
13
13
|
const sortedAddresses =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
srcAddress < destAddress
|
|
15
|
+
? [srcAddress, destAddress]
|
|
16
|
+
: [destAddress, srcAddress];
|
|
17
17
|
return `${sortedAddresses[0]}_${sortedAddresses[1]}`.toLowerCase();
|
|
18
|
-
}
|
|
18
|
+
};
|
|
19
19
|
|
|
20
20
|
export const getCacheKey = (dexKey: string, cacheType: string) => {
|
|
21
21
|
return `${CACHE_PREFIX}_${dexKey}_${cacheType}`.toLowerCase();
|
|
@@ -3,7 +3,6 @@ import joi, { CustomHelpers, ErrorReport } from 'joi';
|
|
|
3
3
|
import * as ethers from 'ethers';
|
|
4
4
|
import { SwaapV2PriceLevel } from './types';
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
const priceLevelsValidator = joi.array().items(
|
|
8
7
|
joi.object({
|
|
9
8
|
level: joi.number().required(),
|
|
@@ -107,12 +106,10 @@ const mustBeAugustusSwapper = (
|
|
|
107
106
|
});
|
|
108
107
|
};
|
|
109
108
|
|
|
110
|
-
export const getTokensResponseValidator = joi
|
|
111
|
-
.object(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
});
|
|
115
|
-
|
|
109
|
+
export const getTokensResponseValidator = joi.object({
|
|
110
|
+
tokens: joi.object().required(),
|
|
111
|
+
success: joi.boolean().required(),
|
|
112
|
+
});
|
|
116
113
|
|
|
117
114
|
export const getQuoteResponseValidator = joi
|
|
118
115
|
.object({
|
|
@@ -788,9 +788,15 @@ export class UniswapV2
|
|
|
788
788
|
destToken: Address,
|
|
789
789
|
srcAmount: NumberAsString,
|
|
790
790
|
destAmount: NumberAsString,
|
|
791
|
+
expectedAmount: NumberAsString,
|
|
791
792
|
_data: UniswapData,
|
|
792
793
|
side: SwapSide,
|
|
793
794
|
permit: string,
|
|
795
|
+
uuid: string,
|
|
796
|
+
feePercent: NumberAsString,
|
|
797
|
+
deadline: NumberAsString,
|
|
798
|
+
partner: string,
|
|
799
|
+
beneficiary: string,
|
|
794
800
|
contractMethod?: string,
|
|
795
801
|
): TxInfo<UniswapParam> {
|
|
796
802
|
if (!contractMethod) throw new Error(`contractMethod need to be passed`);
|
|
@@ -34,3 +34,8 @@ export const ZERO_ORACLE_OBSERVATION = {
|
|
|
34
34
|
export const OUT_OF_RANGE_ERROR_POSTFIX = `INVALID_TICK_BIT_MAP_RANGES`;
|
|
35
35
|
|
|
36
36
|
export const DEFAULT_POOL_INIT_CODE_HASH = `0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54`;
|
|
37
|
+
|
|
38
|
+
export enum DirectMethods {
|
|
39
|
+
directSell = 'directUniV3Swap',
|
|
40
|
+
directBuy = 'directUniV3Buy',
|
|
41
|
+
}
|
|
@@ -57,6 +57,7 @@ export type UniswapV3Data = {
|
|
|
57
57
|
tokenOut: Address;
|
|
58
58
|
fee: NumberAsString;
|
|
59
59
|
}[];
|
|
60
|
+
isApproved?: boolean;
|
|
60
61
|
};
|
|
61
62
|
|
|
62
63
|
export type DexParams = {
|
|
@@ -72,7 +73,7 @@ export type DexParams = {
|
|
|
72
73
|
initHash: string;
|
|
73
74
|
};
|
|
74
75
|
|
|
75
|
-
export type
|
|
76
|
+
export type UniswapV3SimpleSwapSellParam = {
|
|
76
77
|
path: string;
|
|
77
78
|
recipient: Address;
|
|
78
79
|
deadline: string;
|
|
@@ -80,7 +81,7 @@ export type UniswapV3SellParam = {
|
|
|
80
81
|
amountOutMinimum: NumberAsString;
|
|
81
82
|
};
|
|
82
83
|
|
|
83
|
-
export type
|
|
84
|
+
export type UniswapV3SimpleSwapBuyParam = {
|
|
84
85
|
path: string;
|
|
85
86
|
recipient: Address;
|
|
86
87
|
deadline: string;
|
|
@@ -88,7 +89,26 @@ export type UniswapV3BuyParam = {
|
|
|
88
89
|
amountInMaximum: NumberAsString;
|
|
89
90
|
};
|
|
90
91
|
|
|
91
|
-
export type
|
|
92
|
+
export type UniswapV3SimpleSwapParams =
|
|
93
|
+
| UniswapV3SimpleSwapSellParam
|
|
94
|
+
| UniswapV3SimpleSwapBuyParam;
|
|
95
|
+
|
|
96
|
+
export type UniswapV3Param = [
|
|
97
|
+
fromToken: Address,
|
|
98
|
+
toToken: Address,
|
|
99
|
+
exchange: Address,
|
|
100
|
+
fromAmount: NumberAsString,
|
|
101
|
+
toAmount: NumberAsString,
|
|
102
|
+
expectedAmount: NumberAsString,
|
|
103
|
+
feePercent: NumberAsString,
|
|
104
|
+
deadline: NumberAsString,
|
|
105
|
+
partner: Address,
|
|
106
|
+
isApproved: boolean,
|
|
107
|
+
beneficiary: Address,
|
|
108
|
+
path: string,
|
|
109
|
+
permit: string,
|
|
110
|
+
uuid: string,
|
|
111
|
+
];
|
|
92
112
|
|
|
93
113
|
export enum UniswapV3Functions {
|
|
94
114
|
exactInput = 'exactInput',
|
|
@@ -49,6 +49,20 @@ describe('UniswapV3 E2E', () => {
|
|
|
49
49
|
provider,
|
|
50
50
|
);
|
|
51
51
|
});
|
|
52
|
+
|
|
53
|
+
it('directSwap SELL WETH -> USDC', async () => {
|
|
54
|
+
await testE2E(
|
|
55
|
+
tokens['WETH'],
|
|
56
|
+
tokens['USDC'],
|
|
57
|
+
holders['WETH'],
|
|
58
|
+
'1000000000000000000',
|
|
59
|
+
SwapSide.SELL,
|
|
60
|
+
dexKey,
|
|
61
|
+
ContractMethod.directUniV3Swap,
|
|
62
|
+
network,
|
|
63
|
+
provider,
|
|
64
|
+
);
|
|
65
|
+
});
|
|
52
66
|
});
|
|
53
67
|
|
|
54
68
|
describe('UniswapV3 POLYGON', () => {
|
|
@@ -64,7 +78,7 @@ describe('UniswapV3 E2E', () => {
|
|
|
64
78
|
const tokenBSymbol: string = 'WETH';
|
|
65
79
|
const nativeTokenSymbol = NativeTokenSymbols[network];
|
|
66
80
|
|
|
67
|
-
const tokenAAmount: string = '
|
|
81
|
+
const tokenAAmount: string = '11000000';
|
|
68
82
|
const tokenBAmount: string = '11000000000000000000';
|
|
69
83
|
const nativeTokenAmount = '11000000000000000000';
|
|
70
84
|
|
|
@@ -75,9 +89,17 @@ describe('UniswapV3 E2E', () => {
|
|
|
75
89
|
ContractMethod.simpleSwap,
|
|
76
90
|
ContractMethod.multiSwap,
|
|
77
91
|
ContractMethod.megaSwap,
|
|
92
|
+
ContractMethod.directUniV3Swap,
|
|
93
|
+
],
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
SwapSide.BUY,
|
|
97
|
+
[
|
|
98
|
+
ContractMethod.simpleBuy,
|
|
99
|
+
ContractMethod.buy,
|
|
100
|
+
ContractMethod.directUniV3Buy,
|
|
78
101
|
],
|
|
79
102
|
],
|
|
80
|
-
[SwapSide.BUY, [ContractMethod.simpleBuy, ContractMethod.buy]],
|
|
81
103
|
]);
|
|
82
104
|
|
|
83
105
|
sideToContractMethods.forEach((contractMethods, side) =>
|
|
@@ -202,4 +224,80 @@ describe('UniswapV3 E2E', () => {
|
|
|
202
224
|
}),
|
|
203
225
|
);
|
|
204
226
|
});
|
|
227
|
+
|
|
228
|
+
describe('UniswapV3 Optimism', () => {
|
|
229
|
+
const network = Network.OPTIMISM;
|
|
230
|
+
const tokens = Tokens[network];
|
|
231
|
+
const holders = Holders[network];
|
|
232
|
+
const provider = new StaticJsonRpcProvider(
|
|
233
|
+
generateConfig(network).privateHttpProvider,
|
|
234
|
+
network,
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
const tokenASymbol: string = 'OP';
|
|
238
|
+
const tokenBSymbol: string = 'ETH';
|
|
239
|
+
const nativeTokenSymbol = NativeTokenSymbols[network];
|
|
240
|
+
|
|
241
|
+
const tokenAAmount: string = '1000000000000000000';
|
|
242
|
+
const tokenBAmount: string = '1000000000000000000';
|
|
243
|
+
const nativeTokenAmount = '1000000000000000000';
|
|
244
|
+
|
|
245
|
+
const sideToContractMethods = new Map([
|
|
246
|
+
[
|
|
247
|
+
SwapSide.SELL,
|
|
248
|
+
[
|
|
249
|
+
ContractMethod.simpleSwap,
|
|
250
|
+
ContractMethod.multiSwap,
|
|
251
|
+
ContractMethod.megaSwap,
|
|
252
|
+
],
|
|
253
|
+
],
|
|
254
|
+
[SwapSide.BUY, [ContractMethod.simpleBuy, ContractMethod.buy]],
|
|
255
|
+
]);
|
|
256
|
+
|
|
257
|
+
sideToContractMethods.forEach((contractMethods, side) =>
|
|
258
|
+
contractMethods.forEach((contractMethod: ContractMethod) => {
|
|
259
|
+
describe(`${contractMethod}`, () => {
|
|
260
|
+
it(`${network} ${side} ${contractMethod} ${nativeTokenSymbol} -> ${tokenASymbol}`, async () => {
|
|
261
|
+
await testE2E(
|
|
262
|
+
tokens[nativeTokenSymbol],
|
|
263
|
+
tokens[tokenASymbol],
|
|
264
|
+
holders[nativeTokenSymbol],
|
|
265
|
+
side === SwapSide.SELL ? nativeTokenAmount : tokenAAmount,
|
|
266
|
+
side,
|
|
267
|
+
dexKey,
|
|
268
|
+
contractMethod,
|
|
269
|
+
network,
|
|
270
|
+
provider,
|
|
271
|
+
);
|
|
272
|
+
});
|
|
273
|
+
it(`${network} ${side} ${contractMethod} ${tokenASymbol} -> ${nativeTokenSymbol}`, async () => {
|
|
274
|
+
await testE2E(
|
|
275
|
+
tokens[tokenASymbol],
|
|
276
|
+
tokens[nativeTokenSymbol],
|
|
277
|
+
holders[tokenASymbol],
|
|
278
|
+
side === SwapSide.SELL ? tokenAAmount : nativeTokenAmount,
|
|
279
|
+
side,
|
|
280
|
+
dexKey,
|
|
281
|
+
contractMethod,
|
|
282
|
+
network,
|
|
283
|
+
provider,
|
|
284
|
+
);
|
|
285
|
+
});
|
|
286
|
+
it(`${network} ${side} ${contractMethod} ${tokenASymbol} -> ${tokenBSymbol}`, async () => {
|
|
287
|
+
await testE2E(
|
|
288
|
+
tokens[tokenASymbol],
|
|
289
|
+
tokens[tokenBSymbol],
|
|
290
|
+
holders[tokenASymbol],
|
|
291
|
+
side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
|
|
292
|
+
side,
|
|
293
|
+
dexKey,
|
|
294
|
+
contractMethod,
|
|
295
|
+
network,
|
|
296
|
+
provider,
|
|
297
|
+
);
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
}),
|
|
301
|
+
);
|
|
302
|
+
});
|
|
205
303
|
});
|
|
@@ -11,6 +11,9 @@ import {
|
|
|
11
11
|
Logger,
|
|
12
12
|
NumberAsString,
|
|
13
13
|
PoolPrices,
|
|
14
|
+
TxInfo,
|
|
15
|
+
PreprocessTransactionOptions,
|
|
16
|
+
ExchangeTxInfo,
|
|
14
17
|
} from '../../types';
|
|
15
18
|
import { SwapSide, Network, CACHE_PREFIX } from '../../constants';
|
|
16
19
|
import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
|
|
@@ -19,6 +22,7 @@ import {
|
|
|
19
22
|
getDexKeysWithNetwork,
|
|
20
23
|
interpolate,
|
|
21
24
|
isTruthy,
|
|
25
|
+
uuidToBytes16,
|
|
22
26
|
} from '../../utils';
|
|
23
27
|
import { IDex } from '../../dex/idex';
|
|
24
28
|
import { IDexHelper } from '../../dex-helper/idex-helper';
|
|
@@ -29,6 +33,7 @@ import {
|
|
|
29
33
|
UniswapV3Data,
|
|
30
34
|
UniswapV3Functions,
|
|
31
35
|
UniswapV3Param,
|
|
36
|
+
UniswapV3SimpleSwapParams,
|
|
32
37
|
} from './types';
|
|
33
38
|
import {
|
|
34
39
|
getLocalDeadlineAsFriendlyPlaceholder,
|
|
@@ -39,14 +44,16 @@ import { UniswapV3EventPool } from './uniswap-v3-pool';
|
|
|
39
44
|
import UniswapV3RouterABI from '../../abi/uniswap-v3/UniswapV3Router.abi.json';
|
|
40
45
|
import UniswapV3QuoterABI from '../../abi/uniswap-v3/UniswapV3Quoter.abi.json';
|
|
41
46
|
import UniswapV3MultiABI from '../../abi/uniswap-v3/UniswapMulti.abi.json';
|
|
47
|
+
import DirectSwapABI from '../../abi/DirectSwap.json';
|
|
42
48
|
import UniswapV3StateMulticallABI from '../../abi/uniswap-v3/UniswapV3StateMulticall.abi.json';
|
|
43
49
|
import {
|
|
50
|
+
DirectMethods,
|
|
44
51
|
UNISWAPV3_EFFICIENCY_FACTOR,
|
|
45
52
|
UNISWAPV3_POOL_SEARCH_OVERHEAD,
|
|
46
53
|
UNISWAPV3_TICK_BASE_OVERHEAD,
|
|
47
54
|
UNISWAPV3_TICK_GAS_COST,
|
|
48
55
|
} from './constants';
|
|
49
|
-
import { DeepReadonly } from 'ts-essentials';
|
|
56
|
+
import { assert, DeepReadonly } from 'ts-essentials';
|
|
50
57
|
import { uniswapV3Math } from './contract-math/uniswap-v3-math';
|
|
51
58
|
import { Contract } from 'web3-eth-contract';
|
|
52
59
|
import { AbiItem } from 'web3-utils';
|
|
@@ -56,6 +63,7 @@ import {
|
|
|
56
63
|
DEFAULT_ID_ERC20,
|
|
57
64
|
DEFAULT_ID_ERC20_AS_STRING,
|
|
58
65
|
} from '../../lib/tokens/types';
|
|
66
|
+
import { OptimalSwapExchange } from '@paraswap/core';
|
|
59
67
|
|
|
60
68
|
type PoolPairsInfo = {
|
|
61
69
|
token0: Address;
|
|
@@ -77,6 +85,8 @@ export class UniswapV3
|
|
|
77
85
|
readonly hasConstantPriceLargeAmounts = false;
|
|
78
86
|
readonly needWrapNative = true;
|
|
79
87
|
|
|
88
|
+
readonly directSwapIface = new Interface(DirectSwapABI);
|
|
89
|
+
|
|
80
90
|
intervalTask?: NodeJS.Timeout;
|
|
81
91
|
|
|
82
92
|
public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
|
|
@@ -113,7 +123,7 @@ export class UniswapV3
|
|
|
113
123
|
// To receive revert reasons
|
|
114
124
|
this.dexHelper.web3Provider.eth.handleRevert = false;
|
|
115
125
|
|
|
116
|
-
//
|
|
126
|
+
// Normalize once all config addresses and use across all scenarios
|
|
117
127
|
this.config = this._toLowerForAllConfigAddresses();
|
|
118
128
|
|
|
119
129
|
this.notExistingPoolSetKey =
|
|
@@ -449,6 +459,7 @@ export class UniswapV3
|
|
|
449
459
|
fee: pool.feeCodeAsString,
|
|
450
460
|
},
|
|
451
461
|
],
|
|
462
|
+
exchange: pool.poolAddress,
|
|
452
463
|
},
|
|
453
464
|
poolIdentifier: this.getPoolIdentifier(
|
|
454
465
|
pool.token0,
|
|
@@ -731,6 +742,130 @@ export class UniswapV3
|
|
|
731
742
|
return arr;
|
|
732
743
|
}
|
|
733
744
|
|
|
745
|
+
getTokenFromAddress(address: Address): Token {
|
|
746
|
+
// In this Dex decimals are not used
|
|
747
|
+
return { address, decimals: 0 };
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
async preProcessTransaction(
|
|
751
|
+
optimalSwapExchange: OptimalSwapExchange<UniswapV3Data>,
|
|
752
|
+
srcToken: Token,
|
|
753
|
+
_0: Token,
|
|
754
|
+
_1: SwapSide,
|
|
755
|
+
options: PreprocessTransactionOptions,
|
|
756
|
+
): Promise<[OptimalSwapExchange<UniswapV3Data>, ExchangeTxInfo]> {
|
|
757
|
+
if (!options.isDirectMethod) {
|
|
758
|
+
return [
|
|
759
|
+
optimalSwapExchange,
|
|
760
|
+
{
|
|
761
|
+
deadline: BigInt(getLocalDeadlineAsFriendlyPlaceholder()),
|
|
762
|
+
},
|
|
763
|
+
];
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
assert(
|
|
767
|
+
optimalSwapExchange.data !== undefined,
|
|
768
|
+
`preProcessTransaction: data field is missing`,
|
|
769
|
+
);
|
|
770
|
+
|
|
771
|
+
let isApproved: boolean | undefined;
|
|
772
|
+
|
|
773
|
+
try {
|
|
774
|
+
this.erc20Contract.options.address =
|
|
775
|
+
this.dexHelper.config.wrapETH(srcToken).address;
|
|
776
|
+
const allowance = await this.erc20Contract.methods
|
|
777
|
+
.allowance(this.augustusAddress, this.config.router)
|
|
778
|
+
.call(undefined, 'latest');
|
|
779
|
+
isApproved =
|
|
780
|
+
BigInt(allowance.toString()) >= BigInt(optimalSwapExchange.srcAmount);
|
|
781
|
+
} catch (e) {
|
|
782
|
+
this.logger.error(
|
|
783
|
+
`preProcessTransaction failed to retrieve allowance info: `,
|
|
784
|
+
e,
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
return [
|
|
789
|
+
{
|
|
790
|
+
...optimalSwapExchange,
|
|
791
|
+
data: {
|
|
792
|
+
...optimalSwapExchange.data,
|
|
793
|
+
isApproved,
|
|
794
|
+
},
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
deadline: BigInt(getLocalDeadlineAsFriendlyPlaceholder()),
|
|
798
|
+
},
|
|
799
|
+
];
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
getDirectParam(
|
|
803
|
+
srcToken: Address,
|
|
804
|
+
destToken: Address,
|
|
805
|
+
srcAmount: NumberAsString,
|
|
806
|
+
destAmount: NumberAsString,
|
|
807
|
+
expectedAmount: NumberAsString,
|
|
808
|
+
data: UniswapV3Data,
|
|
809
|
+
side: SwapSide,
|
|
810
|
+
permit: string,
|
|
811
|
+
uuid: string,
|
|
812
|
+
feePercent: NumberAsString,
|
|
813
|
+
deadline: NumberAsString,
|
|
814
|
+
partner: string,
|
|
815
|
+
beneficiary: string,
|
|
816
|
+
contractMethod?: string,
|
|
817
|
+
): TxInfo<UniswapV3Param> {
|
|
818
|
+
if (
|
|
819
|
+
contractMethod !== DirectMethods.directSell &&
|
|
820
|
+
contractMethod !== DirectMethods.directBuy
|
|
821
|
+
) {
|
|
822
|
+
throw new Error(`Invalid contract method ${contractMethod}`);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
let isApproved: boolean = !!data.isApproved;
|
|
826
|
+
if (data.isApproved === undefined) {
|
|
827
|
+
this.logger.warn(`isApproved is undefined, defaulting to false`);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
const path = this._encodePath(data.path, side);
|
|
831
|
+
|
|
832
|
+
const swapParams: UniswapV3Param = [
|
|
833
|
+
srcToken,
|
|
834
|
+
destToken,
|
|
835
|
+
this.config.router,
|
|
836
|
+
srcAmount,
|
|
837
|
+
destAmount,
|
|
838
|
+
expectedAmount,
|
|
839
|
+
feePercent,
|
|
840
|
+
deadline,
|
|
841
|
+
partner,
|
|
842
|
+
isApproved,
|
|
843
|
+
beneficiary,
|
|
844
|
+
path,
|
|
845
|
+
permit,
|
|
846
|
+
uuidToBytes16(uuid),
|
|
847
|
+
];
|
|
848
|
+
|
|
849
|
+
const encoder = (...params: UniswapV3Param) => {
|
|
850
|
+
return this.directSwapIface.encodeFunctionData(
|
|
851
|
+
side === SwapSide.SELL
|
|
852
|
+
? DirectMethods.directSell
|
|
853
|
+
: DirectMethods.directBuy,
|
|
854
|
+
[params],
|
|
855
|
+
);
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
return {
|
|
859
|
+
params: swapParams,
|
|
860
|
+
encoder,
|
|
861
|
+
networkFee: '0',
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
static getDirectFunctionName(): string[] {
|
|
866
|
+
return [DirectMethods.directSell, DirectMethods.directBuy];
|
|
867
|
+
}
|
|
868
|
+
|
|
734
869
|
async getSimpleParam(
|
|
735
870
|
srcToken: string,
|
|
736
871
|
destToken: string,
|
|
@@ -745,7 +880,7 @@ export class UniswapV3
|
|
|
745
880
|
: UniswapV3Functions.exactOutput;
|
|
746
881
|
|
|
747
882
|
const path = this._encodePath(data.path, side);
|
|
748
|
-
const swapFunctionParams:
|
|
883
|
+
const swapFunctionParams: UniswapV3SimpleSwapParams =
|
|
749
884
|
side === SwapSide.SELL
|
|
750
885
|
? {
|
|
751
886
|
recipient: this.augustusAddress,
|
package/src/dex/zerox/index.ts
CHANGED
|
@@ -269,9 +269,16 @@ export class ZeroX
|
|
|
269
269
|
destToken: Address,
|
|
270
270
|
srcAmount: NumberAsString,
|
|
271
271
|
destAmount: NumberAsString,
|
|
272
|
+
expectedAmount: NumberAsString,
|
|
272
273
|
data: ZeroXData,
|
|
273
274
|
side: SwapSide,
|
|
274
275
|
permit: string,
|
|
276
|
+
uuid: string,
|
|
277
|
+
feePercent: NumberAsString,
|
|
278
|
+
deadline: NumberAsString,
|
|
279
|
+
partner: string,
|
|
280
|
+
beneficiary: string,
|
|
281
|
+
contractMethod?: string,
|
|
275
282
|
): TxInfo<ZeroXParam> {
|
|
276
283
|
const usePermit = permit !== '0x';
|
|
277
284
|
const encoder = (...params: ZeroXParam) => {
|
|
@@ -17,6 +17,8 @@ import {
|
|
|
17
17
|
} from '../types';
|
|
18
18
|
import { SwapSide, NULL_ADDRESS, ContractMethod } from '../constants';
|
|
19
19
|
import { LimitOrderExchange } from '../dex/limit-order-exchange';
|
|
20
|
+
import { v4 as uuid } from 'uuid';
|
|
21
|
+
import { DirectContractMethods } from '@paraswap/core/build/constants';
|
|
20
22
|
|
|
21
23
|
export interface IParaSwapSDK {
|
|
22
24
|
getPrices(
|
|
@@ -205,6 +207,8 @@ export class LocalParaswapSDK implements IParaSwapSDK {
|
|
|
205
207
|
: priceRoute.srcAmount,
|
|
206
208
|
);
|
|
207
209
|
|
|
210
|
+
const contractMethod = priceRoute.contractMethod;
|
|
211
|
+
|
|
208
212
|
// Call preprocessTransaction for each exchange before we build transaction
|
|
209
213
|
try {
|
|
210
214
|
priceRoute.bestRoute = await Promise.all(
|
|
@@ -234,6 +238,9 @@ export class LocalParaswapSDK implements IParaSwapSDK {
|
|
|
234
238
|
{
|
|
235
239
|
slippageFactor,
|
|
236
240
|
txOrigin: userAddress,
|
|
241
|
+
isDirectMethod: DirectContractMethods.includes(
|
|
242
|
+
contractMethod as ContractMethod,
|
|
243
|
+
),
|
|
237
244
|
},
|
|
238
245
|
);
|
|
239
246
|
|
|
@@ -264,7 +271,7 @@ export class LocalParaswapSDK implements IParaSwapSDK {
|
|
|
264
271
|
partnerAddress: NULL_ADDRESS,
|
|
265
272
|
partnerFeePercent: '0',
|
|
266
273
|
deadline: deadline.toString(),
|
|
267
|
-
uuid:
|
|
274
|
+
uuid: uuid(),
|
|
268
275
|
});
|
|
269
276
|
}
|
|
270
277
|
}
|