@dhedge/v2-sdk 1.9.7 → 1.9.9

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/src/config.ts CHANGED
@@ -54,7 +54,9 @@ export const routerAddress: AddressDappNetworkMap = {
54
54
  },
55
55
  [Network.BASE]: {
56
56
  [Dapp.ONEINCH]: "0x1111111254EEB25477B68fb85Ed929f73A960582",
57
- [Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"
57
+ [Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
58
+ [Dapp.AERODROME]: "0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43",
59
+ [Dapp.AAVEV3]: "0xA238Dd80C259a72e81d7e4664a9801593F98d1c5"
58
60
  }
59
61
  };
60
62
 
@@ -136,3 +138,22 @@ export const UNISWAPV3_QUOTER_ADDRESS =
136
138
 
137
139
  export const SYNTHETIX_TRACKING_CODE =
138
140
  "0x4448454447450000000000000000000000000000000000000000000000000000";
141
+
142
+ export const flatMoneyContractAddresses: Readonly<Partial<
143
+ Record<
144
+ Network,
145
+ {
146
+ DelayedOrder: string;
147
+ FlatcoinVault: string;
148
+ StableModule: string;
149
+ RETH: string;
150
+ }
151
+ >
152
+ >> = {
153
+ [Network.BASE]: {
154
+ DelayedOrder: "0x6D857e9D24a7566bB72a3FB0847A3E0e4E1c2879",
155
+ FlatcoinVault: "0x95Fa1ddc9a78273f795e67AbE8f1Cd2Cd39831fF",
156
+ StableModule: "0xb95fB324b8A2fAF8ec4f76e3dF46C718402736e2",
157
+ RETH: "0xb6fe221fe9eef5aba221c348ba20a1bf5e73624c"
158
+ }
159
+ };
@@ -64,6 +64,11 @@ import {
64
64
  getExitVestTxData
65
65
  } from "../services/ramses/vesting";
66
66
  import { getPoolTxOrGasEstimate } from "../utils/contract";
67
+ import {
68
+ cancelOrderViaFlatMoney,
69
+ mintUnitViaFlatMoney,
70
+ redeemUnitViaFlatMoney
71
+ } from "../services/flatmoney/stableLp";
67
72
 
68
73
  export class Pool {
69
74
  public readonly poolLogic: Contract;
@@ -531,6 +536,7 @@ export class Pool {
531
536
  stakeTxData = getVelodromeStakeTxData(amount, false);
532
537
  break;
533
538
  case Dapp.VELODROMEV2:
539
+ case Dapp.AERODROME:
534
540
  stakeTxData = getVelodromeStakeTxData(amount, true);
535
541
  break;
536
542
  default:
@@ -1153,6 +1159,7 @@ export class Pool {
1153
1159
  txData = getVelodromeClaimTxData(this, tokenId, false);
1154
1160
  break;
1155
1161
  case Dapp.VELODROMEV2:
1162
+ case Dapp.AERODROME:
1156
1163
  contractAddress = tokenId;
1157
1164
  txData = getVelodromeClaimTxData(this, tokenId, true);
1158
1165
  break;
@@ -1356,7 +1363,7 @@ export class Pool {
1356
1363
 
1357
1364
  /**
1358
1365
  * Add liquidity to Velodrome V2 or Ramses pool
1359
- * @param {Dapp} dapp VelodromeV2 or Ramses
1366
+ * @param {Dapp} dapp VelodromeV2, Ramses or Aerodrome
1360
1367
  * @param {string} assetA First asset
1361
1368
  * @param {string} assetB Second asset
1362
1369
  * @param {BigNumber | string} amountA Amount first asset
@@ -1367,7 +1374,7 @@ export class Pool {
1367
1374
  * @returns {Promise<any>} Transaction
1368
1375
  */
1369
1376
  async addLiquidityV2(
1370
- dapp: Dapp.VELODROMEV2 | Dapp.RAMSES,
1377
+ dapp: Dapp.VELODROMEV2 | Dapp.RAMSES | Dapp.AERODROME,
1371
1378
  assetA: string,
1372
1379
  assetB: string,
1373
1380
  amountA: BigNumber | string,
@@ -1397,7 +1404,7 @@ export class Pool {
1397
1404
 
1398
1405
  /**
1399
1406
  * Remove liquidity from Velodrome V2 or Ramses pool
1400
- * @param {Dapp} dapp VelodromeV2 or Ramses
1407
+ * @param {Dapp} dapp VelodromeV2, Ramses or Aerodrome
1401
1408
  * @param {string} assetA First asset
1402
1409
  * @param {string} assetB Second asset
1403
1410
  * @param {BigNumber | string} amount Amount of LP tokens
@@ -1407,7 +1414,7 @@ export class Pool {
1407
1414
  * @returns {Promise<any>} Transaction
1408
1415
  */
1409
1416
  async removeLiquidityV2(
1410
- dapp: Dapp.VELODROMEV2 | Dapp.RAMSES,
1417
+ dapp: Dapp.VELODROMEV2 | Dapp.RAMSES | Dapp.AERODROME,
1411
1418
  assetA: string,
1412
1419
  assetB: string,
1413
1420
  amount: BigNumber | string,
@@ -1627,4 +1634,66 @@ export class Pool {
1627
1634
  );
1628
1635
  return tx;
1629
1636
  }
1637
+
1638
+ /** deposit rETH to mint UNIT via the Flat Money protocol
1639
+ *
1640
+ * @param { BigNumber | string } depositAmount Amount of rETH to deposit
1641
+ * @param { number } slippage slippage, 0.5 represents 0.5%
1642
+ * @param { number | null } maxKeeperFeeInUsd 5 represents $5; null will skip the maxKeeperFee check
1643
+ * @param {any} options Transaction options
1644
+ * @param {boolean} estimateGas Simulate/estimate gas
1645
+ * @returns {Promise<any>} Transaction
1646
+ */
1647
+ async mintUnitViaFlatMoney(
1648
+ depositAmount: ethers.BigNumber | string,
1649
+ slippage = 0.5,
1650
+ maxKeeperFeeInUsd: number | null,
1651
+ options: any = null,
1652
+ estimateGas = false
1653
+ ): Promise<any> {
1654
+ const tx = await mintUnitViaFlatMoney(
1655
+ this,
1656
+ depositAmount,
1657
+ slippage,
1658
+ maxKeeperFeeInUsd,
1659
+ options,
1660
+ estimateGas
1661
+ );
1662
+ return tx;
1663
+ }
1664
+
1665
+ /** redeem UNIT via the Flat Money protocol
1666
+ *
1667
+ * @param { BigNumber | string } depositAmount Amount of UNIT to withdraw
1668
+ * @param { number } slippage slippage, 0.5 represents 0.5%
1669
+ * @param { number | null } maxKeeperFeeInUsd 5 represents $5; null will skip the maxKeeperFee check
1670
+ * @param {any} options Transaction options
1671
+ * @param {boolean} estimateGas Simulate/estimate gas
1672
+ * @returns {Promise<any>} Transaction
1673
+ */
1674
+ async redeemUnitViaFlatMoney(
1675
+ withdrawAmount: ethers.BigNumber | string,
1676
+ slippage = 0.5,
1677
+ maxKeeperFeeInUsd: number | null,
1678
+ options: any = null,
1679
+ estimateGas = false
1680
+ ): Promise<any> {
1681
+ const tx = await redeemUnitViaFlatMoney(
1682
+ this,
1683
+ withdrawAmount,
1684
+ slippage,
1685
+ maxKeeperFeeInUsd,
1686
+ options,
1687
+ estimateGas
1688
+ );
1689
+ return tx;
1690
+ }
1691
+
1692
+ async cancelOrderViaFlatMoney(
1693
+ options: any = null,
1694
+ estimateGas = false
1695
+ ): Promise<any> {
1696
+ const tx = await cancelOrderViaFlatMoney(this, options, estimateGas);
1697
+ return tx;
1698
+ }
1630
1699
  }
@@ -0,0 +1,84 @@
1
+ import { Contract, ethers } from "ethers";
2
+ import { Pool } from "../../entities";
3
+ import IFlatcoinVaultAbi from "../../abi/flatmoney/IFlatcoinVault.json";
4
+ import KeeperFeeAbi from "../../abi/flatmoney/KeeperFee.json";
5
+ import { flatMoneyContractAddresses } from "../../config";
6
+ import BigNumber from "bignumber.js";
7
+
8
+ export const getKeeperFeeContract = async (pool: Pool): Promise<Contract> => {
9
+ const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
10
+ if (!flatMoneyContracts) {
11
+ throw new Error(
12
+ `getStableModuleContract: network of ${pool.network} not supported`
13
+ );
14
+ }
15
+ const flatcoinVaultContract = new Contract(
16
+ flatMoneyContracts.FlatcoinVault,
17
+ IFlatcoinVaultAbi,
18
+ pool.signer
19
+ );
20
+ const key = ethers.utils.formatBytes32String("keeperFee");
21
+ const keeperFeeContractAddress: string = await flatcoinVaultContract.callStatic.moduleAddress(
22
+ key
23
+ );
24
+
25
+ const keeperFeeContract = new ethers.Contract(
26
+ keeperFeeContractAddress,
27
+ KeeperFeeAbi,
28
+ pool.signer
29
+ );
30
+ return keeperFeeContract;
31
+ };
32
+
33
+ export const getKeeperFee = async (
34
+ pool: Pool,
35
+ maxKeeperFeeInUsd: number | null
36
+ ): Promise<ethers.BigNumber> => {
37
+ const keeperFeeContract = await getKeeperFeeContract(pool);
38
+ const gasPrice = await pool.signer.provider.getGasPrice();
39
+
40
+ let keeperfee: ethers.BigNumber;
41
+ if (gasPrice) {
42
+ keeperfee = await keeperFeeContract["getKeeperFee(uint256)"](
43
+ new BigNumber(gasPrice.toString()).times(1.2).toFixed(0)
44
+ );
45
+ } else {
46
+ keeperfee = await keeperFeeContract["getKeeperFee()"]();
47
+ }
48
+
49
+ const keeperFeeInUsd = await getKeeperFeeInUsd(pool, keeperfee);
50
+
51
+ if (
52
+ Number.isFinite(maxKeeperFeeInUsd) &&
53
+ keeperFeeInUsd.gt(ethers.BigNumber.from(maxKeeperFeeInUsd).toString())
54
+ ) {
55
+ throw new Error("mintUnitViaFlatMoney: keeperFee too large");
56
+ }
57
+
58
+ return keeperfee;
59
+ };
60
+
61
+ export const getKeeperFeeInUsd = async (
62
+ pool: Pool,
63
+ keeperFee: ethers.BigNumber
64
+ ): Promise<BigNumber> => {
65
+ const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
66
+ if (!flatMoneyContracts) {
67
+ throw new Error(
68
+ `getKeeperFeeInUsd: network of ${pool.network} not supported`
69
+ );
70
+ }
71
+ const fundComposition = await pool.getComposition();
72
+ const filteredFc = fundComposition.filter(
73
+ fc =>
74
+ fc.asset.toLocaleLowerCase() ===
75
+ flatMoneyContracts.RETH.toLocaleLowerCase()
76
+ );
77
+
78
+ if (!filteredFc[0])
79
+ throw new Error(`getKeeperFeeInUsd: required asset not enabled yet`);
80
+
81
+ const rateD1 = new BigNumber(filteredFc[0].rate.toString()).div(1e18);
82
+
83
+ return rateD1.times(keeperFee.toString()).div(1e18);
84
+ };
@@ -0,0 +1,135 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ import BigNumber from "bignumber.js";
4
+ import { Pool, ethers } from "../..";
5
+ import DelayedOrderAbi from "../../abi/flatmoney/DelayedOrder.json";
6
+ import { flatMoneyContractAddresses } from "../../config";
7
+ import { getPoolTxOrGasEstimate } from "../../utils/contract";
8
+ import { getStableDepositQuote, getStableWithdrawQuote } from "./stableModule";
9
+ import { getKeeperFee } from "./keeperFee";
10
+
11
+ export function getAnnounceStableDepositTxData(
12
+ depositAmount: ethers.BigNumber | string,
13
+ minAmountOut: ethers.BigNumber | string,
14
+ keeperFee: ethers.BigNumber | string
15
+ ): string {
16
+ return new ethers.utils.Interface(
17
+ DelayedOrderAbi
18
+ ).encodeFunctionData("announceStableDeposit", [
19
+ depositAmount,
20
+ minAmountOut,
21
+ keeperFee
22
+ ]);
23
+ }
24
+
25
+ export function getAnnounceStableWithdrawTxData(
26
+ withdrawAmount: ethers.BigNumber | string,
27
+ minAmountOut: ethers.BigNumber | string,
28
+ keeperFee: ethers.BigNumber | string
29
+ ): string {
30
+ return new ethers.utils.Interface(
31
+ DelayedOrderAbi
32
+ ).encodeFunctionData("announceStableWithdraw", [
33
+ withdrawAmount,
34
+ minAmountOut,
35
+ keeperFee
36
+ ]);
37
+ }
38
+
39
+ export function getCancelExistingOrderTxData(account: string): string {
40
+ return new ethers.utils.Interface(
41
+ DelayedOrderAbi
42
+ ).encodeFunctionData("cancelExistingOrder", [account]);
43
+ }
44
+
45
+ export async function mintUnitViaFlatMoney(
46
+ pool: Pool,
47
+ depositAmount: ethers.BigNumber | string,
48
+ slippage: number, // 0.5 means 0.5%
49
+ maxKeeperFeeInUsd: number | null,
50
+ options: any = null,
51
+ estimateGas = false
52
+ ): Promise<any> {
53
+ const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
54
+ if (!flatMoneyContracts) {
55
+ throw new Error("mintUnitViaFlatMoney: network not supported");
56
+ }
57
+
58
+ const keeperfee = await getKeeperFee(pool, maxKeeperFeeInUsd); // in RETH
59
+
60
+ const adjustedDepositAmount = new BigNumber(depositAmount.toString()).minus(
61
+ keeperfee.toString() // keeper fee deducted from amountIn
62
+ );
63
+
64
+ const amountOut = await getStableDepositQuote(
65
+ pool,
66
+ adjustedDepositAmount.toFixed(0)
67
+ );
68
+ const minAmountOut = new BigNumber(amountOut.toString())
69
+ .times(1 - slippage / 100)
70
+ .toFixed(0);
71
+
72
+ const mintUnitTxData = await getAnnounceStableDepositTxData(
73
+ adjustedDepositAmount.toFixed(0),
74
+ minAmountOut,
75
+ keeperfee
76
+ );
77
+
78
+ const tx = await getPoolTxOrGasEstimate(
79
+ pool,
80
+ [flatMoneyContracts.DelayedOrder, mintUnitTxData, options],
81
+ estimateGas
82
+ );
83
+ return tx;
84
+ }
85
+
86
+ export async function redeemUnitViaFlatMoney(
87
+ pool: Pool,
88
+ withdrawAmount: ethers.BigNumber | string,
89
+ slippage: number, // 0.5 means 0.5%
90
+ maxKeeperFeeInUsd: number | null,
91
+ options: any = null,
92
+ estimateGas = false
93
+ ): Promise<any> {
94
+ const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
95
+ if (!flatMoneyContracts) {
96
+ throw new Error("redeemUnitViaFlatMoney: network not supported");
97
+ }
98
+ const keeperfee = await getKeeperFee(pool, maxKeeperFeeInUsd); // in RETH
99
+
100
+ const amountOut = await getStableWithdrawQuote(pool, withdrawAmount);
101
+ const minAmountOut = new BigNumber(amountOut.toString())
102
+ .times(1 - slippage / 100)
103
+ .minus(keeperfee.toString()) // keeper fee deducted from amountOut
104
+ .toFixed(0);
105
+
106
+ const redeemUnitTxData = await getAnnounceStableWithdrawTxData(
107
+ withdrawAmount,
108
+ minAmountOut,
109
+ keeperfee
110
+ );
111
+ const tx = await getPoolTxOrGasEstimate(
112
+ pool,
113
+ [flatMoneyContracts.DelayedOrder, redeemUnitTxData, options],
114
+ estimateGas
115
+ );
116
+ return tx;
117
+ }
118
+
119
+ export async function cancelOrderViaFlatMoney(
120
+ pool: Pool,
121
+ options: any = null,
122
+ estimateGas = false
123
+ ): Promise<any> {
124
+ const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
125
+ if (!flatMoneyContracts) {
126
+ throw new Error("cancelOrderViaFlatMoney: network not supported");
127
+ }
128
+ const cancelOrderTxData = await getCancelExistingOrderTxData(pool.address);
129
+ const tx = await getPoolTxOrGasEstimate(
130
+ pool,
131
+ [flatMoneyContracts.DelayedOrder, cancelOrderTxData, options],
132
+ estimateGas
133
+ );
134
+ return tx;
135
+ }
@@ -0,0 +1,43 @@
1
+ import { BigNumber, Contract } from "ethers";
2
+ import { flatMoneyContractAddresses } from "../../config";
3
+ import { Pool } from "../../entities";
4
+ import StableModuleAbi from "../../abi/flatmoney/StableModule.json";
5
+
6
+ const getStableModuleContract = (pool: Pool): Contract => {
7
+ const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
8
+ if (!flatMoneyContracts) {
9
+ throw new Error(
10
+ `getStableModuleContract: network of ${pool.network} not supported`
11
+ );
12
+ }
13
+ const stableModuleContract = new Contract(
14
+ flatMoneyContracts.StableModule,
15
+ StableModuleAbi,
16
+ pool.signer
17
+ );
18
+ return stableModuleContract;
19
+ };
20
+
21
+ /// @notice Quoter function for getting the stable deposit amount out.
22
+ export const getStableDepositQuote = async (
23
+ pool: Pool,
24
+ depositAmount: string | BigNumber
25
+ ): Promise<BigNumber> => {
26
+ const stableModuleContract = getStableModuleContract(pool);
27
+ const amountOut: BigNumber = await stableModuleContract.stableDepositQuote(
28
+ depositAmount.toString()
29
+ );
30
+ return amountOut;
31
+ };
32
+
33
+ /// @notice Quoter function for getting the stable withdraw amount out.
34
+ export const getStableWithdrawQuote = async (
35
+ pool: Pool,
36
+ withdrawAmount: string | BigNumber
37
+ ): Promise<BigNumber> => {
38
+ const stableModuleContract = getStableModuleContract(pool);
39
+ const amountOut: BigNumber = await stableModuleContract.stableWithdrawQuote(
40
+ withdrawAmount.toString()
41
+ );
42
+ return amountOut;
43
+ };
@@ -0,0 +1,154 @@
1
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ import BigNumber from "bignumber.js";
4
+ import { Dhedge, Pool } from "..";
5
+ import { routerAddress } from "../config";
6
+ import { Dapp, Network } from "../types";
7
+ import { CONTRACT_ADDRESS, MAX_AMOUNT, TEST_POOL } from "./constants";
8
+ import {
9
+ TestingRunParams,
10
+ beforeAfterReset,
11
+ setUSDCAmount,
12
+ testingHelper
13
+ } from "./utils/testingHelper";
14
+ import { allowanceDelta, balanceDelta } from "./utils/token";
15
+ import { getWalletData } from "./wallet";
16
+
17
+ const testAerodrome = ({ network, provider }: TestingRunParams) => {
18
+ const WETH_USDC_Lp = "0xcDAC0d6c6C59727a65F871236188350531885C43";
19
+ const WETH_USDC__Gauge = "0x519BBD1Dd8C6A94C46080E24f316c14Ee758C025";
20
+
21
+ const USDC = CONTRACT_ADDRESS[network].USDC;
22
+ const WETH = CONTRACT_ADDRESS[network].WETH;
23
+ const AERO = "0x940181a94A35A4569E4529A3CDfB74e38FD98631";
24
+
25
+ let dhedge: Dhedge;
26
+ let pool: Pool;
27
+ jest.setTimeout(100000);
28
+
29
+ describe(`[${network}] aerodrome tests`, () => {
30
+ beforeAll(async () => {
31
+ const { wallet } = getWalletData(network);
32
+ // top up ETH (gas)
33
+ await provider.send("hardhat_setBalance", [
34
+ wallet.address,
35
+ "0x100000000000000"
36
+ ]);
37
+ dhedge = new Dhedge(wallet, network);
38
+ pool = await dhedge.loadPool(TEST_POOL[network]);
39
+ await setUSDCAmount({
40
+ amount: new BigNumber(10).times(1e6).toFixed(0),
41
+ userAddress: pool.address,
42
+ network,
43
+ provider
44
+ });
45
+ await pool.approve(Dapp.ONEINCH, USDC, MAX_AMOUNT);
46
+ await pool.trade(Dapp.ONEINCH, USDC, WETH, (5 * 1e6).toString());
47
+ });
48
+ beforeAfterReset({ beforeAll, afterAll, provider });
49
+
50
+ it("approves unlimited USDC and swETH on for Aerodrome", async () => {
51
+ await pool.approve(Dapp.AERODROME, USDC, MAX_AMOUNT);
52
+ await pool.approve(Dapp.AERODROME, WETH, MAX_AMOUNT);
53
+ const UsdcAllowanceDelta = await allowanceDelta(
54
+ pool.address,
55
+ USDC,
56
+ routerAddress[network].aerodrome!,
57
+ pool.signer
58
+ );
59
+ await expect(UsdcAllowanceDelta.gt(0));
60
+ });
61
+
62
+ it("adds USDC and WETH to a Aerodrome volatile pool", async () => {
63
+ const usdcBalance = await pool.utils.getBalance(USDC, pool.address);
64
+ const wethBalance = await pool.utils.getBalance(WETH, pool.address);
65
+ await pool.addLiquidityV2(
66
+ Dapp.AERODROME,
67
+ WETH,
68
+ USDC,
69
+ wethBalance,
70
+ usdcBalance,
71
+ false
72
+ );
73
+
74
+ const lpTokenDelta = await balanceDelta(
75
+ pool.address,
76
+ WETH_USDC_Lp,
77
+ pool.signer
78
+ );
79
+ expect(lpTokenDelta.gt(0));
80
+ });
81
+
82
+ it("should stake WETH-USDC LP in a gauge", async () => {
83
+ const balance = await dhedge.utils.getBalance(WETH_USDC_Lp, pool.address);
84
+ await pool.approveSpender(WETH_USDC__Gauge, WETH_USDC_Lp, MAX_AMOUNT);
85
+ await pool.stakeInGauge(Dapp.AERODROME, WETH_USDC__Gauge, balance);
86
+ const gaugeBalance = await balanceDelta(
87
+ pool.address,
88
+ WETH_USDC__Gauge,
89
+ pool.signer
90
+ );
91
+ expect(gaugeBalance.gt(0));
92
+ });
93
+
94
+ it("should claim rewards from Gauge", async () => {
95
+ await provider.send("evm_increaseTime", [24 * 60 * 60]); // 1 day
96
+ await provider.send("evm_mine", []);
97
+ const claimTx = await pool.claimFees(Dapp.AERODROME, WETH_USDC__Gauge);
98
+ expect(claimTx).not.toBe(null);
99
+ const aeroBalanceDelta = await balanceDelta(
100
+ pool.address,
101
+ AERO,
102
+ pool.signer
103
+ );
104
+ expect(aeroBalanceDelta.gt(0));
105
+ });
106
+
107
+ it("should unStakeWETH-USDC LP from a gauge", async () => {
108
+ const gaugeBalance = await dhedge.utils.getBalance(
109
+ WETH_USDC__Gauge,
110
+ pool.address
111
+ );
112
+ await pool.unstakeFromGauge(WETH_USDC__Gauge, gaugeBalance);
113
+ const lpTokenDelta = await balanceDelta(
114
+ pool.address,
115
+ WETH_USDC_Lp,
116
+ pool.signer
117
+ );
118
+ expect(lpTokenDelta.gt(0));
119
+ });
120
+
121
+ it("approves unlimited WETH-USDC LP for Aerodrome", async () => {
122
+ await pool.approve(Dapp.AERODROME, WETH_USDC_Lp, MAX_AMOUNT);
123
+ const lpAllowanceDelta = await allowanceDelta(
124
+ pool.address,
125
+ WETH_USDC_Lp,
126
+ routerAddress[network].aerodrome!,
127
+ pool.signer
128
+ );
129
+ expect(lpAllowanceDelta.gt(0));
130
+ });
131
+
132
+ it("should remove all liquidity from an existing pool ", async () => {
133
+ const balance = await dhedge.utils.getBalance(WETH_USDC_Lp, pool.address);
134
+ await pool.removeLiquidityV2(Dapp.AERODROME, WETH, USDC, balance, false);
135
+ const usdcBalanceDelta = await balanceDelta(
136
+ pool.address,
137
+ USDC,
138
+ pool.signer
139
+ );
140
+ const wethBalanceDelta = await balanceDelta(
141
+ pool.address,
142
+ WETH,
143
+ pool.signer
144
+ );
145
+ expect(usdcBalanceDelta.gt(0));
146
+ expect(wethBalanceDelta.gt(0));
147
+ });
148
+ });
149
+ };
150
+
151
+ testingHelper({
152
+ network: Network.BASE,
153
+ testingRun: testAerodrome
154
+ });