@dhedge/v2-sdk 1.9.8 → 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/README.md +34 -0
- package/dist/config.d.ts +7 -1
- package/dist/entities/pool.d.ts +22 -1
- package/dist/services/flatmoney/keeperFee.d.ts +6 -0
- package/dist/services/flatmoney/stableLp.d.ts +9 -0
- package/dist/services/flatmoney/stableModule.d.ts +4 -0
- package/dist/test/utils/testingHelper.d.ts +2 -1
- package/dist/test/wallet.d.ts +1 -0
- package/dist/v2-sdk.cjs.development.js +2895 -1
- 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 +2895 -1
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/abi/flatmoney/DelayedOrder.json +547 -0
- package/src/abi/flatmoney/IFlatcoinVault.json +570 -0
- package/src/abi/flatmoney/KeeperFee.json +364 -0
- package/src/abi/flatmoney/StableModule.json +770 -0
- package/src/config.ts +19 -0
- package/src/entities/pool.ts +67 -0
- package/src/services/flatmoney/keeperFee.ts +84 -0
- package/src/services/flatmoney/stableLp.ts +135 -0
- package/src/services/flatmoney/stableModule.ts +43 -0
- package/src/test/flatmoney.test.ts +164 -0
- package/src/test/utils/testingHelper.ts +4 -3
- package/src/test/wallet.ts +4 -1
package/src/config.ts
CHANGED
|
@@ -138,3 +138,22 @@ export const UNISWAPV3_QUOTER_ADDRESS =
|
|
|
138
138
|
|
|
139
139
|
export const SYNTHETIX_TRACKING_CODE =
|
|
140
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
|
+
};
|
package/src/entities/pool.ts
CHANGED
|
@@ -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;
|
|
@@ -1629,4 +1634,66 @@ export class Pool {
|
|
|
1629
1634
|
);
|
|
1630
1635
|
return tx;
|
|
1631
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
|
+
}
|
|
1632
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,164 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import BigNumber from "bignumber.js";
|
|
3
|
+
import { Dhedge, Pool } from "../entities";
|
|
4
|
+
import { AssetEnabled, Network } from "../types";
|
|
5
|
+
import {
|
|
6
|
+
TestingRunParams,
|
|
7
|
+
setTokenAmount,
|
|
8
|
+
testingHelper
|
|
9
|
+
} from "./utils/testingHelper";
|
|
10
|
+
import { Contract, ethers } from "ethers";
|
|
11
|
+
import { CONTRACT_ADDRESS, MAX_AMOUNT, TEST_POOL } from "./constants";
|
|
12
|
+
import { flatMoneyContractAddresses } from "../config";
|
|
13
|
+
import DelayedOrderAbi from "../abi/flatmoney/DelayedOrder.json";
|
|
14
|
+
import { allowanceDelta } from "./utils/token";
|
|
15
|
+
import { getKeeperFee } from "../services/flatmoney/keeperFee";
|
|
16
|
+
|
|
17
|
+
const RETH = "0xb6fe221fe9eef5aba221c348ba20a1bf5e73624c";
|
|
18
|
+
const RETH_SLOT = 0;
|
|
19
|
+
const UNIT = "0xb95fB324b8A2fAF8ec4f76e3dF46C718402736e2";
|
|
20
|
+
// https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/token/ERC20/ERC20Upgradeable.sol#L31
|
|
21
|
+
// https://eips.ethereum.org/EIPS/eip-7201
|
|
22
|
+
const UNIT_SLOT =
|
|
23
|
+
"0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00";
|
|
24
|
+
|
|
25
|
+
const testFlatMoney = ({
|
|
26
|
+
wallet,
|
|
27
|
+
network,
|
|
28
|
+
provider,
|
|
29
|
+
rpcUrl
|
|
30
|
+
}: TestingRunParams) => {
|
|
31
|
+
let dhedge: Dhedge;
|
|
32
|
+
let pool: Pool;
|
|
33
|
+
let delayOrderContract: Contract;
|
|
34
|
+
jest.setTimeout(200000);
|
|
35
|
+
describe(`flatmoney on ${network}`, () => {
|
|
36
|
+
beforeAll(async () => {
|
|
37
|
+
dhedge = new Dhedge(wallet, network);
|
|
38
|
+
pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
39
|
+
|
|
40
|
+
const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
|
|
41
|
+
if (!flatMoneyContracts) {
|
|
42
|
+
throw new Error("testFlatMoney: network not supported");
|
|
43
|
+
}
|
|
44
|
+
delayOrderContract = new Contract(
|
|
45
|
+
flatMoneyContracts.DelayedOrder,
|
|
46
|
+
DelayedOrderAbi,
|
|
47
|
+
pool.signer
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// top up gas
|
|
51
|
+
await provider.send("hardhat_setBalance", [
|
|
52
|
+
wallet.address,
|
|
53
|
+
"0x10000000000000000"
|
|
54
|
+
]);
|
|
55
|
+
await provider.send("evm_mine", []);
|
|
56
|
+
|
|
57
|
+
await setTokenAmount({
|
|
58
|
+
amount: new BigNumber(100).times(1e18).toString(),
|
|
59
|
+
provider,
|
|
60
|
+
tokenAddress: RETH,
|
|
61
|
+
slot: RETH_SLOT,
|
|
62
|
+
userAddress: pool.address
|
|
63
|
+
});
|
|
64
|
+
await setTokenAmount({
|
|
65
|
+
amount: new BigNumber(100).times(1e18).toString(),
|
|
66
|
+
provider,
|
|
67
|
+
tokenAddress: UNIT,
|
|
68
|
+
slot: UNIT_SLOT,
|
|
69
|
+
userAddress: pool.address
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const currentAssets: any[] = await pool.managerLogic.getSupportedAssets();
|
|
73
|
+
const exisitingAssets = currentAssets.map(item => {
|
|
74
|
+
return {
|
|
75
|
+
asset: item[0],
|
|
76
|
+
isDeposit: item[1]
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const newAssets: AssetEnabled[] = [
|
|
81
|
+
...exisitingAssets,
|
|
82
|
+
{ asset: CONTRACT_ADDRESS[network].USDC, isDeposit: true },
|
|
83
|
+
{ asset: CONTRACT_ADDRESS[network].WETH, isDeposit: true },
|
|
84
|
+
{
|
|
85
|
+
asset: UNIT,
|
|
86
|
+
isDeposit: false
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
asset: RETH,
|
|
90
|
+
isDeposit: false
|
|
91
|
+
}
|
|
92
|
+
];
|
|
93
|
+
await pool.changeAssets(newAssets);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("mint UNIT", async () => {
|
|
97
|
+
//approve
|
|
98
|
+
await pool.approveSpender(delayOrderContract.address, RETH, MAX_AMOUNT);
|
|
99
|
+
const collateralAllowanceDelta = await allowanceDelta(
|
|
100
|
+
pool.address,
|
|
101
|
+
RETH,
|
|
102
|
+
delayOrderContract.address,
|
|
103
|
+
pool.signer
|
|
104
|
+
);
|
|
105
|
+
await expect(collateralAllowanceDelta.gt(0));
|
|
106
|
+
|
|
107
|
+
const depositAmountStr = new BigNumber(1).times(1e18).toString();
|
|
108
|
+
const tx = await pool.mintUnitViaFlatMoney(
|
|
109
|
+
depositAmountStr,
|
|
110
|
+
0.5,
|
|
111
|
+
10, // set higher to tolerate high gasPrice returned by forked local chain
|
|
112
|
+
null,
|
|
113
|
+
false
|
|
114
|
+
);
|
|
115
|
+
expect(tx).not.toBe(null);
|
|
116
|
+
const existingOrder = await delayOrderContract.getAnnouncedOrder(
|
|
117
|
+
pool.address
|
|
118
|
+
);
|
|
119
|
+
expect(existingOrder.orderType).toBe(1);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("cancel order", async () => {
|
|
123
|
+
await provider.send("evm_increaseTime", [60 * 2]); // more than 1 min
|
|
124
|
+
await pool.cancelOrderViaFlatMoney();
|
|
125
|
+
const existingOrder = await delayOrderContract.getAnnouncedOrder(
|
|
126
|
+
pool.address
|
|
127
|
+
);
|
|
128
|
+
expect(existingOrder.orderType).toBe(0);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("redeem UNIT", async () => {
|
|
132
|
+
const withdrawAmountStr = new BigNumber(2).times(1e18).toString();
|
|
133
|
+
const tx = await pool.redeemUnitViaFlatMoney(
|
|
134
|
+
withdrawAmountStr,
|
|
135
|
+
0.5,
|
|
136
|
+
10, // set higher to tolerate high gasPrice returned by forked local chain
|
|
137
|
+
null,
|
|
138
|
+
false
|
|
139
|
+
);
|
|
140
|
+
expect(tx).not.toBe(null);
|
|
141
|
+
const existingOrder = await delayOrderContract.getAnnouncedOrder(
|
|
142
|
+
pool.address
|
|
143
|
+
);
|
|
144
|
+
expect(existingOrder.orderType).toBe(2);
|
|
145
|
+
|
|
146
|
+
await provider.send("evm_increaseTime", [60 * 2]); // more than 1 min
|
|
147
|
+
await pool.cancelOrderViaFlatMoney();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("keeperFee is small", async () => {
|
|
151
|
+
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
|
|
152
|
+
const walletOnChain = wallet.connect(provider);
|
|
153
|
+
const dhedge = new Dhedge(walletOnChain, network);
|
|
154
|
+
const pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
155
|
+
const keeperFee = await getKeeperFee(pool, 3);
|
|
156
|
+
expect(keeperFee).toBeTruthy();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
testingHelper({
|
|
162
|
+
network: Network.BASE,
|
|
163
|
+
testingRun: testFlatMoney
|
|
164
|
+
});
|
|
@@ -7,6 +7,7 @@ export type TestingRunParams = {
|
|
|
7
7
|
network: Network;
|
|
8
8
|
wallet: ethers.Wallet;
|
|
9
9
|
provider: ethers.providers.JsonRpcProvider;
|
|
10
|
+
rpcUrl: string;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
type TestHelperParams = {
|
|
@@ -17,8 +18,8 @@ export const testingHelper = ({
|
|
|
17
18
|
network,
|
|
18
19
|
testingRun
|
|
19
20
|
}: TestHelperParams): void => {
|
|
20
|
-
const { wallet, provider } = getWalletData(network);
|
|
21
|
-
testingRun({ network, wallet, provider });
|
|
21
|
+
const { wallet, provider, rpcUrl } = getWalletData(network);
|
|
22
|
+
testingRun({ network, wallet, provider, rpcUrl });
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
export const beforeAfterReset = ({
|
|
@@ -52,7 +53,7 @@ export const setTokenAmount = async ({
|
|
|
52
53
|
amount: string;
|
|
53
54
|
userAddress: string;
|
|
54
55
|
tokenAddress: string;
|
|
55
|
-
slot: number;
|
|
56
|
+
slot: number | string;
|
|
56
57
|
provider: ethers.providers.JsonRpcProvider;
|
|
57
58
|
}): Promise<void> => {
|
|
58
59
|
const toBytes32 = (bn: string) => {
|
package/src/test/wallet.ts
CHANGED
|
@@ -38,12 +38,15 @@ export const getWalletData = (
|
|
|
38
38
|
): {
|
|
39
39
|
wallet: ethers.Wallet;
|
|
40
40
|
provider: ethers.providers.JsonRpcProvider;
|
|
41
|
+
rpcUrl: string;
|
|
41
42
|
} => {
|
|
42
43
|
const provider = new ethers.providers.JsonRpcProvider(
|
|
43
44
|
`http://127.0.0.1:${networkPortMap[network]}/`
|
|
44
45
|
);
|
|
46
|
+
const rpcUrl = process.env[`${network.toUpperCase()}_URL`] || "";
|
|
45
47
|
return {
|
|
46
48
|
wallet: new ethers.Wallet(process.env.PRIVATE_KEY as string, provider),
|
|
47
|
-
provider
|
|
49
|
+
provider,
|
|
50
|
+
rpcUrl
|
|
48
51
|
};
|
|
49
52
|
};
|