@dhedge/v2-sdk 1.9.6 → 1.9.8
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 +213 -76
- package/dist/entities/pool.d.ts +16 -10
- package/dist/test/constants.d.ts +22 -0
- package/dist/types.d.ts +2 -1
- package/dist/v2-sdk.cjs.development.js +180 -75
- 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 +180 -75
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +4 -2
- package/src/entities/pool.ts +52 -10
- package/src/test/aerodrome.test.ts +154 -0
- package/src/test/arrakis.test.ts +119 -75
- package/src/test/constants.ts +32 -4
- package/src/test/uniswap.test.ts +101 -72
- package/src/types.ts +2 -1
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/merkle.d.ts +0 -22
- package/src/utils/index.ts +0 -38
- package/src/utils/merkle.ts +0 -172
package/src/test/uniswap.test.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { FeeAmount } from "@uniswap/v3-sdk";
|
|
3
3
|
import { Dhedge, ethers, Pool } from "..";
|
|
4
4
|
import { routerAddress } from "../config";
|
|
5
|
-
import { Dapp, Network } from "../types";
|
|
5
|
+
import { AssetEnabled, Dapp, Network } from "../types";
|
|
6
6
|
import { CONTRACT_ADDRESS, TEST_POOL } from "./constants";
|
|
7
7
|
import { allowanceDelta, balanceDelta } from "./utils/token";
|
|
8
8
|
import {
|
|
@@ -11,12 +11,15 @@ import {
|
|
|
11
11
|
TestingRunParams
|
|
12
12
|
} from "./utils/testingHelper";
|
|
13
13
|
import BigNumber from "bignumber.js";
|
|
14
|
+
import INonfungiblePositionManager from "../abi/INonfungiblePositionManager.json";
|
|
14
15
|
|
|
15
16
|
const testUniswapV3 = ({ wallet, network, provider }: TestingRunParams) => {
|
|
16
17
|
let dhedge: Dhedge;
|
|
17
18
|
let pool: Pool;
|
|
19
|
+
let nonfungiblePositionManager: ethers.Contract;
|
|
20
|
+
let tokenId: ethers.BigNumber;
|
|
18
21
|
|
|
19
|
-
jest.setTimeout(
|
|
22
|
+
jest.setTimeout(600000);
|
|
20
23
|
describe(`testUniswapV3 on ${network}`, () => {
|
|
21
24
|
beforeAll(async () => {
|
|
22
25
|
dhedge = new Dhedge(wallet, network);
|
|
@@ -29,11 +32,27 @@ const testUniswapV3 = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
29
32
|
]);
|
|
30
33
|
await provider.send("evm_mine", []);
|
|
31
34
|
await setUSDCAmount({
|
|
32
|
-
amount: new BigNumber(
|
|
35
|
+
amount: new BigNumber(1000000).times(1e6).toFixed(0),
|
|
33
36
|
userAddress: pool.address,
|
|
34
37
|
network,
|
|
35
38
|
provider
|
|
36
39
|
});
|
|
40
|
+
|
|
41
|
+
const newAssets: AssetEnabled[] = [
|
|
42
|
+
{ asset: CONTRACT_ADDRESS[network].USDC, isDeposit: true },
|
|
43
|
+
{ asset: CONTRACT_ADDRESS[network].WETH, isDeposit: true },
|
|
44
|
+
{
|
|
45
|
+
asset: CONTRACT_ADDRESS[network].uniswapV3.nonfungiblePositionManager,
|
|
46
|
+
isDeposit: false
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
await pool.changeAssets(newAssets);
|
|
50
|
+
|
|
51
|
+
nonfungiblePositionManager = new ethers.Contract(
|
|
52
|
+
CONTRACT_ADDRESS[network].uniswapV3.nonfungiblePositionManager,
|
|
53
|
+
INonfungiblePositionManager.abi,
|
|
54
|
+
pool.signer
|
|
55
|
+
);
|
|
37
56
|
});
|
|
38
57
|
|
|
39
58
|
it("approves unlimited USDC on for trading on UniswapV3", async () => {
|
|
@@ -52,11 +71,11 @@ const testUniswapV3 = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
52
71
|
expect(UsdcAllowanceDelta.gte(0));
|
|
53
72
|
});
|
|
54
73
|
|
|
55
|
-
it("should swap
|
|
74
|
+
it("should swap 5000 USDC into WETH on UniswapV3", async () => {
|
|
56
75
|
await pool.tradeUniswapV3(
|
|
57
76
|
CONTRACT_ADDRESS[network].USDC,
|
|
58
77
|
CONTRACT_ADDRESS[network].WETH,
|
|
59
|
-
|
|
78
|
+
new BigNumber(5000).times(1e6).toFixed(0),
|
|
60
79
|
FeeAmount.LOW,
|
|
61
80
|
0.5
|
|
62
81
|
);
|
|
@@ -69,78 +88,88 @@ const testUniswapV3 = ({ wallet, network, provider }: TestingRunParams) => {
|
|
|
69
88
|
expect(wethAllowanceDelta.gt(0));
|
|
70
89
|
});
|
|
71
90
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
it("approves unlimited WETH on for UniswapV3 LP", async () => {
|
|
92
|
+
await pool.approveUniswapV3Liquidity(
|
|
93
|
+
CONTRACT_ADDRESS[network].USDC,
|
|
94
|
+
ethers.constants.MaxInt256
|
|
95
|
+
);
|
|
96
|
+
await pool.approveUniswapV3Liquidity(
|
|
97
|
+
CONTRACT_ADDRESS[network].WETH,
|
|
98
|
+
ethers.constants.MaxInt256
|
|
99
|
+
);
|
|
100
|
+
const UsdcAllowanceDelta = await allowanceDelta(
|
|
101
|
+
pool.address,
|
|
102
|
+
CONTRACT_ADDRESS[network].USDC,
|
|
103
|
+
pool.address,
|
|
104
|
+
pool.signer
|
|
105
|
+
);
|
|
83
106
|
|
|
84
|
-
|
|
85
|
-
|
|
107
|
+
expect(UsdcAllowanceDelta).not.toBe(null);
|
|
108
|
+
});
|
|
86
109
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
110
|
+
it("adds WETH and USDC to a new V3 pool", async () => {
|
|
111
|
+
let result = null;
|
|
112
|
+
const pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
113
|
+
const usdcBalance = await dhedge.utils.getBalance(
|
|
114
|
+
CONTRACT_ADDRESS[network].USDC,
|
|
115
|
+
pool.address
|
|
116
|
+
);
|
|
117
|
+
const wethBalance = await dhedge.utils.getBalance(
|
|
118
|
+
CONTRACT_ADDRESS[network].WETH,
|
|
119
|
+
pool.address
|
|
120
|
+
);
|
|
92
121
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
try {
|
|
123
|
+
result = await pool.addLiquidityUniswapV3(
|
|
124
|
+
CONTRACT_ADDRESS[network].WETH,
|
|
125
|
+
CONTRACT_ADDRESS[network].USDC,
|
|
126
|
+
wethBalance,
|
|
127
|
+
usdcBalance,
|
|
128
|
+
2000,
|
|
129
|
+
3000,
|
|
130
|
+
null,
|
|
131
|
+
null,
|
|
132
|
+
FeeAmount.LOW
|
|
133
|
+
// options
|
|
134
|
+
);
|
|
135
|
+
await result.wait(1);
|
|
136
|
+
|
|
137
|
+
tokenId = await nonfungiblePositionManager.tokenOfOwnerByIndex(
|
|
138
|
+
pool.address,
|
|
139
|
+
0
|
|
140
|
+
);
|
|
141
|
+
} catch (e) {
|
|
142
|
+
console.log("e", e);
|
|
143
|
+
}
|
|
144
|
+
expect(result).not.toBe(null);
|
|
145
|
+
});
|
|
112
146
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
// expect(result).not.toBe(null);
|
|
123
|
-
// });
|
|
147
|
+
it("should remove liquidity from an existing pool ", async () => {
|
|
148
|
+
const result = await pool.decreaseLiquidity(
|
|
149
|
+
Dapp.UNISWAPV3,
|
|
150
|
+
tokenId.toString(),
|
|
151
|
+
50 // precent
|
|
152
|
+
);
|
|
153
|
+
// console.log("result", result);
|
|
154
|
+
expect(result).not.toBe(null);
|
|
155
|
+
});
|
|
124
156
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
// expect(result).not.toBe(null);
|
|
136
|
-
// });
|
|
157
|
+
it("should increase liquidity in the existing WETH/USDC pool", async () => {
|
|
158
|
+
const result = await pool.increaseLiquidity(
|
|
159
|
+
Dapp.UNISWAPV3,
|
|
160
|
+
tokenId.toString(),
|
|
161
|
+
new BigNumber(3000).times(1e6).toFixed(0), // usdc
|
|
162
|
+
new BigNumber(1).times(1e18).toFixed(0) // eth
|
|
163
|
+
);
|
|
164
|
+
// console.log("result", result);
|
|
165
|
+
expect(result).not.toBe(null);
|
|
166
|
+
});
|
|
137
167
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// });
|
|
168
|
+
it("should claim fees an existing pool", async () => {
|
|
169
|
+
const result = await pool.claimFees(Dapp.UNISWAPV3, tokenId.toString());
|
|
170
|
+
// console.log("result", result);
|
|
171
|
+
expect(result).not.toBe(null);
|
|
172
|
+
});
|
|
144
173
|
|
|
145
174
|
// it("approves unlimited USDC to swap on UniswapV3", async () => {
|
|
146
175
|
// let result;
|
|
@@ -187,6 +216,6 @@ testingHelper({
|
|
|
187
216
|
});
|
|
188
217
|
|
|
189
218
|
testingHelper({
|
|
190
|
-
network: Network.
|
|
219
|
+
network: Network.ARBITRUM,
|
|
191
220
|
testingRun: testUniswapV3
|
|
192
221
|
});
|
package/src/types.ts
CHANGED
package/dist/utils/index.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import BigNumber from "bignumber.js";
|
|
2
|
-
import { MerkleTree } from "./merkle";
|
|
3
|
-
export declare function scale(input: BigNumber | string, decimalPlaces: number): BigNumber;
|
|
4
|
-
export declare function loadTree(balances: {
|
|
5
|
-
[x: string]: string | BigNumber;
|
|
6
|
-
}, decimals?: number): MerkleTree;
|
|
7
|
-
export declare function bnum(val: string | number | BigNumber): BigNumber;
|
package/dist/utils/merkle.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import BigNumber from "bignumber.js";
|
|
3
|
-
export declare class MerkleTree {
|
|
4
|
-
elements: any;
|
|
5
|
-
layers: any;
|
|
6
|
-
constructor(elements: any[]);
|
|
7
|
-
getLayers(elements: string | any[]): (string | any[])[];
|
|
8
|
-
getNextLayer(elements: any[]): any[];
|
|
9
|
-
combinedHash(first: any, second: any): any;
|
|
10
|
-
getRoot(): any;
|
|
11
|
-
getHexRoot(): string;
|
|
12
|
-
getProof(el: any): any;
|
|
13
|
-
getHexProof(_el: any): string[];
|
|
14
|
-
getPairElement(idx: number, layer: string | any[]): any;
|
|
15
|
-
bufIndexOf(el: string | any[], arr: string | any[]): number;
|
|
16
|
-
bufDedup(elements: any[]): any[];
|
|
17
|
-
bufArrToHexArr(arr: any[]): string[];
|
|
18
|
-
sortAndConcat(...args: any[]): Buffer;
|
|
19
|
-
}
|
|
20
|
-
export declare function loadTree(balances: {
|
|
21
|
-
[x: string]: string | BigNumber;
|
|
22
|
-
}, decimals?: number): MerkleTree;
|
package/src/utils/index.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
3
|
-
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
4
|
-
import BigNumber from "bignumber.js";
|
|
5
|
-
import { soliditySha3 } from "web3-utils";
|
|
6
|
-
import { MerkleTree } from "./merkle";
|
|
7
|
-
|
|
8
|
-
export function scale(
|
|
9
|
-
input: BigNumber | string,
|
|
10
|
-
decimalPlaces: number
|
|
11
|
-
): BigNumber {
|
|
12
|
-
const unscaled = typeof input === "string" ? new BigNumber(input) : input;
|
|
13
|
-
const scalePow = new BigNumber(decimalPlaces.toString());
|
|
14
|
-
const scaleMul = new BigNumber(10).pow(scalePow);
|
|
15
|
-
return unscaled.times(scaleMul);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function loadTree(
|
|
19
|
-
balances: { [x: string]: string | BigNumber },
|
|
20
|
-
decimals = 18
|
|
21
|
-
) {
|
|
22
|
-
const elements: any[] = [];
|
|
23
|
-
Object.keys(balances).forEach(address => {
|
|
24
|
-
const balance: string = scale(balances[address], decimals).toString(10);
|
|
25
|
-
const leaf = soliditySha3(
|
|
26
|
-
{ t: "address", v: address },
|
|
27
|
-
{ t: "uint", v: balance }
|
|
28
|
-
);
|
|
29
|
-
// @ts-ignore
|
|
30
|
-
elements.push(leaf);
|
|
31
|
-
});
|
|
32
|
-
return new MerkleTree(elements);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function bnum(val: string | number | BigNumber): BigNumber {
|
|
36
|
-
const number = typeof val === "string" ? val : val ? val.toString() : "0";
|
|
37
|
-
return new BigNumber(number);
|
|
38
|
-
}
|
package/src/utils/merkle.ts
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
2
|
-
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
-
// Shamelessly adapted from OpenZeppelin-contracts test utils
|
|
5
|
-
import BigNumber from "bignumber.js";
|
|
6
|
-
import { keccak256, keccakFromString, bufferToHex } from "ethereumjs-util";
|
|
7
|
-
import { hexToBytes, soliditySha3 } from "web3-utils";
|
|
8
|
-
import { scale } from "./index";
|
|
9
|
-
|
|
10
|
-
// Merkle tree called with 32 byte hex values
|
|
11
|
-
export class MerkleTree {
|
|
12
|
-
public elements: any;
|
|
13
|
-
public layers: any;
|
|
14
|
-
|
|
15
|
-
constructor(elements: any[]) {
|
|
16
|
-
this.elements = elements
|
|
17
|
-
.filter((el: any) => el)
|
|
18
|
-
.map(el => Buffer.from(hexToBytes(el)));
|
|
19
|
-
|
|
20
|
-
// Sort elements
|
|
21
|
-
this.elements.sort(Buffer.compare);
|
|
22
|
-
// Deduplicate elements
|
|
23
|
-
this.elements = this.bufDedup(this.elements);
|
|
24
|
-
|
|
25
|
-
// Create layers
|
|
26
|
-
this.layers = this.getLayers(this.elements);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
getLayers(elements: string | any[]) {
|
|
30
|
-
if (elements.length === 0) {
|
|
31
|
-
return [[""]];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const layers = [];
|
|
35
|
-
layers.push(elements);
|
|
36
|
-
|
|
37
|
-
// Get next layer until we reach the root=
|
|
38
|
-
while (layers[layers.length - 1].length > 1) {
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
layers.push(this.getNextLayer(layers[layers.length - 1]));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return layers;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
getNextLayer(elements: any[]) {
|
|
47
|
-
return elements.reduce(
|
|
48
|
-
(layer: any[], el: any, idx: number, arr: { [x: string]: any }) => {
|
|
49
|
-
if (idx % 2 === 0) {
|
|
50
|
-
// Hash the current element with its pair element
|
|
51
|
-
layer.push(this.combinedHash(el, arr[idx + 1]));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return layer;
|
|
55
|
-
},
|
|
56
|
-
[]
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
combinedHash(first: any, second: any) {
|
|
61
|
-
if (!first) {
|
|
62
|
-
return second;
|
|
63
|
-
}
|
|
64
|
-
if (!second) {
|
|
65
|
-
return first;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return keccak256(this.sortAndConcat(first, second));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
getRoot() {
|
|
72
|
-
return this.layers[this.layers.length - 1][0];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
getHexRoot() {
|
|
76
|
-
return bufferToHex(this.getRoot());
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
getProof(el: any) {
|
|
80
|
-
let idx = this.bufIndexOf(el, this.elements);
|
|
81
|
-
|
|
82
|
-
if (idx === -1) {
|
|
83
|
-
throw new Error("Element does not exist in Merkle tree");
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return this.layers.reduce((proof: any[], layer: any) => {
|
|
87
|
-
const pairElement = this.getPairElement(idx, layer);
|
|
88
|
-
|
|
89
|
-
if (pairElement) {
|
|
90
|
-
proof.push(pairElement);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
idx = Math.floor(idx / 2);
|
|
94
|
-
|
|
95
|
-
return proof;
|
|
96
|
-
}, []);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// external call - convert to buffer
|
|
100
|
-
getHexProof(_el: any) {
|
|
101
|
-
const el = Buffer.from(hexToBytes(_el));
|
|
102
|
-
|
|
103
|
-
const proof = this.getProof(el);
|
|
104
|
-
|
|
105
|
-
return this.bufArrToHexArr(proof);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
getPairElement(idx: number, layer: string | any[]) {
|
|
109
|
-
const pairIdx = idx % 2 === 0 ? idx + 1 : idx - 1;
|
|
110
|
-
|
|
111
|
-
if (pairIdx < layer.length) {
|
|
112
|
-
return layer[pairIdx];
|
|
113
|
-
} else {
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
bufIndexOf(el: string | any[], arr: string | any[]) {
|
|
119
|
-
let hash;
|
|
120
|
-
|
|
121
|
-
// Convert element to 32 byte hash if it is not one already
|
|
122
|
-
if (el.length !== 32 || !Buffer.isBuffer(el)) {
|
|
123
|
-
hash = keccakFromString(el as string);
|
|
124
|
-
} else {
|
|
125
|
-
hash = el;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
for (let i = 0; i < arr.length; i++) {
|
|
129
|
-
if (hash.equals(arr[i])) {
|
|
130
|
-
return i;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return -1;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
bufDedup(elements: any[]) {
|
|
138
|
-
return elements.filter((el: any, idx: number) => {
|
|
139
|
-
return idx === 0 || !elements[idx - 1].equals(el);
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
bufArrToHexArr(arr: any[]) {
|
|
144
|
-
if (arr.some((el: any) => !Buffer.isBuffer(el))) {
|
|
145
|
-
throw new Error("Array is not an array of buffers");
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return arr.map(
|
|
149
|
-
(el: { toString: (arg0: string) => string }) => "0x" + el.toString("hex")
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
sortAndConcat(...args: any[]) {
|
|
154
|
-
return Buffer.concat([...args].sort(Buffer.compare));
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export function loadTree(
|
|
159
|
-
balances: { [x: string]: string | BigNumber },
|
|
160
|
-
decimals = 18
|
|
161
|
-
) {
|
|
162
|
-
const elements: (string | null)[] = [];
|
|
163
|
-
Object.keys(balances).forEach(address => {
|
|
164
|
-
const balance: string = scale(balances[address], decimals).toString(10);
|
|
165
|
-
const leaf = soliditySha3(
|
|
166
|
-
{ t: "address", v: address },
|
|
167
|
-
{ t: "uint", v: balance }
|
|
168
|
-
);
|
|
169
|
-
elements.push(leaf);
|
|
170
|
-
});
|
|
171
|
-
return new MerkleTree(elements);
|
|
172
|
-
}
|