@paraswap/dex-lib 4.7.20-native-insert-amount.4 → 4.7.20-native-insert-amount.5
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/PendleRouterStatic.json +19 -0
- package/build/abi/apex-defi/ApexDefiFactory.abi.json +1749 -0
- package/build/abi/apex-defi/ApexDefiRouter.abi.json +1120 -0
- package/build/abi/apex-defi/ApexDefiToken.abi.json +229 -0
- package/build/abi/apex-defi/ApexDefiWrapper.abi.json +92 -0
- package/build/abi/apex-defi/ApexDefiWrapperFactory.abi.json +1107 -0
- package/build/abi/pangolin-v3/PangolinV3StateMulticall.abi.json +796 -0
- package/build/abi/pendle/pendle-deployer.abi.json +520 -0
- package/build/abi/pendle/pendle-oracle.abi.json +413 -0
- package/build/abi/ring-v2/few-wrapped-token.json +587 -0
- package/build/abi/ring-v2/ring-v2-factory.json +125 -0
- package/build/abi/ring-v2/ring-v2-pool.json +461 -0
- package/build/abi/ring-v2/ring-v2-router.json +332 -0
- package/build/abi/stabull/stabull-curve.json +738 -0
- package/build/abi/stabull/stabull-router.json +76 -0
- package/build/abi/uniswap-v4/hooks/SpotDynamicFeeManager.json +26 -0
- package/build/abi/uniswap-v4/hooks/SpotHook.json +54 -0
- package/build/abi/uniswap-v4/hooks/SpotPolicyManager.json +45 -0
- package/build/abi/uniswap-v4/hooks/cabalcoin-hook.abi.json +682 -0
- package/build/abi/uniswap-v4/hooks/fee-hook.abi.json +1335 -0
- package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying-factory.d.ts +29 -0
- package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying-factory.js +153 -0
- package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying-factory.js.map +1 -0
- package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying.d.ts +40 -0
- package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying.js +323 -0
- package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying.js.map +1 -0
- package/build/dex/aave-pt-to-underlying/config.d.ts +3 -0
- package/build/dex/aave-pt-to-underlying/config.js +24 -0
- package/build/dex/aave-pt-to-underlying/config.js.map +1 -0
- package/build/dex/aave-pt-to-underlying/constants.d.ts +2 -0
- package/build/dex/aave-pt-to-underlying/constants.js +6 -0
- package/build/dex/aave-pt-to-underlying/constants.js.map +1 -0
- package/build/dex/aave-pt-to-underlying/types.d.ts +24 -0
- package/build/dex/aave-pt-to-underlying/types.js +3 -0
- package/build/dex/aave-pt-to-underlying/types.js.map +1 -0
- package/build/dex/aave-pt-to-usdc/aave-pt-to-usdc.d.ts +39 -0
- package/build/dex/aave-pt-to-usdc/aave-pt-to-usdc.js +244 -0
- package/build/dex/aave-pt-to-usdc/aave-pt-to-usdc.js.map +1 -0
- package/build/dex/aave-pt-to-usdc/config.d.ts +3 -0
- package/build/dex/aave-pt-to-usdc/config.js +47 -0
- package/build/dex/aave-pt-to-usdc/config.js.map +1 -0
- package/build/dex/aave-pt-to-usdc/constants.d.ts +2 -0
- package/build/dex/aave-pt-to-usdc/constants.js +6 -0
- package/build/dex/aave-pt-to-usdc/constants.js.map +1 -0
- package/build/dex/aave-pt-to-usdc/types.d.ts +22 -0
- package/build/dex/aave-pt-to-usdc/types.js +3 -0
- package/build/dex/aave-pt-to-usdc/types.js.map +1 -0
- package/build/dex/apex-defi/apex-defi-factory.d.ts +26 -0
- package/build/dex/apex-defi/apex-defi-factory.js +53 -0
- package/build/dex/apex-defi/apex-defi-factory.js.map +1 -0
- package/build/dex/apex-defi/apex-defi-pool.d.ts +55 -0
- package/build/dex/apex-defi/apex-defi-pool.js +247 -0
- package/build/dex/apex-defi/apex-defi-pool.js.map +1 -0
- package/build/dex/apex-defi/apex-defi-wrapper-factory.d.ts +57 -0
- package/build/dex/apex-defi/apex-defi-wrapper-factory.js +250 -0
- package/build/dex/apex-defi/apex-defi-wrapper-factory.js.map +1 -0
- package/build/dex/apex-defi/apex-defi.d.ts +97 -0
- package/build/dex/apex-defi/apex-defi.js +1021 -0
- package/build/dex/apex-defi/apex-defi.js.map +1 -0
- package/build/dex/apex-defi/config.d.ts +4 -0
- package/build/dex/apex-defi/config.js +138 -0
- package/build/dex/apex-defi/config.js.map +1 -0
- package/build/dex/apex-defi/types.d.ts +32 -0
- package/build/dex/apex-defi/types.js +3 -0
- package/build/dex/apex-defi/types.js.map +1 -0
- package/build/dex/apex-defi/utils.d.ts +46 -0
- package/build/dex/apex-defi/utils.js +133 -0
- package/build/dex/apex-defi/utils.js.map +1 -0
- package/build/dex/idle-dao/idle-dao.d.ts +0 -1
- package/build/dex/idle-dao/idle-dao.js +11 -23
- package/build/dex/idle-dao/idle-dao.js.map +1 -1
- package/build/dex/maker-psm/maker-psm.d.ts +41 -4
- package/build/dex/maker-psm/maker-psm.js +143 -40
- package/build/dex/maker-psm/maker-psm.js.map +1 -1
- package/build/dex/miro-migrator/miro-migrator-state.d.ts +27 -0
- package/build/dex/miro-migrator/miro-migrator-state.js +89 -0
- package/build/dex/miro-migrator/miro-migrator-state.js.map +1 -0
- package/build/dex/native/native.js +6 -16
- package/build/dex/native/native.js.map +1 -1
- package/build/dex/stabull/config.d.ts +3 -0
- package/build/dex/stabull/config.js +177 -0
- package/build/dex/stabull/config.js.map +1 -0
- package/build/dex/stabull/stabull-pool.d.ts +46 -0
- package/build/dex/stabull/stabull-pool.js +113 -0
- package/build/dex/stabull/stabull-pool.js.map +1 -0
- package/build/dex/stabull/stabull.d.ts +55 -0
- package/build/dex/stabull/stabull.js +286 -0
- package/build/dex/stabull/stabull.js.map +1 -0
- package/build/dex/stabull/types.d.ts +21 -0
- package/build/dex/stabull/types.js +3 -0
- package/build/dex/stabull/types.js.map +1 -0
- package/build/dex/uniswap-v3/forks/pangolin-v3/utils.d.ts +4 -0
- package/build/dex/uniswap-v3/forks/pangolin-v3/utils.js +56 -0
- package/build/dex/uniswap-v3/forks/pangolin-v3/utils.js.map +1 -0
- package/build/dex/uniswap-v4/hooks/arena.d.ts +6 -0
- package/build/dex/uniswap-v4/hooks/arena.js +10 -0
- package/build/dex/uniswap-v4/hooks/arena.js.map +1 -0
- package/build/dex/uniswap-v4/hooks/base-fee/base-fee-hook.d.ts +0 -0
- package/build/dex/uniswap-v4/hooks/base-fee/base-fee-hook.js +2 -0
- package/build/dex/uniswap-v4/hooks/base-fee/base-fee-hook.js.map +1 -0
- package/build/dex/uniswap-v4/hooks/cabalcoin-hook/cabalcoin-hook-pool.d.ts +7 -0
- package/build/dex/uniswap-v4/hooks/cabalcoin-hook/cabalcoin-hook-pool.js +28 -0
- package/build/dex/uniswap-v4/hooks/cabalcoin-hook/cabalcoin-hook-pool.js.map +1 -0
- package/build/dex/uniswap-v4/hooks/cabalcoin-hook/types.d.ts +0 -0
- package/build/dex/uniswap-v4/hooks/cabalcoin-hook/types.js +2 -0
- package/build/dex/uniswap-v4/hooks/cabalcoin-hook/types.js.map +1 -0
- package/build/dex/uniswap-v4/hooks/fee-hook/fee-hook-pool.d.ts +7 -0
- package/build/dex/uniswap-v4/hooks/fee-hook/fee-hook-pool.js +28 -0
- package/build/dex/uniswap-v4/hooks/fee-hook/fee-hook-pool.js.map +1 -0
- package/build/dex/uniswap-v4/hooks/fee-hook/types.d.ts +0 -0
- package/build/dex/uniswap-v4/hooks/fee-hook/types.js +2 -0
- package/build/dex/uniswap-v4/hooks/fee-hook/types.js.map +1 -0
- package/build/dex/uniswap-v4/hooks/index.d.ts +1 -0
- package/build/dex/uniswap-v4/hooks/index.js +18 -0
- package/build/dex/uniswap-v4/hooks/index.js.map +1 -0
- package/build/dex/uniswap-v4/hooks/spot.d.ts +15 -0
- package/build/dex/uniswap-v4/hooks/spot.js +109 -0
- package/build/dex/uniswap-v4/hooks/spot.js.map +1 -0
- package/build/dex/uniswap-v4/hooks/template.d.ts +150 -0
- package/build/dex/uniswap-v4/hooks/template.js +104 -0
- package/build/dex/uniswap-v4/hooks/template.js.map +1 -0
- package/build/dex/usdc-transmuter/usdc-transmuter-pool.d.ts +26 -0
- package/build/dex/usdc-transmuter/usdc-transmuter-pool.js +75 -0
- package/build/dex/usdc-transmuter/usdc-transmuter-pool.js.map +1 -0
- package/build/dex/usual/usual-usdc-usdc.d.ts +17 -0
- package/build/dex/usual/usual-usdc-usdc.js +59 -0
- package/build/dex/usual/usual-usdc-usdc.js.map +1 -0
- package/build/dex/yo/config.d.ts +3 -0
- package/build/dex/yo/config.js +21 -0
- package/build/dex/yo/config.js.map +1 -0
- package/build/dex/yo/types.d.ts +13 -0
- package/build/dex/yo/types.js +3 -0
- package/build/dex/yo/types.js.map +1 -0
- package/build/dex/yo/yo-pool.d.ts +13 -0
- package/build/dex/yo/yo-pool.js +26 -0
- package/build/dex/yo/yo-pool.js.map +1 -0
- package/build/dex/yo/yo.d.ts +39 -0
- package/build/dex/yo/yo.js +248 -0
- package/build/dex/yo/yo.js.map +1 -0
- package/build/implementations/api-paraswap-sdk.d.ts +25 -0
- package/build/implementations/api-paraswap-sdk.js +102 -0
- package/build/implementations/api-paraswap-sdk.js.map +1 -0
- package/package.json +1 -1
- package/build/executor/Executor02BytecodeBuilderMultiRoute.d.ts +0 -101
- package/build/executor/Executor02BytecodeBuilderMultiRoute.js +0 -878
- package/build/executor/Executor02BytecodeBuilderMultiRoute.js.map +0 -1
|
@@ -0,0 +1,1021 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.ApexDefi = void 0;
|
|
40
|
+
const constants_1 = require("../../constants");
|
|
41
|
+
const CALLDATA_GAS_COST = __importStar(require("../../calldata-gas-cost"));
|
|
42
|
+
const utils_1 = require("../../utils");
|
|
43
|
+
const simple_exchange_1 = require("../simple-exchange");
|
|
44
|
+
const config_1 = require("./config");
|
|
45
|
+
const apex_defi_pool_1 = require("./apex-defi-pool");
|
|
46
|
+
const abi_1 = require("@ethersproject/abi");
|
|
47
|
+
const ApexDefiRouter_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiRouter.abi.json"));
|
|
48
|
+
const ApexDefiToken_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiToken.abi.json"));
|
|
49
|
+
const ApexDefiFactory_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiFactory.abi.json"));
|
|
50
|
+
const ApexDefiWrapperFactory_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiWrapperFactory.abi.json"));
|
|
51
|
+
const ApexDefiWrapper_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiWrapper.abi.json"));
|
|
52
|
+
const erc20_json_1 = __importDefault(require("../../abi/erc20.json"));
|
|
53
|
+
const apex_defi_factory_1 = require("./apex-defi-factory");
|
|
54
|
+
const utils_2 = require("./utils");
|
|
55
|
+
const apex_defi_wrapper_factory_1 = require("./apex-defi-wrapper-factory");
|
|
56
|
+
const simple_exchange_2 = require("../simple-exchange");
|
|
57
|
+
class ApexDefi extends simple_exchange_1.SimpleExchange {
|
|
58
|
+
network;
|
|
59
|
+
dexKey;
|
|
60
|
+
dexHelper;
|
|
61
|
+
eventPools = {};
|
|
62
|
+
supportedTokensMap = {};
|
|
63
|
+
factory;
|
|
64
|
+
wrapperFactory;
|
|
65
|
+
routerIface;
|
|
66
|
+
erc20Iface;
|
|
67
|
+
tokenIface;
|
|
68
|
+
factoryIface;
|
|
69
|
+
wrapperFactoryIface;
|
|
70
|
+
wrapperIface;
|
|
71
|
+
feeFactor = 10000;
|
|
72
|
+
hasConstantPriceLargeAmounts = false;
|
|
73
|
+
needWrapNative = false;
|
|
74
|
+
isFeeOnTransferSupported = false;
|
|
75
|
+
static dexKeysWithNetwork = (0, utils_1.getDexKeysWithNetwork)(config_1.ApexDefiConfig);
|
|
76
|
+
logger;
|
|
77
|
+
constructor(network, dexKey, dexHelper) {
|
|
78
|
+
super(dexHelper, dexKey);
|
|
79
|
+
this.network = network;
|
|
80
|
+
this.dexKey = dexKey;
|
|
81
|
+
this.dexHelper = dexHelper;
|
|
82
|
+
this.routerIface = new abi_1.Interface(ApexDefiRouter_abi_json_1.default);
|
|
83
|
+
this.erc20Iface = new abi_1.Interface(erc20_json_1.default);
|
|
84
|
+
this.tokenIface = new abi_1.Interface(ApexDefiToken_abi_json_1.default);
|
|
85
|
+
this.factoryIface = new abi_1.Interface(ApexDefiFactory_abi_json_1.default);
|
|
86
|
+
this.wrapperFactoryIface = new abi_1.Interface(ApexDefiWrapperFactory_abi_json_1.default);
|
|
87
|
+
this.wrapperIface = new abi_1.Interface(ApexDefiWrapper_abi_json_1.default);
|
|
88
|
+
this.logger = dexHelper.getLogger(dexKey + '-' + network);
|
|
89
|
+
this.factory = this.getFactoryInstance();
|
|
90
|
+
this.wrapperFactory = this.getWrapperFactoryInstance();
|
|
91
|
+
}
|
|
92
|
+
getFactoryInstance() {
|
|
93
|
+
return new apex_defi_factory_1.ApexDefiFactory(this.dexHelper, this.dexKey, config_1.ApexDefiConfig[this.dexKey][this.network].factoryAddress, this.logger, this.onPoolCreated().bind(this));
|
|
94
|
+
}
|
|
95
|
+
getWrapperFactoryInstance() {
|
|
96
|
+
return new apex_defi_wrapper_factory_1.ApexDefiWrapperFactory(this.dexHelper, this.dexKey, config_1.ApexDefiConfig[this.dexKey][this.network].wrapperFactoryAddress, this.logger, this.onWrapperCreated().bind(this));
|
|
97
|
+
}
|
|
98
|
+
onPoolCreated() {
|
|
99
|
+
return async ({ pairAddress, blockNumber }) => {
|
|
100
|
+
const poolKey = this.getPoolIdentifier(pairAddress);
|
|
101
|
+
await this.fetchAndInitPool(pairAddress, blockNumber, poolKey);
|
|
102
|
+
this.logger.info(`[onPoolCreated] pool=${poolKey}; pairAddress=${pairAddress} initialized`);
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
onWrapperCreated() {
|
|
106
|
+
return async ({ wrapperInfo, blockNumber }) => {
|
|
107
|
+
this.logger.info(`[onWrapperCreated] wrapper=${wrapperInfo.wrapperAddress}; originalToken=${wrapperInfo.originalToken}; wrappedToken=${wrapperInfo.wrappedToken} initialized`);
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Initialize pricing is called once in the start of
|
|
111
|
+
// pricing service. It is intended to setup the integration
|
|
112
|
+
// for pricing requests. It is optional for a DEX to
|
|
113
|
+
// implement this function
|
|
114
|
+
async initializePricing(blockNumber) {
|
|
115
|
+
await this.factory.initialize(blockNumber);
|
|
116
|
+
await this.wrapperFactory.initialize(blockNumber);
|
|
117
|
+
}
|
|
118
|
+
// Legacy: was only used for V5
|
|
119
|
+
// Returns the list of contract adapters (name and index)
|
|
120
|
+
// for a buy/sell. Return null if there are no adapters.
|
|
121
|
+
getAdapters(side) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
// Returns list of pool identifiers that can be used
|
|
125
|
+
// for a given swap. poolIdentifiers must be unique
|
|
126
|
+
// across DEXes. It is recommended to use
|
|
127
|
+
// ${dexKey}_${poolAddress} as a poolIdentifier
|
|
128
|
+
async getPoolIdentifiers(srcToken, destToken, side, blockNumber) {
|
|
129
|
+
if (srcToken.address.toLowerCase() === destToken.address.toLowerCase()) {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
// Check if tokens are wrappers and get their underlying tokens
|
|
133
|
+
const srcTokenToUse = this.getERC314Token(srcToken.address);
|
|
134
|
+
const destTokenToUse = this.getERC314Token(destToken.address);
|
|
135
|
+
// Check if this is a direct AVAX pair
|
|
136
|
+
const isDirectAVAXPair = (0, utils_1.isETHAddress)(srcTokenToUse.address) ||
|
|
137
|
+
(0, utils_1.isETHAddress)(destTokenToUse.address);
|
|
138
|
+
if (isDirectAVAXPair) {
|
|
139
|
+
// Direct AVAX pair - return single pool
|
|
140
|
+
const pairAddress = this.getPoolAddress(srcTokenToUse, destTokenToUse);
|
|
141
|
+
const poolIdentifier = this.getPoolIdentifier(pairAddress).toLowerCase();
|
|
142
|
+
return [poolIdentifier];
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// Token-to-token swap - return both AVAX pairs
|
|
146
|
+
const avaxToken = {
|
|
147
|
+
address: constants_1.ETHER_ADDRESS,
|
|
148
|
+
decimals: 18,
|
|
149
|
+
};
|
|
150
|
+
const srcPoolAddress = this.getPoolAddress(srcTokenToUse, avaxToken);
|
|
151
|
+
const destPoolAddress = this.getPoolAddress(destTokenToUse, avaxToken);
|
|
152
|
+
const srcPoolIdentifier = this.getPoolIdentifier(srcPoolAddress).toLowerCase();
|
|
153
|
+
const destPoolIdentifier = this.getPoolIdentifier(destPoolAddress).toLowerCase();
|
|
154
|
+
return [srcPoolIdentifier, destPoolIdentifier];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
getPoolIdentifier(pairAddress) {
|
|
158
|
+
return `${this.dexKey}_${pairAddress}`.toLowerCase();
|
|
159
|
+
}
|
|
160
|
+
getPoolAddress(srcToken, destToken) {
|
|
161
|
+
// Only handle direct AVAX pairs
|
|
162
|
+
const isSrcNative = (0, utils_1.isETHAddress)(srcToken.address);
|
|
163
|
+
const isDestNative = (0, utils_1.isETHAddress)(destToken.address);
|
|
164
|
+
if (isSrcNative) {
|
|
165
|
+
// AVAX → Token: pool address is the token address
|
|
166
|
+
return destToken.address;
|
|
167
|
+
}
|
|
168
|
+
else if (isDestNative) {
|
|
169
|
+
// Token → AVAX: pool address is the token address
|
|
170
|
+
return srcToken.address;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// This should never happen for direct pairs
|
|
174
|
+
throw new Error('getPoolAddress called for non-AVAX pair');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Returns pool prices for amounts.
|
|
178
|
+
// If limitPools is defined only pools in limitPools
|
|
179
|
+
// should be used. If limitPools is undefined then
|
|
180
|
+
// any pools can be used.
|
|
181
|
+
async getPricesVolume(srcToken, destToken, amounts, side, blockNumber, limitPools) {
|
|
182
|
+
try {
|
|
183
|
+
// Check if this is a wrapper/unwrap operation
|
|
184
|
+
const isWrapperOperation = this.isWrapperOperation(srcToken, destToken);
|
|
185
|
+
if (isWrapperOperation) {
|
|
186
|
+
return this.getWrapperPrices(srcToken, destToken, amounts, side);
|
|
187
|
+
}
|
|
188
|
+
const [_srcAddress, _destAddress] = this._getLoweredAddresses(srcToken, destToken);
|
|
189
|
+
if (_srcAddress === _destAddress) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
// Get underlying ERC314 tokens for pool discovery and pricing
|
|
193
|
+
const srcTokenERC314 = this.getERC314Token(srcToken.address);
|
|
194
|
+
const destTokenERC314 = this.getERC314Token(destToken.address);
|
|
195
|
+
const poolIdentifiers = await this.getPoolIdentifiers(srcTokenERC314, destTokenERC314, side, blockNumber);
|
|
196
|
+
// Filter pools based on limitPools if provided
|
|
197
|
+
const validPoolIdentifiers = limitPools
|
|
198
|
+
? poolIdentifiers.filter(id => limitPools.includes(id))
|
|
199
|
+
: poolIdentifiers;
|
|
200
|
+
if (validPoolIdentifiers.length === 0) {
|
|
201
|
+
this.logger.warn(`No valid pool identifiers found for ${srcToken.address} -> ${destToken.address}`);
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
// Check if this is a direct AVAX pair
|
|
205
|
+
const isDirectAVAXPair = (0, utils_1.isETHAddress)(srcTokenERC314.address) ||
|
|
206
|
+
(0, utils_1.isETHAddress)(destTokenERC314.address);
|
|
207
|
+
if (isDirectAVAXPair) {
|
|
208
|
+
return this.getDirectAVAXPairPrices(srcTokenERC314, destTokenERC314, amounts, side, blockNumber, validPoolIdentifiers[0], srcToken, destToken);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
return this.getCrossPairTokenToTokenPrices(srcTokenERC314, destTokenERC314, amounts, side, blockNumber, validPoolIdentifiers, srcToken, destToken);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch (e) {
|
|
215
|
+
this.logger.error(`Error_getPricesVolume ${srcToken.symbol || srcToken.address}, ${destToken.symbol || destToken.address}, ${side}:`, e);
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async getDirectAVAXPairPrices(srcTokenERC314, destTokenERC314, amounts, side, blockNumber, poolIdentifier, originalSrcToken, originalDestToken) {
|
|
220
|
+
try {
|
|
221
|
+
// Get or discover the pool
|
|
222
|
+
let pool = this.eventPools[poolIdentifier];
|
|
223
|
+
if (!pool) {
|
|
224
|
+
pool = await this.discoverPool(srcTokenERC314, destTokenERC314, blockNumber);
|
|
225
|
+
if (!pool) {
|
|
226
|
+
this.logger.warn(`Failed to discover pool for ${poolIdentifier}`);
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const state = await pool.getStateOrGenerate(blockNumber);
|
|
231
|
+
if (!state) {
|
|
232
|
+
this.logger.warn(`Failed to get pool state for ${poolIdentifier}`);
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
if (!state.tradingEnabled) {
|
|
236
|
+
this.logger.warn(`Pool ${poolIdentifier} is not trading`);
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
const { prices, unit } = await this.calculatePrices(amounts, side, originalSrcToken, originalDestToken, async (amount) => side === constants_1.SwapSide.SELL
|
|
240
|
+
? this.getSellPrice(state, amount, srcTokenERC314, destTokenERC314)
|
|
241
|
+
: this.getBuyPrice(state, amount, srcTokenERC314, destTokenERC314), async (unitAmount) => side === constants_1.SwapSide.SELL
|
|
242
|
+
? this.getSellPrice(state, unitAmount, srcTokenERC314, destTokenERC314)
|
|
243
|
+
: this.getBuyPrice(state, unitAmount, srcTokenERC314, destTokenERC314));
|
|
244
|
+
const isERC314Pair = !this.wrapperFactory.getWrapperByOriginalToken(originalSrcToken.address) &&
|
|
245
|
+
!this.wrapperFactory.getWrapperByOriginalToken(originalDestToken.address);
|
|
246
|
+
return [
|
|
247
|
+
{
|
|
248
|
+
prices,
|
|
249
|
+
unit,
|
|
250
|
+
data: {
|
|
251
|
+
path: [
|
|
252
|
+
{
|
|
253
|
+
tokenIn: originalSrcToken.address.toLowerCase(),
|
|
254
|
+
tokenOut: originalDestToken.address.toLowerCase(),
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
swapType: isERC314Pair ? 'direct' : 'router',
|
|
258
|
+
},
|
|
259
|
+
exchange: this.dexKey,
|
|
260
|
+
poolIdentifiers: [poolIdentifier],
|
|
261
|
+
gasCost: config_1.ApexDefiConfig[this.dexKey][this.network].poolGasCost,
|
|
262
|
+
poolAddresses: [pool.poolAddress],
|
|
263
|
+
},
|
|
264
|
+
];
|
|
265
|
+
}
|
|
266
|
+
catch (e) {
|
|
267
|
+
this.logger.error(`Error in getDirectAVAXPairPrices for ${poolIdentifier}:`, e);
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
async getCrossPairTokenToTokenPrices(srcTokenERC314, destTokenERC314, amounts, side, blockNumber, poolIdentifiers, originalSrcToken, originalDestToken) {
|
|
272
|
+
const avaxToken = { address: constants_1.ETHER_ADDRESS, decimals: 18 };
|
|
273
|
+
// Get both pool states
|
|
274
|
+
const [srcPool, destPool] = await Promise.all([
|
|
275
|
+
this.getOrDiscoverPool(srcTokenERC314, avaxToken, blockNumber, poolIdentifiers[0]),
|
|
276
|
+
this.getOrDiscoverPool(destTokenERC314, avaxToken, blockNumber, poolIdentifiers[1]),
|
|
277
|
+
]);
|
|
278
|
+
if (!srcPool || !destPool) {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
const [srcState, destState] = await Promise.all([
|
|
282
|
+
srcPool.getStateOrGenerate(blockNumber),
|
|
283
|
+
destPool.getStateOrGenerate(blockNumber),
|
|
284
|
+
]);
|
|
285
|
+
if (!srcState || !destState) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
if (!srcState.tradingEnabled || !destState.tradingEnabled) {
|
|
289
|
+
this.logger.warn('Pool is not trading');
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
const { prices, unit } = await this.calculatePrices(amounts, side, originalSrcToken, originalDestToken, async (amount) => side === constants_1.SwapSide.SELL
|
|
293
|
+
? this.calculateCrossPairSellPrice(amount, srcTokenERC314, destTokenERC314, srcState, destState)
|
|
294
|
+
: this.calculateCrossPairBuyPrice(amount, srcTokenERC314, destTokenERC314, srcState, destState), async (unitAmount) => side === constants_1.SwapSide.SELL
|
|
295
|
+
? this.calculateCrossPairSellPrice(unitAmount, srcTokenERC314, destTokenERC314, srcState, destState)
|
|
296
|
+
: this.calculateCrossPairBuyPrice(unitAmount, srcTokenERC314, destTokenERC314, srcState, destState));
|
|
297
|
+
const virtualPoolIdentifier = `${this.dexKey}_virtual_${srcTokenERC314.address}_${destTokenERC314.address}`.toLowerCase();
|
|
298
|
+
return [
|
|
299
|
+
{
|
|
300
|
+
prices,
|
|
301
|
+
unit,
|
|
302
|
+
data: {
|
|
303
|
+
path: [
|
|
304
|
+
{
|
|
305
|
+
tokenIn: originalSrcToken.address.toLowerCase(),
|
|
306
|
+
tokenOut: constants_1.ETHER_ADDRESS.toLowerCase(),
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
tokenIn: constants_1.ETHER_ADDRESS.toLowerCase(),
|
|
310
|
+
tokenOut: originalDestToken.address.toLowerCase(),
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
swapType: 'router',
|
|
314
|
+
},
|
|
315
|
+
exchange: this.dexKey,
|
|
316
|
+
poolIdentifiers: [virtualPoolIdentifier],
|
|
317
|
+
gasCost: config_1.ApexDefiConfig[this.dexKey][this.network].poolGasCost * 2,
|
|
318
|
+
poolAddresses: [srcPool.poolAddress, destPool.poolAddress],
|
|
319
|
+
},
|
|
320
|
+
];
|
|
321
|
+
}
|
|
322
|
+
async getOrDiscoverPool(token, avaxToken, blockNumber, poolIdentifier) {
|
|
323
|
+
let pool = this.eventPools[poolIdentifier];
|
|
324
|
+
if (!pool) {
|
|
325
|
+
pool = await this.discoverPool(token, avaxToken, blockNumber);
|
|
326
|
+
}
|
|
327
|
+
return pool;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Discover and add a pool for a given token pair
|
|
331
|
+
* This method is called when a pool is not found in the eventPools map
|
|
332
|
+
*/
|
|
333
|
+
async discoverPool(srcToken, destToken, blockNumber) {
|
|
334
|
+
const pairAddress = this.getPoolAddress(srcToken, destToken);
|
|
335
|
+
const poolKey = this.getPoolIdentifier(pairAddress);
|
|
336
|
+
if (this.eventPools[poolKey]) {
|
|
337
|
+
return this.eventPools[poolKey];
|
|
338
|
+
}
|
|
339
|
+
return this.fetchAndInitPool(pairAddress, blockNumber, poolKey);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Calculate the output amount for a sell (exact input) swap
|
|
343
|
+
* Uses the constant product formula: amountOut = (amountIn * reserveOut) / (reserveIn + amountIn)
|
|
344
|
+
*/
|
|
345
|
+
getSellPrice(state, amountIn, srcToken, _destToken) {
|
|
346
|
+
const { reserve0, reserve1, baseSwapRate, tradingFee, tradingEnabled } = state;
|
|
347
|
+
if (!tradingEnabled) {
|
|
348
|
+
this.logger.warn('Pool is not trading');
|
|
349
|
+
return 0n;
|
|
350
|
+
}
|
|
351
|
+
// Validate state
|
|
352
|
+
if (reserve0 == null ||
|
|
353
|
+
reserve1 == null ||
|
|
354
|
+
baseSwapRate == null ||
|
|
355
|
+
tradingFee == null) {
|
|
356
|
+
this.logger.warn('Invalid pool state for pricing calculation');
|
|
357
|
+
return 0n;
|
|
358
|
+
}
|
|
359
|
+
// Determine which reserve is for input and which is for output
|
|
360
|
+
const isSrcToken0 = (0, utils_1.isETHAddress)(srcToken.address);
|
|
361
|
+
const reserveIn = BigInt(isSrcToken0 ? reserve0 : reserve1);
|
|
362
|
+
const reserveOut = BigInt(isSrcToken0 ? reserve1 : reserve0);
|
|
363
|
+
if (reserveIn === 0n || reserveOut === 0n)
|
|
364
|
+
return 0n;
|
|
365
|
+
const totalFee = baseSwapRate + tradingFee;
|
|
366
|
+
// Validate fee range
|
|
367
|
+
if (totalFee >= this.feeFactor) {
|
|
368
|
+
this.logger.warn('Invalid fee rate detected');
|
|
369
|
+
return 0n;
|
|
370
|
+
}
|
|
371
|
+
const amountInWithFee = amountIn * BigInt(this.feeFactor - totalFee);
|
|
372
|
+
const numerator = amountInWithFee * reserveOut;
|
|
373
|
+
const denominator = reserveIn * BigInt(this.feeFactor) + amountInWithFee;
|
|
374
|
+
return denominator === 0n ? 0n : numerator / denominator;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Calculate the input amount for a buy (exact output) swap
|
|
378
|
+
* Uses the constant product formula: amountIn = (amountOut * reserveIn * feeFactor) / ((reserveOut - amountOut) * (feeFactor - totalFee))
|
|
379
|
+
*/
|
|
380
|
+
getBuyPrice(state, amountOut, srcToken, _destToken) {
|
|
381
|
+
const { reserve0, reserve1, baseSwapRate, tradingFee, tradingEnabled } = state;
|
|
382
|
+
if (!tradingEnabled) {
|
|
383
|
+
this.logger.warn('Pool is not trading');
|
|
384
|
+
return 0n;
|
|
385
|
+
}
|
|
386
|
+
// Validate state
|
|
387
|
+
if (reserve0 == null ||
|
|
388
|
+
reserve1 == null ||
|
|
389
|
+
baseSwapRate == null ||
|
|
390
|
+
tradingFee == null) {
|
|
391
|
+
this.logger.warn('Invalid pool state for pricing calculation');
|
|
392
|
+
return 0n;
|
|
393
|
+
}
|
|
394
|
+
// Determine which reserve is for input and which is for output
|
|
395
|
+
const isSrcToken0 = (0, utils_1.isETHAddress)(srcToken.address);
|
|
396
|
+
const reserveIn = BigInt(isSrcToken0 ? reserve0 : reserve1);
|
|
397
|
+
const reserveOut = BigInt(isSrcToken0 ? reserve1 : reserve0);
|
|
398
|
+
if (reserveIn === 0n || reserveOut === 0n)
|
|
399
|
+
return 0n;
|
|
400
|
+
if (amountOut >= reserveOut)
|
|
401
|
+
return 0n;
|
|
402
|
+
const totalFee = baseSwapRate + tradingFee;
|
|
403
|
+
// Validate fee range
|
|
404
|
+
if (totalFee >= this.feeFactor) {
|
|
405
|
+
this.logger.warn('Invalid fee rate detected');
|
|
406
|
+
return 0n;
|
|
407
|
+
}
|
|
408
|
+
const numerator = reserveIn * amountOut * BigInt(this.feeFactor);
|
|
409
|
+
const denominator = (BigInt(this.feeFactor) - BigInt(totalFee)) * (reserveOut - amountOut);
|
|
410
|
+
if (denominator <= 0n)
|
|
411
|
+
return 0n;
|
|
412
|
+
return numerator === 0n ? 0n : 1n + numerator / denominator;
|
|
413
|
+
}
|
|
414
|
+
calculateCrossPairSellPrice(amountIn, srcToken, destToken, srcPoolState, destPoolState) {
|
|
415
|
+
const avaxToken = {
|
|
416
|
+
address: constants_1.ETHER_ADDRESS,
|
|
417
|
+
decimals: 18,
|
|
418
|
+
};
|
|
419
|
+
if (!srcPoolState.tradingEnabled || !destPoolState.tradingEnabled) {
|
|
420
|
+
this.logger.warn('Pool is not trading');
|
|
421
|
+
return 0n;
|
|
422
|
+
}
|
|
423
|
+
// Step 1: Calculate tokenA → AVAX (with fees)
|
|
424
|
+
const avaxReceived = this.getSellPrice(srcPoolState, amountIn, srcToken, avaxToken);
|
|
425
|
+
if (avaxReceived === 0n)
|
|
426
|
+
return 0n;
|
|
427
|
+
// Step 2: Calculate AVAX → tokenB (with fees)
|
|
428
|
+
const finalOutput = this.getSellPrice(destPoolState, avaxReceived, avaxToken, destToken);
|
|
429
|
+
return finalOutput;
|
|
430
|
+
}
|
|
431
|
+
calculateCrossPairBuyPrice(amountOut, srcToken, destToken, srcPoolState, destPoolState) {
|
|
432
|
+
const avaxToken = {
|
|
433
|
+
address: constants_1.ETHER_ADDRESS,
|
|
434
|
+
decimals: 18,
|
|
435
|
+
};
|
|
436
|
+
if (!srcPoolState.tradingEnabled || !destPoolState.tradingEnabled) {
|
|
437
|
+
this.logger.warn('Pool is not trading');
|
|
438
|
+
return 0n;
|
|
439
|
+
}
|
|
440
|
+
// Step 1: Calculate AVAX → tokenB (reverse with fees)
|
|
441
|
+
const avaxNeeded = this.getBuyPrice(destPoolState, amountOut, avaxToken, destToken);
|
|
442
|
+
if (avaxNeeded === 0n)
|
|
443
|
+
return 0n;
|
|
444
|
+
// Step 2: Calculate tokenA → AVAX (reverse with fees)
|
|
445
|
+
const finalInput = this.getBuyPrice(srcPoolState, avaxNeeded, srcToken, avaxToken);
|
|
446
|
+
return finalInput;
|
|
447
|
+
}
|
|
448
|
+
// Common pricing logic for both direct and cross-pair swaps
|
|
449
|
+
async calculatePrices(amounts, side, originalSrcToken, originalDestToken, priceCalculator, unitCalculator) {
|
|
450
|
+
// Convert input amounts to ERC314 decimals (18) for internal calculations
|
|
451
|
+
const erc314Amounts = this.convertAmountsToERC314(amounts, side === constants_1.SwapSide.SELL
|
|
452
|
+
? originalSrcToken.decimals
|
|
453
|
+
: originalDestToken.decimals);
|
|
454
|
+
// Calculate prices in ERC314 space (18 decimals)
|
|
455
|
+
const erc314Prices = await Promise.all(erc314Amounts.map(amount => {
|
|
456
|
+
if (amount === 0n)
|
|
457
|
+
return 0n;
|
|
458
|
+
return priceCalculator(amount);
|
|
459
|
+
}));
|
|
460
|
+
// Convert prices back to original token decimals
|
|
461
|
+
const finalPrices = this.convertPricesFromERC314(erc314Prices, side === constants_1.SwapSide.SELL
|
|
462
|
+
? originalDestToken.decimals
|
|
463
|
+
: originalSrcToken.decimals);
|
|
464
|
+
// Calculate unit price
|
|
465
|
+
const unitAmount = (0, utils_1.getBigIntPow)(side === constants_1.SwapSide.SELL
|
|
466
|
+
? originalSrcToken.decimals
|
|
467
|
+
: originalDestToken.decimals);
|
|
468
|
+
const erc314UnitAmount = this.convertAmountToERC314(unitAmount, side === constants_1.SwapSide.SELL
|
|
469
|
+
? originalSrcToken.decimals
|
|
470
|
+
: originalDestToken.decimals, 18);
|
|
471
|
+
const erc314Unit = await unitCalculator(erc314UnitAmount);
|
|
472
|
+
const finalUnit = this.convertAmountFromERC314(erc314Unit, 18, side === constants_1.SwapSide.SELL
|
|
473
|
+
? originalDestToken.decimals
|
|
474
|
+
: originalSrcToken.decimals);
|
|
475
|
+
return { prices: finalPrices, unit: finalUnit };
|
|
476
|
+
}
|
|
477
|
+
getCalldataGasCost(_poolPrices) {
|
|
478
|
+
return (CALLDATA_GAS_COST.DEX_OVERHEAD +
|
|
479
|
+
CALLDATA_GAS_COST.LENGTH_SMALL +
|
|
480
|
+
// ParentStruct header
|
|
481
|
+
CALLDATA_GAS_COST.OFFSET_SMALL +
|
|
482
|
+
// ParentStruct -> avax
|
|
483
|
+
CALLDATA_GAS_COST.ADDRESS +
|
|
484
|
+
// ParentStruct -> pools[] header
|
|
485
|
+
CALLDATA_GAS_COST.OFFSET_SMALL +
|
|
486
|
+
// ParentStruct -> pools[]
|
|
487
|
+
CALLDATA_GAS_COST.LENGTH_SMALL +
|
|
488
|
+
// ParentStruct -> pools[0]
|
|
489
|
+
CALLDATA_GAS_COST.wordNonZeroBytes(22));
|
|
490
|
+
}
|
|
491
|
+
// Encode params required by the exchange adapter
|
|
492
|
+
// V5: Used for multiSwap, buy & megaSwap
|
|
493
|
+
// V6: Not used, can be left blank
|
|
494
|
+
// Hint: abiCoder.encodeParameter() could be useful
|
|
495
|
+
getAdapterParam(_srcToken, _destToken, _srcAmount, _destAmount, _data, _side) {
|
|
496
|
+
// Not implemented for ApexDefi
|
|
497
|
+
const payload = '';
|
|
498
|
+
return {
|
|
499
|
+
targetExchange: config_1.ApexDefiConfig[this.dexKey][this.network].routerAddress,
|
|
500
|
+
payload,
|
|
501
|
+
networkFee: '0',
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
// Encode params required by the exchange adapter for V6
|
|
505
|
+
// This is the main method used for swaps in V6
|
|
506
|
+
getDexParam(srcToken, destToken, srcAmount, destAmount, recipient, data, _side) {
|
|
507
|
+
// Handle wrapper operations
|
|
508
|
+
if (data.swapType === 'wrapper') {
|
|
509
|
+
return this.getWrapperSwap(srcToken, destToken, srcAmount, destAmount, recipient, data);
|
|
510
|
+
}
|
|
511
|
+
if (data.swapType === 'direct') {
|
|
512
|
+
return this.getDirectTokenSwap(data.path[0].tokenIn, data.path[0].tokenOut, srcAmount, destAmount);
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
return this.getRouterSwap(srcAmount, destAmount, recipient, data);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
getDirectTokenSwap(srcToken, destToken, srcAmount, destAmount) {
|
|
519
|
+
const isSrcAVAX = (0, utils_1.isETHAddress)(srcToken);
|
|
520
|
+
const isDestAVAX = (0, utils_1.isETHAddress)(destToken);
|
|
521
|
+
let swapFunction;
|
|
522
|
+
let swapParams;
|
|
523
|
+
let targetExchange;
|
|
524
|
+
if (isSrcAVAX && !isDestAVAX) {
|
|
525
|
+
// AVAX → Token: call swapNativeToToken on the token
|
|
526
|
+
swapFunction = 'swapNativeToToken';
|
|
527
|
+
swapParams = [
|
|
528
|
+
destAmount, // minimumTokensOut
|
|
529
|
+
(0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline
|
|
530
|
+
];
|
|
531
|
+
targetExchange = destToken; // Call directly on the token
|
|
532
|
+
}
|
|
533
|
+
else if (!isSrcAVAX && isDestAVAX) {
|
|
534
|
+
// Token → AVAX: call swapTokenToNative on the token
|
|
535
|
+
swapFunction = 'swapTokenToNative';
|
|
536
|
+
swapParams = [
|
|
537
|
+
srcAmount, // tokensSold
|
|
538
|
+
destAmount, // minimumNativeOut
|
|
539
|
+
(0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline
|
|
540
|
+
];
|
|
541
|
+
targetExchange = srcToken; // Call directly on the token
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
throw new Error('Invalid direct swap pair');
|
|
545
|
+
}
|
|
546
|
+
const exchangeData = this.tokenIface.encodeFunctionData(swapFunction, swapParams);
|
|
547
|
+
return {
|
|
548
|
+
needWrapNative: false,
|
|
549
|
+
dexFuncHasRecipient: false,
|
|
550
|
+
exchangeData,
|
|
551
|
+
targetExchange,
|
|
552
|
+
returnAmountPos: undefined,
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
getRouterSwap(srcAmount, destAmount, recipient, data) {
|
|
556
|
+
const { path } = data;
|
|
557
|
+
// Convert native AVAX to WAVAX for router calls, but leave ERC20 tokens as-is
|
|
558
|
+
const routerPath = this.fixPathForRouter(path.map(p => p.tokenIn).concat(path[path.length - 1].tokenOut));
|
|
559
|
+
// Determine the correct swap function based on token types
|
|
560
|
+
const isSrcAVAX = (0, utils_1.isETHAddress)(path[0].tokenIn);
|
|
561
|
+
const isDestAVAX = (0, utils_1.isETHAddress)(path[path.length - 1].tokenOut);
|
|
562
|
+
let swapFunction;
|
|
563
|
+
let swapParams;
|
|
564
|
+
if (isSrcAVAX && !isDestAVAX) {
|
|
565
|
+
// AVAX -> Token
|
|
566
|
+
swapFunction = 'swapExactAVAXForTokens';
|
|
567
|
+
swapParams = [
|
|
568
|
+
destAmount, // Keep original amount - router handles decimal conversion
|
|
569
|
+
routerPath,
|
|
570
|
+
recipient,
|
|
571
|
+
(0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(),
|
|
572
|
+
];
|
|
573
|
+
}
|
|
574
|
+
else if (!isSrcAVAX && isDestAVAX) {
|
|
575
|
+
// Token -> AVAX
|
|
576
|
+
swapFunction = 'swapExactTokensForAVAX';
|
|
577
|
+
swapParams = [
|
|
578
|
+
srcAmount, // Keep original amount - router handles decimal conversion
|
|
579
|
+
destAmount,
|
|
580
|
+
routerPath,
|
|
581
|
+
recipient,
|
|
582
|
+
(0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(),
|
|
583
|
+
];
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
// Token -> Token (cross-pair via AVAX)
|
|
587
|
+
swapFunction = 'swapExactTokensForTokens';
|
|
588
|
+
swapParams = [
|
|
589
|
+
srcAmount, // Keep original amount - router handles decimal conversion
|
|
590
|
+
destAmount,
|
|
591
|
+
routerPath,
|
|
592
|
+
recipient,
|
|
593
|
+
(0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(),
|
|
594
|
+
];
|
|
595
|
+
}
|
|
596
|
+
const exchangeData = this.routerIface.encodeFunctionData(swapFunction, swapParams);
|
|
597
|
+
return {
|
|
598
|
+
needWrapNative: this.needWrapNative,
|
|
599
|
+
dexFuncHasRecipient: true,
|
|
600
|
+
exchangeData,
|
|
601
|
+
targetExchange: config_1.ApexDefiConfig[this.dexKey][this.network].routerAddress,
|
|
602
|
+
returnAmountPos: undefined,
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
// Encode params for simple swap (V5)
|
|
606
|
+
async getSimpleParam(srcToken, destToken, srcAmount, destAmount, data, _side) {
|
|
607
|
+
// Handle wrapper operations
|
|
608
|
+
if (data.swapType === 'wrapper') {
|
|
609
|
+
return this.getWrapperSimpleParam(srcToken, destToken, srcAmount, destAmount, data);
|
|
610
|
+
}
|
|
611
|
+
const { path } = data;
|
|
612
|
+
// Convert native AVAX to WAVAX for router calls
|
|
613
|
+
const routerPath = this.fixPathForRouter(path.map(p => p.tokenIn).concat(path[path.length - 1].tokenOut));
|
|
614
|
+
// Determine the swap function based on the token types
|
|
615
|
+
let swapFunction;
|
|
616
|
+
let swapParams;
|
|
617
|
+
const isSrcAVAX = (0, utils_1.isETHAddress)(srcToken);
|
|
618
|
+
const isDestAVAX = (0, utils_1.isETHAddress)(destToken);
|
|
619
|
+
const targetExchange = config_1.ApexDefiConfig[this.dexKey][this.network].routerAddress;
|
|
620
|
+
if (isSrcAVAX && !isDestAVAX) {
|
|
621
|
+
// AVAX -> Token
|
|
622
|
+
swapFunction = 'swapExactAVAXForTokens';
|
|
623
|
+
swapParams = [
|
|
624
|
+
destAmount,
|
|
625
|
+
routerPath, // Use converted path
|
|
626
|
+
targetExchange, // recipient - will be set by the router
|
|
627
|
+
(0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline: 7 days from now
|
|
628
|
+
];
|
|
629
|
+
}
|
|
630
|
+
else if (!isSrcAVAX && isDestAVAX) {
|
|
631
|
+
// Token -> AVAX
|
|
632
|
+
swapFunction = 'swapExactTokensForAVAX';
|
|
633
|
+
swapParams = [
|
|
634
|
+
srcAmount,
|
|
635
|
+
destAmount,
|
|
636
|
+
routerPath, // Use converted path
|
|
637
|
+
targetExchange, // recipient - will be set by the router
|
|
638
|
+
(0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline: 7 days from now
|
|
639
|
+
];
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
// Token -> Token
|
|
643
|
+
swapFunction = 'swapExactTokensForTokens';
|
|
644
|
+
swapParams = [
|
|
645
|
+
srcAmount,
|
|
646
|
+
destAmount,
|
|
647
|
+
routerPath, // Use converted path
|
|
648
|
+
targetExchange, // recipient - will be set by the router
|
|
649
|
+
(0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline: 7 days from now
|
|
650
|
+
];
|
|
651
|
+
}
|
|
652
|
+
const swapData = this.routerIface.encodeFunctionData(swapFunction, swapParams);
|
|
653
|
+
return this.buildSimpleParamWithoutWETHConversion(srcToken, srcAmount, destToken, destAmount, swapData, targetExchange, targetExchange, '0');
|
|
654
|
+
}
|
|
655
|
+
// Direct swap methods for V5
|
|
656
|
+
getDirectParam(_srcToken, _destToken, _srcAmount, _destAmount, _expectedAmount, _data, _side, _permit, _uuid, _feePercent, _deadline, _partner, _beneficiary, _contractMethod) {
|
|
657
|
+
// This method is not implemented for ApexDefi
|
|
658
|
+
throw new Error('Direct swaps not supported for ApexDefi');
|
|
659
|
+
}
|
|
660
|
+
// Direct swap methods for V6
|
|
661
|
+
getDirectParamV6(_srcToken, _destToken, _fromAmount, _toAmount, _quotedAmount, _data, _side, _permit, _uuid, _partnerAndFee, _beneficiary, _blockNumber, _contractMethod) {
|
|
662
|
+
// This method is not implemented for ApexDefi
|
|
663
|
+
throw new Error('Direct swaps not supported for ApexDefi');
|
|
664
|
+
}
|
|
665
|
+
// Static methods for direct function names
|
|
666
|
+
static getDirectFunctionName() {
|
|
667
|
+
// ApexDefi doesn't support direct swaps
|
|
668
|
+
return [];
|
|
669
|
+
}
|
|
670
|
+
static getDirectFunctionNameV6() {
|
|
671
|
+
// ApexDefi doesn't support direct swaps
|
|
672
|
+
return [];
|
|
673
|
+
}
|
|
674
|
+
// This is called once before getTopPoolsForToken is
|
|
675
|
+
// called for multiple tokens. This can be helpful to
|
|
676
|
+
// update common state required for calculating
|
|
677
|
+
// getTopPoolsForToken. It is optional for a DEX
|
|
678
|
+
// to implement this
|
|
679
|
+
async updatePoolState() {
|
|
680
|
+
// Update all existing pools to their latest state
|
|
681
|
+
const blockNumber = await this.dexHelper.web3Provider.eth.getBlockNumber();
|
|
682
|
+
const poolUpdatePromises = Object.values(this.eventPools).map(async (pool) => {
|
|
683
|
+
if (pool) {
|
|
684
|
+
try {
|
|
685
|
+
await pool.getStateOrGenerate(blockNumber);
|
|
686
|
+
}
|
|
687
|
+
catch (error) {
|
|
688
|
+
this.logger.error(`Error updating pool state for ${pool.poolAddress}:`, error);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
await Promise.all(poolUpdatePromises);
|
|
693
|
+
}
|
|
694
|
+
// Returns list of top pools based on liquidity. Max
|
|
695
|
+
// limit number pools should be returned.
|
|
696
|
+
async getTopPoolsForToken(tokenAddress, limit) {
|
|
697
|
+
try {
|
|
698
|
+
const blockNumber = await this.dexHelper.web3Provider.eth.getBlockNumber();
|
|
699
|
+
// Check if this token has a wrapper
|
|
700
|
+
const tokenInfo = this.getERC314Token(tokenAddress);
|
|
701
|
+
const hasWrapper = tokenInfo.address !== tokenAddress;
|
|
702
|
+
// Use the underlying ERC314 token for pool lookups
|
|
703
|
+
const tokenToCheck = hasWrapper ? tokenInfo.address : tokenAddress;
|
|
704
|
+
// Check if the input token is AVAX
|
|
705
|
+
const isAVAX = (0, utils_1.isETHAddress)(tokenToCheck);
|
|
706
|
+
if (isAVAX) {
|
|
707
|
+
// If asking for AVAX pools, return all tokens that have AVAX pairs
|
|
708
|
+
const tokenAddresses = await this.dexHelper.multiContract.methods
|
|
709
|
+
.aggregate([
|
|
710
|
+
{
|
|
711
|
+
target: config_1.ApexDefiConfig[this.dexKey][this.network].factoryAddress,
|
|
712
|
+
callData: this.factoryIface.encodeFunctionData('getAllTokens', []),
|
|
713
|
+
},
|
|
714
|
+
])
|
|
715
|
+
.call({}, blockNumber);
|
|
716
|
+
const tokens = this.factoryIface.decodeFunctionResult('getAllTokens', tokenAddresses.returnData[0])[0];
|
|
717
|
+
if (!tokens.length) {
|
|
718
|
+
return [];
|
|
719
|
+
}
|
|
720
|
+
// Get reserves for all tokens (limit to requested limit)
|
|
721
|
+
const reservesCallData = this.tokenIface.encodeFunctionData('getReserves', []);
|
|
722
|
+
const multiCall = tokens.map(token => ({
|
|
723
|
+
target: token,
|
|
724
|
+
callData: reservesCallData,
|
|
725
|
+
}));
|
|
726
|
+
const result = await this.dexHelper.multiContract.methods
|
|
727
|
+
.aggregate(multiCall)
|
|
728
|
+
.call({}, blockNumber);
|
|
729
|
+
const pools = [];
|
|
730
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
731
|
+
const token = tokens[i];
|
|
732
|
+
const reserves = this.tokenIface.decodeFunctionResult('getReserves', result.returnData[i]);
|
|
733
|
+
// If reserves are 0, skip this pool
|
|
734
|
+
if (reserves[0] === 0n && reserves[1] === 0n) {
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
// Calculate liquidity in USD using getTokenUSDPrice
|
|
738
|
+
const liquidityUSD = await this.dexHelper.getTokenUSDPrice({
|
|
739
|
+
address: this.dexHelper.config.data.wrappedNativeTokenAddress,
|
|
740
|
+
decimals: 18,
|
|
741
|
+
}, reserves[0]);
|
|
742
|
+
pools.push({
|
|
743
|
+
exchange: this.dexKey,
|
|
744
|
+
address: token.toLowerCase(),
|
|
745
|
+
poolIdentifier: this.getPoolIdentifier(token),
|
|
746
|
+
connectorTokens: [
|
|
747
|
+
{
|
|
748
|
+
address: this.dexHelper.config.data.wrappedNativeTokenAddress.toLowerCase(),
|
|
749
|
+
decimals: 18,
|
|
750
|
+
},
|
|
751
|
+
],
|
|
752
|
+
liquidityUSD,
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
// Sort by liquidity and return top pools
|
|
756
|
+
return pools
|
|
757
|
+
.sort((a, b) => b.liquidityUSD - a.liquidityUSD)
|
|
758
|
+
.slice(0, limit);
|
|
759
|
+
}
|
|
760
|
+
else {
|
|
761
|
+
// For non-AVAX tokens, check if they exist as a pool
|
|
762
|
+
const tokenInfo = await this.dexHelper.multiContract.methods
|
|
763
|
+
.aggregate([
|
|
764
|
+
{
|
|
765
|
+
target: config_1.ApexDefiConfig[this.dexKey][this.network].factoryAddress,
|
|
766
|
+
callData: this.factoryIface.encodeFunctionData('tokenInfoByTokenAddress', [tokenToCheck]),
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
target: tokenToCheck, // Use underlying token
|
|
770
|
+
callData: this.tokenIface.encodeFunctionData('getReserves', []),
|
|
771
|
+
},
|
|
772
|
+
])
|
|
773
|
+
.call({}, blockNumber);
|
|
774
|
+
// Decode token info
|
|
775
|
+
const tokenData = this.factoryIface.decodeFunctionResult('tokenInfoByTokenAddress', tokenInfo.returnData[0]);
|
|
776
|
+
// If name is empty, the token doesn't exist in the factory
|
|
777
|
+
if (!tokenData[0] || tokenData[0] === '') {
|
|
778
|
+
return [];
|
|
779
|
+
}
|
|
780
|
+
// Decode reserves
|
|
781
|
+
const reserves = this.tokenIface.decodeFunctionResult('getReserves', tokenInfo.returnData[1]);
|
|
782
|
+
// If reserves are 0, the pool has no liquidity
|
|
783
|
+
if (reserves[0] === 0n && reserves[1] === 0n) {
|
|
784
|
+
return [];
|
|
785
|
+
}
|
|
786
|
+
// Calculate liquidity in USD using getTokenUSDPrice
|
|
787
|
+
const liquidityUSD = await this.dexHelper.getTokenUSDPrice({
|
|
788
|
+
address: this.dexHelper.config.data.wrappedNativeTokenAddress,
|
|
789
|
+
decimals: 18,
|
|
790
|
+
}, reserves[0]);
|
|
791
|
+
return [
|
|
792
|
+
{
|
|
793
|
+
exchange: this.dexKey,
|
|
794
|
+
address: tokenAddress.toLowerCase(), // Return original token address
|
|
795
|
+
poolIdentifier: this.getPoolIdentifier(tokenToCheck), // Use underlying token for pool ID
|
|
796
|
+
connectorTokens: [
|
|
797
|
+
{
|
|
798
|
+
address: this.dexHelper.config.data.wrappedNativeTokenAddress.toLowerCase(),
|
|
799
|
+
decimals: 18,
|
|
800
|
+
},
|
|
801
|
+
],
|
|
802
|
+
liquidityUSD,
|
|
803
|
+
},
|
|
804
|
+
];
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
catch (error) {
|
|
808
|
+
// If the call fails, the token doesn't exist as a pool
|
|
809
|
+
this.logger.debug(`Token ${tokenAddress} is not a valid ApexDefi pool: ${error}`);
|
|
810
|
+
return [];
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
// Shared logic for pool discovery/creation
|
|
814
|
+
async fetchAndInitPool(pairAddress, blockNumber, poolKey) {
|
|
815
|
+
try {
|
|
816
|
+
const poolData = await (0, utils_2.fetchApexDefiOnChainPoolData)(pairAddress, this.network, blockNumber, this.dexHelper, this.tokenIface, this.factoryIface, this.logger);
|
|
817
|
+
// No pool data found, return null
|
|
818
|
+
if (!poolData) {
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
const eventPool = new apex_defi_pool_1.ApexDefiEventPool(this.dexKey, this.network, this.dexHelper, this.dexHelper.config.data.wrappedNativeTokenAddress, pairAddress, pairAddress, this.logger, poolData.factoryAddress);
|
|
822
|
+
await eventPool.initialize(blockNumber, {
|
|
823
|
+
state: {
|
|
824
|
+
reserve0: poolData.reserve0,
|
|
825
|
+
reserve1: poolData.reserve1,
|
|
826
|
+
baseSwapRate: poolData.baseSwapRate,
|
|
827
|
+
protocolFee: poolData.protocolFee,
|
|
828
|
+
lpFee: poolData.lpFee,
|
|
829
|
+
tradingFee: poolData.tradingFee,
|
|
830
|
+
isLegacy: poolData.isLegacy,
|
|
831
|
+
tradingEnabled: poolData.tradingEnabled,
|
|
832
|
+
},
|
|
833
|
+
});
|
|
834
|
+
this.eventPools[poolKey] = eventPool;
|
|
835
|
+
return eventPool;
|
|
836
|
+
}
|
|
837
|
+
catch (error) {
|
|
838
|
+
this.logger.error('Error fetching/initializing pool:', error);
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
releaseResources() {
|
|
843
|
+
// Clean up event pools
|
|
844
|
+
Object.values(this.eventPools).forEach(pool => {
|
|
845
|
+
if (pool) {
|
|
846
|
+
pool.releaseResources();
|
|
847
|
+
}
|
|
848
|
+
});
|
|
849
|
+
// Clear the pools map
|
|
850
|
+
Object.keys(this.eventPools).forEach(key => {
|
|
851
|
+
delete this.eventPools[key];
|
|
852
|
+
});
|
|
853
|
+
// Clear supported tokens map
|
|
854
|
+
Object.keys(this.supportedTokensMap).forEach(key => {
|
|
855
|
+
delete this.supportedTokensMap[key];
|
|
856
|
+
});
|
|
857
|
+
// Clean up factory if it has releaseResources
|
|
858
|
+
if (this.factory && this.factory.releaseResources) {
|
|
859
|
+
this.factory.releaseResources();
|
|
860
|
+
}
|
|
861
|
+
// Clean up wrapper factory
|
|
862
|
+
if (this.wrapperFactory && this.wrapperFactory.releaseResources) {
|
|
863
|
+
this.wrapperFactory.releaseResources();
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
_getLoweredAddresses(srcToken, destToken) {
|
|
867
|
+
return [srcToken.address.toLowerCase(), destToken.address.toLowerCase()];
|
|
868
|
+
}
|
|
869
|
+
fixPathForRouter(path) {
|
|
870
|
+
return path.map(token => {
|
|
871
|
+
// Only convert native AVAX to WAVAX for router calls
|
|
872
|
+
if (token.toLowerCase() === constants_1.ETHER_ADDRESS.toLowerCase()) {
|
|
873
|
+
return this.dexHelper.config.data.wrappedNativeTokenAddress;
|
|
874
|
+
}
|
|
875
|
+
// Leave all other tokens as-is (including ERC20 tokens like USDC)
|
|
876
|
+
return token;
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
// Helper method to get ERC314 token for pricing/pools
|
|
880
|
+
// Simplified getERC314Token method - always return ERC314 token for pricing
|
|
881
|
+
getERC314Token(tokenAddress) {
|
|
882
|
+
// if token is AVAX, return AVAX
|
|
883
|
+
if ((0, utils_1.isETHAddress)(tokenAddress)) {
|
|
884
|
+
return {
|
|
885
|
+
address: tokenAddress,
|
|
886
|
+
decimals: 18,
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
// PRIORITY 1: Check if this is an original token (ERC20) that has a wrapper
|
|
890
|
+
const wrapperAddress = this.wrapperFactory.getWrapperByOriginalToken(tokenAddress);
|
|
891
|
+
if (wrapperAddress) {
|
|
892
|
+
const wrapperInfo = this.wrapperFactory.getWrapperInfo(wrapperAddress);
|
|
893
|
+
if (wrapperInfo) {
|
|
894
|
+
return {
|
|
895
|
+
address: wrapperInfo.wrappedToken,
|
|
896
|
+
decimals: wrapperInfo.wrappedTokenDecimals,
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
// PRIORITY 2: No wrapper found - this is a native ERC314 token (like APEX)
|
|
901
|
+
return {
|
|
902
|
+
address: tokenAddress,
|
|
903
|
+
decimals: 18,
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
// 2. Add decimal conversion helper methods
|
|
907
|
+
convertAmountToERC314(amount, fromDecimals, toDecimals) {
|
|
908
|
+
if (fromDecimals === toDecimals)
|
|
909
|
+
return amount;
|
|
910
|
+
if (fromDecimals > toDecimals) {
|
|
911
|
+
return amount / 10n ** BigInt(fromDecimals - toDecimals);
|
|
912
|
+
}
|
|
913
|
+
else {
|
|
914
|
+
return amount * 10n ** BigInt(toDecimals - fromDecimals);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
convertAmountFromERC314(amount, fromDecimals, toDecimals) {
|
|
918
|
+
if (fromDecimals === toDecimals)
|
|
919
|
+
return amount;
|
|
920
|
+
if (fromDecimals > toDecimals) {
|
|
921
|
+
return amount / 10n ** BigInt(fromDecimals - toDecimals);
|
|
922
|
+
}
|
|
923
|
+
else {
|
|
924
|
+
return amount * 10n ** BigInt(toDecimals - fromDecimals);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
convertAmountsToERC314(amounts, fromDecimals) {
|
|
928
|
+
return amounts.map(amount => {
|
|
929
|
+
if (amount === 0n)
|
|
930
|
+
return 0n;
|
|
931
|
+
return this.convertAmountToERC314(amount, fromDecimals, 18);
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
convertPricesFromERC314(prices, toDecimals) {
|
|
935
|
+
return prices.map(price => {
|
|
936
|
+
if (price === 0n)
|
|
937
|
+
return 0n;
|
|
938
|
+
return this.convertAmountFromERC314(price, 18, toDecimals);
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
// Simplified wrapper detection using helper
|
|
942
|
+
isWrapperOperation(srcToken, destToken) {
|
|
943
|
+
return this.wrapperFactory.isWrapperOperation(srcToken.address, destToken.address);
|
|
944
|
+
}
|
|
945
|
+
// Fixed wrapper prices to handle both SELL and BUY operations
|
|
946
|
+
getWrapperPrices(srcToken, destToken, amounts, side) {
|
|
947
|
+
const wrapperPairInfo = this.wrapperFactory.getWrapperPairInfo(srcToken.address, destToken.address);
|
|
948
|
+
if (!wrapperPairInfo) {
|
|
949
|
+
return [];
|
|
950
|
+
}
|
|
951
|
+
const { wrapperAddress, isWrap } = wrapperPairInfo;
|
|
952
|
+
const prices = amounts.map(amount => {
|
|
953
|
+
if (amount === 0n)
|
|
954
|
+
return 0n;
|
|
955
|
+
const isSell = side === constants_1.SwapSide.SELL;
|
|
956
|
+
const fromDecimals = isSell ? srcToken.decimals : destToken.decimals;
|
|
957
|
+
const toDecimals = isSell ? destToken.decimals : srcToken.decimals;
|
|
958
|
+
// For SELL: convert input to output
|
|
959
|
+
// For BUY: convert desired output to required input
|
|
960
|
+
return isWrap
|
|
961
|
+
? this.convertAmountToERC314(amount, fromDecimals, toDecimals)
|
|
962
|
+
: this.convertAmountFromERC314(amount, fromDecimals, toDecimals);
|
|
963
|
+
});
|
|
964
|
+
const unit = (0, utils_1.getBigIntPow)(side === constants_1.SwapSide.SELL ? srcToken.decimals : destToken.decimals);
|
|
965
|
+
return [
|
|
966
|
+
{
|
|
967
|
+
prices,
|
|
968
|
+
unit,
|
|
969
|
+
data: {
|
|
970
|
+
path: [
|
|
971
|
+
{
|
|
972
|
+
tokenIn: srcToken.address.toLowerCase(),
|
|
973
|
+
tokenOut: destToken.address.toLowerCase(),
|
|
974
|
+
},
|
|
975
|
+
],
|
|
976
|
+
swapType: 'wrapper',
|
|
977
|
+
wrapperAddress,
|
|
978
|
+
isWrap,
|
|
979
|
+
},
|
|
980
|
+
exchange: this.dexKey,
|
|
981
|
+
poolIdentifiers: [
|
|
982
|
+
`${this.dexKey}_wrapper_${srcToken.address.toLowerCase()}`,
|
|
983
|
+
],
|
|
984
|
+
gasCost: 100000,
|
|
985
|
+
poolAddresses: [wrapperAddress],
|
|
986
|
+
},
|
|
987
|
+
];
|
|
988
|
+
}
|
|
989
|
+
// Simplified wrapper swap
|
|
990
|
+
getWrapperSwap(_srcToken, _destToken, srcAmount, _destAmount, _recipient, data) {
|
|
991
|
+
const { wrapperAddress, isWrap } = data;
|
|
992
|
+
if (!wrapperAddress)
|
|
993
|
+
throw new Error('Wrapper address not found');
|
|
994
|
+
if (isWrap === undefined)
|
|
995
|
+
throw new Error('isWrap not found in data');
|
|
996
|
+
const swapFunction = isWrap ? 'wrap' : 'unwrap';
|
|
997
|
+
const swapParams = [srcAmount];
|
|
998
|
+
const exchangeData = this.wrapperIface.encodeFunctionData(swapFunction, swapParams);
|
|
999
|
+
return {
|
|
1000
|
+
needWrapNative: false,
|
|
1001
|
+
dexFuncHasRecipient: false,
|
|
1002
|
+
exchangeData,
|
|
1003
|
+
targetExchange: wrapperAddress,
|
|
1004
|
+
returnAmountPos: undefined,
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
// Simplified wrapper simple param
|
|
1008
|
+
async getWrapperSimpleParam(srcToken, destToken, srcAmount, destAmount, data) {
|
|
1009
|
+
const { wrapperAddress, isWrap } = data;
|
|
1010
|
+
if (!wrapperAddress)
|
|
1011
|
+
throw new Error('Wrapper address not found');
|
|
1012
|
+
if (isWrap === undefined)
|
|
1013
|
+
throw new Error('isWrap not found in data');
|
|
1014
|
+
const swapFunction = isWrap ? 'wrap' : 'unwrap';
|
|
1015
|
+
const swapParams = [srcAmount];
|
|
1016
|
+
const swapData = this.wrapperIface.encodeFunctionData(swapFunction, swapParams);
|
|
1017
|
+
return this.buildSimpleParamWithoutWETHConversion(srcToken, srcAmount, destToken, destAmount, swapData, wrapperAddress, wrapperAddress, '0');
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
exports.ApexDefi = ApexDefi;
|
|
1021
|
+
//# sourceMappingURL=apex-defi.js.map
|