@dhedge/v2-sdk 2.1.7 → 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 +14 -2
- package/dist/entities/pool.d.ts +25 -86
- package/dist/entities/utils.d.ts +15 -0
- package/dist/services/cowSwap/index.d.ts +10 -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 +21 -5
- package/dist/utils/contract.d.ts +20 -0
- package/dist/v2-sdk.cjs.development.js +5193 -6711
- 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 +5198 -6711
- 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 +19 -9
- package/src/entities/pool.ts +103 -254
- package/src/entities/utils.ts +15 -0
- package/src/services/cowSwap/index.ts +281 -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 +57 -12
- package/src/test/cowswap.test.ts +79 -0
- 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 +22 -6
- 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,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,
|
package/src/test/aave.test.ts
CHANGED
|
@@ -1,87 +1,116 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
import BigNumber from "bignumber.js";
|
|
2
3
|
import { Dhedge, Pool } from "..";
|
|
3
4
|
import { routerAddress } from "../config";
|
|
4
5
|
import { Dapp, Network } from "../types";
|
|
5
|
-
import { CONTRACT_ADDRESS, MAX_AMOUNT
|
|
6
|
+
import { CONTRACT_ADDRESS, MAX_AMOUNT } from "./constants";
|
|
7
|
+
import {
|
|
8
|
+
TestingRunParams,
|
|
9
|
+
fixOracleAggregatorStaleness,
|
|
10
|
+
setChainlinkTimeout,
|
|
11
|
+
setUSDCAmount,
|
|
12
|
+
testingHelper
|
|
13
|
+
} from "./utils/testingHelper";
|
|
6
14
|
import { allowanceDelta, balanceDelta } from "./utils/token";
|
|
7
15
|
|
|
8
|
-
|
|
16
|
+
const testAave = ({ wallet, network, provider }: TestingRunParams) => {
|
|
17
|
+
const USDC = CONTRACT_ADDRESS[network].USDC;
|
|
18
|
+
const WBTC = CONTRACT_ADDRESS[network].WBTC;
|
|
9
19
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const USDC = CONTRACT_ADDRESS[network].USDC;
|
|
14
|
-
const WETH = CONTRACT_ADDRESS[network].WETH;
|
|
20
|
+
let dhedge: Dhedge;
|
|
21
|
+
let pool: Pool;
|
|
22
|
+
jest.setTimeout(100000);
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
24
|
+
describe(`[${network}] aave v3 tests`, () => {
|
|
25
|
+
beforeAll(async () => {
|
|
26
|
+
await provider.send("hardhat_setBalance", [
|
|
27
|
+
wallet.address,
|
|
28
|
+
"0x10000000000000000"
|
|
29
|
+
]);
|
|
30
|
+
dhedge = new Dhedge(wallet, network);
|
|
19
31
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
pool = await dhedge.createPool("Test Manager", "Aave Test", "AT", [
|
|
33
|
+
[USDC, true],
|
|
34
|
+
[WBTC, false],
|
|
35
|
+
[routerAddress[network][Dapp.AAVEV3]!, false]
|
|
36
|
+
]);
|
|
25
37
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const usdcAllowanceDelta = await allowanceDelta(
|
|
29
|
-
pool.address,
|
|
30
|
-
USDC,
|
|
31
|
-
routerAddress[network]["aavev3"]!,
|
|
32
|
-
pool.signer
|
|
33
|
-
);
|
|
34
|
-
await expect(usdcAllowanceDelta.gt(0));
|
|
35
|
-
});
|
|
38
|
+
await setChainlinkTimeout({ pool, provider }, 86400 * 365);
|
|
39
|
+
await fixOracleAggregatorStaleness({ pool, provider });
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
);
|
|
45
|
-
await expect(wethAllowanceDelta.gt(0));
|
|
46
|
-
});
|
|
41
|
+
await setUSDCAmount({
|
|
42
|
+
amount: new BigNumber(1000).times(1e6).toFixed(0),
|
|
43
|
+
userAddress: pool.address,
|
|
44
|
+
network,
|
|
45
|
+
provider
|
|
46
|
+
});
|
|
47
|
+
});
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
it("approves unlimited USDC on Aave Lending pool", async () => {
|
|
50
|
+
await pool.approve(Dapp.AAVEV3, USDC, MAX_AMOUNT);
|
|
51
|
+
const usdcAllowanceDelta = await allowanceDelta(
|
|
52
|
+
pool.address,
|
|
53
|
+
USDC,
|
|
54
|
+
routerAddress[network][Dapp.AAVEV3]!,
|
|
55
|
+
pool.signer
|
|
56
|
+
);
|
|
57
|
+
expect(usdcAllowanceDelta.gt(0)).toBe(true);
|
|
58
|
+
});
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
it("approves unlimited WBTC on Aave Lending pool", async () => {
|
|
61
|
+
await pool.approve(Dapp.AAVEV3, WBTC, MAX_AMOUNT);
|
|
62
|
+
const wbtcAllowanceDelta = await allowanceDelta(
|
|
63
|
+
pool.address,
|
|
64
|
+
WBTC,
|
|
65
|
+
routerAddress[network][Dapp.AAVEV3]!,
|
|
66
|
+
pool.signer
|
|
67
|
+
);
|
|
68
|
+
expect(wbtcAllowanceDelta.gt(0)).toBe(true);
|
|
69
|
+
});
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
it("lends 500 USDC into Aave lending pool", async () => {
|
|
72
|
+
await pool.lend(Dapp.AAVEV3, USDC, "500000000");
|
|
73
|
+
const usdcBalanceDelta = await balanceDelta(
|
|
74
|
+
pool.address,
|
|
75
|
+
USDC,
|
|
76
|
+
pool.signer
|
|
77
|
+
);
|
|
78
|
+
expect(usdcBalanceDelta.eq("-500000000")).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("borrows 0.0001 WBTC from Aave lending pool", async () => {
|
|
82
|
+
await pool.borrow(Dapp.AAVEV3, WBTC, "10000");
|
|
83
|
+
const wbtcBalanceDelta = await balanceDelta(
|
|
84
|
+
pool.address,
|
|
85
|
+
WBTC,
|
|
86
|
+
pool.signer
|
|
87
|
+
);
|
|
88
|
+
expect(wbtcBalanceDelta.eq("10000")).toBe(true);
|
|
89
|
+
});
|
|
77
90
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
it("repays 0.0001 WBTC to Aave lending pool", async () => {
|
|
92
|
+
await pool.repay(Dapp.AAVEV3, WBTC, "10000");
|
|
93
|
+
const wbtcBalanceDelta = await balanceDelta(
|
|
94
|
+
pool.address,
|
|
95
|
+
WBTC,
|
|
96
|
+
pool.signer
|
|
97
|
+
);
|
|
98
|
+
expect(wbtcBalanceDelta.eq("-10000")).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("withdraws 400 USDC from Aave lending pool", async () => {
|
|
102
|
+
await pool.withdrawDeposit(Dapp.AAVEV3, USDC, "400000000");
|
|
103
|
+
const usdcBalanceDelta = await balanceDelta(
|
|
104
|
+
pool.address,
|
|
105
|
+
USDC,
|
|
106
|
+
pool.signer
|
|
107
|
+
);
|
|
108
|
+
expect(usdcBalanceDelta.eq("400000000")).toBe(true);
|
|
109
|
+
});
|
|
86
110
|
});
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
testingHelper({
|
|
114
|
+
network: Network.ARBITRUM,
|
|
115
|
+
testingRun: testAave
|
|
87
116
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
3
|
import BigNumber from "bignumber.js";
|
|
4
|
-
import { Dhedge, Pool } from "..";
|
|
4
|
+
import { Dhedge, ethers, Pool } from "..";
|
|
5
5
|
import { routerAddress } from "../config";
|
|
6
6
|
import { Dapp, Network } from "../types";
|
|
7
7
|
import { CONTRACT_ADDRESS, MAX_AMOUNT, TEST_POOL } from "./constants";
|
|
@@ -9,12 +9,13 @@ import {
|
|
|
9
9
|
TestingRunParams,
|
|
10
10
|
beforeAfterReset,
|
|
11
11
|
setUSDCAmount,
|
|
12
|
+
setWETHAmount,
|
|
13
|
+
runWithImpersonateAccount,
|
|
12
14
|
testingHelper
|
|
13
15
|
} from "./utils/testingHelper";
|
|
14
16
|
import { allowanceDelta, balanceDelta } from "./utils/token";
|
|
15
|
-
import { getWalletData } from "./wallet";
|
|
16
17
|
|
|
17
|
-
const testAerodrome = ({ network, provider }: TestingRunParams) => {
|
|
18
|
+
const testAerodrome = ({ wallet, network, provider }: TestingRunParams) => {
|
|
18
19
|
const WETH_USDC_Lp = "0xcDAC0d6c6C59727a65F871236188350531885C43";
|
|
19
20
|
const WETH_USDC__Gauge = "0x519BBD1Dd8C6A94C46080E24f316c14Ee758C025";
|
|
20
21
|
|
|
@@ -28,38 +29,66 @@ const testAerodrome = ({ network, provider }: TestingRunParams) => {
|
|
|
28
29
|
|
|
29
30
|
describe(`[${network}] aerodrome tests`, () => {
|
|
30
31
|
beforeAll(async () => {
|
|
31
|
-
const { wallet } = getWalletData(network);
|
|
32
32
|
// top up ETH (gas)
|
|
33
33
|
await provider.send("hardhat_setBalance", [
|
|
34
34
|
wallet.address,
|
|
35
|
-
"
|
|
35
|
+
"0x10000000000000000"
|
|
36
36
|
]);
|
|
37
37
|
dhedge = new Dhedge(wallet, network);
|
|
38
38
|
pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
39
|
+
|
|
40
|
+
// Fund pool with USDC and WETH
|
|
39
41
|
await setUSDCAmount({
|
|
40
|
-
amount: new BigNumber(
|
|
42
|
+
amount: new BigNumber(10000).times(1e6).toFixed(0),
|
|
43
|
+
userAddress: pool.address,
|
|
44
|
+
network,
|
|
45
|
+
provider
|
|
46
|
+
});
|
|
47
|
+
await setWETHAmount({
|
|
48
|
+
amount: new BigNumber(5).times(1e18).toFixed(0),
|
|
41
49
|
userAddress: pool.address,
|
|
42
50
|
network,
|
|
43
51
|
provider
|
|
44
52
|
});
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
|
|
54
|
+
// Impersonate the pool manager to set trader and configure assets
|
|
55
|
+
await runWithImpersonateAccount(
|
|
56
|
+
{ provider, account: await pool.managerLogic.manager() },
|
|
57
|
+
async ({ signer }) => {
|
|
58
|
+
await pool.managerLogic.connect(signer).setTrader(wallet.address);
|
|
59
|
+
const newAssets = [
|
|
60
|
+
[USDC, true],
|
|
61
|
+
[WETH, true],
|
|
62
|
+
[WETH_USDC_Lp, false],
|
|
63
|
+
[AERO, false]
|
|
64
|
+
];
|
|
65
|
+
await pool.managerLogic.connect(signer).changeAssets(newAssets, []);
|
|
66
|
+
}
|
|
67
|
+
);
|
|
47
68
|
});
|
|
48
69
|
beforeAfterReset({ beforeAll, afterAll, provider });
|
|
49
70
|
|
|
50
|
-
it("approves unlimited USDC and
|
|
71
|
+
it("approves unlimited USDC and WETH for Aerodrome", async () => {
|
|
51
72
|
await pool.approve(Dapp.AERODROME, USDC, MAX_AMOUNT);
|
|
52
73
|
await pool.approve(Dapp.AERODROME, WETH, MAX_AMOUNT);
|
|
53
|
-
const
|
|
54
|
-
|
|
74
|
+
const allowanceAbi = [
|
|
75
|
+
"function allowance(address,address) view returns (uint256)"
|
|
76
|
+
];
|
|
77
|
+
const usdcAllowance = await new ethers.Contract(
|
|
55
78
|
USDC,
|
|
56
|
-
|
|
79
|
+
allowanceAbi,
|
|
57
80
|
pool.signer
|
|
58
|
-
);
|
|
59
|
-
await
|
|
81
|
+
).allowance(pool.address, routerAddress[network].aerodrome!);
|
|
82
|
+
const wethAllowance = await new ethers.Contract(
|
|
83
|
+
WETH,
|
|
84
|
+
allowanceAbi,
|
|
85
|
+
pool.signer
|
|
86
|
+
).allowance(pool.address, routerAddress[network].aerodrome!);
|
|
87
|
+
expect(usdcAllowance.gt(0)).toBe(true);
|
|
88
|
+
expect(wethAllowance.gt(0)).toBe(true);
|
|
60
89
|
});
|
|
61
90
|
|
|
62
|
-
it("adds USDC and WETH to
|
|
91
|
+
it("adds USDC and WETH to an Aerodrome volatile pool", async () => {
|
|
63
92
|
const usdcBalance = await pool.utils.getBalance(USDC, pool.address);
|
|
64
93
|
const wethBalance = await pool.utils.getBalance(WETH, pool.address);
|
|
65
94
|
await pool.addLiquidityV2(
|
|
@@ -76,7 +105,7 @@ const testAerodrome = ({ network, provider }: TestingRunParams) => {
|
|
|
76
105
|
WETH_USDC_Lp,
|
|
77
106
|
pool.signer
|
|
78
107
|
);
|
|
79
|
-
expect(lpTokenDelta.gt(0));
|
|
108
|
+
expect(lpTokenDelta.gt(0)).toBe(true);
|
|
80
109
|
});
|
|
81
110
|
|
|
82
111
|
it("should stake WETH-USDC LP in a gauge", async () => {
|
|
@@ -88,7 +117,7 @@ const testAerodrome = ({ network, provider }: TestingRunParams) => {
|
|
|
88
117
|
WETH_USDC__Gauge,
|
|
89
118
|
pool.signer
|
|
90
119
|
);
|
|
91
|
-
expect(gaugeBalance.gt(0));
|
|
120
|
+
expect(gaugeBalance.gt(0)).toBe(true);
|
|
92
121
|
});
|
|
93
122
|
|
|
94
123
|
it("should claim rewards from Gauge", async () => {
|
|
@@ -101,10 +130,10 @@ const testAerodrome = ({ network, provider }: TestingRunParams) => {
|
|
|
101
130
|
AERO,
|
|
102
131
|
pool.signer
|
|
103
132
|
);
|
|
104
|
-
expect(aeroBalanceDelta.gt(0));
|
|
133
|
+
expect(aeroBalanceDelta.gt(0)).toBe(true);
|
|
105
134
|
});
|
|
106
135
|
|
|
107
|
-
it("should
|
|
136
|
+
it("should unstake WETH-USDC LP from a gauge", async () => {
|
|
108
137
|
const gaugeBalance = await dhedge.utils.getBalance(
|
|
109
138
|
WETH_USDC__Gauge,
|
|
110
139
|
pool.address
|
|
@@ -115,7 +144,7 @@ const testAerodrome = ({ network, provider }: TestingRunParams) => {
|
|
|
115
144
|
WETH_USDC_Lp,
|
|
116
145
|
pool.signer
|
|
117
146
|
);
|
|
118
|
-
expect(lpTokenDelta.gt(0));
|
|
147
|
+
expect(lpTokenDelta.gt(0)).toBe(true);
|
|
119
148
|
});
|
|
120
149
|
|
|
121
150
|
it("approves unlimited WETH-USDC LP for Aerodrome", async () => {
|
|
@@ -126,10 +155,10 @@ const testAerodrome = ({ network, provider }: TestingRunParams) => {
|
|
|
126
155
|
routerAddress[network].aerodrome!,
|
|
127
156
|
pool.signer
|
|
128
157
|
);
|
|
129
|
-
expect(lpAllowanceDelta.gt(0));
|
|
158
|
+
expect(lpAllowanceDelta.gt(0)).toBe(true);
|
|
130
159
|
});
|
|
131
160
|
|
|
132
|
-
it("should remove all liquidity from an existing pool
|
|
161
|
+
it("should remove all liquidity from an existing pool", async () => {
|
|
133
162
|
const balance = await dhedge.utils.getBalance(WETH_USDC_Lp, pool.address);
|
|
134
163
|
await pool.removeLiquidityV2(Dapp.AERODROME, WETH, USDC, balance, false);
|
|
135
164
|
const usdcBalanceDelta = await balanceDelta(
|
|
@@ -142,8 +171,8 @@ const testAerodrome = ({ network, provider }: TestingRunParams) => {
|
|
|
142
171
|
WETH,
|
|
143
172
|
pool.signer
|
|
144
173
|
);
|
|
145
|
-
expect(usdcBalanceDelta.gt(0));
|
|
146
|
-
expect(wethBalanceDelta.gt(0));
|
|
174
|
+
expect(usdcBalanceDelta.gt(0)).toBe(true);
|
|
175
|
+
expect(wethBalanceDelta.gt(0)).toBe(true);
|
|
147
176
|
});
|
|
148
177
|
});
|
|
149
178
|
};
|