@dhedge/v2-sdk 1.5.3 → 1.5.4
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/entities/pool.d.ts +23 -1
- package/dist/services/velodrome/liquidity.d.ts +4 -0
- package/dist/services/velodrome/staking.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 +2508 -288
- 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 +2506 -286
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/abi/IVeldodromeRouter.json +438 -0
- package/src/abi/IVelodromeGauge.json +559 -0
- package/src/config.ts +2 -1
- package/src/entities/pool.ts +106 -19
- package/src/services/velodrome/liquidity.ts +48 -0
- package/src/services/velodrome/staking.ts +31 -0
- package/src/test/constants.ts +2 -0
- package/src/test/velodrome.test.ts +141 -0
- package/src/types.ts +2 -1
package/src/entities/pool.ts
CHANGED
|
@@ -43,6 +43,14 @@ import { getUniswapV3SwapTxData } from "../services/uniswap/V3Trade";
|
|
|
43
43
|
import { getEasySwapperTxData } from "../services/toros/easySwapper";
|
|
44
44
|
import { getOneInchProtocols } from "../services/oneInch/protocols";
|
|
45
45
|
import { getAaveV3ClaimTxData } from "../services/aave/incentives";
|
|
46
|
+
import {
|
|
47
|
+
getVelodromeAddLiquidityTxData,
|
|
48
|
+
getVelodromeRemoveLiquidityTxData
|
|
49
|
+
} from "../services/velodrome/liquidity";
|
|
50
|
+
import {
|
|
51
|
+
getVelodromeClaimTxData,
|
|
52
|
+
getVelodromeStakeTxData
|
|
53
|
+
} from "../services/velodrome/staking";
|
|
46
54
|
|
|
47
55
|
export class Pool {
|
|
48
56
|
public readonly poolLogic: Contract;
|
|
@@ -430,20 +438,34 @@ export class Pool {
|
|
|
430
438
|
|
|
431
439
|
/**
|
|
432
440
|
* Stake liquidity pool tokens in gauge contract
|
|
441
|
+
* @param {Dapp} dapp Platform like Balancer or Velodrome
|
|
433
442
|
* @param {string} gauge Gauge contract address
|
|
434
443
|
* @param {BigNumber | string} amount Amount of liquidity pool tokens
|
|
435
444
|
* @param {any} options Transaction options
|
|
436
445
|
* @returns {Promise<any>} Transaction
|
|
437
446
|
*/
|
|
438
447
|
async stakeInGauge(
|
|
448
|
+
dapp: Dapp,
|
|
439
449
|
gauge: string,
|
|
440
450
|
amount: BigNumber | string,
|
|
441
451
|
options: any = null
|
|
442
452
|
): Promise<any> {
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
453
|
+
let stakeTxData;
|
|
454
|
+
switch (dapp) {
|
|
455
|
+
case Dapp.BALANCER:
|
|
456
|
+
const rewardsGauge = new ethers.utils.Interface(
|
|
457
|
+
IBalancerRewardsGauge.abi
|
|
458
|
+
);
|
|
459
|
+
stakeTxData = rewardsGauge.encodeFunctionData("deposit(uint256)", [
|
|
460
|
+
amount
|
|
461
|
+
]);
|
|
462
|
+
break;
|
|
463
|
+
case Dapp.VELODROME:
|
|
464
|
+
stakeTxData = getVelodromeStakeTxData(amount);
|
|
465
|
+
break;
|
|
466
|
+
default:
|
|
467
|
+
throw new Error("dapp not supported");
|
|
468
|
+
}
|
|
447
469
|
const tx = await this.poolLogic.execTransaction(
|
|
448
470
|
gauge,
|
|
449
471
|
stakeTxData,
|
|
@@ -1020,21 +1042,29 @@ export class Pool {
|
|
|
1020
1042
|
): Promise<any> {
|
|
1021
1043
|
let txData;
|
|
1022
1044
|
let contractAddress;
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1045
|
+
switch (dapp) {
|
|
1046
|
+
case Dapp.UNISWAPV3:
|
|
1047
|
+
contractAddress = nonfungiblePositionManagerAddress[this.network];
|
|
1048
|
+
const iNonfungiblePositionManager = new ethers.utils.Interface(
|
|
1049
|
+
INonfungiblePositionManager.abi
|
|
1050
|
+
);
|
|
1051
|
+
txData = iNonfungiblePositionManager.encodeFunctionData(
|
|
1052
|
+
Transaction.COLLECT,
|
|
1053
|
+
[[tokenId, this.address, MaxUint128, MaxUint128]]
|
|
1054
|
+
);
|
|
1055
|
+
break;
|
|
1056
|
+
case Dapp.ARRAKIS:
|
|
1057
|
+
case Dapp.BALANCER:
|
|
1058
|
+
contractAddress = tokenId;
|
|
1059
|
+
const abi = new ethers.utils.Interface(ILiquidityGaugeV4.abi);
|
|
1060
|
+
txData = abi.encodeFunctionData("claim_rewards()", []);
|
|
1061
|
+
break;
|
|
1062
|
+
case Dapp.VELODROME:
|
|
1063
|
+
contractAddress = tokenId;
|
|
1064
|
+
txData = getVelodromeClaimTxData(this, tokenId);
|
|
1065
|
+
break;
|
|
1066
|
+
default:
|
|
1067
|
+
throw new Error("dapp not supported");
|
|
1038
1068
|
}
|
|
1039
1069
|
const tx = await this.poolLogic.execTransaction(
|
|
1040
1070
|
contractAddress,
|
|
@@ -1078,4 +1108,61 @@ export class Pool {
|
|
|
1078
1108
|
);
|
|
1079
1109
|
return tx;
|
|
1080
1110
|
}
|
|
1111
|
+
|
|
1112
|
+
/**
|
|
1113
|
+
* Add liquidity to Velodrome pool
|
|
1114
|
+
* @param {string} assetA First asset
|
|
1115
|
+
* @param {string} assetB Second asset
|
|
1116
|
+
* @param {BigNumber | string} amountA Amount first asset
|
|
1117
|
+
* @param {BigNumber | string} amountB Amount second asset
|
|
1118
|
+
* @param { boolean } isStable Is stable pool
|
|
1119
|
+
* @param {any} options Transaction options
|
|
1120
|
+
* @returns {Promise<any>} Transaction
|
|
1121
|
+
*/
|
|
1122
|
+
async addLiquidityVelodrome(
|
|
1123
|
+
assetA: string,
|
|
1124
|
+
assetB: string,
|
|
1125
|
+
amountA: BigNumber | string,
|
|
1126
|
+
amountB: BigNumber | string,
|
|
1127
|
+
isStable: boolean,
|
|
1128
|
+
options: any = null
|
|
1129
|
+
): Promise<any> {
|
|
1130
|
+
const tx = await this.poolLogic.execTransaction(
|
|
1131
|
+
routerAddress[this.network][Dapp.VELODROME],
|
|
1132
|
+
getVelodromeAddLiquidityTxData(
|
|
1133
|
+
this,
|
|
1134
|
+
assetA,
|
|
1135
|
+
assetB,
|
|
1136
|
+
amountA,
|
|
1137
|
+
amountB,
|
|
1138
|
+
isStable
|
|
1139
|
+
),
|
|
1140
|
+
options
|
|
1141
|
+
);
|
|
1142
|
+
return tx;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
/**
|
|
1146
|
+
* Remove liquidity from Velodrome pool
|
|
1147
|
+
* @param {string} assetA First asset
|
|
1148
|
+
* @param {string} assetB Second asset
|
|
1149
|
+
* @param {BigNumber | string} amount Amount of LP tokens
|
|
1150
|
+
* @param { boolean } isStable Is stable pool
|
|
1151
|
+
* @param {any} options Transaction options
|
|
1152
|
+
* @returns {Promise<any>} Transaction
|
|
1153
|
+
*/
|
|
1154
|
+
async removeLiquidityVelodrome(
|
|
1155
|
+
assetA: string,
|
|
1156
|
+
assetB: string,
|
|
1157
|
+
amount: BigNumber | string,
|
|
1158
|
+
isStable: boolean,
|
|
1159
|
+
options: any = null
|
|
1160
|
+
): Promise<any> {
|
|
1161
|
+
const tx = await this.poolLogic.execTransaction(
|
|
1162
|
+
routerAddress[this.network][Dapp.VELODROME],
|
|
1163
|
+
getVelodromeRemoveLiquidityTxData(this, assetA, assetB, amount, isStable),
|
|
1164
|
+
options
|
|
1165
|
+
);
|
|
1166
|
+
return tx;
|
|
1167
|
+
}
|
|
1081
1168
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { BigNumber, ethers } from "ethers";
|
|
3
|
+
import IVelodromeRouter from "../../abi/IVeldodromeRouter.json";
|
|
4
|
+
import { deadline } from "../../config";
|
|
5
|
+
import { Pool } from "../../entities";
|
|
6
|
+
import { Transaction } from "../../types";
|
|
7
|
+
|
|
8
|
+
export function getVelodromeAddLiquidityTxData(
|
|
9
|
+
pool: Pool,
|
|
10
|
+
assetA: string,
|
|
11
|
+
assetB: string,
|
|
12
|
+
amountA: BigNumber | string,
|
|
13
|
+
amountB: BigNumber | string,
|
|
14
|
+
isStable: boolean
|
|
15
|
+
): any {
|
|
16
|
+
const iVelodromeRouter = new ethers.utils.Interface(IVelodromeRouter.abi);
|
|
17
|
+
return iVelodromeRouter.encodeFunctionData(Transaction.ADD_LIQUIDITY, [
|
|
18
|
+
assetA,
|
|
19
|
+
assetB,
|
|
20
|
+
isStable,
|
|
21
|
+
amountA,
|
|
22
|
+
amountB,
|
|
23
|
+
"0",
|
|
24
|
+
"0",
|
|
25
|
+
pool.address,
|
|
26
|
+
deadline
|
|
27
|
+
]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function getVelodromeRemoveLiquidityTxData(
|
|
31
|
+
pool: Pool,
|
|
32
|
+
assetA: string,
|
|
33
|
+
assetB: string,
|
|
34
|
+
amount: BigNumber | string,
|
|
35
|
+
isStable: boolean
|
|
36
|
+
): any {
|
|
37
|
+
const iVelodromeRouter = new ethers.utils.Interface(IVelodromeRouter.abi);
|
|
38
|
+
return iVelodromeRouter.encodeFunctionData(Transaction.REMOVE_LIQUIDITY, [
|
|
39
|
+
assetA,
|
|
40
|
+
assetB,
|
|
41
|
+
isStable,
|
|
42
|
+
amount,
|
|
43
|
+
"0",
|
|
44
|
+
"0",
|
|
45
|
+
pool.address,
|
|
46
|
+
deadline
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { BigNumber, ethers } from "ethers";
|
|
3
|
+
import IVelodromeGauge from "../../abi/IVelodromeGauge.json";
|
|
4
|
+
import { Pool } from "../../entities";
|
|
5
|
+
import { Transaction } from "../../types";
|
|
6
|
+
import { call } from "../../utils/contract";
|
|
7
|
+
const iVelodromeGauge = new ethers.utils.Interface(IVelodromeGauge.abi);
|
|
8
|
+
|
|
9
|
+
export function getVelodromeStakeTxData(amount: BigNumber | string): any {
|
|
10
|
+
return iVelodromeGauge.encodeFunctionData(Transaction.DEPOSIT, [amount, "0"]);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function getVelodromeClaimTxData(
|
|
14
|
+
pool: Pool,
|
|
15
|
+
gauge: string
|
|
16
|
+
): Promise<any> {
|
|
17
|
+
const rewardAssetCount = await call(pool.signer, IVelodromeGauge.abi, [
|
|
18
|
+
gauge,
|
|
19
|
+
"rewardsListLength",
|
|
20
|
+
[]
|
|
21
|
+
]);
|
|
22
|
+
const rewardAssets = await Promise.all(
|
|
23
|
+
Array.from(Array(rewardAssetCount.toNumber()).keys()).map(e =>
|
|
24
|
+
call(pool.signer, IVelodromeGauge.abi, [gauge, "rewards", [e]])
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
return iVelodromeGauge.encodeFunctionData("getReward", [
|
|
28
|
+
pool.address,
|
|
29
|
+
rewardAssets
|
|
30
|
+
]);
|
|
31
|
+
}
|
package/src/test/constants.ts
CHANGED
|
@@ -26,5 +26,7 @@ export const DAI = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1";
|
|
|
26
26
|
export const USDy = "0x1ec50880101022c11530a069690f5446d1464592";
|
|
27
27
|
export const WBTC = "0x68f180fcCe6836688e9084f035309E29Bf0A2095";
|
|
28
28
|
export const OP = "4200000000000000000000000000000000000042";
|
|
29
|
+
export const WSTETH = "0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb";
|
|
30
|
+
export const VEL = "0x3c8B650257cFb5f272f799F5e2b4e65093a11a05";
|
|
29
31
|
|
|
30
32
|
export const TEST_POOL = "TEST_POOL";
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { Dhedge, ethers } from "..";
|
|
3
|
+
import { Dapp, Network } from "../types";
|
|
4
|
+
import { TEST_POOL, WETH, WSTETH } from "./constants";
|
|
5
|
+
import { getTxOptions } from "./txOptions";
|
|
6
|
+
|
|
7
|
+
import { wallet } from "./wallet";
|
|
8
|
+
|
|
9
|
+
const wETHwstETHLp = "0xBf205335De602ac38244F112d712ab04CB59A498";
|
|
10
|
+
const wETHwstETHGauge = "0x131Ae347E654248671Afc885F0767cB605C065d7";
|
|
11
|
+
|
|
12
|
+
let dhedge: Dhedge;
|
|
13
|
+
let options: any;
|
|
14
|
+
jest.setTimeout(100000);
|
|
15
|
+
|
|
16
|
+
describe("pool", () => {
|
|
17
|
+
beforeAll(async () => {
|
|
18
|
+
dhedge = new Dhedge(wallet, Network.OPTIMISM);
|
|
19
|
+
options = await getTxOptions(Network.OPTIMISM);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("approves unlimited WETH on for Velodrome", async () => {
|
|
23
|
+
let result;
|
|
24
|
+
const pool = await dhedge.loadPool(TEST_POOL);
|
|
25
|
+
try {
|
|
26
|
+
result = await pool.approve(
|
|
27
|
+
Dapp.VELODROME,
|
|
28
|
+
WSTETH,
|
|
29
|
+
ethers.constants.MaxInt256,
|
|
30
|
+
options
|
|
31
|
+
);
|
|
32
|
+
console.log(result);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.log(e);
|
|
35
|
+
}
|
|
36
|
+
expect(result).not.toBe(null);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("adds WETH and wstETH to a Velodrome stable pool", async () => {
|
|
40
|
+
const pool = await dhedge.loadPool(TEST_POOL);
|
|
41
|
+
const wethBalance = await dhedge.utils.getBalance(WETH, pool.address);
|
|
42
|
+
const stwethBalance = await dhedge.utils.getBalance(WSTETH, pool.address);
|
|
43
|
+
|
|
44
|
+
const result = await pool.addLiquidityVelodrome(
|
|
45
|
+
WETH,
|
|
46
|
+
WSTETH,
|
|
47
|
+
wethBalance,
|
|
48
|
+
stwethBalance,
|
|
49
|
+
true,
|
|
50
|
+
options
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
result.wait(1);
|
|
54
|
+
const lpBalance = await dhedge.utils.getBalance(wETHwstETHLp, pool.address);
|
|
55
|
+
expect(lpBalance.gt(0));
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("should stake wETH/wStETH LP in a gauge", async () => {
|
|
59
|
+
const pool = await dhedge.loadPool(TEST_POOL);
|
|
60
|
+
const balance = await dhedge.utils.getBalance(wETHwstETHLp, pool.address);
|
|
61
|
+
const result = await pool.stakeInGauge(
|
|
62
|
+
Dapp.VELODROME,
|
|
63
|
+
wETHwstETHGauge,
|
|
64
|
+
balance,
|
|
65
|
+
options
|
|
66
|
+
);
|
|
67
|
+
result.wait(1);
|
|
68
|
+
const gaugeBalance = await dhedge.utils.getBalance(
|
|
69
|
+
wETHwstETHGauge,
|
|
70
|
+
pool.address
|
|
71
|
+
);
|
|
72
|
+
expect(gaugeBalance.gt(0));
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("should claim rewards from Gauge", async () => {
|
|
76
|
+
const pool = await dhedge.loadPool(TEST_POOL);
|
|
77
|
+
const result = await pool.claimFees(
|
|
78
|
+
Dapp.VELODROME,
|
|
79
|
+
wETHwstETHGauge,
|
|
80
|
+
options
|
|
81
|
+
);
|
|
82
|
+
result.wait(1);
|
|
83
|
+
const velBalance = await dhedge.utils.getBalance(VEL, pool.address);
|
|
84
|
+
expect(velBalance.gt(0));
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("should unStake wETH/wStETH LP from a gauge", async () => {
|
|
88
|
+
const pool = await dhedge.loadPool(TEST_POOL);
|
|
89
|
+
const gaugeBalance = await dhedge.utils.getBalance(
|
|
90
|
+
wETHwstETHGauge,
|
|
91
|
+
pool.address
|
|
92
|
+
);
|
|
93
|
+
const result = await pool.unstakeFromGauge(
|
|
94
|
+
wETHwstETHGauge,
|
|
95
|
+
gaugeBalance,
|
|
96
|
+
options
|
|
97
|
+
);
|
|
98
|
+
result.wait(1);
|
|
99
|
+
const lpBalance = await dhedge.utils.getBalance(wETHwstETHLp, pool.address);
|
|
100
|
+
expect(lpBalance.gt(0));
|
|
101
|
+
const gaugeBalanceAfter = await dhedge.utils.getBalance(
|
|
102
|
+
wETHwstETHGauge,
|
|
103
|
+
pool.address
|
|
104
|
+
);
|
|
105
|
+
expect(gaugeBalanceAfter.eq(0));
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("approves unlimited wETH/stwETH LP for Velodrome", async () => {
|
|
109
|
+
let result;
|
|
110
|
+
const pool = await dhedge.loadPool(TEST_POOL);
|
|
111
|
+
try {
|
|
112
|
+
result = await pool.approve(
|
|
113
|
+
Dapp.VELODROME,
|
|
114
|
+
wETHwstETHLp,
|
|
115
|
+
ethers.constants.MaxInt256,
|
|
116
|
+
options
|
|
117
|
+
);
|
|
118
|
+
console.log(result);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
console.log(e);
|
|
121
|
+
}
|
|
122
|
+
expect(result).not.toBe(null);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("should remove all liquidity from an existing pool ", async () => {
|
|
126
|
+
const pool = await dhedge.loadPool(TEST_POOL);
|
|
127
|
+
const balance = await dhedge.utils.getBalance(wETHwstETHLp, pool.address);
|
|
128
|
+
const result = await pool.removeLiquidityVelodrome(
|
|
129
|
+
WETH,
|
|
130
|
+
WSTETH,
|
|
131
|
+
balance,
|
|
132
|
+
options
|
|
133
|
+
);
|
|
134
|
+
result.wait(1);
|
|
135
|
+
const balanceAfter = await dhedge.utils.getBalance(
|
|
136
|
+
wETHwstETHLp,
|
|
137
|
+
pool.address
|
|
138
|
+
);
|
|
139
|
+
expect(balanceAfter.eq(0));
|
|
140
|
+
});
|
|
141
|
+
});
|