@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
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import {
|
|
2
|
+
import { AbiItem } from 'web3-utils';
|
|
3
|
+
import { NumberAsString, OptimalSwapExchange } from '@paraswap/core';
|
|
4
|
+
import { assert, AsyncOrSync } from 'ts-essentials';
|
|
3
5
|
import { Interface, JsonFragment } from '@ethersproject/abi';
|
|
4
6
|
import {
|
|
5
7
|
Token,
|
|
@@ -11,6 +13,9 @@ import {
|
|
|
11
13
|
PoolLiquidity,
|
|
12
14
|
Logger,
|
|
13
15
|
TransferFeeParams,
|
|
16
|
+
TxInfo,
|
|
17
|
+
PreprocessTransactionOptions,
|
|
18
|
+
ExchangeTxInfo,
|
|
14
19
|
} from '../../types';
|
|
15
20
|
import {
|
|
16
21
|
SwapSide,
|
|
@@ -23,6 +28,7 @@ import {
|
|
|
23
28
|
getBigIntPow,
|
|
24
29
|
getDexKeysWithNetwork,
|
|
25
30
|
isSrcTokenTransferFeeToBeExchanged,
|
|
31
|
+
uuidToBytes16,
|
|
26
32
|
} from '../../utils';
|
|
27
33
|
import { IDex } from '../idex';
|
|
28
34
|
import { IDexHelper } from '../../dex-helper/idex-helper';
|
|
@@ -30,13 +36,19 @@ import {
|
|
|
30
36
|
CurveSwapFunctions,
|
|
31
37
|
CurveV1FactoryData,
|
|
32
38
|
CurveV1FactoryIfaces,
|
|
39
|
+
CurveV1SwapType,
|
|
33
40
|
CustomImplementationNames,
|
|
34
41
|
ImplementationNames,
|
|
35
42
|
PoolConstants,
|
|
43
|
+
DirectCurveV1Param,
|
|
36
44
|
} from './types';
|
|
37
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
getLocalDeadlineAsFriendlyPlaceholder,
|
|
47
|
+
SimpleExchange,
|
|
48
|
+
} from '../simple-exchange';
|
|
38
49
|
import { CurveV1FactoryConfig, Adapters } from './config';
|
|
39
50
|
import {
|
|
51
|
+
DIRECT_METHOD_NAME,
|
|
40
52
|
FACTORY_MAX_PLAIN_COINS,
|
|
41
53
|
FACTORY_MAX_PLAIN_IMPLEMENTATIONS_FOR_COIN,
|
|
42
54
|
MIN_AMOUNT_TO_RECEIVE,
|
|
@@ -44,6 +56,7 @@ import {
|
|
|
44
56
|
} from './constants';
|
|
45
57
|
import { CurveV1FactoryPoolManager } from './curve-v1-pool-manager';
|
|
46
58
|
import CurveABI from '../../abi/Curve.json';
|
|
59
|
+
import DirectSwapABI from '../../abi/DirectSwap.json';
|
|
47
60
|
import FactoryCurveV1ABI from '../../abi/curve-v1-factory/FactoryCurveV1.json';
|
|
48
61
|
import ThreePoolABI from '../../abi/curve-v1-factory/ThreePool.json';
|
|
49
62
|
import ERC20ABI from '../../abi/erc20.json';
|
|
@@ -61,7 +74,6 @@ import { CustomBasePoolForFactory } from './state-polling-pools/custom-pool-poll
|
|
|
61
74
|
import ImplementationConstants from './price-handlers/functions/constants';
|
|
62
75
|
import { applyTransferFee } from '../../lib/token-transfer-fee';
|
|
63
76
|
import { PriceHandler } from './price-handlers/price-handler';
|
|
64
|
-
import { AbiItem } from 'web3-utils';
|
|
65
77
|
|
|
66
78
|
const DefaultCoinsABI: AbiItem = {
|
|
67
79
|
type: 'function',
|
|
@@ -82,7 +94,7 @@ const DefaultCoinsABI: AbiItem = {
|
|
|
82
94
|
|
|
83
95
|
export class CurveV1Factory
|
|
84
96
|
extends SimpleExchange
|
|
85
|
-
implements IDex<CurveV1FactoryData>
|
|
97
|
+
implements IDex<CurveV1FactoryData, DirectCurveV1Param>
|
|
86
98
|
{
|
|
87
99
|
readonly hasConstantPriceLargeAmounts = false;
|
|
88
100
|
readonly needWrapNative = false;
|
|
@@ -98,6 +110,8 @@ export class CurveV1Factory
|
|
|
98
110
|
readonly SRC_TOKEN_DEX_TRANSFERS = 1;
|
|
99
111
|
readonly DEST_TOKEN_DEX_TRANSFERS = 1;
|
|
100
112
|
|
|
113
|
+
readonly directSwapIface = new Interface(DirectSwapABI);
|
|
114
|
+
|
|
101
115
|
public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
|
|
102
116
|
getDexKeysWithNetwork(CurveV1FactoryConfig);
|
|
103
117
|
|
|
@@ -814,6 +828,128 @@ export class CurveV1Factory
|
|
|
814
828
|
};
|
|
815
829
|
}
|
|
816
830
|
|
|
831
|
+
getTokenFromAddress(address: Address): Token {
|
|
832
|
+
// In this Dex decimals are not used
|
|
833
|
+
return { address, decimals: 0 };
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
async preProcessTransaction(
|
|
837
|
+
optimalSwapExchange: OptimalSwapExchange<CurveV1FactoryData>,
|
|
838
|
+
srcToken: Token,
|
|
839
|
+
_0: Token,
|
|
840
|
+
_1: SwapSide,
|
|
841
|
+
options: PreprocessTransactionOptions,
|
|
842
|
+
): Promise<[OptimalSwapExchange<CurveV1FactoryData>, ExchangeTxInfo]> {
|
|
843
|
+
if (!options.isDirectMethod) {
|
|
844
|
+
return [
|
|
845
|
+
optimalSwapExchange,
|
|
846
|
+
{
|
|
847
|
+
deadline: BigInt(getLocalDeadlineAsFriendlyPlaceholder()),
|
|
848
|
+
},
|
|
849
|
+
];
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
assert(
|
|
853
|
+
optimalSwapExchange.data !== undefined,
|
|
854
|
+
`preProcessTransaction: data field is missing`,
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
let isApproved: boolean | undefined;
|
|
858
|
+
|
|
859
|
+
try {
|
|
860
|
+
this.erc20Contract.options.address =
|
|
861
|
+
this.dexHelper.config.wrapETH(srcToken).address;
|
|
862
|
+
const allowance = await this.erc20Contract.methods
|
|
863
|
+
.allowance(this.augustusAddress, optimalSwapExchange.data.exchange)
|
|
864
|
+
.call(undefined, 'latest');
|
|
865
|
+
isApproved =
|
|
866
|
+
BigInt(allowance.toString()) >= BigInt(optimalSwapExchange.srcAmount);
|
|
867
|
+
} catch (e) {
|
|
868
|
+
this.logger.error(
|
|
869
|
+
`preProcessTransaction failed to retrieve allowance info: `,
|
|
870
|
+
e,
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
return [
|
|
875
|
+
{
|
|
876
|
+
...optimalSwapExchange,
|
|
877
|
+
data: {
|
|
878
|
+
...optimalSwapExchange.data,
|
|
879
|
+
isApproved,
|
|
880
|
+
},
|
|
881
|
+
},
|
|
882
|
+
{
|
|
883
|
+
deadline: BigInt(getLocalDeadlineAsFriendlyPlaceholder()),
|
|
884
|
+
},
|
|
885
|
+
];
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
getDirectParam(
|
|
889
|
+
srcToken: Address,
|
|
890
|
+
destToken: Address,
|
|
891
|
+
srcAmount: NumberAsString,
|
|
892
|
+
destAmount: NumberAsString,
|
|
893
|
+
expectedAmount: NumberAsString,
|
|
894
|
+
data: CurveV1FactoryData,
|
|
895
|
+
side: SwapSide,
|
|
896
|
+
permit: string,
|
|
897
|
+
uuid: string,
|
|
898
|
+
feePercent: NumberAsString,
|
|
899
|
+
deadline: NumberAsString,
|
|
900
|
+
partner: string,
|
|
901
|
+
beneficiary: string,
|
|
902
|
+
contractMethod?: string,
|
|
903
|
+
): TxInfo<DirectCurveV1Param> {
|
|
904
|
+
if (contractMethod !== DIRECT_METHOD_NAME) {
|
|
905
|
+
throw new Error(`Invalid contract method ${contractMethod}`);
|
|
906
|
+
}
|
|
907
|
+
assert(side === SwapSide.SELL, 'Buy not supported');
|
|
908
|
+
|
|
909
|
+
let isApproved: boolean = !!data.isApproved;
|
|
910
|
+
if (data.isApproved === undefined) {
|
|
911
|
+
this.logger.warn(`isApproved is undefined, defaulting to false`);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
const swapParams: DirectCurveV1Param = [
|
|
915
|
+
srcToken,
|
|
916
|
+
destToken,
|
|
917
|
+
data.exchange,
|
|
918
|
+
srcAmount,
|
|
919
|
+
destAmount,
|
|
920
|
+
expectedAmount,
|
|
921
|
+
feePercent,
|
|
922
|
+
data.i.toString(),
|
|
923
|
+
data.j.toString(),
|
|
924
|
+
partner,
|
|
925
|
+
isApproved,
|
|
926
|
+
data.underlyingSwap
|
|
927
|
+
? CurveV1SwapType.EXCHANGE_UNDERLYING
|
|
928
|
+
: CurveV1SwapType.EXCHANGE,
|
|
929
|
+
beneficiary,
|
|
930
|
+
// For CurveV1 we work as it is, without wrapping and unwrapping
|
|
931
|
+
false,
|
|
932
|
+
permit,
|
|
933
|
+
uuidToBytes16(uuid),
|
|
934
|
+
];
|
|
935
|
+
|
|
936
|
+
const encoder = (...params: DirectCurveV1Param) => {
|
|
937
|
+
return this.directSwapIface.encodeFunctionData(DIRECT_METHOD_NAME, [
|
|
938
|
+
params,
|
|
939
|
+
]);
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
return {
|
|
943
|
+
params: swapParams,
|
|
944
|
+
encoder,
|
|
945
|
+
networkFee: '0',
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
static getDirectFunctionName(): string[] {
|
|
950
|
+
return [DIRECT_METHOD_NAME];
|
|
951
|
+
}
|
|
952
|
+
|
|
817
953
|
async getSimpleParam(
|
|
818
954
|
srcToken: string,
|
|
819
955
|
destToken: string,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Interface } from '@ethersproject/abi';
|
|
2
|
+
import { NumberAsString } from '@paraswap/core';
|
|
2
3
|
import { Address } from '../../types';
|
|
3
4
|
|
|
4
5
|
// The difference between PoolContextConstants and PoolConstants lies in the fact
|
|
@@ -69,6 +70,7 @@ export type CurveV1FactoryData = {
|
|
|
69
70
|
i: number;
|
|
70
71
|
j: number;
|
|
71
72
|
underlyingSwap: boolean;
|
|
73
|
+
isApproved?: boolean;
|
|
72
74
|
};
|
|
73
75
|
|
|
74
76
|
export enum FactoryImplementationNames {
|
|
@@ -181,3 +183,27 @@ export type CurveV1FactoryIfaces = {
|
|
|
181
183
|
};
|
|
182
184
|
|
|
183
185
|
export type LiquidityInCache = Record<string, number>;
|
|
186
|
+
|
|
187
|
+
export enum CurveV1SwapType {
|
|
188
|
+
EXCHANGE,
|
|
189
|
+
EXCHANGE_UNDERLYING,
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export type DirectCurveV1Param = [
|
|
193
|
+
fromToken: Address,
|
|
194
|
+
toToken: Address,
|
|
195
|
+
exchange: Address,
|
|
196
|
+
fromAmount: NumberAsString,
|
|
197
|
+
toAmount: NumberAsString,
|
|
198
|
+
expectedAmount: NumberAsString,
|
|
199
|
+
feePercent: NumberAsString,
|
|
200
|
+
i: NumberAsString,
|
|
201
|
+
j: NumberAsString,
|
|
202
|
+
partner: Address,
|
|
203
|
+
isApproved: boolean,
|
|
204
|
+
swapType: CurveV1SwapType,
|
|
205
|
+
beneficiary: Address,
|
|
206
|
+
needWrapNative: boolean,
|
|
207
|
+
permit: string,
|
|
208
|
+
uuid: string,
|
|
209
|
+
];
|
package/src/dex/curve-v2.ts
CHANGED
|
@@ -3,15 +3,26 @@ import { SwapSide } from '../constants';
|
|
|
3
3
|
import {
|
|
4
4
|
AdapterExchangeParam,
|
|
5
5
|
Address,
|
|
6
|
+
ExchangeTxInfo,
|
|
6
7
|
NumberAsString,
|
|
8
|
+
PreprocessTransactionOptions,
|
|
7
9
|
SimpleExchangeParam,
|
|
10
|
+
Token,
|
|
11
|
+
TxInfo,
|
|
8
12
|
} from '../types';
|
|
9
13
|
import { IDexTxBuilder } from './idex';
|
|
10
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
getLocalDeadlineAsFriendlyPlaceholder,
|
|
16
|
+
SimpleExchange,
|
|
17
|
+
} from './simple-exchange';
|
|
11
18
|
import GenericFactoryZapABI from '../abi/curve-v2/GenericFactoryZap.json';
|
|
19
|
+
import DirectSwapABI from '../abi/DirectSwap.json';
|
|
12
20
|
import CurveV2ABI from '../abi/CurveV2.json';
|
|
13
|
-
import Web3 from 'web3';
|
|
14
21
|
import { IDexHelper } from '../dex-helper';
|
|
22
|
+
import { assert } from 'ts-essentials';
|
|
23
|
+
import { Logger } from 'log4js';
|
|
24
|
+
import { OptimalSwapExchange } from '@paraswap/core';
|
|
25
|
+
import { uuidToBytes16 } from '../utils';
|
|
15
26
|
|
|
16
27
|
export enum CurveV2SwapType {
|
|
17
28
|
EXCHANGE,
|
|
@@ -19,12 +30,15 @@ export enum CurveV2SwapType {
|
|
|
19
30
|
EXCHANGE_GENERIC_FACTORY_ZAP,
|
|
20
31
|
}
|
|
21
32
|
|
|
33
|
+
const DIRECT_METHOD_NAME = 'directCurveV2Swap';
|
|
34
|
+
|
|
22
35
|
type CurveV2Data = {
|
|
23
36
|
i: number;
|
|
24
37
|
j: number;
|
|
25
38
|
exchange: string;
|
|
26
39
|
originalPoolAddress: Address;
|
|
27
40
|
swapType: CurveV2SwapType;
|
|
41
|
+
isApproved?: boolean;
|
|
28
42
|
};
|
|
29
43
|
|
|
30
44
|
type CurveV2Param = [
|
|
@@ -43,6 +57,26 @@ type CurveV2ParamsForGenericFactoryZap = [
|
|
|
43
57
|
min_dy: NumberAsString,
|
|
44
58
|
];
|
|
45
59
|
|
|
60
|
+
export type DirectCurveV2Param = [
|
|
61
|
+
fromToken: Address,
|
|
62
|
+
toToken: Address,
|
|
63
|
+
exchange: Address,
|
|
64
|
+
poolAddress: Address,
|
|
65
|
+
fromAmount: NumberAsString,
|
|
66
|
+
toAmount: NumberAsString,
|
|
67
|
+
expectedAmount: NumberAsString,
|
|
68
|
+
feePercent: NumberAsString,
|
|
69
|
+
i: NumberAsString,
|
|
70
|
+
j: NumberAsString,
|
|
71
|
+
partner: Address,
|
|
72
|
+
isApproved: boolean,
|
|
73
|
+
swapType: CurveV2SwapType,
|
|
74
|
+
beneficiary: Address,
|
|
75
|
+
needWrapNative: boolean,
|
|
76
|
+
permit: string,
|
|
77
|
+
uuid: string,
|
|
78
|
+
];
|
|
79
|
+
|
|
46
80
|
enum CurveV2SwapFunctions {
|
|
47
81
|
exchange = 'exchange(uint256 i, uint256 j, uint256 dx, uint256 minDy)',
|
|
48
82
|
exchange_underlying = 'exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 minDy)',
|
|
@@ -51,25 +85,31 @@ enum CurveV2SwapFunctions {
|
|
|
51
85
|
|
|
52
86
|
export class CurveV2
|
|
53
87
|
extends SimpleExchange
|
|
54
|
-
implements IDexTxBuilder<CurveV2Data,
|
|
88
|
+
implements IDexTxBuilder<CurveV2Data, DirectCurveV2Param>
|
|
55
89
|
{
|
|
56
90
|
static dexKeys = ['curvev2'];
|
|
57
91
|
exchangeRouterInterface: Interface;
|
|
58
92
|
genericFactoryZapIface: Interface;
|
|
59
93
|
minConversionRate = '1';
|
|
60
94
|
needWrapNative = true;
|
|
95
|
+
logger: Logger;
|
|
96
|
+
|
|
97
|
+
readonly directSwapIface = new Interface(DirectSwapABI);
|
|
61
98
|
|
|
62
|
-
constructor(dexHelper: IDexHelper) {
|
|
99
|
+
constructor(readonly dexHelper: IDexHelper) {
|
|
63
100
|
super(dexHelper, 'curvev2');
|
|
64
101
|
this.exchangeRouterInterface = new Interface(CurveV2ABI as JsonFragment[]);
|
|
65
102
|
this.genericFactoryZapIface = new Interface(GenericFactoryZapABI);
|
|
103
|
+
this.logger = dexHelper.getLogger(
|
|
104
|
+
`CurveV2_${dexHelper.config.data.network}`,
|
|
105
|
+
);
|
|
66
106
|
}
|
|
67
107
|
|
|
68
108
|
getAdapterParam(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
109
|
+
_0: string,
|
|
110
|
+
_1: string,
|
|
111
|
+
_2: string,
|
|
112
|
+
_3: string,
|
|
73
113
|
data: CurveV2Data,
|
|
74
114
|
side: SwapSide,
|
|
75
115
|
): AdapterExchangeParam {
|
|
@@ -100,6 +140,127 @@ export class CurveV2
|
|
|
100
140
|
};
|
|
101
141
|
}
|
|
102
142
|
|
|
143
|
+
getTokenFromAddress(address: Address): Token {
|
|
144
|
+
// In this Dex decimals are not used
|
|
145
|
+
return { address, decimals: 0 };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async preProcessTransaction(
|
|
149
|
+
optimalSwapExchange: OptimalSwapExchange<CurveV2Data>,
|
|
150
|
+
srcToken: Token,
|
|
151
|
+
_0: Token,
|
|
152
|
+
_1: SwapSide,
|
|
153
|
+
options: PreprocessTransactionOptions,
|
|
154
|
+
): Promise<[OptimalSwapExchange<CurveV2Data>, ExchangeTxInfo]> {
|
|
155
|
+
if (!options.isDirectMethod) {
|
|
156
|
+
return [
|
|
157
|
+
optimalSwapExchange,
|
|
158
|
+
{
|
|
159
|
+
deadline: BigInt(getLocalDeadlineAsFriendlyPlaceholder()),
|
|
160
|
+
},
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
assert(
|
|
165
|
+
optimalSwapExchange.data !== undefined,
|
|
166
|
+
`preProcessTransaction: data field is missing`,
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
let isApproved: boolean | undefined;
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
this.erc20Contract.options.address =
|
|
173
|
+
this.dexHelper.config.wrapETH(srcToken).address;
|
|
174
|
+
const allowance = await this.erc20Contract.methods
|
|
175
|
+
.allowance(this.augustusAddress, optimalSwapExchange.data.exchange)
|
|
176
|
+
.call(undefined, 'latest');
|
|
177
|
+
isApproved =
|
|
178
|
+
BigInt(allowance.toString()) >= BigInt(optimalSwapExchange.srcAmount);
|
|
179
|
+
} catch (e) {
|
|
180
|
+
this.logger.error(
|
|
181
|
+
`preProcessTransaction failed to retrieve allowance info: `,
|
|
182
|
+
e,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return [
|
|
187
|
+
{
|
|
188
|
+
...optimalSwapExchange,
|
|
189
|
+
data: {
|
|
190
|
+
...optimalSwapExchange.data,
|
|
191
|
+
isApproved,
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
deadline: BigInt(getLocalDeadlineAsFriendlyPlaceholder()),
|
|
196
|
+
},
|
|
197
|
+
];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
getDirectParam(
|
|
201
|
+
srcToken: Address,
|
|
202
|
+
destToken: Address,
|
|
203
|
+
srcAmount: NumberAsString,
|
|
204
|
+
destAmount: NumberAsString,
|
|
205
|
+
expectedAmount: NumberAsString,
|
|
206
|
+
data: CurveV2Data,
|
|
207
|
+
side: SwapSide,
|
|
208
|
+
permit: string,
|
|
209
|
+
uuid: string,
|
|
210
|
+
feePercent: NumberAsString,
|
|
211
|
+
_0: NumberAsString,
|
|
212
|
+
partner: string,
|
|
213
|
+
beneficiary: string,
|
|
214
|
+
contractMethod?: string,
|
|
215
|
+
): TxInfo<DirectCurveV2Param> {
|
|
216
|
+
if (contractMethod !== DIRECT_METHOD_NAME) {
|
|
217
|
+
throw new Error(`Invalid contract method ${contractMethod}`);
|
|
218
|
+
}
|
|
219
|
+
assert(side === SwapSide.SELL, 'Buy not supported');
|
|
220
|
+
|
|
221
|
+
let isApproved: boolean = !!data.isApproved;
|
|
222
|
+
if (data.isApproved === undefined) {
|
|
223
|
+
this.logger.warn(`isApproved is undefined, defaulting to false`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const swapParams: DirectCurveV2Param = [
|
|
227
|
+
srcToken,
|
|
228
|
+
destToken,
|
|
229
|
+
data.exchange,
|
|
230
|
+
data.originalPoolAddress,
|
|
231
|
+
srcAmount,
|
|
232
|
+
destAmount,
|
|
233
|
+
expectedAmount,
|
|
234
|
+
feePercent,
|
|
235
|
+
data.i.toString(),
|
|
236
|
+
data.j.toString(),
|
|
237
|
+
partner,
|
|
238
|
+
isApproved,
|
|
239
|
+
data.swapType,
|
|
240
|
+
beneficiary,
|
|
241
|
+
// For now we always wrap native. We don't support non native trade
|
|
242
|
+
true,
|
|
243
|
+
permit,
|
|
244
|
+
uuidToBytes16(uuid),
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
const encoder = (...params: DirectCurveV2Param) => {
|
|
248
|
+
return this.directSwapIface.encodeFunctionData(DIRECT_METHOD_NAME, [
|
|
249
|
+
params,
|
|
250
|
+
]);
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
params: swapParams,
|
|
255
|
+
encoder,
|
|
256
|
+
networkFee: '0',
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
static getDirectFunctionName(): string[] {
|
|
261
|
+
return [DIRECT_METHOD_NAME];
|
|
262
|
+
}
|
|
263
|
+
|
|
103
264
|
async getSimpleParam(
|
|
104
265
|
srcToken: string,
|
|
105
266
|
destToken: string,
|
package/src/dex/idex.ts
CHANGED
|
@@ -76,9 +76,15 @@ export interface IDexTxBuilder<ExchangeData, DirectParam = null> {
|
|
|
76
76
|
destToken: Address,
|
|
77
77
|
srcAmount: NumberAsString,
|
|
78
78
|
destAmount: NumberAsString,
|
|
79
|
+
expectedAmount: NumberAsString,
|
|
79
80
|
data: ExchangeData,
|
|
80
81
|
side: SwapSide,
|
|
81
82
|
permit: string,
|
|
83
|
+
uuid: string,
|
|
84
|
+
feePercent: NumberAsString,
|
|
85
|
+
deadline: NumberAsString,
|
|
86
|
+
partner: string,
|
|
87
|
+
beneficiary: string,
|
|
82
88
|
contractMethod?: string,
|
|
83
89
|
): TxInfo<DirectParam>;
|
|
84
90
|
}
|
|
@@ -32,10 +32,7 @@ describe('PancakeswapV3 E2E', () => {
|
|
|
32
32
|
ContractMethod.megaSwap,
|
|
33
33
|
],
|
|
34
34
|
],
|
|
35
|
-
[SwapSide.BUY, [
|
|
36
|
-
ContractMethod.simpleBuy,
|
|
37
|
-
ContractMethod.buy,
|
|
38
|
-
]],
|
|
35
|
+
[SwapSide.BUY, [ContractMethod.simpleBuy, ContractMethod.buy]],
|
|
39
36
|
]);
|
|
40
37
|
|
|
41
38
|
const pairs: { name: string; sellAmount: string; buyAmount: string }[][] = [
|
|
@@ -98,8 +95,8 @@ describe('PancakeswapV3 E2E', () => {
|
|
|
98
95
|
sellAmount: '10000000000',
|
|
99
96
|
buyAmount: '500000000000000000000',
|
|
100
97
|
},
|
|
101
|
-
]
|
|
102
|
-
]
|
|
98
|
+
],
|
|
99
|
+
];
|
|
103
100
|
|
|
104
101
|
sideToContractMethods.forEach((contractMethods, side) =>
|
|
105
102
|
describe(`${side}`, () => {
|
|
@@ -76,7 +76,6 @@ const testingData: Partial<{ [key in Network]: any }> = {
|
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
describe('PancakeswapV3', function () {
|
|
79
|
-
|
|
80
79
|
describe('BSC', () => {
|
|
81
80
|
describe('WBNB -> USDT', () => {
|
|
82
81
|
it('getPoolIdentifiers and getPricesVolume SELL', async function () {
|
|
@@ -88,11 +87,7 @@ describe('PancakeswapV3', function () {
|
|
|
88
87
|
const WBNB = Tokens[network]['WBNB'];
|
|
89
88
|
const USDT = Tokens[network]['USDT'];
|
|
90
89
|
|
|
91
|
-
const amounts = [
|
|
92
|
-
0n,
|
|
93
|
-
1n * BI_POWS[18],
|
|
94
|
-
2n * BI_POWS[18],
|
|
95
|
-
];
|
|
90
|
+
const amounts = [0n, 1n * BI_POWS[18], 2n * BI_POWS[18]];
|
|
96
91
|
|
|
97
92
|
const pools = await pancakeswapV3.getPoolIdentifiers(
|
|
98
93
|
WBNB,
|
|
@@ -100,10 +95,7 @@ describe('PancakeswapV3', function () {
|
|
|
100
95
|
SwapSide.SELL,
|
|
101
96
|
blockNumber,
|
|
102
97
|
);
|
|
103
|
-
console.log(
|
|
104
|
-
`WBNB <> USDT Pool Identifiers: `,
|
|
105
|
-
pools,
|
|
106
|
-
);
|
|
98
|
+
console.log(`WBNB <> USDT Pool Identifiers: `, pools);
|
|
107
99
|
|
|
108
100
|
expect(pools.length).toBeGreaterThan(0);
|
|
109
101
|
|
|
@@ -115,10 +107,7 @@ describe('PancakeswapV3', function () {
|
|
|
115
107
|
blockNumber,
|
|
116
108
|
pools,
|
|
117
109
|
);
|
|
118
|
-
console.log(
|
|
119
|
-
`WBNB <> USDT Pool Prices: `,
|
|
120
|
-
poolPrices,
|
|
121
|
-
);
|
|
110
|
+
console.log(`WBNB <> USDT Pool Prices: `, poolPrices);
|
|
122
111
|
|
|
123
112
|
expect(poolPrices).not.toBeNull();
|
|
124
113
|
checkPoolPrices(
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
PoolState,
|
|
29
29
|
UniswapV3Data,
|
|
30
30
|
UniswapV3Functions,
|
|
31
|
-
|
|
31
|
+
UniswapV3SimpleSwapParams,
|
|
32
32
|
} from '../uniswap-v3/types';
|
|
33
33
|
import {
|
|
34
34
|
getLocalDeadlineAsFriendlyPlaceholder,
|
|
@@ -69,7 +69,7 @@ const PANCAKESWAPV3_QUOTE_GASLIMIT = 200_000;
|
|
|
69
69
|
|
|
70
70
|
export class PancakeswapV3
|
|
71
71
|
extends SimpleExchange
|
|
72
|
-
implements IDex<UniswapV3Data
|
|
72
|
+
implements IDex<UniswapV3Data>
|
|
73
73
|
{
|
|
74
74
|
readonly isFeeOnTransferSupported: boolean = false;
|
|
75
75
|
readonly eventPools: Record<string, PancakeSwapV3EventPool | null> = {};
|
|
@@ -733,7 +733,7 @@ export class PancakeswapV3
|
|
|
733
733
|
: UniswapV3Functions.exactOutput;
|
|
734
734
|
|
|
735
735
|
const path = this._encodePath(data.path, side);
|
|
736
|
-
const swapFunctionParams:
|
|
736
|
+
const swapFunctionParams: UniswapV3SimpleSwapParams =
|
|
737
737
|
side === SwapSide.SELL
|
|
738
738
|
? {
|
|
739
739
|
recipient: this.augustusAddress,
|
|
@@ -2,10 +2,7 @@ import { BytesLike, ethers } from 'ethers';
|
|
|
2
2
|
import { assert } from 'ts-essentials';
|
|
3
3
|
import { extractSuccessAndValue } from '../../lib/decoders';
|
|
4
4
|
import { MultiResult } from '../../lib/multi-wrapper';
|
|
5
|
-
import {
|
|
6
|
-
DecodedStateMultiCallResultWithRelativeBitmaps,
|
|
7
|
-
} from '../uniswap-v3/types';
|
|
8
|
-
|
|
5
|
+
import { DecodedStateMultiCallResultWithRelativeBitmaps } from '../uniswap-v3/types';
|
|
9
6
|
|
|
10
7
|
export function decodeStateMultiCallResultWithRelativeBitmaps(
|
|
11
8
|
result: MultiResult<BytesLike> | BytesLike,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Interface } from '@ethersproject/abi';
|
|
2
2
|
import Web3Abi, { AbiCoder } from 'web3-eth-abi';
|
|
3
|
+
import { Contract } from 'web3-eth-contract';
|
|
3
4
|
import { Address, SimpleExchangeParam, NumberAsString } from '../types';
|
|
4
5
|
import { CACHE_PREFIX, ETHER_ADDRESS } from '../constants';
|
|
5
6
|
import SimpleSwapHelperABI from '../abi/SimpleSwapHelperRouter.json';
|
|
@@ -9,6 +10,7 @@ import { isETHAddress } from '../utils';
|
|
|
9
10
|
import { MAX_UINT } from '../constants';
|
|
10
11
|
import Web3 from 'web3';
|
|
11
12
|
import { IDexHelper } from '../dex-helper';
|
|
13
|
+
import { AbiItem } from 'web3-utils';
|
|
12
14
|
|
|
13
15
|
/*
|
|
14
16
|
* Context: Augustus routers have all a deadline protection logic implemented globally.
|
|
@@ -26,6 +28,7 @@ export class SimpleExchange {
|
|
|
26
28
|
simpleSwapHelper: Interface;
|
|
27
29
|
protected abiCoder: AbiCoder;
|
|
28
30
|
erc20Interface: Interface;
|
|
31
|
+
erc20Contract: Contract;
|
|
29
32
|
|
|
30
33
|
needWrapNative = false;
|
|
31
34
|
isFeeOnTransferSupported = false;
|
|
@@ -42,6 +45,9 @@ export class SimpleExchange {
|
|
|
42
45
|
constructor(dexHelper: IDexHelper, public dexKey: string) {
|
|
43
46
|
this.simpleSwapHelper = new Interface(SimpleSwapHelperABI);
|
|
44
47
|
this.erc20Interface = new Interface(ERC20ABI);
|
|
48
|
+
this.erc20Contract = new dexHelper.web3Provider.eth.Contract(
|
|
49
|
+
ERC20ABI as AbiItem[],
|
|
50
|
+
);
|
|
45
51
|
this.abiCoder = Web3Abi as unknown as AbiCoder;
|
|
46
52
|
|
|
47
53
|
this.network = dexHelper.config.data.network;
|