@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
package/src/test/lyra.test.ts
CHANGED
|
@@ -1,164 +1,173 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
import { utils } from "ethers";
|
|
1
3
|
import { Dhedge } from "..";
|
|
2
4
|
import { Network } from "../types";
|
|
3
|
-
import {
|
|
4
|
-
import { SUSD, TEST_POOL } from "./constants";
|
|
5
|
+
import { CONTRACT_ADDRESS, TEST_POOL } from "./constants";
|
|
5
6
|
import { getTxOptions } from "./txOptions";
|
|
6
|
-
import {
|
|
7
|
+
import { TestingRunParams, testingHelper } from "./utils/testingHelper";
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
const
|
|
9
|
+
const testLyra = ({ wallet, network }: TestingRunParams) => {
|
|
10
|
+
const SUSD = CONTRACT_ADDRESS[network].SUSD;
|
|
10
11
|
|
|
11
|
-
describe("pool", () => {
|
|
12
12
|
let dhedge: Dhedge;
|
|
13
|
-
|
|
14
|
-
beforeAll(async () => {
|
|
15
|
-
dhedge = new Dhedge(wallet, Network.OPTIMISM);
|
|
16
|
-
});
|
|
13
|
+
jest.setTimeout(100000);
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
let
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
1666944000,
|
|
25
|
-
1400,
|
|
26
|
-
"call",
|
|
27
|
-
"buy",
|
|
28
|
-
utils.parseEther("0.1"),
|
|
29
|
-
SUSD
|
|
30
|
-
);
|
|
31
|
-
} catch (e) {
|
|
32
|
-
console.log(e);
|
|
33
|
-
}
|
|
34
|
-
result.wait(1);
|
|
35
|
-
const positions = await pool.getLyraPositions("eth");
|
|
36
|
-
expect(positions.length > 0);
|
|
37
|
-
});
|
|
15
|
+
describe(`pool on ${network}`, () => {
|
|
16
|
+
let options: any;
|
|
17
|
+
beforeAll(async () => {
|
|
18
|
+
options = await getTxOptions(network);
|
|
19
|
+
dhedge = new Dhedge(wallet, network);
|
|
20
|
+
});
|
|
38
21
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const positions = await pool.getLyraPositions("eth");
|
|
60
|
-
expect(utils.formatEther(positions[0].amount)).toBe("0.15");
|
|
61
|
-
});
|
|
22
|
+
it("buys 0.1 1400 calls with expiry October 28th", async () => {
|
|
23
|
+
let result;
|
|
24
|
+
const pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
25
|
+
try {
|
|
26
|
+
result = await pool.tradeLyraOption(
|
|
27
|
+
"eth",
|
|
28
|
+
1666944000,
|
|
29
|
+
1400,
|
|
30
|
+
"call",
|
|
31
|
+
"buy",
|
|
32
|
+
utils.parseEther("0.1"),
|
|
33
|
+
SUSD
|
|
34
|
+
);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.log(e);
|
|
37
|
+
}
|
|
38
|
+
result.wait(1);
|
|
39
|
+
const positions = await pool.getLyraPositions("eth");
|
|
40
|
+
expect(positions.length > 0);
|
|
41
|
+
});
|
|
62
42
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
});
|
|
43
|
+
it("adds 0.05 1400 calls with expiry October 28th", async () => {
|
|
44
|
+
let result;
|
|
45
|
+
const pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
46
|
+
try {
|
|
47
|
+
result = await pool.tradeLyraOption(
|
|
48
|
+
"eth",
|
|
49
|
+
1666944000,
|
|
50
|
+
1400,
|
|
51
|
+
"call",
|
|
52
|
+
"buy",
|
|
53
|
+
utils.parseEther("0.05"),
|
|
54
|
+
SUSD,
|
|
55
|
+
"0",
|
|
56
|
+
false,
|
|
57
|
+
options
|
|
58
|
+
);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
console.log(e);
|
|
61
|
+
}
|
|
62
|
+
result.wait(1);
|
|
63
|
+
const positions = await pool.getLyraPositions("eth");
|
|
64
|
+
expect(utils.formatEther(positions[0].amount)).toBe("0.15");
|
|
65
|
+
});
|
|
87
66
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
expect(utils.formatEther(cCall!.amount)).toBe("0.15");
|
|
113
|
-
});
|
|
67
|
+
it("sells 0.1 1300 Covered Call with expiry October 28th", async () => {
|
|
68
|
+
let result;
|
|
69
|
+
const pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
70
|
+
try {
|
|
71
|
+
result = await pool.tradeLyraOption(
|
|
72
|
+
"eth",
|
|
73
|
+
1666944000,
|
|
74
|
+
1300,
|
|
75
|
+
"call",
|
|
76
|
+
"sell",
|
|
77
|
+
utils.parseEther("0.1"),
|
|
78
|
+
SUSD,
|
|
79
|
+
utils.parseEther("0.1"),
|
|
80
|
+
true,
|
|
81
|
+
options
|
|
82
|
+
);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
console.log(e);
|
|
85
|
+
}
|
|
86
|
+
result.wait(1);
|
|
87
|
+
const positions = await pool.getLyraPositions("eth");
|
|
88
|
+
const cCall = positions.find(e => e.optionType === 2);
|
|
89
|
+
expect(cCall).not.toBe(undefined);
|
|
90
|
+
});
|
|
114
91
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
92
|
+
it("adds 0.05 1300 Covered Call with expiry October 28th", async () => {
|
|
93
|
+
let result;
|
|
94
|
+
const pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
95
|
+
try {
|
|
96
|
+
result = await pool.tradeLyraOption(
|
|
97
|
+
"eth",
|
|
98
|
+
1666944000,
|
|
99
|
+
1300,
|
|
100
|
+
"call",
|
|
101
|
+
"sell",
|
|
102
|
+
utils.parseEther("0.05"),
|
|
103
|
+
SUSD,
|
|
104
|
+
utils.parseEther("0.05"),
|
|
105
|
+
true,
|
|
106
|
+
options
|
|
107
|
+
);
|
|
108
|
+
} catch (e) {
|
|
109
|
+
console.log(e);
|
|
110
|
+
}
|
|
111
|
+
result.wait(1);
|
|
112
|
+
const positions = await pool.getLyraPositions("eth");
|
|
113
|
+
const cCall = positions.find(e => e.optionType === 2);
|
|
114
|
+
expect(cCall);
|
|
115
|
+
expect(utils.formatEther(cCall!.amount)).toBe("0.15");
|
|
116
|
+
});
|
|
139
117
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
118
|
+
it("closes all 0.15 1300 Covered Call with expiry October 28th", async () => {
|
|
119
|
+
let result;
|
|
120
|
+
const pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
121
|
+
try {
|
|
122
|
+
result = await pool.tradeLyraOption(
|
|
123
|
+
"eth",
|
|
124
|
+
1666944000,
|
|
125
|
+
1300,
|
|
126
|
+
"call",
|
|
127
|
+
"buy",
|
|
128
|
+
utils.parseEther("0.15"),
|
|
129
|
+
SUSD,
|
|
130
|
+
utils.parseEther("0.15"),
|
|
131
|
+
true,
|
|
132
|
+
options
|
|
133
|
+
);
|
|
134
|
+
} catch (e) {
|
|
135
|
+
console.log(e);
|
|
136
|
+
}
|
|
137
|
+
result.wait(1);
|
|
138
|
+
const positions = await pool.getLyraPositions("eth");
|
|
139
|
+
const cCall = positions.find(e => e.optionType === 2 && e.state === 1);
|
|
140
|
+
expect(cCall).toBe(undefined);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("closes all 0.15 1400 Calls with expiry October 28th", async () => {
|
|
144
|
+
let result;
|
|
145
|
+
const pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
146
|
+
try {
|
|
147
|
+
result = await pool.tradeLyraOption(
|
|
148
|
+
"eth",
|
|
149
|
+
1666944000,
|
|
150
|
+
1400,
|
|
151
|
+
"call",
|
|
152
|
+
"sell",
|
|
153
|
+
utils.parseEther("0.15"),
|
|
154
|
+
SUSD,
|
|
155
|
+
"0",
|
|
156
|
+
false,
|
|
157
|
+
options
|
|
158
|
+
);
|
|
159
|
+
} catch (e) {
|
|
160
|
+
console.log(e);
|
|
161
|
+
}
|
|
162
|
+
result.wait(1);
|
|
163
|
+
const positions = await pool.getLyraPositions("eth");
|
|
164
|
+
const call = positions.find(e => e.optionType === 0 && e.state === 1);
|
|
165
|
+
expect(call).toBe(undefined);
|
|
166
|
+
});
|
|
163
167
|
});
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
testingHelper({
|
|
171
|
+
network: Network.OPTIMISM,
|
|
172
|
+
testingRun: testLyra
|
|
164
173
|
});
|
package/src/test/odos.test.ts
CHANGED
|
@@ -50,7 +50,7 @@ const testOdos = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
50
50
|
routerAddress[network]["odos"]!,
|
|
51
51
|
pool.signer
|
|
52
52
|
);
|
|
53
|
-
|
|
53
|
+
expect(usdcAllowanceDelta.gt(0)).toBe(true);
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
it("gets gas estimation for 10 USDC into WETH on Odos", async () => {
|
|
@@ -82,7 +82,7 @@ const testOdos = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
82
82
|
WETH,
|
|
83
83
|
pool.signer
|
|
84
84
|
);
|
|
85
|
-
expect(wethBalanceDelta.gt(0));
|
|
85
|
+
expect(wethBalanceDelta.gt(0)).toBe(true);
|
|
86
86
|
const wethBalanceDeltaForFeeRecipient = await balanceDelta(
|
|
87
87
|
OdosSwapFeeRecipient[network],
|
|
88
88
|
WETH,
|
package/src/test/oneInch.test.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
2
|
|
|
3
|
+
import BigNumber from "bignumber.js";
|
|
4
|
+
import { ethers } from "ethers";
|
|
3
5
|
import { Dhedge, Pool } from "..";
|
|
4
6
|
|
|
7
|
+
import { routerAddress } from "../config";
|
|
5
8
|
import { Dapp, Network } from "../types";
|
|
6
9
|
import { CONTRACT_ADDRESS, MAX_AMOUNT, TEST_POOL } from "./constants";
|
|
10
|
+
import { getTxOptions } from "./txOptions";
|
|
7
11
|
import {
|
|
8
12
|
TestingRunParams,
|
|
13
|
+
fixOracleAggregatorStaleness,
|
|
14
|
+
runWithImpersonateAccount,
|
|
15
|
+
setChainlinkTimeout,
|
|
9
16
|
setUSDCAmount,
|
|
10
17
|
testingHelper,
|
|
11
18
|
wait
|
|
12
19
|
} from "./utils/testingHelper";
|
|
13
|
-
import {
|
|
14
|
-
import { getTxOptions } from "./txOptions";
|
|
15
|
-
import BigNumber from "bignumber.js";
|
|
16
|
-
import { routerAddress } from "../config";
|
|
17
|
-
// import { routerAddress } from "../config";
|
|
20
|
+
import { balanceDelta } from "./utils/token";
|
|
18
21
|
|
|
19
22
|
const testOneInch = ({ wallet, network, provider }: TestingRunParams) => {
|
|
20
23
|
const USDC = CONTRACT_ADDRESS[network].USDC;
|
|
@@ -26,22 +29,30 @@ const testOneInch = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
26
29
|
|
|
27
30
|
describe(`pool on ${network}`, () => {
|
|
28
31
|
beforeAll(async () => {
|
|
29
|
-
dhedge = new Dhedge(wallet, network);
|
|
30
|
-
pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
31
|
-
// top up gas
|
|
32
32
|
await provider.send("hardhat_setBalance", [
|
|
33
33
|
wallet.address,
|
|
34
34
|
"0x10000000000000000"
|
|
35
35
|
]);
|
|
36
|
-
|
|
36
|
+
dhedge = new Dhedge(wallet, network);
|
|
37
|
+
pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
await setChainlinkTimeout({ pool, provider }, 86400 * 365);
|
|
40
|
+
await fixOracleAggregatorStaleness({ pool, provider });
|
|
41
|
+
|
|
42
|
+
await runWithImpersonateAccount(
|
|
43
|
+
{ provider, account: await pool.managerLogic.manager() },
|
|
44
|
+
async ({ signer }) => {
|
|
45
|
+
await pool.managerLogic.connect(signer).setTrader(wallet.address);
|
|
46
|
+
await pool.managerLogic.connect(signer).changeAssets(
|
|
47
|
+
[
|
|
48
|
+
[USDC, true],
|
|
49
|
+
[WETH, true]
|
|
50
|
+
],
|
|
51
|
+
[]
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
);
|
|
42
55
|
|
|
43
|
-
await pool.managerLogic.changeAssets(newAssets, []);
|
|
44
|
-
// top up USDC
|
|
45
56
|
await setUSDCAmount({
|
|
46
57
|
amount: new BigNumber(2).times(1e6).toFixed(0),
|
|
47
58
|
userAddress: pool.address,
|
|
@@ -52,13 +63,16 @@ const testOneInch = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
52
63
|
|
|
53
64
|
it("approves unlimited USDC on 1Inch", async () => {
|
|
54
65
|
await pool.approve(Dapp.ONEINCH, USDC, MAX_AMOUNT);
|
|
55
|
-
const
|
|
56
|
-
pool.address,
|
|
66
|
+
const iERC20 = new ethers.Contract(
|
|
57
67
|
USDC,
|
|
58
|
-
|
|
68
|
+
["function allowance(address,address) view returns (uint256)"],
|
|
59
69
|
pool.signer
|
|
60
70
|
);
|
|
61
|
-
await
|
|
71
|
+
const usdcAllowance = await iERC20.allowance(
|
|
72
|
+
pool.address,
|
|
73
|
+
routerAddress[network][Dapp.ONEINCH]!
|
|
74
|
+
);
|
|
75
|
+
expect(usdcAllowance.gt(0)).toBe(true);
|
|
62
76
|
});
|
|
63
77
|
|
|
64
78
|
it("gets gas estimation for 2 USDC into WETH on 1Inch", async () => {
|
|
@@ -71,7 +85,7 @@ const testOneInch = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
71
85
|
await getTxOptions(network),
|
|
72
86
|
true
|
|
73
87
|
);
|
|
74
|
-
expect(gasEstimate.gas.gt(0));
|
|
88
|
+
expect(gasEstimate.gas.gt(0)).toBe(true);
|
|
75
89
|
expect(gasEstimate.minAmountOut).not.toBeNull();
|
|
76
90
|
});
|
|
77
91
|
|
|
@@ -104,13 +118,13 @@ const testOneInch = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
104
118
|
WETH,
|
|
105
119
|
pool.signer
|
|
106
120
|
);
|
|
107
|
-
expect(wethBalanceDelta.gt(0));
|
|
121
|
+
expect(wethBalanceDelta.gt(0)).toBe(true);
|
|
108
122
|
});
|
|
109
123
|
});
|
|
110
124
|
};
|
|
111
125
|
|
|
112
126
|
testingHelper({
|
|
113
|
-
network: Network.
|
|
127
|
+
network: Network.ARBITRUM,
|
|
114
128
|
testingRun: testOneInch
|
|
115
129
|
});
|
|
116
130
|
|
|
@@ -1,23 +1,31 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
import BigNumber from "bignumber.js";
|
|
1
3
|
import { Dhedge, Pool, ethers } from "..";
|
|
2
4
|
|
|
3
5
|
import { nonfungiblePositionManagerAddress, stakingAddress } from "../config";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
+
import { Dapp, Network } from "../types";
|
|
7
|
+
import {
|
|
8
|
+
CONTRACT_ADDRESS,
|
|
9
|
+
MAX_AMOUNT,
|
|
10
|
+
TEST_POOL,
|
|
11
|
+
USDC_BALANCEOF_SLOT
|
|
12
|
+
} from "./constants";
|
|
6
13
|
import {
|
|
7
14
|
TestingRunParams,
|
|
8
15
|
beforeAfterReset,
|
|
16
|
+
fixOracleAggregatorStaleness,
|
|
17
|
+
runWithImpersonateAccount,
|
|
9
18
|
setChainlinkTimeout,
|
|
19
|
+
setTokenAmount,
|
|
10
20
|
testingHelper
|
|
11
21
|
} from "./utils/testingHelper";
|
|
12
|
-
import {
|
|
22
|
+
import { balanceDelta } from "./utils/token";
|
|
13
23
|
import INonfungiblePositionManager from "../abi/INonfungiblePositionManager.json";
|
|
14
24
|
|
|
15
25
|
const testPancakeCL = ({ wallet, network, provider }: TestingRunParams) => {
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
17
26
|
const PANCAKE_POSITION_MANGER = nonfungiblePositionManagerAddress[network][
|
|
18
27
|
Dapp.PANCAKECL
|
|
19
28
|
]!;
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
21
29
|
const GAUGE = stakingAddress[network][Dapp.PANCAKECL]!;
|
|
22
30
|
|
|
23
31
|
const USDC = CONTRACT_ADDRESS[network].USDC;
|
|
@@ -31,27 +39,45 @@ const testPancakeCL = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
31
39
|
|
|
32
40
|
describe(`[${network}] Pancake CL tests`, () => {
|
|
33
41
|
beforeAll(async () => {
|
|
34
|
-
await provider.send("evm_mine", []);
|
|
35
|
-
// top up ETH (gas)
|
|
36
42
|
await provider.send("hardhat_setBalance", [
|
|
37
43
|
wallet.address,
|
|
38
|
-
"
|
|
44
|
+
"0x10000000000000000"
|
|
39
45
|
]);
|
|
40
46
|
dhedge = new Dhedge(wallet, network);
|
|
41
47
|
pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
42
48
|
|
|
43
|
-
// setChainlinkTimeout
|
|
44
49
|
await setChainlinkTimeout({ pool, provider }, 86400 * 365);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
{
|
|
49
|
-
{
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
await fixOracleAggregatorStaleness({ pool, provider });
|
|
51
|
+
|
|
52
|
+
await runWithImpersonateAccount(
|
|
53
|
+
{ provider, account: await pool.managerLogic.manager() },
|
|
54
|
+
async ({ signer }) => {
|
|
55
|
+
await pool.managerLogic.connect(signer).setTrader(wallet.address);
|
|
56
|
+
await pool.managerLogic.connect(signer).changeAssets(
|
|
57
|
+
[
|
|
58
|
+
[USDC, true],
|
|
59
|
+
[USDT, true],
|
|
60
|
+
[PANCAKE_POSITION_MANGER, false]
|
|
61
|
+
],
|
|
62
|
+
[]
|
|
63
|
+
);
|
|
52
64
|
}
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
await setTokenAmount({
|
|
68
|
+
amount: new BigNumber(1000).times(1e6).toFixed(0),
|
|
69
|
+
userAddress: pool.address,
|
|
70
|
+
tokenAddress: USDC,
|
|
71
|
+
slot: USDC_BALANCEOF_SLOT[network],
|
|
72
|
+
provider
|
|
73
|
+
});
|
|
74
|
+
await setTokenAmount({
|
|
75
|
+
amount: new BigNumber(1000).times(1e6).toFixed(0),
|
|
76
|
+
userAddress: pool.address,
|
|
77
|
+
tokenAddress: USDT,
|
|
78
|
+
slot: 0,
|
|
79
|
+
provider
|
|
80
|
+
});
|
|
55
81
|
|
|
56
82
|
positionManager = new ethers.Contract(
|
|
57
83
|
PANCAKE_POSITION_MANGER,
|
|
@@ -63,16 +89,19 @@ const testPancakeCL = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
63
89
|
beforeAfterReset({ beforeAll, afterAll, provider });
|
|
64
90
|
|
|
65
91
|
describe("Liquidity", () => {
|
|
66
|
-
it("approves unlimited USDC and USDT on for
|
|
92
|
+
it("approves unlimited USDC and USDT on for Pancake CL", async () => {
|
|
67
93
|
await pool.approveSpender(PANCAKE_POSITION_MANGER, USDC, MAX_AMOUNT);
|
|
68
94
|
await pool.approveSpender(PANCAKE_POSITION_MANGER, USDT, MAX_AMOUNT);
|
|
69
|
-
const
|
|
70
|
-
pool.address,
|
|
95
|
+
const iERC20 = new ethers.Contract(
|
|
71
96
|
USDC,
|
|
72
|
-
|
|
97
|
+
["function allowance(address,address) view returns (uint256)"],
|
|
73
98
|
pool.signer
|
|
74
99
|
);
|
|
75
|
-
await
|
|
100
|
+
const usdcAllowance = await iERC20.allowance(
|
|
101
|
+
pool.address,
|
|
102
|
+
PANCAKE_POSITION_MANGER
|
|
103
|
+
);
|
|
104
|
+
expect(usdcAllowance.gt(0)).toBe(true);
|
|
76
105
|
});
|
|
77
106
|
|
|
78
107
|
it("adds USDC and USDT to a CL (mint position)", async () => {
|
|
@@ -108,21 +137,24 @@ const testPancakeCL = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
108
137
|
usdtBalance.div(2)
|
|
109
138
|
);
|
|
110
139
|
const positionAfter = await positionManager.positions(tokenId);
|
|
111
|
-
expect(positionAfter.liquidity.gt(positionBefore.liquidity));
|
|
140
|
+
expect(positionAfter.liquidity.gt(positionBefore.liquidity)).toBe(true);
|
|
112
141
|
});
|
|
113
142
|
|
|
114
143
|
it("decreases liquidity from a CL position", async () => {
|
|
115
144
|
const positionBefore = await positionManager.positions(tokenId);
|
|
116
145
|
await pool.decreaseLiquidity(Dapp.PANCAKECL, tokenId, 50);
|
|
117
146
|
const positionAfter = await positionManager.positions(tokenId);
|
|
118
|
-
expect(positionAfter.liquidity.lt(positionBefore.liquidity));
|
|
147
|
+
expect(positionAfter.liquidity.lt(positionBefore.liquidity)).toBe(true);
|
|
119
148
|
});
|
|
120
149
|
|
|
121
150
|
it("collects fess of a CL position", async () => {
|
|
122
|
-
await provider.send("evm_increaseTime", [24 * 3600 * 3]); //
|
|
151
|
+
await provider.send("evm_increaseTime", [24 * 3600 * 3]); // 3 days
|
|
123
152
|
await provider.send("evm_mine", []);
|
|
124
153
|
await pool.claimFees(Dapp.PANCAKECL, tokenId);
|
|
125
|
-
|
|
154
|
+
// Fork has no trading activity during evm_increaseTime so no fees accrue — assert gte(0) to verify the call succeeds
|
|
155
|
+
expect(
|
|
156
|
+
(await balanceDelta(pool.address, USDC, pool.signer)).gte(0)
|
|
157
|
+
).toBe(true);
|
|
126
158
|
});
|
|
127
159
|
});
|
|
128
160
|
describe("Liquidity staking", () => {
|
|
@@ -164,18 +196,19 @@ const testPancakeCL = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
164
196
|
usdtBalance.div(2)
|
|
165
197
|
);
|
|
166
198
|
const positionAfter = await positionManager.positions(tokenId);
|
|
167
|
-
expect(positionAfter.liquidity.gt(positionBefore.liquidity));
|
|
199
|
+
expect(positionAfter.liquidity.gt(positionBefore.liquidity)).toBe(true);
|
|
168
200
|
});
|
|
169
201
|
|
|
170
202
|
it("collects fess from a staked CL position", async () => {
|
|
171
|
-
await pool.claimFees(Dapp.PANCAKECL, tokenId);
|
|
203
|
+
const tx = await pool.claimFees(Dapp.PANCAKECL, tokenId);
|
|
204
|
+
expect(tx).toBeDefined();
|
|
172
205
|
});
|
|
173
206
|
|
|
174
207
|
it("decreases liquidity from a CL position", async () => {
|
|
175
208
|
const positionBefore = await positionManager.positions(tokenId);
|
|
176
209
|
await pool.decreaseLiquidity(Dapp.PANCAKECL, tokenId, 50);
|
|
177
210
|
const positionAfter = await positionManager.positions(tokenId);
|
|
178
|
-
expect(positionAfter.liquidity.lt(positionBefore.liquidity));
|
|
211
|
+
expect(positionAfter.liquidity.lt(positionBefore.liquidity)).toBe(true);
|
|
179
212
|
});
|
|
180
213
|
|
|
181
214
|
it("unstakes a CL position from a gauge", async () => {
|
|
@@ -188,7 +221,15 @@ const testPancakeCL = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
188
221
|
it("remove all liquidity from a staked CL position", async () => {
|
|
189
222
|
await pool.stakeInGauge(Dapp.PANCAKECL, GAUGE, tokenId);
|
|
190
223
|
await pool.decreaseLiquidity(Dapp.PANCAKECL, tokenId, 100);
|
|
191
|
-
|
|
224
|
+
// (a) NFT burned — ownerOf reverts for non-existent tokenId
|
|
225
|
+
await expect(positionManager.ownerOf(tokenId)).rejects.toThrow();
|
|
226
|
+
// (b) position data cleared — liquidity is 0 (or positions() reverts post-burn)
|
|
227
|
+
try {
|
|
228
|
+
const positionAfter = await positionManager.positions(tokenId);
|
|
229
|
+
expect(positionAfter.liquidity.eq(0)).toBe(true);
|
|
230
|
+
} catch {
|
|
231
|
+
// positions() reverted — acceptable for burned tokens on some NPM implementations
|
|
232
|
+
}
|
|
192
233
|
});
|
|
193
234
|
});
|
|
194
235
|
});
|