@dhedge/v2-sdk 1.10.10 → 1.10.12
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/config.d.ts +2 -1
- package/dist/entities/dhedge.d.ts +1 -1
- package/dist/entities/pool.d.ts +2 -1
- package/dist/services/flatmoney/stableLp.d.ts +1 -0
- package/dist/test/constants.d.ts +4 -0
- package/dist/types.d.ts +0 -1
- package/dist/v2-sdk.cjs.development.js +311 -172
- 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 +311 -172
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +2 -2
- package/src/abi/flatmoney/v2/IOrderExecutionModule.json +96 -0
- package/src/config.ts +10 -6
- package/src/entities/dhedge.ts +5 -4
- package/src/entities/pool.ts +4 -12
- package/src/services/flatmoney/keeperFee.ts +12 -4
- package/src/services/flatmoney/stableLp.ts +30 -8
- package/src/test/constants.ts +6 -1
- package/src/test/flatmoney.test.ts +30 -11
- package/src/types.ts +0 -1
- package/src/utils/contract.ts +19 -7
- package/dist/services/zeroEx/zeroExTrade.d.ts +0 -3
- package/src/services/zeroEx/zeroExTrade.ts +0 -52
- package/src/test/zeroEx.test.ts +0 -95
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhedge/v2-sdk",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.12",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "🛠 An SDK for building applications on top of dHEDGE V2",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@size-limit/preset-small-lib": "^5.0.1",
|
|
35
35
|
"@types/jest": "^28.1.7",
|
|
36
36
|
"@types/lodash": "^4.14.178",
|
|
37
|
-
"hardhat": "2.
|
|
37
|
+
"hardhat": "2.23.0",
|
|
38
38
|
"husky": "^7.0.1",
|
|
39
39
|
"jest": "^28.1.3",
|
|
40
40
|
"size-limit": "^5.0.1",
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"type": "function",
|
|
4
|
+
"name": "cancelExistingOrder",
|
|
5
|
+
"inputs": [
|
|
6
|
+
{
|
|
7
|
+
"name": "account",
|
|
8
|
+
"type": "address",
|
|
9
|
+
"internalType": "address"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"outputs": [],
|
|
13
|
+
"stateMutability": "nonpayable"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"type": "function",
|
|
17
|
+
"name": "cancelOrderByModule",
|
|
18
|
+
"inputs": [
|
|
19
|
+
{
|
|
20
|
+
"name": "account",
|
|
21
|
+
"type": "address",
|
|
22
|
+
"internalType": "address"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"outputs": [],
|
|
26
|
+
"stateMutability": "nonpayable"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "function",
|
|
30
|
+
"name": "executeLimitOrder",
|
|
31
|
+
"inputs": [
|
|
32
|
+
{
|
|
33
|
+
"name": "tokenId",
|
|
34
|
+
"type": "uint256",
|
|
35
|
+
"internalType": "uint256"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "priceUpdateData",
|
|
39
|
+
"type": "bytes[]",
|
|
40
|
+
"internalType": "bytes[]"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"outputs": [],
|
|
44
|
+
"stateMutability": "payable"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"type": "function",
|
|
48
|
+
"name": "executeOrder",
|
|
49
|
+
"inputs": [
|
|
50
|
+
{
|
|
51
|
+
"name": "account",
|
|
52
|
+
"type": "address",
|
|
53
|
+
"internalType": "address"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "priceUpdateData",
|
|
57
|
+
"type": "bytes[]",
|
|
58
|
+
"internalType": "bytes[]"
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"outputs": [],
|
|
62
|
+
"stateMutability": "payable"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"type": "function",
|
|
66
|
+
"name": "hasOrderExpired",
|
|
67
|
+
"inputs": [
|
|
68
|
+
{
|
|
69
|
+
"name": "account",
|
|
70
|
+
"type": "address",
|
|
71
|
+
"internalType": "address"
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"outputs": [
|
|
75
|
+
{
|
|
76
|
+
"name": "expired",
|
|
77
|
+
"type": "bool",
|
|
78
|
+
"internalType": "bool"
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"stateMutability": "view"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"type": "function",
|
|
85
|
+
"name": "maxExecutabilityAge",
|
|
86
|
+
"inputs": [],
|
|
87
|
+
"outputs": [
|
|
88
|
+
{
|
|
89
|
+
"name": "maxExecutabilityAge",
|
|
90
|
+
"type": "uint64",
|
|
91
|
+
"internalType": "uint64"
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"stateMutability": "view"
|
|
95
|
+
}
|
|
96
|
+
]
|
package/src/config.ts
CHANGED
|
@@ -31,7 +31,6 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
31
31
|
[Dapp.UNISWAPV3]: "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
32
32
|
[Dapp.ARRAKIS]: "0xc73fb100a995b33f9fa181d420f4c8d74506df66",
|
|
33
33
|
[Dapp.TOROS]: "0x45b90480D6F643dE2f128db091A357C3c90399f2",
|
|
34
|
-
[Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
|
35
34
|
[Dapp.ODOS]: "0x4e3288c9ca110bcc82bf38f09a7b425c095d92bf"
|
|
36
35
|
},
|
|
37
36
|
[Network.OPTIMISM]: {
|
|
@@ -44,7 +43,6 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
44
43
|
[Dapp.VELODROMEV2]: "0xa062ae8a9c5e11aaa026fc2670b0d65ccc8b2858",
|
|
45
44
|
[Dapp.LYRA]: "0xCCE7819d65f348c64B7Beb205BA367b3fE33763B",
|
|
46
45
|
[Dapp.ARRAKIS]: "0x9ce88a56d120300061593eF7AD074A1B710094d5",
|
|
47
|
-
[Dapp.ZEROEX]: "0xdef1abe32c034e558cdd535791643c58a13acc10",
|
|
48
46
|
[Dapp.ODOS]: "0xca423977156bb05b13a2ba3b76bc5419e2fe9680"
|
|
49
47
|
},
|
|
50
48
|
[Network.ARBITRUM]: {
|
|
@@ -53,13 +51,11 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
53
51
|
[Dapp.AAVEV3]: "0x794a61358D6845594F94dc1DB02A252b5b4814aD",
|
|
54
52
|
[Dapp.BALANCER]: "0xBA12222222228d8Ba445958a75a0704d566BF2C8",
|
|
55
53
|
[Dapp.RAMSES]: "0xaaa87963efeb6f7e0a2711f397663105acb1805e",
|
|
56
|
-
[Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
|
57
54
|
[Dapp.TOROS]: "0xA5679C4272A056Bb83f039961fae7D99C48529F5",
|
|
58
55
|
[Dapp.ODOS]: "0xa669e7A0d4b3e4Fa48af2dE86BD4CD7126Be4e13"
|
|
59
56
|
},
|
|
60
57
|
[Network.BASE]: {
|
|
61
58
|
[Dapp.ONEINCH]: "0x111111125421ca6dc452d289314280a0f8842a65",
|
|
62
|
-
[Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
|
63
59
|
[Dapp.AERODROME]: "0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43",
|
|
64
60
|
[Dapp.AAVEV3]: "0xA238Dd80C259a72e81d7e4664a9801593F98d1c5",
|
|
65
61
|
[Dapp.TOROS]: "0xf067575Eb60c7587C11e867907AA7284833704d1",
|
|
@@ -170,10 +166,11 @@ export const flatMoneyContractAddresses: Readonly<Partial<
|
|
|
170
166
|
Record<
|
|
171
167
|
Network,
|
|
172
168
|
{
|
|
169
|
+
OrderExecution?: string;
|
|
173
170
|
DelayedOrder: string;
|
|
174
171
|
FlatcoinVault: string;
|
|
175
172
|
StableModule: string;
|
|
176
|
-
|
|
173
|
+
COLLATERAL: string;
|
|
177
174
|
}
|
|
178
175
|
>
|
|
179
176
|
>> = {
|
|
@@ -181,6 +178,13 @@ export const flatMoneyContractAddresses: Readonly<Partial<
|
|
|
181
178
|
DelayedOrder: "0x6D857e9D24a7566bB72a3FB0847A3E0e4E1c2879",
|
|
182
179
|
FlatcoinVault: "0x95Fa1ddc9a78273f795e67AbE8f1Cd2Cd39831fF",
|
|
183
180
|
StableModule: "0xb95fB324b8A2fAF8ec4f76e3dF46C718402736e2",
|
|
184
|
-
|
|
181
|
+
COLLATERAL: "0xb6fe221fe9eef5aba221c348ba20a1bf5e73624c" // RETH
|
|
182
|
+
},
|
|
183
|
+
[Network.OPTIMISM]: {
|
|
184
|
+
OrderExecution: "0x7805CB7fb2C2e70FDdF92949065D9Ee1Fc2F72a8",
|
|
185
|
+
DelayedOrder: "0xd917A0C9B21Bb71DF1209d2c211Ad83004F01554", // OrderAnnouncementModule
|
|
186
|
+
FlatcoinVault: "0x86C7b9640302082B0dF78023F930d8612bFcaD3f",
|
|
187
|
+
COLLATERAL: "0x68f180fcCe6836688e9084f035309E29Bf0A2095", // WBTC
|
|
188
|
+
StableModule: "0x357CB23571EF7a3d6189b7FAcFC361eA71f7CAB5"
|
|
185
189
|
}
|
|
186
190
|
};
|
package/src/entities/dhedge.ts
CHANGED
|
@@ -23,7 +23,6 @@ export class Dhedge {
|
|
|
23
23
|
PoolFactory.abi,
|
|
24
24
|
this.signer
|
|
25
25
|
);
|
|
26
|
-
|
|
27
26
|
this.utils = new Utils(this.network, this.signer);
|
|
28
27
|
}
|
|
29
28
|
|
|
@@ -87,9 +86,10 @@ export class Dhedge {
|
|
|
87
86
|
* @param {string} address Pool address
|
|
88
87
|
* @returns {Pool} Loaded Pool
|
|
89
88
|
*/
|
|
90
|
-
public async loadPool(address: string): Promise<Pool> {
|
|
89
|
+
public async loadPool(address: string, isDhedge = true): Promise<Pool> {
|
|
91
90
|
const poolLogic = new Contract(address, PoolLogic.abi, this.signer);
|
|
92
|
-
|
|
91
|
+
let managerLogicAddress = address;
|
|
92
|
+
if (isDhedge) managerLogicAddress = await poolLogic.poolManagerLogic();
|
|
93
93
|
const managerLogic = new Contract(
|
|
94
94
|
managerLogicAddress,
|
|
95
95
|
ManagerLogic.abi,
|
|
@@ -102,7 +102,8 @@ export class Dhedge {
|
|
|
102
102
|
poolLogic,
|
|
103
103
|
managerLogic,
|
|
104
104
|
this.utils,
|
|
105
|
-
this.factory
|
|
105
|
+
this.factory,
|
|
106
|
+
isDhedge
|
|
106
107
|
);
|
|
107
108
|
}
|
|
108
109
|
|
package/src/entities/pool.ts
CHANGED
|
@@ -63,7 +63,6 @@ import {
|
|
|
63
63
|
getFuturesChangeMarginTxData
|
|
64
64
|
} from "../services/futures";
|
|
65
65
|
import { getFuturesCancelOrderTxData } from "../services/futures/trade";
|
|
66
|
-
import { getZeroExTradeTxData } from "../services/zeroEx/zeroExTrade";
|
|
67
66
|
import { getOneInchSwapTxData } from "../services/oneInch";
|
|
68
67
|
import {
|
|
69
68
|
getCreateVestTxData,
|
|
@@ -96,6 +95,7 @@ export class Pool {
|
|
|
96
95
|
public readonly address: string;
|
|
97
96
|
public readonly utils: Utils;
|
|
98
97
|
public readonly network: Network;
|
|
98
|
+
public readonly isDhedge: boolean;
|
|
99
99
|
|
|
100
100
|
public constructor(
|
|
101
101
|
network: Network,
|
|
@@ -103,7 +103,8 @@ export class Pool {
|
|
|
103
103
|
poolLogic: Contract,
|
|
104
104
|
mangerLogic: Contract,
|
|
105
105
|
utils: Utils,
|
|
106
|
-
factory: Contract
|
|
106
|
+
factory: Contract,
|
|
107
|
+
isDhedge = true
|
|
107
108
|
) {
|
|
108
109
|
this.network = network;
|
|
109
110
|
this.poolLogic = poolLogic;
|
|
@@ -112,6 +113,7 @@ export class Pool {
|
|
|
112
113
|
this.signer = signer;
|
|
113
114
|
this.utils = utils;
|
|
114
115
|
this.factory = factory;
|
|
116
|
+
this.isDhedge = isDhedge;
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
/**
|
|
@@ -370,16 +372,6 @@ export class Pool {
|
|
|
370
372
|
): Promise<any> {
|
|
371
373
|
let swapTxData: string;
|
|
372
374
|
switch (dapp) {
|
|
373
|
-
case Dapp.ZEROEX:
|
|
374
|
-
swapTxData = await getZeroExTradeTxData(
|
|
375
|
-
this.network,
|
|
376
|
-
assetFrom,
|
|
377
|
-
assetTo,
|
|
378
|
-
amountIn,
|
|
379
|
-
slippage,
|
|
380
|
-
this.address
|
|
381
|
-
);
|
|
382
|
-
break;
|
|
383
375
|
case Dapp.ONEINCH:
|
|
384
376
|
({ swapTxData } = await getOneInchSwapTxData(
|
|
385
377
|
this,
|
|
@@ -4,6 +4,7 @@ import IFlatcoinVaultAbi from "../../abi/flatmoney/IFlatcoinVault.json";
|
|
|
4
4
|
import KeeperFeeAbi from "../../abi/flatmoney/KeeperFee.json";
|
|
5
5
|
import { flatMoneyContractAddresses } from "../../config";
|
|
6
6
|
import BigNumber from "bignumber.js";
|
|
7
|
+
import { JsonRpcProvider } from "@ethersproject/providers";
|
|
7
8
|
|
|
8
9
|
export const getKeeperFeeContract = async (pool: Pool): Promise<Contract> => {
|
|
9
10
|
const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
|
|
@@ -35,12 +36,16 @@ export const getKeeperFee = async (
|
|
|
35
36
|
maxKeeperFeeInUsd: number | null
|
|
36
37
|
): Promise<ethers.BigNumber> => {
|
|
37
38
|
const keeperFeeContract = await getKeeperFeeContract(pool);
|
|
38
|
-
|
|
39
|
+
|
|
40
|
+
const feeHistory = await (pool.signer
|
|
41
|
+
.provider as JsonRpcProvider).send("eth_feeHistory", [1, "latest"]);
|
|
42
|
+
|
|
43
|
+
const gasPrice = Number(feeHistory.baseFeePerGas[0]);
|
|
39
44
|
|
|
40
45
|
let keeperfee: ethers.BigNumber;
|
|
41
46
|
if (gasPrice) {
|
|
42
47
|
keeperfee = await keeperFeeContract["getKeeperFee(uint256)"](
|
|
43
|
-
new BigNumber(gasPrice.toString()).times(1.
|
|
48
|
+
new BigNumber(gasPrice.toString()).times(1.5).toFixed(0)
|
|
44
49
|
);
|
|
45
50
|
} else {
|
|
46
51
|
keeperfee = await keeperFeeContract["getKeeperFee()"]();
|
|
@@ -72,7 +77,7 @@ export const getKeeperFeeInUsd = async (
|
|
|
72
77
|
const filteredFc = fundComposition.filter(
|
|
73
78
|
fc =>
|
|
74
79
|
fc.asset.toLocaleLowerCase() ===
|
|
75
|
-
flatMoneyContracts.
|
|
80
|
+
flatMoneyContracts.COLLATERAL.toLocaleLowerCase()
|
|
76
81
|
);
|
|
77
82
|
|
|
78
83
|
if (!filteredFc[0])
|
|
@@ -80,5 +85,8 @@ export const getKeeperFeeInUsd = async (
|
|
|
80
85
|
|
|
81
86
|
const rateD1 = new BigNumber(filteredFc[0].rate.toString()).div(1e18);
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
const assetDecimal = await pool.utils.getDecimals(
|
|
89
|
+
flatMoneyContracts.COLLATERAL
|
|
90
|
+
);
|
|
91
|
+
return rateD1.times(keeperFee.toString()).div(10 ** assetDecimal);
|
|
84
92
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import BigNumber from "bignumber.js";
|
|
4
4
|
import { Pool, ethers } from "../..";
|
|
5
5
|
import DelayedOrderAbi from "../../abi/flatmoney/DelayedOrder.json";
|
|
6
|
+
import IOrderExecutionModuleAbi from "../../abi/flatmoney/v2/IOrderExecutionModule.json";
|
|
6
7
|
import { flatMoneyContractAddresses } from "../../config";
|
|
7
8
|
import { getPoolTxOrGasEstimate } from "../../utils/contract";
|
|
8
9
|
import { getStableDepositQuote, getStableWithdrawQuote } from "./stableModule";
|
|
@@ -42,6 +43,12 @@ export function getCancelExistingOrderTxData(account: string): string {
|
|
|
42
43
|
).encodeFunctionData("cancelExistingOrder", [account]);
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
export function getCancelExistingOrderTxDataForV2(account: string): string {
|
|
47
|
+
return new ethers.utils.Interface(
|
|
48
|
+
IOrderExecutionModuleAbi
|
|
49
|
+
).encodeFunctionData("cancelExistingOrder", [account]);
|
|
50
|
+
}
|
|
51
|
+
|
|
45
52
|
export async function mintUnitViaFlatMoney(
|
|
46
53
|
pool: Pool,
|
|
47
54
|
depositAmount: ethers.BigNumber | string,
|
|
@@ -55,7 +62,7 @@ export async function mintUnitViaFlatMoney(
|
|
|
55
62
|
throw new Error("mintUnitViaFlatMoney: network not supported");
|
|
56
63
|
}
|
|
57
64
|
|
|
58
|
-
const keeperfee = await getKeeperFee(pool, maxKeeperFeeInUsd); // in
|
|
65
|
+
const keeperfee = await getKeeperFee(pool, maxKeeperFeeInUsd); // in COLLATERAL
|
|
59
66
|
|
|
60
67
|
const adjustedDepositAmount = new BigNumber(depositAmount.toString()).minus(
|
|
61
68
|
keeperfee.toString() // keeper fee deducted from amountIn
|
|
@@ -125,11 +132,26 @@ export async function cancelOrderViaFlatMoney(
|
|
|
125
132
|
if (!flatMoneyContracts) {
|
|
126
133
|
throw new Error("cancelOrderViaFlatMoney: network not supported");
|
|
127
134
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
// flat money v2
|
|
136
|
+
// use OrderExecution module to cancel order
|
|
137
|
+
let toAddress = flatMoneyContracts.DelayedOrder;
|
|
138
|
+
let cancelOrderTxData = getCancelExistingOrderTxData(pool.address);
|
|
139
|
+
if (flatMoneyContracts.OrderExecution) {
|
|
140
|
+
toAddress = flatMoneyContracts.OrderExecution;
|
|
141
|
+
cancelOrderTxData = await getCancelExistingOrderTxDataForV2(pool.address);
|
|
142
|
+
}
|
|
143
|
+
// use trader address to cancel order
|
|
144
|
+
if (estimateGas) {
|
|
145
|
+
return pool.signer.estimateGas({
|
|
146
|
+
to: toAddress,
|
|
147
|
+
data: cancelOrderTxData
|
|
148
|
+
});
|
|
149
|
+
} else {
|
|
150
|
+
const tx = await pool.signer.sendTransaction({
|
|
151
|
+
to: toAddress,
|
|
152
|
+
data: cancelOrderTxData,
|
|
153
|
+
...options
|
|
154
|
+
});
|
|
155
|
+
return tx;
|
|
156
|
+
}
|
|
135
157
|
}
|
package/src/test/constants.ts
CHANGED
|
@@ -62,7 +62,8 @@ export const CONTRACT_ADDRESS = {
|
|
|
62
62
|
VELODROME_CL_USDC_WETH_GAUGE: "",
|
|
63
63
|
VELO: "",
|
|
64
64
|
COMPOUNDV3_WETH: "",
|
|
65
|
-
TOROS: ""
|
|
65
|
+
TOROS: "",
|
|
66
|
+
UNIT: ""
|
|
66
67
|
},
|
|
67
68
|
|
|
68
69
|
[Network.OPTIMISM]: {
|
|
@@ -77,6 +78,7 @@ export const CONTRACT_ADDRESS = {
|
|
|
77
78
|
nonfungiblePositionManager: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"
|
|
78
79
|
},
|
|
79
80
|
|
|
81
|
+
UNIT: "0x357CB23571EF7a3d6189b7FAcFC361eA71f7CAB5",
|
|
80
82
|
WMATIC: "",
|
|
81
83
|
//
|
|
82
84
|
ARRAKIS_USDC_WETH_GAUGE: "",
|
|
@@ -101,6 +103,8 @@ export const CONTRACT_ADDRESS = {
|
|
|
101
103
|
nonfungiblePositionManager: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"
|
|
102
104
|
},
|
|
103
105
|
|
|
106
|
+
UNIT: "",
|
|
107
|
+
|
|
104
108
|
//
|
|
105
109
|
ARRAKIS_USDC_WETH_GAUGE: "",
|
|
106
110
|
ARRAKIS_USDC_WETH_LP: "",
|
|
@@ -117,6 +121,7 @@ export const CONTRACT_ADDRESS = {
|
|
|
117
121
|
WETH: "0x4200000000000000000000000000000000000006",
|
|
118
122
|
WBTC: "",
|
|
119
123
|
SWETH: "",
|
|
124
|
+
UNIT: "0xb95fB324b8A2fAF8ec4f76e3dF46C718402736e2",
|
|
120
125
|
uniswapV3: {
|
|
121
126
|
nonfungiblePositionManager: ""
|
|
122
127
|
},
|
|
@@ -4,6 +4,7 @@ import { Dhedge, Pool } from "../entities";
|
|
|
4
4
|
import { AssetEnabled, Network } from "../types";
|
|
5
5
|
import {
|
|
6
6
|
TestingRunParams,
|
|
7
|
+
runWithImpersonateAccount,
|
|
7
8
|
setTokenAmount,
|
|
8
9
|
testingHelper
|
|
9
10
|
} from "./utils/testingHelper";
|
|
@@ -14,9 +15,7 @@ import DelayedOrderAbi from "../abi/flatmoney/DelayedOrder.json";
|
|
|
14
15
|
import { allowanceDelta } from "./utils/token";
|
|
15
16
|
import { getKeeperFee } from "../services/flatmoney/keeperFee";
|
|
16
17
|
|
|
17
|
-
const
|
|
18
|
-
const RETH_SLOT = 0;
|
|
19
|
-
const UNIT = "0xb95fB324b8A2fAF8ec4f76e3dF46C718402736e2";
|
|
18
|
+
const COLLATERAL_SLOT = 0; // same for RETH(base) and WBTC(optimism)
|
|
20
19
|
// https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/token/ERC20/ERC20Upgradeable.sol#L31
|
|
21
20
|
// https://eips.ethereum.org/EIPS/eip-7201
|
|
22
21
|
const UNIT_SLOT =
|
|
@@ -31,16 +30,26 @@ const testFlatMoney = ({
|
|
|
31
30
|
let dhedge: Dhedge;
|
|
32
31
|
let pool: Pool;
|
|
33
32
|
let delayOrderContract: Contract;
|
|
33
|
+
let COLLATERAL: string;
|
|
34
34
|
jest.setTimeout(200000);
|
|
35
35
|
describe(`flatmoney on ${network}`, () => {
|
|
36
36
|
beforeAll(async () => {
|
|
37
|
+
await provider.send("evm_mine", []);
|
|
37
38
|
dhedge = new Dhedge(wallet, network);
|
|
38
39
|
pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
39
40
|
|
|
41
|
+
await runWithImpersonateAccount(
|
|
42
|
+
{ provider, account: await pool.managerLogic.manager() },
|
|
43
|
+
async ({ signer }) => {
|
|
44
|
+
await pool.managerLogic.connect(signer).setTrader(wallet.address);
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
|
|
40
48
|
const flatMoneyContracts = flatMoneyContractAddresses[pool.network];
|
|
41
49
|
if (!flatMoneyContracts) {
|
|
42
50
|
throw new Error("testFlatMoney: network not supported");
|
|
43
51
|
}
|
|
52
|
+
COLLATERAL = flatMoneyContracts.COLLATERAL;
|
|
44
53
|
delayOrderContract = new Contract(
|
|
45
54
|
flatMoneyContracts.DelayedOrder,
|
|
46
55
|
DelayedOrderAbi,
|
|
@@ -57,14 +66,14 @@ const testFlatMoney = ({
|
|
|
57
66
|
await setTokenAmount({
|
|
58
67
|
amount: new BigNumber(100).times(1e18).toString(),
|
|
59
68
|
provider,
|
|
60
|
-
tokenAddress:
|
|
61
|
-
slot:
|
|
69
|
+
tokenAddress: COLLATERAL,
|
|
70
|
+
slot: COLLATERAL_SLOT,
|
|
62
71
|
userAddress: pool.address
|
|
63
72
|
});
|
|
64
73
|
await setTokenAmount({
|
|
65
74
|
amount: new BigNumber(100).times(1e18).toString(),
|
|
66
75
|
provider,
|
|
67
|
-
tokenAddress: UNIT,
|
|
76
|
+
tokenAddress: CONTRACT_ADDRESS[network].UNIT,
|
|
68
77
|
slot: UNIT_SLOT,
|
|
69
78
|
userAddress: pool.address
|
|
70
79
|
});
|
|
@@ -82,11 +91,11 @@ const testFlatMoney = ({
|
|
|
82
91
|
{ asset: CONTRACT_ADDRESS[network].USDC, isDeposit: true },
|
|
83
92
|
{ asset: CONTRACT_ADDRESS[network].WETH, isDeposit: true },
|
|
84
93
|
{
|
|
85
|
-
asset: UNIT,
|
|
94
|
+
asset: CONTRACT_ADDRESS[network].UNIT,
|
|
86
95
|
isDeposit: false
|
|
87
96
|
},
|
|
88
97
|
{
|
|
89
|
-
asset:
|
|
98
|
+
asset: COLLATERAL,
|
|
90
99
|
isDeposit: false
|
|
91
100
|
}
|
|
92
101
|
];
|
|
@@ -95,10 +104,14 @@ const testFlatMoney = ({
|
|
|
95
104
|
|
|
96
105
|
it("mint UNIT", async () => {
|
|
97
106
|
//approve
|
|
98
|
-
await pool.approveSpender(
|
|
107
|
+
await pool.approveSpender(
|
|
108
|
+
delayOrderContract.address,
|
|
109
|
+
COLLATERAL,
|
|
110
|
+
MAX_AMOUNT
|
|
111
|
+
);
|
|
99
112
|
const collateralAllowanceDelta = await allowanceDelta(
|
|
100
113
|
pool.address,
|
|
101
|
-
|
|
114
|
+
COLLATERAL,
|
|
102
115
|
delayOrderContract.address,
|
|
103
116
|
pool.signer
|
|
104
117
|
);
|
|
@@ -129,7 +142,13 @@ const testFlatMoney = ({
|
|
|
129
142
|
});
|
|
130
143
|
|
|
131
144
|
it("redeem UNIT", async () => {
|
|
132
|
-
|
|
145
|
+
let withdrawAmountStr;
|
|
146
|
+
if (Network.OPTIMISM === network) {
|
|
147
|
+
withdrawAmountStr = new BigNumber(2).times(1e8).toString(); // smaller amount
|
|
148
|
+
} else {
|
|
149
|
+
withdrawAmountStr = new BigNumber(2).times(1e18).toString();
|
|
150
|
+
}
|
|
151
|
+
|
|
133
152
|
const tx = await pool.redeemUnitViaFlatMoney(
|
|
134
153
|
withdrawAmountStr,
|
|
135
154
|
0.5,
|
package/src/types.ts
CHANGED
package/src/utils/contract.ts
CHANGED
|
@@ -99,13 +99,25 @@ export const getPoolTxOrGasEstimate = async (
|
|
|
99
99
|
args: any[],
|
|
100
100
|
estimateGas: boolean
|
|
101
101
|
): Promise<any> => {
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
if (pool.isDhedge) {
|
|
103
|
+
if (estimateGas) {
|
|
104
|
+
return await pool.poolLogic.estimateGas.execTransaction(
|
|
105
|
+
args[0],
|
|
106
|
+
args[1],
|
|
107
|
+
args[2]
|
|
108
|
+
);
|
|
109
|
+
} else {
|
|
110
|
+
return await pool.poolLogic.execTransaction(args[0], args[1], args[2]);
|
|
111
|
+
}
|
|
108
112
|
} else {
|
|
109
|
-
|
|
113
|
+
if (estimateGas) {
|
|
114
|
+
return await pool.signer.estimateGas({ to: args[0], data: args[1] });
|
|
115
|
+
} else {
|
|
116
|
+
return await pool.signer.sendTransaction({
|
|
117
|
+
to: args[0],
|
|
118
|
+
data: args[1],
|
|
119
|
+
...args[2]
|
|
120
|
+
});
|
|
121
|
+
}
|
|
110
122
|
}
|
|
111
123
|
};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { BigNumber } from "ethers";
|
|
2
|
-
import { Network } from "../../types";
|
|
3
|
-
export declare const getZeroExTradeTxData: (network: Network, assetFrom: string, assetTo: string, amountIn: BigNumber | string, slippage: number | undefined, takerAddress: string) => Promise<string>;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
|
-
import { BigNumber } from "ethers";
|
|
3
|
-
import { Network } from "../../types";
|
|
4
|
-
import { ApiError } from "../../errors";
|
|
5
|
-
|
|
6
|
-
// slippage of 0x is different from that of 1Inch
|
|
7
|
-
// in 0x, e.g. 0.03 for 3% slippage allowed
|
|
8
|
-
// 1inch slippage 0.5% represented by 0.5
|
|
9
|
-
// 0x slippage 0.5% represented by 0.005
|
|
10
|
-
const getZeroExSlippage = (slippage: number): number => {
|
|
11
|
-
return Number(slippage) / 100;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export const getZeroExTradeTxData = async (
|
|
15
|
-
network: Network,
|
|
16
|
-
assetFrom: string,
|
|
17
|
-
assetTo: string,
|
|
18
|
-
amountIn: BigNumber | string,
|
|
19
|
-
slippage = 0.5,
|
|
20
|
-
takerAddress: string
|
|
21
|
-
): Promise<string> => {
|
|
22
|
-
if (!process.env.ZEROEX_API_KEY)
|
|
23
|
-
throw new Error("ZEROEX_API_KEY not configured in .env file");
|
|
24
|
-
try {
|
|
25
|
-
const slippagePercentage = getZeroExSlippage(slippage);
|
|
26
|
-
const params = {
|
|
27
|
-
buyToken: assetTo,
|
|
28
|
-
sellToken: assetFrom,
|
|
29
|
-
sellAmount: amountIn.toString(),
|
|
30
|
-
// necessary to skip quote validation is that in which the takerAddress refers to a smart contract
|
|
31
|
-
skipValidation: true,
|
|
32
|
-
// Used to enable RFQ-T liquidity
|
|
33
|
-
intentOnFilling: true,
|
|
34
|
-
takerAddress,
|
|
35
|
-
slippagePercentage
|
|
36
|
-
// excludedSourcesParam
|
|
37
|
-
};
|
|
38
|
-
const response = await axios.get(
|
|
39
|
-
`https://${network}.api.0x.org/swap/v1/quote`,
|
|
40
|
-
{
|
|
41
|
-
params,
|
|
42
|
-
headers: {
|
|
43
|
-
"0x-api-key": process.env.ZEROEX_API_KEY
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
return response.data.data;
|
|
49
|
-
} catch (e) {
|
|
50
|
-
throw new ApiError("Swap api request of 0x failed");
|
|
51
|
-
}
|
|
52
|
-
};
|