@dhedge/v2-sdk 1.4.2 → 1.5.1
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/dist/config.d.ts +1 -0
- package/dist/entities/dhedge.d.ts +6 -0
- package/dist/entities/pool.d.ts +8 -0
- package/dist/services/aave/assets.d.ts +2 -0
- package/dist/services/aave/incentives.d.ts +2 -0
- package/dist/services/chainLink/price.d.ts +2 -0
- package/dist/services/oneInch/protocols.d.ts +1 -0
- package/dist/services/toros/easySwapper.d.ts +7 -0
- package/dist/services/toros/pool.d.ts +3 -0
- package/dist/test/constants.d.ts +15 -1
- package/dist/types.d.ts +2 -1
- package/dist/v2-sdk.cjs.development.js +4558 -115
- 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 +4556 -113
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/abi/IAaveV3Incentives.json +614 -0
- package/src/abi/IAaveV3LendingPool.json +1241 -0
- package/src/abi/IAaveV3PoolAddressProvider.json +468 -0
- package/src/abi/IDhedgeEasySwapper.json +443 -0
- package/src/abi/IPriceOracle.json +244 -0
- package/src/config.ts +18 -4
- package/src/entities/dhedge.ts +9 -0
- package/src/entities/pool.ts +94 -51
- package/src/services/aave/assets.ts +26 -0
- package/src/services/aave/incentives.ts +23 -0
- package/src/services/chainLink/price.ts +26 -0
- package/src/services/oneInch/protocols.ts +18 -0
- package/src/services/toros/easySwapper.ts +110 -0
- package/src/services/toros/pool.ts +14 -0
- package/src/test/1inch.test.ts +3 -3
- package/src/test/aave.test.ts +40 -13
- package/src/test/arrakis.test.ts +2 -2
- package/src/test/constants.ts +17 -10
- package/src/test/toros.test.ts +117 -0
- package/src/test/wallet.ts +5 -5
- package/src/types.ts +2 -1
package/src/config.ts
CHANGED
|
@@ -25,13 +25,15 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
25
25
|
[Dapp.QUICKSWAP]: "0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff",
|
|
26
26
|
[Dapp.BALANCER]: "0xBA12222222228d8Ba445958a75a0704d566BF2C8",
|
|
27
27
|
[Dapp.UNISWAPV3]: "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
28
|
-
[Dapp.ARRAKIS]: "0xbc91a120cCD8F80b819EAF32F0996daC3Fa76a6C"
|
|
28
|
+
[Dapp.ARRAKIS]: "0xbc91a120cCD8F80b819EAF32F0996daC3Fa76a6C",
|
|
29
|
+
[Dapp.TOROS]: "0x42B1DDcFa1c43E06F483BA0Dd1b9cC923043677f"
|
|
29
30
|
},
|
|
30
31
|
[Network.OPTIMISM]: {
|
|
31
32
|
[Dapp.UNISWAPV3]: "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
32
33
|
[Dapp.SYNTHETIX]: "0x8700dAec35aF8Ff88c16BdF0418774CB3D7599B4",
|
|
33
34
|
[Dapp.AAVEV3]: "0x794a61358D6845594F94dc1DB02A252b5b4814aD",
|
|
34
|
-
[Dapp.ONEINCH]: "0x1111111254760F7ab3F16433eea9304126DCd199"
|
|
35
|
+
[Dapp.ONEINCH]: "0x1111111254760F7ab3F16433eea9304126DCd199",
|
|
36
|
+
[Dapp.TOROS]: "0xf8C62BD5f2fEf9E1a329c197F32E77AD6866B022"
|
|
35
37
|
}
|
|
36
38
|
};
|
|
37
39
|
|
|
@@ -47,11 +49,23 @@ export const stakingAddress: AddressDappNetworkMap = {
|
|
|
47
49
|
[Network.POLYGON]: {
|
|
48
50
|
[Dapp.SUSHISWAP]: "0x0769fd68dFb93167989C6f7254cd0D766Fb2841F",
|
|
49
51
|
[Dapp.BALANCER]: "0x0F3e0c4218b7b0108a3643cFe9D3ec0d4F57c54e",
|
|
50
|
-
[Dapp.AAVE]: "0x357D51124f59836DeD84c8a1730D72B749d8BC23"
|
|
52
|
+
[Dapp.AAVE]: "0x357D51124f59836DeD84c8a1730D72B749d8BC23",
|
|
53
|
+
[Dapp.AAVEV3]: "0x929EC64c34a17401F460460D4B9390518E5B473e"
|
|
51
54
|
},
|
|
52
|
-
[Network.OPTIMISM]: {
|
|
55
|
+
[Network.OPTIMISM]: {
|
|
56
|
+
[Dapp.AAVEV3]: "0x929EC64c34a17401F460460D4B9390518E5B473e"
|
|
57
|
+
}
|
|
53
58
|
};
|
|
54
59
|
|
|
60
|
+
export const aaveAddressProvider: AddressDappNetworkMap = {
|
|
61
|
+
[Network.POLYGON]: {
|
|
62
|
+
[Dapp.AAVE]: "0xd05e3E715d945B59290df0ae8eF85c1BdB684744",
|
|
63
|
+
[Dapp.AAVEV3]: "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb"
|
|
64
|
+
},
|
|
65
|
+
[Network.OPTIMISM]: {
|
|
66
|
+
[Dapp.AAVEV3]: "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb"
|
|
67
|
+
}
|
|
68
|
+
};
|
|
55
69
|
export const nonfungiblePositionManagerAddress: AddressNetworkMap = {
|
|
56
70
|
[Network.POLYGON]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
|
|
57
71
|
[Network.OPTIMISM]: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"
|
package/src/entities/dhedge.ts
CHANGED
|
@@ -105,4 +105,13 @@ export class Dhedge {
|
|
|
105
105
|
this.factory
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Check if pool address is valid
|
|
111
|
+
* @param {string} address Pool address
|
|
112
|
+
* @returns {boolean} Is valid pool address
|
|
113
|
+
*/
|
|
114
|
+
validatePool(address: string): Promise<boolean> {
|
|
115
|
+
return this.factory.isPool(address);
|
|
116
|
+
}
|
|
108
117
|
}
|
package/src/entities/pool.ts
CHANGED
|
@@ -40,6 +40,9 @@ import {
|
|
|
40
40
|
} from "../services/uniswap/V3Liquidity";
|
|
41
41
|
import { FeeAmount } from "@uniswap/v3-sdk";
|
|
42
42
|
import { getUniswapV3SwapTxData } from "../services/uniswap/V3Trade";
|
|
43
|
+
import { getEasySwapperTxData } from "../services/toros/easySwapper";
|
|
44
|
+
import { getOneInchProtocols } from "../services/oneInch/protocols";
|
|
45
|
+
import { getAaveV3ClaimTxData } from "../services/aave/incentives";
|
|
43
46
|
|
|
44
47
|
export class Pool {
|
|
45
48
|
public readonly poolLogic: Contract;
|
|
@@ -265,52 +268,68 @@ export class Pool {
|
|
|
265
268
|
options: any = null
|
|
266
269
|
): Promise<any> {
|
|
267
270
|
let swapTxData: string;
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
271
|
+
switch (dapp) {
|
|
272
|
+
case Dapp.ONEINCH:
|
|
273
|
+
const chainId = networkChainIdMap[this.network];
|
|
274
|
+
const protocols = await getOneInchProtocols(chainId);
|
|
275
|
+
const apiUrl = `https://api.1inch.exchange/v4.0/${chainId}/swap?fromTokenAddress=${assetFrom}&toTokenAddress=${assetTo}&amount=${amountIn.toString()}&fromAddress=${
|
|
276
|
+
this.address
|
|
277
|
+
}&destReceiver=${
|
|
278
|
+
this.address
|
|
279
|
+
}&slippage=${slippage.toString()}&disableEstimate=true${protocols}`;
|
|
280
|
+
const response = await axios.get(apiUrl);
|
|
281
|
+
swapTxData = response.data.tx.data;
|
|
282
|
+
break;
|
|
283
|
+
case Dapp.BALANCER:
|
|
284
|
+
swapTxData = await this.utils.getBalancerSwapTx(
|
|
285
|
+
this,
|
|
286
|
+
assetFrom,
|
|
287
|
+
assetTo,
|
|
288
|
+
amountIn,
|
|
289
|
+
slippage
|
|
290
|
+
);
|
|
291
|
+
break;
|
|
292
|
+
case Dapp.SYNTHETIX:
|
|
293
|
+
const iSynthetix = new ethers.utils.Interface(ISynthetix.abi);
|
|
294
|
+
const assets = [assetFrom, assetTo].map(asset =>
|
|
295
|
+
ethers.utils.formatBytes32String(asset)
|
|
296
|
+
);
|
|
297
|
+
const daoAddress = await this.factory.owner();
|
|
298
|
+
swapTxData = iSynthetix.encodeFunctionData(Transaction.SWAP_SYNTHS, [
|
|
299
|
+
assets[0],
|
|
300
|
+
amountIn,
|
|
301
|
+
assets[1],
|
|
302
|
+
daoAddress,
|
|
303
|
+
SYNTHETIX_TRACKING_CODE
|
|
304
|
+
]);
|
|
305
|
+
break;
|
|
306
|
+
case Dapp.TOROS:
|
|
307
|
+
swapTxData = await getEasySwapperTxData(
|
|
308
|
+
this,
|
|
309
|
+
assetFrom,
|
|
310
|
+
assetTo,
|
|
311
|
+
ethers.BigNumber.from(amountIn),
|
|
312
|
+
slippage
|
|
313
|
+
);
|
|
314
|
+
break;
|
|
315
|
+
default:
|
|
316
|
+
const iUniswapV2Router = new ethers.utils.Interface(
|
|
317
|
+
IUniswapV2Router.abi
|
|
318
|
+
);
|
|
319
|
+
const minAmountOut = await this.utils.getMinAmountOut(
|
|
320
|
+
dapp,
|
|
321
|
+
assetFrom,
|
|
322
|
+
assetTo,
|
|
323
|
+
amountIn,
|
|
324
|
+
slippage
|
|
325
|
+
);
|
|
326
|
+
swapTxData = iUniswapV2Router.encodeFunctionData(Transaction.SWAP, [
|
|
327
|
+
amountIn,
|
|
328
|
+
minAmountOut,
|
|
329
|
+
[assetFrom, assetTo],
|
|
330
|
+
this.address,
|
|
331
|
+
deadline
|
|
332
|
+
]);
|
|
314
333
|
}
|
|
315
334
|
const tx = await this.poolLogic.execTransaction(
|
|
316
335
|
routerAddress[this.network][dapp],
|
|
@@ -795,6 +814,27 @@ export class Pool {
|
|
|
795
814
|
return tx;
|
|
796
815
|
}
|
|
797
816
|
|
|
817
|
+
/**
|
|
818
|
+
* Claim rewards from Aave platform
|
|
819
|
+
* @param {string[]} assets Assets invested in Aave
|
|
820
|
+
* @param {string} rewardAssets Reward token address
|
|
821
|
+
* @param {any} options Transaction options
|
|
822
|
+
* @returns {Promise<any>} Transaction
|
|
823
|
+
*/
|
|
824
|
+
async harvestAaveV3Rewards(
|
|
825
|
+
assets: string[],
|
|
826
|
+
rewardAsset: string,
|
|
827
|
+
options: any = null
|
|
828
|
+
): Promise<any> {
|
|
829
|
+
const claimTxData = await getAaveV3ClaimTxData(this, assets, rewardAsset);
|
|
830
|
+
const tx = await this.poolLogic.execTransaction(
|
|
831
|
+
stakingAddress[this.network][Dapp.AAVEV3] as string,
|
|
832
|
+
claimTxData,
|
|
833
|
+
options
|
|
834
|
+
);
|
|
835
|
+
return tx;
|
|
836
|
+
}
|
|
837
|
+
|
|
798
838
|
/**
|
|
799
839
|
* Create UniswapV3 liquidity pool
|
|
800
840
|
* @param {string} assetA First asset
|
|
@@ -821,7 +861,10 @@ export class Pool {
|
|
|
821
861
|
feeAmount: FeeAmount,
|
|
822
862
|
options: any = null
|
|
823
863
|
): Promise<any> {
|
|
824
|
-
if (
|
|
864
|
+
if (
|
|
865
|
+
(minPrice === null || maxPrice === null) &&
|
|
866
|
+
(minTick === null || maxTick === null)
|
|
867
|
+
)
|
|
825
868
|
throw new Error("Need to provide price or tick range");
|
|
826
869
|
|
|
827
870
|
const iNonfungiblePositionManager = new ethers.utils.Interface(
|
|
@@ -872,8 +915,8 @@ export class Pool {
|
|
|
872
915
|
dappAddress = nonfungiblePositionManagerAddress[this.network];
|
|
873
916
|
const abi = new ethers.utils.Interface(INonfungiblePositionManager.abi);
|
|
874
917
|
const liquidity = (await getUniswapV3Liquidity(tokenId, this))
|
|
875
|
-
.mul(amount)
|
|
876
|
-
.div(
|
|
918
|
+
.mul(Math.round(amount * 1e4))
|
|
919
|
+
.div(1e6);
|
|
877
920
|
const decreaseLiquidityTxData = abi.encodeFunctionData(
|
|
878
921
|
Transaction.DECREASE_LIQUIDITY,
|
|
879
922
|
[[tokenId, liquidity, 0, 0, deadline]]
|
|
@@ -895,8 +938,8 @@ export class Pool {
|
|
|
895
938
|
dappAddress = routerAddress[this.network][dapp];
|
|
896
939
|
const abi = new ethers.utils.Interface(IArrakisV1RouterStaking.abi);
|
|
897
940
|
const liquidity = (await this.utils.getBalance(tokenId, this.address))
|
|
898
|
-
.mul(amount)
|
|
899
|
-
.div(
|
|
941
|
+
.mul(Math.round(amount * 1e4))
|
|
942
|
+
.div(1e6);
|
|
900
943
|
txData = abi.encodeFunctionData(Transaction.REMOVE_LIQUIDITY_UNSTAKE, [
|
|
901
944
|
tokenId,
|
|
902
945
|
liquidity,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Dapp, ethers, Pool } from "../..";
|
|
2
|
+
|
|
3
|
+
import ILendingPool from "../../abi/ILendingPool.json";
|
|
4
|
+
import ILendingPoolV3 from "../../abi/IAaveV3LendingPool.json";
|
|
5
|
+
import { routerAddress } from "../../config";
|
|
6
|
+
|
|
7
|
+
export async function getAaveAssetsForUnderlying(
|
|
8
|
+
pool: Pool,
|
|
9
|
+
dapp: Dapp,
|
|
10
|
+
assets: string[]
|
|
11
|
+
): Promise<string[]> {
|
|
12
|
+
const iLendingPool = dapp === Dapp.AAVEV3 ? ILendingPoolV3 : ILendingPool;
|
|
13
|
+
const lendingPool = new ethers.Contract(
|
|
14
|
+
routerAddress[pool.network][dapp] as string,
|
|
15
|
+
iLendingPool.abi,
|
|
16
|
+
pool.signer
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const reserveData = await Promise.all(
|
|
20
|
+
assets.map(e => lendingPool.getReserveData(e))
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const aTokens = reserveData.map(e => e.aTokenAddress);
|
|
24
|
+
const debtTokens = reserveData.map(e => e.variableDebtTokenAddress);
|
|
25
|
+
return aTokens.concat(debtTokens);
|
|
26
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { ethers } from "ethers";
|
|
3
|
+
import { Dapp } from "../../types";
|
|
4
|
+
import IAaveV3Incentives from "../../abi/IAaveV3Incentives.json";
|
|
5
|
+
import { Pool } from "../..";
|
|
6
|
+
import { getAaveAssetsForUnderlying } from "./assets";
|
|
7
|
+
|
|
8
|
+
export async function getAaveV3ClaimTxData(
|
|
9
|
+
pool: Pool,
|
|
10
|
+
assets: string[],
|
|
11
|
+
rewardAsset: string
|
|
12
|
+
): Promise<any> {
|
|
13
|
+
const iAaveIncentives = new ethers.utils.Interface(IAaveV3Incentives.abi);
|
|
14
|
+
const aaveAsset = await getAaveAssetsForUnderlying(pool, Dapp.AAVEV3, assets);
|
|
15
|
+
|
|
16
|
+
const claimTxData = iAaveIncentives.encodeFunctionData("claimRewards", [
|
|
17
|
+
aaveAsset,
|
|
18
|
+
ethers.constants.MaxUint256,
|
|
19
|
+
pool.address,
|
|
20
|
+
rewardAsset
|
|
21
|
+
]);
|
|
22
|
+
return claimTxData;
|
|
23
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Dapp, ethers, Pool } from "../..";
|
|
2
|
+
|
|
3
|
+
import IAaveV3PoolAddressProvider from "../../abi/IAaveV3PoolAddressProvider.json";
|
|
4
|
+
import IPriceOracle from "../../abi/IPriceOracle.json";
|
|
5
|
+
import { aaveAddressProvider } from "../../config";
|
|
6
|
+
|
|
7
|
+
export async function getChainlinkPriceInUsd(
|
|
8
|
+
pool: Pool,
|
|
9
|
+
asset: string
|
|
10
|
+
): Promise<ethers.BigNumber> {
|
|
11
|
+
//Workaround as Chainlink doesn't have feed registry on Polygon/Optimism
|
|
12
|
+
//Use oracle from Aave which uses Chainlink
|
|
13
|
+
const lendingPoolAddressProvider = new ethers.Contract(
|
|
14
|
+
aaveAddressProvider[pool.network][Dapp.AAVEV3] as string,
|
|
15
|
+
IAaveV3PoolAddressProvider.abi,
|
|
16
|
+
pool.signer
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const priceOracleAddress = await lendingPoolAddressProvider.getPriceOracle();
|
|
20
|
+
const priceOracle = new ethers.Contract(
|
|
21
|
+
priceOracleAddress,
|
|
22
|
+
IPriceOracle.abi,
|
|
23
|
+
pool.signer
|
|
24
|
+
);
|
|
25
|
+
return await priceOracle.getAssetPrice(asset);
|
|
26
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
|
|
3
|
+
const excludedProtocols = ["OPTIMISM_PMM6"]; //Clipper
|
|
4
|
+
|
|
5
|
+
export async function getOneInchProtocols(chainId: number): Promise<string> {
|
|
6
|
+
try {
|
|
7
|
+
const response = await axios.get(
|
|
8
|
+
`https://api.1inch.io/v4.0/${chainId}/liquidity-sources`
|
|
9
|
+
);
|
|
10
|
+
const protocols = response.data.protocols.map((e: { id: string }) => e.id);
|
|
11
|
+
const filteredProtocols = protocols.filter(
|
|
12
|
+
(e: string) => !excludedProtocols.includes(e)
|
|
13
|
+
);
|
|
14
|
+
return `&protocols=${filteredProtocols.join(",")}`;
|
|
15
|
+
} catch {
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
import { Dapp, Pool } from "../..";
|
|
3
|
+
|
|
4
|
+
import IDhedgeEasySwapper from "../../abi/IDhedgeEasySwapper.json";
|
|
5
|
+
import { routerAddress } from "../../config";
|
|
6
|
+
import { getChainlinkPriceInUsd } from "../chainLink/price";
|
|
7
|
+
import { isPool, loadPool } from "./pool";
|
|
8
|
+
|
|
9
|
+
export async function getPoolDepositAsset(
|
|
10
|
+
pool: Pool,
|
|
11
|
+
poolAddress: string
|
|
12
|
+
): Promise<string | undefined> {
|
|
13
|
+
const torosPool = await loadPool(pool, poolAddress);
|
|
14
|
+
const composition = await torosPool.getComposition();
|
|
15
|
+
return composition.find(e => e.isDeposit)?.asset;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function getTorosPoolTokenPrice(
|
|
19
|
+
pool: Pool,
|
|
20
|
+
poolAddress: string
|
|
21
|
+
): Promise<ethers.BigNumber> {
|
|
22
|
+
const torosPool = await loadPool(pool, poolAddress);
|
|
23
|
+
return await torosPool.poolLogic.tokenPrice();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function getEasySwapperDepositQuote(
|
|
27
|
+
pool: Pool,
|
|
28
|
+
torosAsset: string,
|
|
29
|
+
investAsset: string,
|
|
30
|
+
depositAsset: string,
|
|
31
|
+
amountIn: ethers.BigNumber
|
|
32
|
+
): Promise<ethers.BigNumber> {
|
|
33
|
+
const easySwapper = new ethers.Contract(
|
|
34
|
+
routerAddress[pool.network][Dapp.TOROS] as string,
|
|
35
|
+
IDhedgeEasySwapper.abi,
|
|
36
|
+
pool.signer
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
return await easySwapper.depositQuote(
|
|
40
|
+
torosAsset,
|
|
41
|
+
investAsset,
|
|
42
|
+
amountIn,
|
|
43
|
+
depositAsset
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function getEasySwapperWithdrawalQuote(
|
|
48
|
+
pool: Pool,
|
|
49
|
+
torosAsset: string,
|
|
50
|
+
investAsset: string,
|
|
51
|
+
amountIn: ethers.BigNumber
|
|
52
|
+
): Promise<ethers.BigNumber> {
|
|
53
|
+
const [torosTokenPrice, assetPrice, assetDecimals] = await Promise.all([
|
|
54
|
+
getTorosPoolTokenPrice(pool, torosAsset),
|
|
55
|
+
getChainlinkPriceInUsd(pool, investAsset),
|
|
56
|
+
pool.utils.getDecimals(investAsset)
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
return amountIn
|
|
60
|
+
.mul(torosTokenPrice)
|
|
61
|
+
.div(assetPrice)
|
|
62
|
+
.div(1e10)
|
|
63
|
+
.div(10 ** (18 - assetDecimals));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function getEasySwapperTxData(
|
|
67
|
+
pool: Pool,
|
|
68
|
+
assetFrom: string,
|
|
69
|
+
assetTo: string,
|
|
70
|
+
amountIn: ethers.BigNumber,
|
|
71
|
+
slippage: number
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
73
|
+
): Promise<any> {
|
|
74
|
+
const isWithdrawal = await isPool(pool, assetFrom);
|
|
75
|
+
const [torosAsset, investAsset] = isWithdrawal
|
|
76
|
+
? [assetFrom, assetTo]
|
|
77
|
+
: [assetTo, assetFrom];
|
|
78
|
+
const iDhedgeEasySwapper = new ethers.utils.Interface(IDhedgeEasySwapper.abi);
|
|
79
|
+
if (isWithdrawal) {
|
|
80
|
+
const minAmountOut = await getEasySwapperWithdrawalQuote(
|
|
81
|
+
pool,
|
|
82
|
+
torosAsset,
|
|
83
|
+
investAsset,
|
|
84
|
+
amountIn
|
|
85
|
+
);
|
|
86
|
+
return iDhedgeEasySwapper.encodeFunctionData("withdraw", [
|
|
87
|
+
torosAsset,
|
|
88
|
+
amountIn,
|
|
89
|
+
investAsset,
|
|
90
|
+
minAmountOut.mul(10000 - slippage * 100).div(10000)
|
|
91
|
+
]);
|
|
92
|
+
} else {
|
|
93
|
+
const depositAsset = await getPoolDepositAsset(pool, torosAsset);
|
|
94
|
+
if (!depositAsset) throw new Error("no deposit assets");
|
|
95
|
+
const minAmountOut = await getEasySwapperDepositQuote(
|
|
96
|
+
pool,
|
|
97
|
+
torosAsset,
|
|
98
|
+
investAsset,
|
|
99
|
+
depositAsset,
|
|
100
|
+
amountIn
|
|
101
|
+
);
|
|
102
|
+
return iDhedgeEasySwapper.encodeFunctionData("deposit", [
|
|
103
|
+
torosAsset,
|
|
104
|
+
investAsset,
|
|
105
|
+
amountIn,
|
|
106
|
+
depositAsset,
|
|
107
|
+
minAmountOut.mul(10000 - slippage * 100).div(10000)
|
|
108
|
+
]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Dhedge, Pool } from "../..";
|
|
2
|
+
|
|
3
|
+
export async function loadPool(pool: Pool, poolAddress: string): Promise<Pool> {
|
|
4
|
+
const dhedge = new Dhedge(pool.signer, pool.network);
|
|
5
|
+
return await dhedge.loadPool(poolAddress);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export async function isPool(
|
|
9
|
+
pool: Pool,
|
|
10
|
+
poolAddress: string
|
|
11
|
+
): Promise<boolean> {
|
|
12
|
+
const dhedge = new Dhedge(pool.signer, pool.network);
|
|
13
|
+
return await dhedge.validatePool(poolAddress);
|
|
14
|
+
}
|
package/src/test/1inch.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Dhedge } from "..";
|
|
2
2
|
import { Dapp, Network } from "../types";
|
|
3
|
-
import { TEST_POOL, USDC,
|
|
3
|
+
import { TEST_POOL, USDC, WBTC } from "./constants";
|
|
4
4
|
import { getTxOptions } from "./txOptions";
|
|
5
5
|
|
|
6
6
|
import { wallet } from "./wallet";
|
|
@@ -33,14 +33,14 @@ describe("pool", () => {
|
|
|
33
33
|
// expect(result).not.toBe(null);
|
|
34
34
|
// });
|
|
35
35
|
|
|
36
|
-
it("trades 1 USDC into
|
|
36
|
+
it("trades 1 USDC into WBTC on 1Inch", async () => {
|
|
37
37
|
let result;
|
|
38
38
|
const pool = await dhedge.loadPool(TEST_POOL);
|
|
39
39
|
try {
|
|
40
40
|
result = await pool.trade(
|
|
41
41
|
Dapp.ONEINCH,
|
|
42
42
|
USDC,
|
|
43
|
-
|
|
43
|
+
WBTC,
|
|
44
44
|
"1000000",
|
|
45
45
|
0.5,
|
|
46
46
|
options
|
package/src/test/aave.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Dhedge } from "..";
|
|
2
|
-
import {
|
|
3
|
-
import { TEST_POOL, WETH } from "./constants";
|
|
2
|
+
import { Network } from "../types";
|
|
3
|
+
import { OP, TEST_POOL, USDC, WBTC, WETH } from "./constants";
|
|
4
4
|
|
|
5
5
|
import { wallet } from "./wallet";
|
|
6
6
|
|
|
@@ -51,17 +51,17 @@ describe("pool", () => {
|
|
|
51
51
|
// expect(result).not.toBe(null);
|
|
52
52
|
// });
|
|
53
53
|
|
|
54
|
-
it("borrows 0.001 WETH from Aave lending pool", async () => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
});
|
|
54
|
+
// it("borrows 0.001 WETH from Aave lending pool", async () => {
|
|
55
|
+
// let result;
|
|
56
|
+
// const pool = await dhedge.loadPool(TEST_POOL);
|
|
57
|
+
// try {
|
|
58
|
+
// result = await pool.borrow(Dapp.AAVEV3, WETH, "1000000000000000");
|
|
59
|
+
// console.log(result);
|
|
60
|
+
// } catch (e) {
|
|
61
|
+
// console.log(e);
|
|
62
|
+
// }
|
|
63
|
+
// expect(result).not.toBe(null);
|
|
64
|
+
// });
|
|
65
65
|
|
|
66
66
|
// it("reapys 1USDC to Aave lending pool", async () => {
|
|
67
67
|
// let result;
|
|
@@ -98,4 +98,31 @@ describe("pool", () => {
|
|
|
98
98
|
// }
|
|
99
99
|
// expect(result).not.toBe(null);
|
|
100
100
|
// });
|
|
101
|
+
|
|
102
|
+
// it("gets Aave assets for underlying", async () => {
|
|
103
|
+
// let result;
|
|
104
|
+
// const pool = await dhedge.loadPool(TEST_POOL);
|
|
105
|
+
// try {
|
|
106
|
+
// result = await getAaveAssetsForUnderlying(pool, Dapp.AAVEV3, [
|
|
107
|
+
// USDC,
|
|
108
|
+
// WETH
|
|
109
|
+
// ]);
|
|
110
|
+
// console.log(result);
|
|
111
|
+
// } catch (e) {
|
|
112
|
+
// console.log(e);
|
|
113
|
+
// }
|
|
114
|
+
// expect(result).not.toBe(null);
|
|
115
|
+
// });
|
|
116
|
+
|
|
117
|
+
it("claims rewards from AaveV3", async () => {
|
|
118
|
+
let result;
|
|
119
|
+
const pool = await dhedge.loadPool(TEST_POOL);
|
|
120
|
+
try {
|
|
121
|
+
result = await pool.harvestAaveV3Rewards([USDC, WETH, WBTC], OP);
|
|
122
|
+
console.log(result);
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.log(e);
|
|
125
|
+
}
|
|
126
|
+
expect(result).not.toBe(null);
|
|
127
|
+
});
|
|
101
128
|
});
|
package/src/test/arrakis.test.ts
CHANGED
|
@@ -14,7 +14,7 @@ jest.setTimeout(100000);
|
|
|
14
14
|
describe("pool", () => {
|
|
15
15
|
beforeAll(async () => {
|
|
16
16
|
dhedge = new Dhedge(wallet, Network.POLYGON);
|
|
17
|
-
options = await getTxOptions();
|
|
17
|
+
options = await getTxOptions(Network.POLYGON);
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
// it("approves unlimited WETH on Arrakis", async () => {
|
|
@@ -69,7 +69,7 @@ describe("pool", () => {
|
|
|
69
69
|
const result = await pool.decreaseLiquidity(
|
|
70
70
|
Dapp.ARRAKIS,
|
|
71
71
|
ARRAKIS_USDC_WETH_GAUGE,
|
|
72
|
-
|
|
72
|
+
50.6576575755,
|
|
73
73
|
options
|
|
74
74
|
);
|
|
75
75
|
console.log("result", result);
|
package/src/test/constants.ts
CHANGED
|
@@ -5,19 +5,26 @@
|
|
|
5
5
|
// export const DAI = "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063";
|
|
6
6
|
// export const TUSD = "0x2e1ad108ff1d8c782fcbbb89aad783ac49586756";
|
|
7
7
|
// export const WBTC = "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
export const SUSHI = "0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a";
|
|
9
|
+
export const WMATIC = "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270";
|
|
10
|
+
export const BAL = "0x9a71012B13CA4d3D0Cdc72A177DF3ef03b0E76A3";
|
|
11
|
+
export const AMUSDC = "0x1a13f4ca1d028320a707d99520abfefca3998b7f";
|
|
12
|
+
export const VDEBTWETH = "0xede17e9d79fc6f9ff9250d9eefbdb88cc18038b5";
|
|
13
|
+
export const ARRAKIS_USDC_WETH_GAUGE =
|
|
14
|
+
"0x33d1ad9Cd88A509397CD924C2d7613C285602C20";
|
|
15
|
+
export const STMATIC = "0x3A58a54C066FdC0f2D55FC9C89F0415C92eBf3C4";
|
|
16
|
+
export const WMATIC_STMATIC_LP = "0xaF5E0B5425dE1F5a630A8cB5AA9D97B8141C908D";
|
|
17
|
+
export const AARAKIS_WNATIC_STMATIC_GAUGE =
|
|
18
|
+
"0x9928340f9E1aaAd7dF1D95E27bd9A5c715202a56";
|
|
19
|
+
export const ETHBULL3X = "0x460b60565cb73845d56564384ab84bf84c13e47d";
|
|
20
|
+
export const BTCBEAR2X = "0x3dbce2c8303609c17aa23b69ebe83c2f5c510ada";
|
|
17
21
|
|
|
18
22
|
//Optimism
|
|
19
23
|
export const WETH = "0x4200000000000000000000000000000000000006";
|
|
20
24
|
export const USDC = "0x7F5c764cBc14f9669B88837ca1490cCa17c31607";
|
|
21
25
|
export const DAI = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1";
|
|
26
|
+
export const USDy = "0x1ec50880101022c11530a069690f5446d1464592";
|
|
27
|
+
export const WBTC = "0x68f180fcCe6836688e9084f035309E29Bf0A2095";
|
|
28
|
+
export const OP = "4200000000000000000000000000000000000042";
|
|
22
29
|
|
|
23
|
-
export const TEST_POOL = "
|
|
30
|
+
export const TEST_POOL = "TEST_POOL";
|