@dhedge/v2-sdk 2.1.8 → 2.2.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/README.md +400 -53
- package/dist/config.d.ts +13 -2
- package/dist/entities/pool.d.ts +25 -86
- package/dist/entities/utils.d.ts +15 -0
- package/dist/services/hyperliquid/index.d.ts +22 -0
- package/dist/services/kyberSwap/index.d.ts +1 -1
- package/dist/services/oneInch/index.d.ts +1 -1
- package/dist/services/toros/easySwapper.d.ts +14 -0
- package/dist/services/toros/swapData.d.ts +5 -5
- package/dist/services/uniswap/V3Liquidity.d.ts +2 -2
- package/dist/services/velodrome/liquidity.d.ts +3 -0
- package/dist/test/constants.d.ts +48 -3
- package/dist/test/utils/testingHelper.d.ts +4 -0
- package/dist/types.d.ts +19 -4
- package/dist/utils/contract.d.ts +20 -0
- package/dist/v2-sdk.cjs.development.js +4996 -6742
- package/dist/v2-sdk.cjs.development.js.map +1 -1
- package/dist/v2-sdk.cjs.production.min.js +1 -1
- package/dist/v2-sdk.cjs.production.min.js.map +1 -1
- package/dist/v2-sdk.esm.js +5001 -6742
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/abi/PoolFactory.json +414 -204
- package/src/abi/PoolLogic.json +160 -134
- package/src/config.ts +13 -8
- package/src/entities/pool.ts +46 -253
- package/src/entities/utils.ts +15 -0
- package/src/services/hyperliquid/index.ts +22 -0
- package/src/services/kyberSwap/index.ts +5 -3
- package/src/services/oneInch/index.ts +5 -4
- package/src/services/toros/completeWithdrawal.ts +57 -40
- package/src/services/toros/easySwapper.ts +15 -1
- package/src/services/toros/initWithdrawal.ts +39 -31
- package/src/services/toros/swapData.ts +45 -131
- package/src/services/uniswap/V3Liquidity.ts +3 -24
- package/src/services/velodrome/liquidity.ts +3 -0
- package/src/test/aave.test.ts +99 -70
- package/src/test/aerodrome.test.ts +53 -24
- package/src/test/aerodromeCL.test.ts +64 -30
- package/src/test/arrakis.test.ts +23 -35
- package/src/test/balancer.test.ts +114 -106
- package/src/test/compoundV3.test.ts +45 -29
- package/src/test/constants.ts +56 -11
- package/src/test/cowswap.test.ts +33 -35
- package/src/test/dhedge.test.ts +45 -12
- package/src/test/flatmoney.test.ts +25 -39
- package/src/test/fluid.test.ts +33 -24
- package/src/test/hyperliquid.onchain.test.ts +131 -0
- package/src/test/kyberSwap.test.ts +37 -16
- package/src/test/lyra.test.ts +159 -150
- package/src/test/odos.test.ts +2 -2
- package/src/test/oneInch.test.ts +36 -22
- package/src/test/pancakeCL.test.ts +72 -31
- package/src/test/pendle.test.ts +94 -54
- package/src/test/{pendleMint.test.ts → pendleMint.onchain.test.ts} +22 -8
- package/src/test/pool.test.ts +152 -95
- package/src/test/toros.onchain.test.ts +92 -0
- package/src/test/toros.test.ts +74 -20
- package/src/test/torosLimitOrder.test.ts +87 -42
- package/src/test/uniswap.test.ts +77 -128
- package/src/test/utils/testingHelper.ts +120 -0
- package/src/test/velodrome.test.ts +126 -92
- package/src/test/velodromeCL.test.ts +43 -31
- package/src/test/velodromeV2.test.ts +153 -95
- package/src/types.ts +20 -5
- package/src/utils/contract.ts +20 -0
- package/dist/services/futures/constants.d.ts +0 -1
- package/dist/services/futures/index.d.ts +0 -2
- package/dist/services/futures/margin.d.ts +0 -2
- package/dist/services/futures/trade.d.ts +0 -3
- package/dist/services/ramses/vesting.d.ts +0 -4
- package/dist/services/uniswap/V3Trade.d.ts +0 -3
- package/dist/test/utils/futures.d.ts +0 -2
- package/src/abi/IRamsesNonfungiblePositionManager.json +0 -486
- package/src/abi/ISynthetiXFuturesMarketV2.json +0 -531
- package/src/abi/ISynthetix.json +0 -139
- package/src/abi/IUniswapV3Quoter.json +0 -195
- package/src/abi/IUniswapV3Router.json +0 -221
- package/src/abi/IXRam.json +0 -99
- package/src/services/futures/constants.ts +0 -1
- package/src/services/futures/index.ts +0 -2
- package/src/services/futures/margin.ts +0 -10
- package/src/services/futures/trade.ts +0 -32
- package/src/services/ramses/vesting.ts +0 -24
- package/src/services/uniswap/V3Trade.ts +0 -46
- package/src/test/futures.test.ts +0 -51
- package/src/test/hyperliquid.test.ts +0 -107
- package/src/test/ramses.test.ts +0 -190
- package/src/test/ramsesCL.test.ts +0 -155
- package/src/test/synthetix.test.ts +0 -36
- package/src/test/utils/futures.ts +0 -14
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { Dapp, ethers, Pool } from "../..";
|
|
3
|
-
import {
|
|
3
|
+
import { routerAddress } from "../../config";
|
|
4
4
|
import IEasySwapperV2 from "../../abi/IEasySwapperV2.json";
|
|
5
5
|
import BigNumber from "bignumber.js";
|
|
6
6
|
import AssetHandlerAbi from "../../abi/AssetHandler.json";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
SLIPPAGE_FOR_LOW_VALUE_SWAP
|
|
11
11
|
} from "./easySwapper";
|
|
12
12
|
import { retry } from "./retry";
|
|
13
|
-
import {
|
|
13
|
+
import { getSwapData, ROUTER_KEYS } from "./swapData";
|
|
14
14
|
|
|
15
15
|
export interface TrackedAsset {
|
|
16
16
|
token: string;
|
|
@@ -19,46 +19,56 @@ export interface TrackedAsset {
|
|
|
19
19
|
|
|
20
20
|
const getSwapWithdrawData = async (
|
|
21
21
|
pool: Pool,
|
|
22
|
-
trackedAssets:
|
|
22
|
+
trackedAssets: {
|
|
23
|
+
token: string;
|
|
24
|
+
balance: ethers.BigNumber;
|
|
25
|
+
slippage: number;
|
|
26
|
+
}[],
|
|
23
27
|
receiveToken: string,
|
|
24
|
-
slippage: number,
|
|
25
28
|
swapDestMinDestAmount: BigNumber
|
|
26
29
|
) => {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
for (const routerKeyString of ROUTER_KEYS) {
|
|
31
|
+
try {
|
|
32
|
+
const srcData = [];
|
|
33
|
+
const routerKey = ethers.utils.formatBytes32String(routerKeyString);
|
|
34
|
+
for (const { token, balance, slippage } of trackedAssets) {
|
|
35
|
+
if (token.toLowerCase() === receiveToken.toLowerCase()) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const swapData = await retry({
|
|
39
|
+
fn: () => {
|
|
40
|
+
return getSwapData(
|
|
41
|
+
pool,
|
|
42
|
+
{
|
|
43
|
+
srcAsset: token,
|
|
44
|
+
srcAmount: balance.toString(),
|
|
45
|
+
dstAsset: receiveToken,
|
|
46
|
+
slippage
|
|
47
|
+
},
|
|
48
|
+
routerKeyString
|
|
49
|
+
);
|
|
50
|
+
},
|
|
51
|
+
delayMs: 1500,
|
|
52
|
+
maxRetries: 7
|
|
53
|
+
});
|
|
54
|
+
srcData.push({
|
|
55
|
+
token,
|
|
56
|
+
amount: balance,
|
|
57
|
+
aggregatorData: { routerKey, swapData }
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
srcData,
|
|
62
|
+
destData: {
|
|
63
|
+
destToken: receiveToken,
|
|
64
|
+
minDestAmount: swapDestMinDestAmount.toString()
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
} catch {
|
|
32
68
|
continue;
|
|
33
69
|
}
|
|
34
|
-
const swapData = await retry({
|
|
35
|
-
fn: () => {
|
|
36
|
-
return getSwapDataViaOdos({
|
|
37
|
-
srcAsset: token,
|
|
38
|
-
srcAmount: balance.toString(),
|
|
39
|
-
dstAsset: receiveToken,
|
|
40
|
-
chainId: networkChainIdMap[pool.network],
|
|
41
|
-
from: SWAPPER_ADDERSS,
|
|
42
|
-
receiver: SWAPPER_ADDERSS,
|
|
43
|
-
slippage
|
|
44
|
-
});
|
|
45
|
-
},
|
|
46
|
-
delayMs: 1500,
|
|
47
|
-
maxRetries: 7
|
|
48
|
-
});
|
|
49
|
-
srcData.push({
|
|
50
|
-
token,
|
|
51
|
-
amount: balance,
|
|
52
|
-
aggregatorData: { routerKey, swapData }
|
|
53
|
-
});
|
|
54
70
|
}
|
|
55
|
-
|
|
56
|
-
srcData,
|
|
57
|
-
destData: {
|
|
58
|
-
destToken: receiveToken,
|
|
59
|
-
minDestAmount: swapDestMinDestAmount.toString()
|
|
60
|
-
}
|
|
61
|
-
};
|
|
71
|
+
throw new Error("All swap routers failed for complete withdrawal");
|
|
62
72
|
};
|
|
63
73
|
export const createCompleteWithdrawalTxArguments = async (
|
|
64
74
|
pool: Pool,
|
|
@@ -138,12 +148,16 @@ export const createCompleteWithdrawalTxArguments = async (
|
|
|
138
148
|
.div(receiveTokenPriceD18)
|
|
139
149
|
.div(10 ** Number(swapTAssetDecimals.toString()))
|
|
140
150
|
.times(10 ** Number(receiveTokenDecimals.toString()))
|
|
141
|
-
|
|
151
|
+
// Outer floor stays strict on the user slippage — this is the
|
|
152
|
+
// withdrawer's safety check. Dust leniency applies only to the
|
|
153
|
+
// aggregator calldata below.
|
|
154
|
+
.times(1 - slippage / 10000) // slippage is in basis points, so divide by 10000
|
|
142
155
|
.decimalPlaces(0, BigNumber.ROUND_DOWN);
|
|
143
156
|
|
|
144
157
|
return {
|
|
145
158
|
token: swapTAsset.token,
|
|
146
159
|
balance: swapTAsset.balance,
|
|
160
|
+
slippage: adjustedSlippage,
|
|
147
161
|
estimatedMinReceiveAmount
|
|
148
162
|
};
|
|
149
163
|
})
|
|
@@ -167,10 +181,13 @@ export const createCompleteWithdrawalTxArguments = async (
|
|
|
167
181
|
|
|
168
182
|
const swapData = await getSwapWithdrawData(
|
|
169
183
|
pool,
|
|
170
|
-
|
|
184
|
+
tAssetInfos.map(({ token, balance, slippage }) => ({
|
|
185
|
+
token,
|
|
186
|
+
balance,
|
|
187
|
+
slippage
|
|
188
|
+
})),
|
|
171
189
|
receiveToken,
|
|
172
|
-
|
|
173
|
-
estimatedMinReceiveAmount
|
|
190
|
+
swapDestMinDestAmount
|
|
174
191
|
);
|
|
175
192
|
|
|
176
193
|
return {
|
|
@@ -8,9 +8,16 @@ import { isPool, loadPool } from "./pool";
|
|
|
8
8
|
|
|
9
9
|
import { getInitWithdrawalTxData } from "./initWithdrawal";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/** Minimum USD value of a leftover token to bother swapping during a withdrawal. */
|
|
12
|
+
export const LOW_USD_VALUE_FOR_WITHDRAWAL = 1;
|
|
13
|
+
/** Slippage (bps) applied to the swap of small-value leftover tokens during withdrawal. */
|
|
12
14
|
export const SLIPPAGE_FOR_LOW_VALUE_SWAP = 500;
|
|
13
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Resolve which asset should be used to deposit into a Toros pool. Returns the
|
|
18
|
+
* caller's `investAsset` if the pool already accepts it, otherwise the pool's
|
|
19
|
+
* primary deposit asset.
|
|
20
|
+
*/
|
|
14
21
|
export async function getPoolDepositAsset(
|
|
15
22
|
pool: Pool,
|
|
16
23
|
poolAddress: string,
|
|
@@ -26,6 +33,7 @@ export async function getPoolDepositAsset(
|
|
|
26
33
|
return composition.find(e => e.isDeposit)?.asset;
|
|
27
34
|
}
|
|
28
35
|
|
|
36
|
+
/** Read the current per-token price of a Toros vault from its PoolLogic. */
|
|
29
37
|
export async function getTorosPoolTokenPrice(
|
|
30
38
|
pool: Pool,
|
|
31
39
|
poolAddress: string
|
|
@@ -34,6 +42,7 @@ export async function getTorosPoolTokenPrice(
|
|
|
34
42
|
return await torosPool.poolLogic.tokenPrice();
|
|
35
43
|
}
|
|
36
44
|
|
|
45
|
+
/** Quote how many Toros vault tokens a deposit of `investAsset` would mint. */
|
|
37
46
|
export async function getEasySwapperDepositQuote(
|
|
38
47
|
pool: Pool,
|
|
39
48
|
torosAsset: string,
|
|
@@ -49,6 +58,11 @@ export async function getEasySwapperDepositQuote(
|
|
|
49
58
|
return await easySwapper.depositQuote(torosAsset, investAsset, amountIn);
|
|
50
59
|
}
|
|
51
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Build the EasySwapper calldata for a Toros deposit or the start of a withdrawal.
|
|
63
|
+
* If `assetFrom` is a Toros pool, this is treated as a withdrawal and routes through
|
|
64
|
+
* `getInitWithdrawalTxData`. Otherwise it builds a `depositWithCustomCooldown` call.
|
|
65
|
+
*/
|
|
52
66
|
export async function getEasySwapperTxData(
|
|
53
67
|
pool: Pool,
|
|
54
68
|
assetFrom: string,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { Dapp, ethers, Pool } from "../..";
|
|
3
|
-
import {
|
|
3
|
+
import { routerAddress } from "../../config";
|
|
4
4
|
import { retry } from "./retry";
|
|
5
5
|
import AaveLendingPoolAssetGuardAbi from "../../abi/IAaveLendingPoolAssetGuard.json";
|
|
6
6
|
import IEasySwapperV2 from "../../abi/IEasySwapperV2.json";
|
|
7
7
|
import { loadPool } from "./pool";
|
|
8
|
-
import {
|
|
8
|
+
import { getSwapData, ROUTER_KEYS } from "./swapData";
|
|
9
9
|
const AAVE_WITHDRAW_ONCHAIN_SWAP_SLIPPAGE = 150; // 1.5% slippage for onchain swap in Aave withdrawal
|
|
10
10
|
|
|
11
11
|
const getCalculateSwapDataParams = async (
|
|
@@ -45,38 +45,46 @@ const getAaveAssetWithdrawData = async (
|
|
|
45
45
|
) => {
|
|
46
46
|
const { srcData, dstData } = swapDataParams;
|
|
47
47
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
48
|
+
for (const routerKeyString of ROUTER_KEYS) {
|
|
49
|
+
try {
|
|
50
|
+
const srcDataToEncode: unknown[] = [];
|
|
51
|
+
const routerKey = ethers.utils.formatBytes32String(routerKeyString);
|
|
52
|
+
for (const { asset, amount } of srcData) {
|
|
53
|
+
const swapData = await retry({
|
|
54
|
+
fn: () => {
|
|
55
|
+
return getSwapData(
|
|
56
|
+
pool,
|
|
57
|
+
{
|
|
58
|
+
srcAsset: asset,
|
|
59
|
+
srcAmount: amount.toString(),
|
|
60
|
+
dstAsset: dstData.asset,
|
|
61
|
+
slippage
|
|
62
|
+
},
|
|
63
|
+
routerKeyString
|
|
64
|
+
);
|
|
65
|
+
},
|
|
66
|
+
delayMs: 1500,
|
|
67
|
+
maxRetries: 7
|
|
61
68
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
});
|
|
66
|
-
srcDataToEncode.push([asset, amount, [routerKey, swapData]]);
|
|
67
|
-
}
|
|
68
|
-
const coder = ethers.utils.defaultAbiCoder;
|
|
69
|
+
srcDataToEncode.push([asset, amount, [routerKey, swapData]]);
|
|
70
|
+
}
|
|
71
|
+
const coder = ethers.utils.defaultAbiCoder;
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
const encodedSrcData = coder.encode(
|
|
74
|
+
["tuple(address, uint256, tuple(bytes32, bytes))[]"],
|
|
75
|
+
[srcDataToEncode]
|
|
76
|
+
);
|
|
77
|
+
const withdrawData = coder.encode(
|
|
78
|
+
["tuple(bytes, tuple(address, uint256), uint256)"],
|
|
79
|
+
[[encodedSrcData, [dstData.asset, dstData.amount], slippage]]
|
|
80
|
+
);
|
|
78
81
|
|
|
79
|
-
|
|
82
|
+
return withdrawData;
|
|
83
|
+
} catch {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
throw new Error("All swap routers failed for init withdrawal");
|
|
80
88
|
};
|
|
81
89
|
|
|
82
90
|
export const createWithdrawTxArguments = async (
|
|
@@ -1,141 +1,55 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
1
|
import BigNumber from "bignumber.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import OdosRouterV3Abi from "../../abi/odos/OdosRouterV3.json";
|
|
2
|
+
import { Pool } from "../..";
|
|
3
|
+
import { getKyberSwapTxData } from "../kyberSwap";
|
|
4
|
+
import { getOneInchSwapTxData } from "../oneInch";
|
|
7
5
|
|
|
8
|
-
export const
|
|
6
|
+
export const SWAPPER_ADDRESS = "0x4F754e0F0924afD74980886b0B479Fa1D7C58D0D";
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
dstAsset: string; // Destination asset address
|
|
14
|
-
chainId: number; // Chain ID
|
|
15
|
-
from: string; // Sender address
|
|
16
|
-
receiver: string; // Receiver address
|
|
17
|
-
slippage: number; // Slippage tolerance in basis points (100 = 1%)
|
|
18
|
-
}
|
|
8
|
+
// Order matters: routers are tried in sequence by init/completeWithdrawal.
|
|
9
|
+
// KyberSwap is the primary route; 1inch is the fallback.
|
|
10
|
+
export const ROUTER_KEYS = ["KYBER_SWAP_V2", "ONE_INCH"] as const;
|
|
19
11
|
|
|
20
|
-
export
|
|
21
|
-
srcAsset,
|
|
22
|
-
srcAmount,
|
|
23
|
-
dstAsset,
|
|
24
|
-
chainId,
|
|
25
|
-
from,
|
|
26
|
-
slippage
|
|
27
|
-
}: SwapParams): Promise<string> => {
|
|
28
|
-
if (!process.env.ODOS_API_KEY) {
|
|
29
|
-
throw new Error("ODOS_API_KEY is not set");
|
|
30
|
-
}
|
|
31
|
-
const ODOS_API_KEY = process.env.ODOS_API_KEY;
|
|
32
|
-
const network = (Object.keys(networkChainIdMap) as Array<
|
|
33
|
-
keyof typeof networkChainIdMap
|
|
34
|
-
>).find(key => networkChainIdMap[key] === chainId);
|
|
35
|
-
if (!network) {
|
|
36
|
-
throw new Error(`Unsupported chainId: ${chainId}`);
|
|
37
|
-
}
|
|
12
|
+
export type RouterKey = typeof ROUTER_KEYS[number];
|
|
38
13
|
|
|
39
|
-
|
|
14
|
+
export interface SwapParams {
|
|
15
|
+
srcAsset: string;
|
|
16
|
+
srcAmount: string;
|
|
17
|
+
dstAsset: string;
|
|
18
|
+
slippage: number; // in basis points (100 = 1%)
|
|
19
|
+
}
|
|
40
20
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
compact: false
|
|
60
|
-
};
|
|
61
|
-
try {
|
|
62
|
-
const quoteResult = await axios.post(
|
|
63
|
-
`${odosBaseUrl}/quote/v3`,
|
|
64
|
-
quoteParams,
|
|
65
|
-
{
|
|
66
|
-
headers: {
|
|
67
|
-
"Content-Type": "application/json",
|
|
68
|
-
"x-api-key": ODOS_API_KEY
|
|
69
|
-
}
|
|
70
|
-
}
|
|
21
|
+
export const getSwapData = async (
|
|
22
|
+
pool: Pool,
|
|
23
|
+
params: SwapParams,
|
|
24
|
+
routerKeyString: RouterKey
|
|
25
|
+
): Promise<string> => {
|
|
26
|
+
const { srcAsset, srcAmount, dstAsset, slippage } = params;
|
|
27
|
+
// Convert basis points to percentage for aggregator APIs
|
|
28
|
+
const slippagePercent = new BigNumber(slippage).div(100).toNumber();
|
|
29
|
+
|
|
30
|
+
if (routerKeyString === "KYBER_SWAP_V2") {
|
|
31
|
+
const { swapTxData } = await getKyberSwapTxData(
|
|
32
|
+
pool,
|
|
33
|
+
srcAsset,
|
|
34
|
+
dstAsset,
|
|
35
|
+
srcAmount,
|
|
36
|
+
slippagePercent,
|
|
37
|
+
SWAPPER_ADDRESS,
|
|
38
|
+
SWAPPER_ADDRESS
|
|
71
39
|
);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
headers: {
|
|
83
|
-
"Content-Type": "application/json",
|
|
84
|
-
"x-api-key": ODOS_API_KEY
|
|
85
|
-
}
|
|
86
|
-
}
|
|
40
|
+
return swapTxData;
|
|
41
|
+
} else if (routerKeyString === "ONE_INCH") {
|
|
42
|
+
const { swapTxData } = await getOneInchSwapTxData(
|
|
43
|
+
pool,
|
|
44
|
+
srcAsset,
|
|
45
|
+
dstAsset,
|
|
46
|
+
srcAmount,
|
|
47
|
+
slippagePercent,
|
|
48
|
+
SWAPPER_ADDRESS,
|
|
49
|
+
SWAPPER_ADDRESS
|
|
87
50
|
);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// Decode the transaction data
|
|
92
|
-
const iface = new ethers.utils.Interface(OdosRouterV3Abi.abi);
|
|
93
|
-
const decodedData = iface.parseTransaction({ data: txData });
|
|
94
|
-
|
|
95
|
-
const tokenInfo = decodedData.args[0] as SwapTokenInfo;
|
|
96
|
-
const pathDefinition = decodedData.args[1] as string;
|
|
97
|
-
const executor = decodedData.args[2] as string;
|
|
98
|
-
const referralInfo = decodedData.args[3] as SwapReferralInfo;
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
referralInfo.fee.lte(
|
|
102
|
-
ethers.BigNumber.from((referralFeeBips * 1e18) / 10000)
|
|
103
|
-
)
|
|
104
|
-
) {
|
|
105
|
-
// Referral fee is already correct, return original txData
|
|
106
|
-
return txData;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const FEE_DENOM = new BigNumber(1e18);
|
|
110
|
-
const correctedFee = new BigNumber((referralFeeBips * 1e18) / 10000);
|
|
111
|
-
const factor = 1.1;
|
|
112
|
-
const correctedOutputQuote = new BigNumber(tokenInfo.outputQuote.toString())
|
|
113
|
-
.times(
|
|
114
|
-
FEE_DENOM.minus(correctedFee).div(
|
|
115
|
-
FEE_DENOM.minus(referralInfo.fee.toString())
|
|
116
|
-
)
|
|
117
|
-
)
|
|
118
|
-
.times(factor);
|
|
119
|
-
|
|
120
|
-
// example referralInfo.fee could be 0.0005 * 1e18 = 500000000000000, which is 0.05%
|
|
121
|
-
// Create corrected referral info
|
|
122
|
-
const correctedTxData = iface.encodeFunctionData(decodedData.name, [
|
|
123
|
-
{
|
|
124
|
-
...tokenInfo,
|
|
125
|
-
outputQuote: correctedOutputQuote.toFixed(0)
|
|
126
|
-
},
|
|
127
|
-
pathDefinition,
|
|
128
|
-
executor,
|
|
129
|
-
{
|
|
130
|
-
code: referralInfo.code,
|
|
131
|
-
fee: correctedFee.toFixed(0), // align with referralFeeBips
|
|
132
|
-
feeRecipient: referralInfo.feeRecipient
|
|
133
|
-
}
|
|
134
|
-
]);
|
|
135
|
-
|
|
136
|
-
return correctedTxData;
|
|
137
|
-
} catch (e) {
|
|
138
|
-
console.error("Error in Odos API request:", e);
|
|
139
|
-
throw new Error("Swap api request of Odos failed");
|
|
51
|
+
return swapTxData;
|
|
52
|
+
} else {
|
|
53
|
+
throw new Error(`Unsupported router: ${routerKeyString}`);
|
|
140
54
|
}
|
|
141
55
|
};
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "../../config";
|
|
20
20
|
import INonfungiblePositionManager from "../../abi/INonfungiblePositionManager.json";
|
|
21
21
|
import IVeldodromePositionManager from "../../abi/IVelodromeNonfungiblePositionManager.json";
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
import IArrakisV1RouterStaking from "../../abi/IArrakisV1RouterStaking.json";
|
|
24
24
|
import IPancakeMasterChef from "../../abi/IPancakeMasterChefV3.json";
|
|
25
25
|
import { getDeadline } from "../../utils/deadline";
|
|
@@ -72,12 +72,7 @@ export function tryParseTick(
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
export async function getUniswapV3MintTxData(
|
|
75
|
-
dapp:
|
|
76
|
-
| Dapp.UNISWAPV3
|
|
77
|
-
| Dapp.VELODROMECL
|
|
78
|
-
| Dapp.AERODROMECL
|
|
79
|
-
| Dapp.RAMSESCL
|
|
80
|
-
| Dapp.PANCAKECL,
|
|
75
|
+
dapp: Dapp.UNISWAPV3 | Dapp.VELODROMECL | Dapp.AERODROMECL | Dapp.PANCAKECL,
|
|
81
76
|
|
|
82
77
|
pool: Pool,
|
|
83
78
|
assetA: string,
|
|
@@ -162,27 +157,13 @@ export async function getUniswapV3MintTxData(
|
|
|
162
157
|
mintParams.push(0);
|
|
163
158
|
}
|
|
164
159
|
|
|
165
|
-
if (dapp === Dapp.RAMSESCL) {
|
|
166
|
-
iNonfungiblePositionManager = new ethers.utils.Interface(
|
|
167
|
-
IRamsesPositionManager
|
|
168
|
-
);
|
|
169
|
-
mintParams.push(0);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
160
|
return iNonfungiblePositionManager.encodeFunctionData(Transaction.MINT, [
|
|
173
161
|
mintParams
|
|
174
162
|
]);
|
|
175
|
-
|
|
176
|
-
return;
|
|
177
163
|
}
|
|
178
164
|
|
|
179
165
|
export async function getUniswapV3Liquidity(
|
|
180
|
-
dapp:
|
|
181
|
-
| Dapp.UNISWAPV3
|
|
182
|
-
| Dapp.VELODROMECL
|
|
183
|
-
| Dapp.AERODROMECL
|
|
184
|
-
| Dapp.RAMSESCL
|
|
185
|
-
| Dapp,
|
|
166
|
+
dapp: Dapp,
|
|
186
167
|
tokenId: string,
|
|
187
168
|
pool: Pool
|
|
188
169
|
): Promise<BigNumber> {
|
|
@@ -208,7 +189,6 @@ export async function getIncreaseLiquidityTxData(
|
|
|
208
189
|
dapp === Dapp.UNISWAPV3 ||
|
|
209
190
|
dapp === Dapp.VELODROMECL ||
|
|
210
191
|
dapp === Dapp.AERODROMECL ||
|
|
211
|
-
dapp === Dapp.RAMSESCL ||
|
|
212
192
|
dapp === Dapp.PANCAKECL
|
|
213
193
|
) {
|
|
214
194
|
const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
|
|
@@ -245,7 +225,6 @@ export async function getDecreaseLiquidityTxData(
|
|
|
245
225
|
dapp === Dapp.UNISWAPV3 ||
|
|
246
226
|
dapp === Dapp.VELODROMECL ||
|
|
247
227
|
dapp === Dapp.AERODROMECL ||
|
|
248
|
-
dapp === Dapp.RAMSESCL ||
|
|
249
228
|
dapp === Dapp.PANCAKECL
|
|
250
229
|
) {
|
|
251
230
|
const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
|
|
@@ -7,6 +7,7 @@ import { getDeadline } from "../../utils/deadline";
|
|
|
7
7
|
import { nonfungiblePositionManagerAddress } from "../../config";
|
|
8
8
|
import INonfungiblePositionManager from "../../abi/INonfungiblePositionManager.json";
|
|
9
9
|
|
|
10
|
+
/** Encode Velodrome router calldata to add liquidity to a stable or volatile pair. */
|
|
10
11
|
export async function getVelodromeAddLiquidityTxData(
|
|
11
12
|
pool: Pool,
|
|
12
13
|
assetA: string,
|
|
@@ -29,6 +30,7 @@ export async function getVelodromeAddLiquidityTxData(
|
|
|
29
30
|
]);
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
/** Encode Velodrome router calldata to remove liquidity from a stable or volatile pair. */
|
|
32
34
|
export async function getVelodromeRemoveLiquidityTxData(
|
|
33
35
|
pool: Pool,
|
|
34
36
|
assetA: string,
|
|
@@ -49,6 +51,7 @@ export async function getVelodromeRemoveLiquidityTxData(
|
|
|
49
51
|
]);
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
/** Read the current owner of a Velodrome/Aerodrome/Pancake CL position NFT. */
|
|
52
55
|
export async function getClOwner(
|
|
53
56
|
pool: Pool,
|
|
54
57
|
dapp: Dapp.VELODROMECL | Dapp.AERODROMECL | Dapp.PANCAKECL,
|