@dhedge/v2-sdk 1.10.9 → 1.10.10
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/services/odos/index.d.ts +3 -0
- package/dist/types.d.ts +2 -1
- package/dist/v2-sdk.cjs.development.js +89 -15
- 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 +89 -15
- package/dist/v2-sdk.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +8 -4
- package/src/entities/pool.ts +10 -0
- package/src/services/odos/index.ts +61 -0
- package/src/test/odos.test.ts +109 -0
- package/src/types.ts +2 -1
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -31,7 +31,8 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
31
31
|
[Dapp.UNISWAPV3]: "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
32
32
|
[Dapp.ARRAKIS]: "0xc73fb100a995b33f9fa181d420f4c8d74506df66",
|
|
33
33
|
[Dapp.TOROS]: "0x45b90480D6F643dE2f128db091A357C3c90399f2",
|
|
34
|
-
[Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff"
|
|
34
|
+
[Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
|
35
|
+
[Dapp.ODOS]: "0x4e3288c9ca110bcc82bf38f09a7b425c095d92bf"
|
|
35
36
|
},
|
|
36
37
|
[Network.OPTIMISM]: {
|
|
37
38
|
[Dapp.UNISWAPV3]: "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
|
|
@@ -43,7 +44,8 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
43
44
|
[Dapp.VELODROMEV2]: "0xa062ae8a9c5e11aaa026fc2670b0d65ccc8b2858",
|
|
44
45
|
[Dapp.LYRA]: "0xCCE7819d65f348c64B7Beb205BA367b3fE33763B",
|
|
45
46
|
[Dapp.ARRAKIS]: "0x9ce88a56d120300061593eF7AD074A1B710094d5",
|
|
46
|
-
[Dapp.ZEROEX]: "0xdef1abe32c034e558cdd535791643c58a13acc10"
|
|
47
|
+
[Dapp.ZEROEX]: "0xdef1abe32c034e558cdd535791643c58a13acc10",
|
|
48
|
+
[Dapp.ODOS]: "0xca423977156bb05b13a2ba3b76bc5419e2fe9680"
|
|
47
49
|
},
|
|
48
50
|
[Network.ARBITRUM]: {
|
|
49
51
|
[Dapp.ONEINCH]: "0x111111125421ca6dc452d289314280a0f8842a65",
|
|
@@ -52,14 +54,16 @@ export const routerAddress: AddressDappNetworkMap = {
|
|
|
52
54
|
[Dapp.BALANCER]: "0xBA12222222228d8Ba445958a75a0704d566BF2C8",
|
|
53
55
|
[Dapp.RAMSES]: "0xaaa87963efeb6f7e0a2711f397663105acb1805e",
|
|
54
56
|
[Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
|
55
|
-
[Dapp.TOROS]: "0xA5679C4272A056Bb83f039961fae7D99C48529F5"
|
|
57
|
+
[Dapp.TOROS]: "0xA5679C4272A056Bb83f039961fae7D99C48529F5",
|
|
58
|
+
[Dapp.ODOS]: "0xa669e7A0d4b3e4Fa48af2dE86BD4CD7126Be4e13"
|
|
56
59
|
},
|
|
57
60
|
[Network.BASE]: {
|
|
58
61
|
[Dapp.ONEINCH]: "0x111111125421ca6dc452d289314280a0f8842a65",
|
|
59
62
|
[Dapp.ZEROEX]: "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
|
60
63
|
[Dapp.AERODROME]: "0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43",
|
|
61
64
|
[Dapp.AAVEV3]: "0xA238Dd80C259a72e81d7e4664a9801593F98d1c5",
|
|
62
|
-
[Dapp.TOROS]: "0xf067575Eb60c7587C11e867907AA7284833704d1"
|
|
65
|
+
[Dapp.TOROS]: "0xf067575Eb60c7587C11e867907AA7284833704d1",
|
|
66
|
+
[Dapp.ODOS]: "0x19cEeAd7105607Cd444F5ad10dd51356436095a1"
|
|
63
67
|
}
|
|
64
68
|
};
|
|
65
69
|
|
package/src/entities/pool.ts
CHANGED
|
@@ -86,6 +86,7 @@ import {
|
|
|
86
86
|
getPancakeStakeTxData,
|
|
87
87
|
getPancakeUnStakeTxData
|
|
88
88
|
} from "../services/pancake/staking";
|
|
89
|
+
import { getOdosSwapTxData } from "../services/odos";
|
|
89
90
|
|
|
90
91
|
export class Pool {
|
|
91
92
|
public readonly poolLogic: Contract;
|
|
@@ -420,6 +421,15 @@ export class Pool {
|
|
|
420
421
|
slippage
|
|
421
422
|
);
|
|
422
423
|
break;
|
|
424
|
+
case Dapp.ODOS:
|
|
425
|
+
swapTxData = await getOdosSwapTxData(
|
|
426
|
+
this,
|
|
427
|
+
assetFrom,
|
|
428
|
+
assetTo,
|
|
429
|
+
amountIn,
|
|
430
|
+
slippage
|
|
431
|
+
);
|
|
432
|
+
break;
|
|
423
433
|
default:
|
|
424
434
|
const iUniswapV2Router = new ethers.utils.Interface(
|
|
425
435
|
IUniswapV2Router.abi
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import { ApiError, ethers } from "../..";
|
|
4
|
+
import { networkChainIdMap } from "../../config";
|
|
5
|
+
import { Pool } from "../../entities";
|
|
6
|
+
|
|
7
|
+
const odosBaseUrl = "https://api.odos.xyz/sor";
|
|
8
|
+
|
|
9
|
+
export async function getOdosSwapTxData(
|
|
10
|
+
pool: Pool,
|
|
11
|
+
assetFrom: string,
|
|
12
|
+
assetTo: string,
|
|
13
|
+
amountIn: ethers.BigNumber | string,
|
|
14
|
+
slippage: number
|
|
15
|
+
): Promise<string> {
|
|
16
|
+
let referralCode = 0; // Defaults to 0 for unregistered activity.
|
|
17
|
+
if (
|
|
18
|
+
process.env.ODOS_REFERAL_CODE &&
|
|
19
|
+
Number(process.env.ODOS_REFERAL_CODE) > 0
|
|
20
|
+
) {
|
|
21
|
+
referralCode = Number(process.env.ODOS_REFERAL_CODE);
|
|
22
|
+
}
|
|
23
|
+
const quoteParams = {
|
|
24
|
+
chainId: networkChainIdMap[pool.network],
|
|
25
|
+
inputTokens: [
|
|
26
|
+
{
|
|
27
|
+
tokenAddress: assetFrom,
|
|
28
|
+
amount: amountIn.toString()
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
outputTokens: [
|
|
32
|
+
{
|
|
33
|
+
tokenAddress: assetTo,
|
|
34
|
+
proportion: 1
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
slippageLimitPercent: slippage,
|
|
38
|
+
userAddr: pool.address,
|
|
39
|
+
referralCode
|
|
40
|
+
};
|
|
41
|
+
try {
|
|
42
|
+
const quoteResult = await axios.post(
|
|
43
|
+
`${odosBaseUrl}/quote/v2`,
|
|
44
|
+
quoteParams
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const assembleParams = {
|
|
48
|
+
pathId: quoteResult.data.pathId,
|
|
49
|
+
userAddr: pool.address
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const assembleResult = await axios.post(
|
|
53
|
+
`${odosBaseUrl}/assemble`,
|
|
54
|
+
assembleParams
|
|
55
|
+
);
|
|
56
|
+
return assembleResult.data.transaction.data;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.error("Error in Odos API request:", e);
|
|
59
|
+
throw new ApiError("Swap api request of Odos failed");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
|
|
3
|
+
import { Dhedge, Pool } from "..";
|
|
4
|
+
|
|
5
|
+
import { Dapp, Network } from "../types";
|
|
6
|
+
import { CONTRACT_ADDRESS, MAX_AMOUNT, TEST_POOL } from "./constants";
|
|
7
|
+
import {
|
|
8
|
+
TestingRunParams,
|
|
9
|
+
setUSDCAmount,
|
|
10
|
+
testingHelper,
|
|
11
|
+
wait
|
|
12
|
+
} from "./utils/testingHelper";
|
|
13
|
+
import { allowanceDelta, balanceDelta } from "./utils/token";
|
|
14
|
+
import { getTxOptions } from "./txOptions";
|
|
15
|
+
import BigNumber from "bignumber.js";
|
|
16
|
+
import { routerAddress } from "../config";
|
|
17
|
+
|
|
18
|
+
const testOdos = ({ wallet, network, provider }: TestingRunParams) => {
|
|
19
|
+
const USDC = CONTRACT_ADDRESS[network].USDC;
|
|
20
|
+
const WETH = CONTRACT_ADDRESS[network].WETH;
|
|
21
|
+
|
|
22
|
+
let dhedge: Dhedge;
|
|
23
|
+
let pool: Pool;
|
|
24
|
+
jest.setTimeout(100000);
|
|
25
|
+
|
|
26
|
+
describe(`pool on ${network}`, () => {
|
|
27
|
+
beforeAll(async () => {
|
|
28
|
+
dhedge = new Dhedge(wallet, network);
|
|
29
|
+
pool = await dhedge.loadPool(TEST_POOL[network]);
|
|
30
|
+
// top up gas
|
|
31
|
+
await provider.send("hardhat_setBalance", [
|
|
32
|
+
wallet.address,
|
|
33
|
+
"0x10000000000000000"
|
|
34
|
+
]);
|
|
35
|
+
await provider.send("evm_mine", []);
|
|
36
|
+
// top up USDC
|
|
37
|
+
await setUSDCAmount({
|
|
38
|
+
amount: new BigNumber(2).times(1e6).toFixed(0),
|
|
39
|
+
userAddress: pool.address,
|
|
40
|
+
network,
|
|
41
|
+
provider
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("approves unlimited USDC on Odos", async () => {
|
|
46
|
+
await pool.approve(Dapp.ODOS, USDC, MAX_AMOUNT);
|
|
47
|
+
const usdcAllowanceDelta = await allowanceDelta(
|
|
48
|
+
pool.address,
|
|
49
|
+
USDC,
|
|
50
|
+
routerAddress[network]["odos"]!,
|
|
51
|
+
pool.signer
|
|
52
|
+
);
|
|
53
|
+
await expect(usdcAllowanceDelta.gt(0));
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("gets gas estimation for 2 USDC into WETH on Odos", async () => {
|
|
57
|
+
const gasEstimate = await pool.trade(
|
|
58
|
+
Dapp.ODOS,
|
|
59
|
+
USDC,
|
|
60
|
+
WETH,
|
|
61
|
+
"2000000",
|
|
62
|
+
1,
|
|
63
|
+
await getTxOptions(network),
|
|
64
|
+
true
|
|
65
|
+
);
|
|
66
|
+
expect(gasEstimate.gt(0));
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("trades 2 USDC into WETH on Odos", async () => {
|
|
70
|
+
await wait(1);
|
|
71
|
+
await pool.trade(
|
|
72
|
+
Dapp.ODOS,
|
|
73
|
+
USDC,
|
|
74
|
+
WETH,
|
|
75
|
+
"2000000",
|
|
76
|
+
0.5,
|
|
77
|
+
await getTxOptions(network)
|
|
78
|
+
);
|
|
79
|
+
const wethBalanceDelta = await balanceDelta(
|
|
80
|
+
pool.address,
|
|
81
|
+
WETH,
|
|
82
|
+
pool.signer
|
|
83
|
+
);
|
|
84
|
+
expect(wethBalanceDelta.gt(0));
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// testingHelper({
|
|
90
|
+
// network: Network.OPTIMISM,
|
|
91
|
+
// testingRun: testOdos
|
|
92
|
+
// });
|
|
93
|
+
|
|
94
|
+
testingHelper({
|
|
95
|
+
network: Network.ARBITRUM,
|
|
96
|
+
testingRun: testOdos
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// testingHelper({
|
|
100
|
+
// network: Network.POLYGON,
|
|
101
|
+
// onFork: false,
|
|
102
|
+
// testingRun: testOdos
|
|
103
|
+
// });
|
|
104
|
+
|
|
105
|
+
// testingHelper({
|
|
106
|
+
// network: Network.BASE,
|
|
107
|
+
// onFork: false,
|
|
108
|
+
// testingRun: testOdos
|
|
109
|
+
// });
|