@dhedge/v2-sdk 1.10.14 → 1.10.16
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/services/pendle/index.d.ts +4 -0
- package/dist/test/constants.d.ts +2 -0
- package/dist/types.d.ts +2 -1
- package/dist/v2-sdk.cjs.development.js +363 -18
- 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 +363 -18
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/abi/pendle/ActionMiscV3.json +122 -0
- package/src/config.ts +15 -4
- package/src/entities/pool.ts +10 -0
- package/src/services/flatmoney/keeperFee.ts +1 -1
- package/src/services/pendle/index.ts +141 -0
- package/src/test/constants.ts +4 -2
- package/src/test/pendle.test.ts +132 -0
- package/src/types.ts +2 -1
package/package.json
CHANGED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"internalType": "address",
|
|
6
|
+
"name": "receiver",
|
|
7
|
+
"type": "address"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"internalType": "address",
|
|
11
|
+
"name": "market",
|
|
12
|
+
"type": "address"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"internalType": "uint256",
|
|
16
|
+
"name": "netPtIn",
|
|
17
|
+
"type": "uint256"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"internalType": "uint256",
|
|
21
|
+
"name": "netLpIn",
|
|
22
|
+
"type": "uint256"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"components": [
|
|
26
|
+
{
|
|
27
|
+
"internalType": "address",
|
|
28
|
+
"name": "tokenOut",
|
|
29
|
+
"type": "address"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"internalType": "uint256",
|
|
33
|
+
"name": "minTokenOut",
|
|
34
|
+
"type": "uint256"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"internalType": "address",
|
|
38
|
+
"name": "tokenRedeemSy",
|
|
39
|
+
"type": "address"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"internalType": "address",
|
|
43
|
+
"name": "pendleSwap",
|
|
44
|
+
"type": "address"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"components": [
|
|
48
|
+
{
|
|
49
|
+
"internalType": "enum SwapType",
|
|
50
|
+
"name": "swapType",
|
|
51
|
+
"type": "uint8"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"internalType": "address",
|
|
55
|
+
"name": "extRouter",
|
|
56
|
+
"type": "address"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"internalType": "bytes",
|
|
60
|
+
"name": "extCalldata",
|
|
61
|
+
"type": "bytes"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"internalType": "bool",
|
|
65
|
+
"name": "needScale",
|
|
66
|
+
"type": "bool"
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
"internalType": "struct SwapData",
|
|
70
|
+
"name": "swapData",
|
|
71
|
+
"type": "tuple"
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"internalType": "struct TokenOutput",
|
|
75
|
+
"name": "output",
|
|
76
|
+
"type": "tuple"
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"name": "exitPostExpToToken",
|
|
80
|
+
"outputs": [
|
|
81
|
+
{
|
|
82
|
+
"internalType": "uint256",
|
|
83
|
+
"name": "totalTokenOut",
|
|
84
|
+
"type": "uint256"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"components": [
|
|
88
|
+
{
|
|
89
|
+
"internalType": "uint256",
|
|
90
|
+
"name": "netPtFromRemove",
|
|
91
|
+
"type": "uint256"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"internalType": "uint256",
|
|
95
|
+
"name": "netSyFromRemove",
|
|
96
|
+
"type": "uint256"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"internalType": "uint256",
|
|
100
|
+
"name": "netPtRedeem",
|
|
101
|
+
"type": "uint256"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"internalType": "uint256",
|
|
105
|
+
"name": "netSyFromRedeem",
|
|
106
|
+
"type": "uint256"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"internalType": "uint256",
|
|
110
|
+
"name": "totalSyOut",
|
|
111
|
+
"type": "uint256"
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"internalType": "struct IPActionMiscV3.ExitPostExpReturnParams",
|
|
115
|
+
"name": "params",
|
|
116
|
+
"type": "tuple"
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"stateMutability": "nonpayable",
|
|
120
|
+
"type": "function"
|
|
121
|
+
}
|
|
122
|
+
]
|
package/src/config.ts
CHANGED
|
@@ -44,7 +44,8 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
44
44
|
[Dapp.VELODROMEV2]: "0xa062ae8a9c5e11aaa026fc2670b0d65ccc8b2858",
|
|
45
45
|
[Dapp.LYRA]: "0xCCE7819d65f348c64B7Beb205BA367b3fE33763B",
|
|
46
46
|
[Dapp.ARRAKIS]: "0x9ce88a56d120300061593eF7AD074A1B710094d5",
|
|
47
|
-
[Dapp.ODOS]: "0xca423977156bb05b13a2ba3b76bc5419e2fe9680"
|
|
47
|
+
[Dapp.ODOS]: "0xca423977156bb05b13a2ba3b76bc5419e2fe9680",
|
|
48
|
+
[Dapp.PENDLE]: "0x888888888889758F76e7103c6CbF23ABbF58F946"
|
|
48
49
|
},
|
|
49
50
|
[Network.ARBITRUM]: {
|
|
50
51
|
[Dapp.ONEINCH]: "0x111111125421ca6dc452d289314280a0f8842a65",
|
|
@@ -53,18 +54,21 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
53
54
|
[Dapp.BALANCER]: "0xBA12222222228d8Ba445958a75a0704d566BF2C8",
|
|
54
55
|
[Dapp.RAMSES]: "0xaaa87963efeb6f7e0a2711f397663105acb1805e",
|
|
55
56
|
[Dapp.TOROS]: "0xA5679C4272A056Bb83f039961fae7D99C48529F5",
|
|
56
|
-
[Dapp.ODOS]: "0xa669e7A0d4b3e4Fa48af2dE86BD4CD7126Be4e13"
|
|
57
|
+
[Dapp.ODOS]: "0xa669e7A0d4b3e4Fa48af2dE86BD4CD7126Be4e13",
|
|
58
|
+
[Dapp.PENDLE]: "0x888888888889758F76e7103c6CbF23ABbF58F946"
|
|
57
59
|
},
|
|
58
60
|
[Network.BASE]: {
|
|
59
61
|
[Dapp.ONEINCH]: "0x111111125421ca6dc452d289314280a0f8842a65",
|
|
60
62
|
[Dapp.AERODROME]: "0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43",
|
|
61
63
|
[Dapp.AAVEV3]: "0xA238Dd80C259a72e81d7e4664a9801593F98d1c5",
|
|
62
64
|
[Dapp.TOROS]: "0xf067575Eb60c7587C11e867907AA7284833704d1",
|
|
63
|
-
[Dapp.ODOS]: "0x19cEeAd7105607Cd444F5ad10dd51356436095a1"
|
|
65
|
+
[Dapp.ODOS]: "0x19cEeAd7105607Cd444F5ad10dd51356436095a1",
|
|
66
|
+
[Dapp.PENDLE]: "0x888888888889758F76e7103c6CbF23ABbF58F946"
|
|
64
67
|
},
|
|
65
68
|
[Network.SONIC]: {
|
|
66
69
|
[Dapp.AAVEV3]: "0x5362dBb1e601abF3a4c14c22ffEdA64042E5eAA3",
|
|
67
|
-
[Dapp.ODOS]: "0xaC041Df48dF9791B0654f1Dbbf2CC8450C5f2e9D"
|
|
70
|
+
[Dapp.ODOS]: "0xaC041Df48dF9791B0654f1Dbbf2CC8450C5f2e9D",
|
|
71
|
+
[Dapp.PENDLE]: "0x888888888889758F76e7103c6CbF23ABbF58F946"
|
|
68
72
|
}
|
|
69
73
|
};
|
|
70
74
|
|
|
@@ -204,5 +208,12 @@ export const flatMoneyContractAddresses: Readonly<Partial<
|
|
|
204
208
|
FlatcoinVault: "0x86C7b9640302082B0dF78023F930d8612bFcaD3f",
|
|
205
209
|
COLLATERAL: "0x68f180fcCe6836688e9084f035309E29Bf0A2095", // WBTC
|
|
206
210
|
StableModule: "0x357CB23571EF7a3d6189b7FAcFC361eA71f7CAB5"
|
|
211
|
+
},
|
|
212
|
+
[Network.ARBITRUM]: {
|
|
213
|
+
OrderExecution: "0x7e50AD6E467D9FAFC3B4BFd003247cEaA2F17e5b",
|
|
214
|
+
DelayedOrder: "0x2326BB21B769D81E134C9b305ca156f989249fE7", // OrderAnnouncementModule
|
|
215
|
+
FlatcoinVault: "0x29fAD9d44C550e5D8081AB35763797B39d75b858",
|
|
216
|
+
COLLATERAL: "0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f", // WBTC
|
|
217
|
+
StableModule: "0xcD3657cB0E851b6a734c4D1e7FC2640Bcd9f6B2d"
|
|
207
218
|
}
|
|
208
219
|
};
|
package/src/entities/pool.ts
CHANGED
|
@@ -86,6 +86,7 @@ import {
|
|
|
86
86
|
getPancakeUnStakeTxData,
|
|
87
87
|
} from "../services/pancake/staking";
|
|
88
88
|
import { getOdosSwapTxData } from "../services/odos";
|
|
89
|
+
import { getPendleSwapTxData } from "../services/pendle";
|
|
89
90
|
|
|
90
91
|
export class Pool {
|
|
91
92
|
public readonly poolLogic: Contract;
|
|
@@ -422,6 +423,15 @@ export class Pool {
|
|
|
422
423
|
slippage
|
|
423
424
|
);
|
|
424
425
|
break;
|
|
426
|
+
case Dapp.PENDLE:
|
|
427
|
+
swapTxData = await getPendleSwapTxData(
|
|
428
|
+
this,
|
|
429
|
+
assetFrom,
|
|
430
|
+
assetTo,
|
|
431
|
+
amountIn,
|
|
432
|
+
slippage
|
|
433
|
+
);
|
|
434
|
+
break;
|
|
425
435
|
default:
|
|
426
436
|
const iUniswapV2Router = new ethers.utils.Interface(
|
|
427
437
|
IUniswapV2Router.abi
|
|
@@ -38,7 +38,7 @@ export const getKeeperFee = async (
|
|
|
38
38
|
const keeperFeeContract = await getKeeperFeeContract(pool);
|
|
39
39
|
|
|
40
40
|
const feeHistory = await (pool.signer
|
|
41
|
-
.provider as JsonRpcProvider).send("eth_feeHistory", [1, "latest"]);
|
|
41
|
+
.provider as JsonRpcProvider).send("eth_feeHistory", [1, "latest", []]);
|
|
42
42
|
|
|
43
43
|
const gasPrice = Number(feeHistory.baseFeePerGas[0]);
|
|
44
44
|
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import { ApiError, ethers } from "../..";
|
|
4
|
+
import { networkChainIdMap } from "../../config";
|
|
5
|
+
import { Pool } from "../../entities";
|
|
6
|
+
import ActionMiscV3Abi from "../../abi/pendle/ActionMiscV3.json";
|
|
7
|
+
|
|
8
|
+
const pendleBaseUrl = "https://api-v2.pendle.finance/core/v1";
|
|
9
|
+
|
|
10
|
+
export async function getPendleSwapTxData(
|
|
11
|
+
pool: Pool,
|
|
12
|
+
tokenIn: string,
|
|
13
|
+
tokenOut: string,
|
|
14
|
+
amountIn: ethers.BigNumber | string,
|
|
15
|
+
slippage: number
|
|
16
|
+
): Promise<string> {
|
|
17
|
+
const expiredMarket = await checkExitPostExpPT(pool, tokenIn, tokenOut);
|
|
18
|
+
if (expiredMarket) {
|
|
19
|
+
return getExitExpPTTxData(pool, tokenOut, amountIn, expiredMarket);
|
|
20
|
+
}
|
|
21
|
+
const params = {
|
|
22
|
+
receiver: pool.address,
|
|
23
|
+
tokenIn,
|
|
24
|
+
tokenOut,
|
|
25
|
+
amountIn: amountIn.toString(),
|
|
26
|
+
slippage
|
|
27
|
+
};
|
|
28
|
+
const market = await getMarket(pool, tokenIn, tokenOut);
|
|
29
|
+
try {
|
|
30
|
+
const swapResult = await axios.get(
|
|
31
|
+
`${pendleBaseUrl}/sdk/${
|
|
32
|
+
networkChainIdMap[pool.network]
|
|
33
|
+
}/markets/${market}/swap`,
|
|
34
|
+
{ params }
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
return swapResult.data.tx.data;
|
|
38
|
+
} catch (e) {
|
|
39
|
+
console.error("Error in Pendle API request:", e);
|
|
40
|
+
throw new ApiError("Pendle api request failed");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const checkUnderlying = (market: any, token: string, networkId: number) => {
|
|
45
|
+
if (market.underlyingAsset !== `${networkId}-${token.toLocaleLowerCase()}`) {
|
|
46
|
+
throw new Error("Can only trade in or out of the underlying asset");
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export async function getMarket(
|
|
51
|
+
pool: Pool,
|
|
52
|
+
tokenIn: string,
|
|
53
|
+
tokenOut: string
|
|
54
|
+
): Promise<string> {
|
|
55
|
+
const networkId = networkChainIdMap[pool.network];
|
|
56
|
+
let marketResult;
|
|
57
|
+
try {
|
|
58
|
+
marketResult = await axios.get(
|
|
59
|
+
`${pendleBaseUrl}/${networkId}/markets/active`
|
|
60
|
+
);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.error("Error in Pendle API request:", e);
|
|
63
|
+
throw new ApiError("Pendle api request failed");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const allMarkets = marketResult.data.markets;
|
|
67
|
+
const markets = [tokenIn, tokenOut].map(token =>
|
|
68
|
+
allMarkets.find(
|
|
69
|
+
(market: any) => market.pt === `${networkId}-${token.toLocaleLowerCase()}`
|
|
70
|
+
)
|
|
71
|
+
);
|
|
72
|
+
if (markets[0]) {
|
|
73
|
+
checkUnderlying(markets[0], tokenOut, networkId);
|
|
74
|
+
return markets[0].address;
|
|
75
|
+
} else if (markets[1]) {
|
|
76
|
+
checkUnderlying(markets[1], tokenIn, networkId);
|
|
77
|
+
return markets[1].address;
|
|
78
|
+
} else {
|
|
79
|
+
throw new Error("Can only trade PT assets");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const checkExitPostExpPT = async (
|
|
84
|
+
pool: Pool,
|
|
85
|
+
tokenIn: string,
|
|
86
|
+
tokenOut: string
|
|
87
|
+
): Promise<string | null> => {
|
|
88
|
+
const networkId = networkChainIdMap[pool.network];
|
|
89
|
+
let inactiveMarketResult;
|
|
90
|
+
try {
|
|
91
|
+
inactiveMarketResult = await axios.get(
|
|
92
|
+
`${pendleBaseUrl}/${networkId}/markets/inactive`
|
|
93
|
+
);
|
|
94
|
+
} catch (e) {
|
|
95
|
+
console.error("Error in Pendle API request:", e);
|
|
96
|
+
throw new ApiError("Pendle api request failed");
|
|
97
|
+
}
|
|
98
|
+
const allInactiveMarkets = inactiveMarketResult.data.markets;
|
|
99
|
+
const markets = [tokenIn, tokenOut].map(token =>
|
|
100
|
+
allInactiveMarkets.find(
|
|
101
|
+
(market: any) => market.pt === `${networkId}-${token.toLocaleLowerCase()}`
|
|
102
|
+
)
|
|
103
|
+
);
|
|
104
|
+
if (markets[0]) {
|
|
105
|
+
checkUnderlying(markets[0], tokenOut, networkId);
|
|
106
|
+
return markets[0].address;
|
|
107
|
+
} else if (markets[1]) {
|
|
108
|
+
throw new Error("Can not trade to expired PT asset");
|
|
109
|
+
} else {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const getExitExpPTTxData = (
|
|
115
|
+
pool: Pool,
|
|
116
|
+
tokenOut: string,
|
|
117
|
+
amountIn: ethers.BigNumber | string,
|
|
118
|
+
market: string
|
|
119
|
+
) => {
|
|
120
|
+
const actionMiscV3 = new ethers.utils.Interface(ActionMiscV3Abi);
|
|
121
|
+
const txData = actionMiscV3.encodeFunctionData("exitPostExpToToken", [
|
|
122
|
+
pool.address, // receiver
|
|
123
|
+
market, // market
|
|
124
|
+
amountIn.toString(), // netPtIn
|
|
125
|
+
0, // netLpIn
|
|
126
|
+
[
|
|
127
|
+
tokenOut,
|
|
128
|
+
0, // minTokenOut
|
|
129
|
+
tokenOut, // tokenRedeemSy,
|
|
130
|
+
ethers.constants.AddressZero, //pendleSwap;
|
|
131
|
+
// swapData
|
|
132
|
+
[
|
|
133
|
+
0, // swapType
|
|
134
|
+
ethers.constants.AddressZero, // extRouter
|
|
135
|
+
ethers.constants.HashZero, // extCalldata
|
|
136
|
+
false // needScale
|
|
137
|
+
]
|
|
138
|
+
]
|
|
139
|
+
]);
|
|
140
|
+
return txData;
|
|
141
|
+
};
|
package/src/test/constants.ts
CHANGED
|
@@ -42,7 +42,8 @@ export const TEST_POOL = {
|
|
|
42
42
|
[Network.POLYGON]: "0x699fd4d6eadb216704c7e355cfa0a12f51813163",
|
|
43
43
|
[Network.OPTIMISM]: "0x12573bfdf764ab9d52aca20e2827497a66829716",
|
|
44
44
|
[Network.ARBITRUM]: "0x0b5f6591c8eb23e5a68102d3d39ebbb464ee5c14",
|
|
45
|
-
[Network.BASE]: "0x4842b42F68524383F609aa46eAfc18c1459cE3cD"
|
|
45
|
+
[Network.BASE]: "0x4842b42F68524383F609aa46eAfc18c1459cE3cD",
|
|
46
|
+
[Network.SONIC]: ""
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
export const CONTRACT_ADDRESS = {
|
|
@@ -151,7 +152,8 @@ export const CONTRACT_ADDRESS = {
|
|
|
151
152
|
VELODROME_CL_USDC_WETH_GAUGE: "",
|
|
152
153
|
VELO: "",
|
|
153
154
|
COMPOUNDV3_WETH: "",
|
|
154
|
-
TOROS: ""
|
|
155
|
+
TOROS: "",
|
|
156
|
+
UNIT: ""
|
|
155
157
|
}
|
|
156
158
|
};
|
|
157
159
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
|
|
3
|
+
import { Dhedge, Pool } from "..";
|
|
4
|
+
|
|
5
|
+
import { Dapp, Network } from "../types";
|
|
6
|
+
import { CONTRACT_ADDRESS, MAX_AMOUNT } from "./constants";
|
|
7
|
+
import {
|
|
8
|
+
TestingRunParams,
|
|
9
|
+
setTokenAmount,
|
|
10
|
+
setUSDCAmount,
|
|
11
|
+
testingHelper,
|
|
12
|
+
wait
|
|
13
|
+
} from "./utils/testingHelper";
|
|
14
|
+
|
|
15
|
+
import { getTxOptions } from "./txOptions";
|
|
16
|
+
import BigNumber from "bignumber.js";
|
|
17
|
+
import { balanceDelta } from "./utils/token";
|
|
18
|
+
|
|
19
|
+
const testPendle = ({ wallet, network, provider }: TestingRunParams) => {
|
|
20
|
+
const USDC = CONTRACT_ADDRESS[network].USDC;
|
|
21
|
+
const weETH = "0x35751007a407ca6feffe80b3cb397736d2cf4dbe";
|
|
22
|
+
const PTweETH = "0xb33808ea0e883138680ba29311a220a7377cdb92";
|
|
23
|
+
const PTweETH_matured = "0xe2b2d203577c7cb3d043e89ccf90b5e24d19b66f";
|
|
24
|
+
|
|
25
|
+
let dhedge: Dhedge;
|
|
26
|
+
let pool: Pool;
|
|
27
|
+
jest.setTimeout(100000);
|
|
28
|
+
|
|
29
|
+
describe(`pool on ${network}`, () => {
|
|
30
|
+
beforeAll(async () => {
|
|
31
|
+
dhedge = new Dhedge(wallet, network);
|
|
32
|
+
pool = await dhedge.loadPool(wallet.address, false);
|
|
33
|
+
// top up gas
|
|
34
|
+
await provider.send("hardhat_setBalance", [
|
|
35
|
+
wallet.address,
|
|
36
|
+
"0x10000000000000000"
|
|
37
|
+
]);
|
|
38
|
+
await provider.send("evm_mine", []);
|
|
39
|
+
// top up USDC
|
|
40
|
+
await setUSDCAmount({
|
|
41
|
+
amount: new BigNumber(2000).times(1e6).toFixed(0),
|
|
42
|
+
userAddress: pool.address,
|
|
43
|
+
network,
|
|
44
|
+
provider
|
|
45
|
+
});
|
|
46
|
+
await pool.approve(Dapp.ODOS, USDC, MAX_AMOUNT);
|
|
47
|
+
await pool.trade(
|
|
48
|
+
Dapp.ODOS,
|
|
49
|
+
USDC,
|
|
50
|
+
weETH,
|
|
51
|
+
"2000000000",
|
|
52
|
+
0.5,
|
|
53
|
+
await getTxOptions(network)
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("swaps weETH to PTweETH on Pendle", async () => {
|
|
58
|
+
await pool.approve(Dapp.PENDLE, weETH, MAX_AMOUNT);
|
|
59
|
+
const weEthBalance = await pool.utils.getBalance(weETH, pool.address);
|
|
60
|
+
await pool.trade(
|
|
61
|
+
Dapp.PENDLE,
|
|
62
|
+
weETH,
|
|
63
|
+
PTweETH,
|
|
64
|
+
weEthBalance,
|
|
65
|
+
0.5,
|
|
66
|
+
await getTxOptions(network)
|
|
67
|
+
);
|
|
68
|
+
const ptWeEthBalanceDelta = await balanceDelta(
|
|
69
|
+
pool.address,
|
|
70
|
+
PTweETH,
|
|
71
|
+
pool.signer
|
|
72
|
+
);
|
|
73
|
+
expect(ptWeEthBalanceDelta.gt(0));
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("swaps PTweETH to weETH on Pendle", async () => {
|
|
77
|
+
await pool.approve(Dapp.PENDLE, PTweETH, MAX_AMOUNT);
|
|
78
|
+
const PTweEthBalance = await pool.utils.getBalance(PTweETH, pool.address);
|
|
79
|
+
console.log("PTweEthBalance", PTweEthBalance.toString());
|
|
80
|
+
await wait(3);
|
|
81
|
+
await pool.trade(
|
|
82
|
+
Dapp.PENDLE,
|
|
83
|
+
PTweETH,
|
|
84
|
+
weETH,
|
|
85
|
+
PTweEthBalance,
|
|
86
|
+
0.5,
|
|
87
|
+
await getTxOptions(network)
|
|
88
|
+
);
|
|
89
|
+
const weEthBalanceDelta = await balanceDelta(
|
|
90
|
+
pool.address,
|
|
91
|
+
weETH,
|
|
92
|
+
pool.signer
|
|
93
|
+
);
|
|
94
|
+
expect(weEthBalanceDelta.gt(0));
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("exit matured PTweETH to weETH on Pendle", async () => {
|
|
98
|
+
await setTokenAmount({
|
|
99
|
+
amount: new BigNumber(1).times(1e18).toString(),
|
|
100
|
+
provider,
|
|
101
|
+
tokenAddress: PTweETH_matured,
|
|
102
|
+
slot: 0,
|
|
103
|
+
userAddress: pool.address
|
|
104
|
+
});
|
|
105
|
+
await pool.approve(Dapp.PENDLE, PTweETH_matured, MAX_AMOUNT);
|
|
106
|
+
const PTweEthBalance = await pool.utils.getBalance(
|
|
107
|
+
PTweETH_matured,
|
|
108
|
+
pool.address
|
|
109
|
+
);
|
|
110
|
+
await wait(3);
|
|
111
|
+
await pool.trade(
|
|
112
|
+
Dapp.PENDLE,
|
|
113
|
+
PTweETH_matured,
|
|
114
|
+
weETH,
|
|
115
|
+
PTweEthBalance,
|
|
116
|
+
0.5,
|
|
117
|
+
await getTxOptions(network)
|
|
118
|
+
);
|
|
119
|
+
const weEthBalanceDelta = await balanceDelta(
|
|
120
|
+
pool.address,
|
|
121
|
+
weETH,
|
|
122
|
+
pool.signer
|
|
123
|
+
);
|
|
124
|
+
expect(weEthBalanceDelta.eq(PTweEthBalance));
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
testingHelper({
|
|
130
|
+
network: Network.ARBITRUM,
|
|
131
|
+
testingRun: testPendle
|
|
132
|
+
});
|