@paraswap/dex-lib 2.50.6 → 2.50.7-sdai
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/build/abi/maker-psm/pot.json +322 -0
- package/build/abi/{wombat/pool.json → sdai/SavingsDai.abi.json} +289 -701
- package/build/config.js +5 -2
- package/build/config.js.map +1 -1
- package/build/dex/dexalot/config.js +7 -0
- package/build/dex/dexalot/config.js.map +1 -1
- package/build/dex/index.js +2 -0
- package/build/dex/index.js.map +1 -1
- package/build/dex/sdai/config.d.ts +11 -0
- package/build/dex/sdai/config.js +24 -0
- package/build/dex/sdai/config.js.map +1 -0
- package/build/dex/sdai/constants.d.ts +2 -0
- package/build/dex/sdai/constants.js +6 -0
- package/build/dex/sdai/constants.js.map +1 -0
- package/build/dex/sdai/scripts/validate-state.js +102 -0
- package/build/dex/sdai/scripts/validate-state.js.map +1 -0
- package/build/dex/sdai/sdai-pool.d.ts +16 -0
- package/build/dex/sdai/sdai-pool.js +85 -0
- package/build/dex/sdai/sdai-pool.js.map +1 -0
- package/build/dex/sdai/sdai.d.ts +51 -0
- package/build/dex/sdai/sdai.js +172 -0
- package/build/dex/sdai/sdai.js.map +1 -0
- package/build/dex/sdai/types.d.ts +21 -0
- package/build/dex/sdai/types.js +11 -0
- package/build/dex/sdai/types.js.map +1 -0
- package/build/dex/sdai/utils.d.ts +4 -0
- package/build/dex/sdai/utils.js +39 -0
- package/build/dex/sdai/utils.js.map +1 -0
- package/package.json +1 -1
- package/src/abi/maker-psm/pot.json +322 -0
- package/src/abi/sdai/SavingsDai.abi.json +877 -0
- package/src/config.ts +5 -2
- package/src/dex/dexalot/config.ts +7 -0
- package/src/dex/dexalot/dexalot-e2e.test.ts +23 -1
- package/src/dex/dexalot/dexalot-integration.test.ts +121 -0
- package/src/dex/index.ts +2 -0
- package/src/dex/sdai/config.ts +28 -0
- package/src/dex/sdai/constants.ts +2 -0
- package/src/dex/sdai/scripts/validate-state.ts +144 -0
- package/src/dex/sdai/sdai-e2e.test.ts +96 -0
- package/src/dex/sdai/sdai-events.test.ts +105 -0
- package/src/dex/sdai/sdai-integration.test.ts +148 -0
- package/src/dex/sdai/sdai-pool.ts +113 -0
- package/src/dex/sdai/sdai.ts +233 -0
- package/src/dex/sdai/types.ts +23 -0
- package/src/dex/sdai/utils.ts +48 -0
- package/tests/constants-e2e.ts +2 -2
- package/.vscode/launch.json +0 -53
- package/.vscode/settings.json +0 -2
- package/.vscode/tasks.json +0 -15
- package/build/abi/uniswap-v3/AlienBaseV3Router.abi.json +0 -52
- package/build/dex/aave-v2/tokens-avalanche.json +0 -44
- package/build/dex/aave-v2/tokens-mainnet.json +0 -188
- package/build/dex/aave-v2/tokens-polygon.json +0 -44
- package/build/dex/solidly-v3/scripts/check-event-pool-event.js +0 -53
- package/build/dex/solidly-v3/scripts/check-event-pool-event.js.map +0 -1
- package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.d.ts +0 -17
- package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js +0 -64
- package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js.map +0 -1
- package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.d.ts +0 -17
- package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js +0 -79
- package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js.map +0 -1
- package/main-config.ts +0 -4484
- /package/build/dex/{solidly-v3/scripts/check-event-pool-event.d.ts → sdai/scripts/validate-state.d.ts} +0 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
dotenv.config();
|
|
3
|
+
|
|
4
|
+
import { DummyDexHelper } from '../../dex-helper/index';
|
|
5
|
+
import { Network, SwapSide } from '../../constants';
|
|
6
|
+
import { checkPoolPrices, checkPoolsLiquidity } from '../../../tests/utils';
|
|
7
|
+
import { Tokens } from '../../../tests/constants-e2e';
|
|
8
|
+
import { BI_POWS } from '../../bigint-constants';
|
|
9
|
+
import { SDai } from './sdai';
|
|
10
|
+
|
|
11
|
+
const network = Network.MAINNET;
|
|
12
|
+
|
|
13
|
+
const SDaiSymbol = 'sDAI';
|
|
14
|
+
const SDaiToken = Tokens[network][SDaiSymbol];
|
|
15
|
+
|
|
16
|
+
const DaiSymbol = 'DAI';
|
|
17
|
+
const DaiToken = Tokens[network][DaiSymbol];
|
|
18
|
+
|
|
19
|
+
const amounts = [0n, BI_POWS[18], 2000000000000000000n];
|
|
20
|
+
|
|
21
|
+
const dexKey = 'SDai';
|
|
22
|
+
const dexHelper = new DummyDexHelper(network);
|
|
23
|
+
let blocknumber: number;
|
|
24
|
+
let sdai: SDai;
|
|
25
|
+
|
|
26
|
+
describe('SDai', function () {
|
|
27
|
+
beforeAll(async () => {
|
|
28
|
+
blocknumber = await dexHelper.web3Provider.eth.getBlockNumber();
|
|
29
|
+
sdai = new SDai(network, dexKey, dexHelper);
|
|
30
|
+
if (sdai.initializePricing) {
|
|
31
|
+
await sdai.initializePricing(blocknumber);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('getPoolIdentifiers and getPricesVolume DAI -> sDAI SELL', async function () {
|
|
36
|
+
const pools = await sdai.getPoolIdentifiers(
|
|
37
|
+
DaiToken,
|
|
38
|
+
SDaiToken,
|
|
39
|
+
SwapSide.SELL,
|
|
40
|
+
blocknumber,
|
|
41
|
+
);
|
|
42
|
+
console.log(`${DaiSymbol} <> ${SDaiSymbol} Pool Identifiers: `, pools);
|
|
43
|
+
|
|
44
|
+
expect(pools.length).toBeGreaterThan(0);
|
|
45
|
+
|
|
46
|
+
const poolPrices = await sdai.getPricesVolume(
|
|
47
|
+
DaiToken,
|
|
48
|
+
SDaiToken,
|
|
49
|
+
amounts,
|
|
50
|
+
SwapSide.SELL,
|
|
51
|
+
blocknumber,
|
|
52
|
+
pools,
|
|
53
|
+
);
|
|
54
|
+
console.log(`${DaiSymbol} <> ${SDaiSymbol} Pool Prices: `, poolPrices);
|
|
55
|
+
|
|
56
|
+
expect(poolPrices).not.toBeNull();
|
|
57
|
+
checkPoolPrices(poolPrices!, amounts, SwapSide.SELL, dexKey);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('getPoolIdentifiers and getPricesVolume sDAI -> DAI SELL', async function () {
|
|
61
|
+
const pools = await sdai.getPoolIdentifiers(
|
|
62
|
+
SDaiToken,
|
|
63
|
+
DaiToken,
|
|
64
|
+
SwapSide.SELL,
|
|
65
|
+
blocknumber,
|
|
66
|
+
);
|
|
67
|
+
console.log(`${SDaiSymbol} <> ${DaiSymbol} Pool Identifiers: `, pools);
|
|
68
|
+
|
|
69
|
+
expect(pools.length).toBeGreaterThan(0);
|
|
70
|
+
|
|
71
|
+
const poolPrices = await sdai.getPricesVolume(
|
|
72
|
+
SDaiToken,
|
|
73
|
+
DaiToken,
|
|
74
|
+
amounts,
|
|
75
|
+
SwapSide.SELL,
|
|
76
|
+
blocknumber,
|
|
77
|
+
pools,
|
|
78
|
+
);
|
|
79
|
+
console.log(`${SDaiSymbol} <> ${DaiSymbol} Pool Prices: `, poolPrices);
|
|
80
|
+
|
|
81
|
+
expect(poolPrices).not.toBeNull();
|
|
82
|
+
checkPoolPrices(poolPrices!, amounts, SwapSide.SELL, dexKey);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('getPoolIdentifiers and getPricesVolume DAI -> sDAI BUY', async function () {
|
|
86
|
+
const pools = await sdai.getPoolIdentifiers(
|
|
87
|
+
DaiToken,
|
|
88
|
+
SDaiToken,
|
|
89
|
+
SwapSide.BUY,
|
|
90
|
+
blocknumber,
|
|
91
|
+
);
|
|
92
|
+
console.log(`${DaiSymbol} <> ${SDaiSymbol} Pool Identifiers: `, pools);
|
|
93
|
+
|
|
94
|
+
expect(pools.length).toBeGreaterThan(0);
|
|
95
|
+
|
|
96
|
+
const poolPrices = await sdai.getPricesVolume(
|
|
97
|
+
DaiToken,
|
|
98
|
+
SDaiToken,
|
|
99
|
+
amounts,
|
|
100
|
+
SwapSide.BUY,
|
|
101
|
+
blocknumber,
|
|
102
|
+
pools,
|
|
103
|
+
);
|
|
104
|
+
console.log(`${DaiSymbol} <> ${SDaiSymbol} Pool Prices: `, poolPrices);
|
|
105
|
+
|
|
106
|
+
expect(poolPrices).not.toBeNull();
|
|
107
|
+
checkPoolPrices(poolPrices!, amounts, SwapSide.BUY, dexKey);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('getPoolIdentifiers and getPricesVolume sDAI -> DAI BUY', async function () {
|
|
111
|
+
const pools = await sdai.getPoolIdentifiers(
|
|
112
|
+
SDaiToken,
|
|
113
|
+
DaiToken,
|
|
114
|
+
SwapSide.BUY,
|
|
115
|
+
blocknumber,
|
|
116
|
+
);
|
|
117
|
+
console.log(`${SDaiSymbol} <> ${DaiSymbol} Pool Identifiers: `, pools);
|
|
118
|
+
|
|
119
|
+
expect(pools.length).toBeGreaterThan(0);
|
|
120
|
+
|
|
121
|
+
const poolPrices = await sdai.getPricesVolume(
|
|
122
|
+
SDaiToken,
|
|
123
|
+
DaiToken,
|
|
124
|
+
amounts,
|
|
125
|
+
SwapSide.BUY,
|
|
126
|
+
blocknumber,
|
|
127
|
+
pools,
|
|
128
|
+
);
|
|
129
|
+
console.log(`${SDaiSymbol} <> ${DaiSymbol} Pool Prices: `, poolPrices);
|
|
130
|
+
|
|
131
|
+
expect(poolPrices).not.toBeNull();
|
|
132
|
+
checkPoolPrices(poolPrices!, amounts, SwapSide.BUY, dexKey);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('Dai getTopPoolsForToken', async function () {
|
|
136
|
+
const poolLiquidity = await sdai.getTopPoolsForToken(DaiToken.address, 10);
|
|
137
|
+
console.log(`${DaiSymbol} Top Pools:`, poolLiquidity);
|
|
138
|
+
|
|
139
|
+
checkPoolsLiquidity(poolLiquidity, DaiToken.address, dexKey);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('SDai getTopPoolsForToken', async function () {
|
|
143
|
+
const poolLiquidity = await sdai.getTopPoolsForToken(SDaiToken.address, 10);
|
|
144
|
+
console.log(`${SDaiSymbol} Top Pools:`, poolLiquidity);
|
|
145
|
+
|
|
146
|
+
checkPoolsLiquidity(poolLiquidity, SDaiToken.address, dexKey);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { BI_POWS } from '../../bigint-constants';
|
|
2
|
+
import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
|
|
3
|
+
import { Interface } from '@ethersproject/abi';
|
|
4
|
+
|
|
5
|
+
import type { IDexHelper } from '../../dex-helper';
|
|
6
|
+
import type { AsyncOrSync, DeepReadonly } from 'ts-essentials';
|
|
7
|
+
import type { Address, BlockHeader, Log, Logger } from '../../types';
|
|
8
|
+
import type { SDaiPoolState } from './types';
|
|
9
|
+
import { getOnChainState } from './utils';
|
|
10
|
+
|
|
11
|
+
const RAY = BI_POWS[27];
|
|
12
|
+
const ZERO = BigInt(0);
|
|
13
|
+
const TWO = BigInt(2);
|
|
14
|
+
const HALF = RAY / TWO;
|
|
15
|
+
|
|
16
|
+
// function file(bytes32,uint256)
|
|
17
|
+
const FILE_TOPICHASH = `0x29ae811400000000000000000000000000000000000000000000000000000000`;
|
|
18
|
+
// function drip()
|
|
19
|
+
const DRIP_TOPICHASH = `0x9f678cca00000000000000000000000000000000000000000000000000000000`;
|
|
20
|
+
// function cage()
|
|
21
|
+
const CAGE_TOPICHASH = `0x6924500900000000000000000000000000000000000000000000000000000000`;
|
|
22
|
+
// bytes32 repr of "dsr" string
|
|
23
|
+
const DSR_TOPIC = `0x6473720000000000000000000000000000000000000000000000000000000000`;
|
|
24
|
+
|
|
25
|
+
const rpow = (x: bigint, n: bigint): bigint => {
|
|
26
|
+
if (!x && !n) return RAY;
|
|
27
|
+
if (!x) return ZERO;
|
|
28
|
+
|
|
29
|
+
let z = n % TWO > ZERO ? x : RAY;
|
|
30
|
+
|
|
31
|
+
for (n = n / TWO; n; n /= TWO) {
|
|
32
|
+
x = (x * x + HALF) / RAY;
|
|
33
|
+
if (n % TWO > ZERO) {
|
|
34
|
+
z = (z * x + HALF) / RAY;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return z;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const calcChi = (state: SDaiPoolState, currentTimestamp?: number) => {
|
|
42
|
+
currentTimestamp ||= Math.floor(Date.now() / 1000);
|
|
43
|
+
if (!state.live) return RAY;
|
|
44
|
+
|
|
45
|
+
const { dsr: dsr_, chi: chi_, rho: rho_ } = state;
|
|
46
|
+
const now = BigInt(currentTimestamp);
|
|
47
|
+
const rho = BigInt(rho_);
|
|
48
|
+
const dsr = BigInt(dsr_);
|
|
49
|
+
const chi = BigInt(chi_);
|
|
50
|
+
|
|
51
|
+
return now > rho ? (rpow(dsr, now - rho) * chi) / RAY : chi;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export class SDaiEventPool extends StatefulEventSubscriber<SDaiPoolState> {
|
|
55
|
+
constructor(
|
|
56
|
+
parentName: string,
|
|
57
|
+
protected dexHelper: IDexHelper,
|
|
58
|
+
private potAddress: Address,
|
|
59
|
+
private potInterface: Interface,
|
|
60
|
+
logger: Logger,
|
|
61
|
+
) {
|
|
62
|
+
super(parentName, 'sdai', dexHelper, logger);
|
|
63
|
+
this.addressesSubscribed = [potAddress];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected processLog(
|
|
67
|
+
state: DeepReadonly<SDaiPoolState>,
|
|
68
|
+
log: Readonly<Log>,
|
|
69
|
+
blockHeader: Readonly<BlockHeader>,
|
|
70
|
+
): AsyncOrSync<DeepReadonly<SDaiPoolState> | null> {
|
|
71
|
+
if (log.topics[0] === FILE_TOPICHASH && log.topics[2] === DSR_TOPIC) {
|
|
72
|
+
return {
|
|
73
|
+
...state,
|
|
74
|
+
dsr: BigInt(log.topics[3]).toString(),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (log.topics[0] === DRIP_TOPICHASH) {
|
|
79
|
+
return {
|
|
80
|
+
...state,
|
|
81
|
+
rho: blockHeader.timestamp.toString(),
|
|
82
|
+
chi: calcChi(state, +blockHeader.timestamp).toString(),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async generateState(
|
|
90
|
+
blockNumber: number | 'latest' = 'latest',
|
|
91
|
+
): Promise<DeepReadonly<SDaiPoolState>> {
|
|
92
|
+
return getOnChainState(
|
|
93
|
+
this.dexHelper.multiContract,
|
|
94
|
+
this.potAddress,
|
|
95
|
+
this.potInterface,
|
|
96
|
+
blockNumber,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
convertToSDai(daiAmount: bigint, blockNumber: number): bigint {
|
|
101
|
+
const state = this.getState(blockNumber);
|
|
102
|
+
if (!state) throw new Error(`SDai state at ${blockNumber} does not exists`);
|
|
103
|
+
|
|
104
|
+
return (daiAmount * RAY) / calcChi(state);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
convertToDai(sdaiAmount: bigint, blockNumber: number): bigint {
|
|
108
|
+
const state = this.getState(blockNumber);
|
|
109
|
+
if (!state) throw new Error(`SDai state at ${blockNumber} does not exists`);
|
|
110
|
+
|
|
111
|
+
return (sdaiAmount * calcChi(state)) / RAY;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { SimpleExchange } from '../simple-exchange';
|
|
2
|
+
import { IDex } from '../idex';
|
|
3
|
+
import { SDaiParams, SDaiData, SDaiFunctions } from './types';
|
|
4
|
+
import { Network, SwapSide } from '../../constants';
|
|
5
|
+
import { getDexKeysWithNetwork } from '../../utils';
|
|
6
|
+
import { Adapters, SDaiConfig } from './config';
|
|
7
|
+
import {
|
|
8
|
+
AdapterExchangeParam,
|
|
9
|
+
Address,
|
|
10
|
+
ExchangePrices,
|
|
11
|
+
Logger,
|
|
12
|
+
PoolLiquidity,
|
|
13
|
+
PoolPrices,
|
|
14
|
+
SimpleExchangeParam,
|
|
15
|
+
Token,
|
|
16
|
+
} from '../../types';
|
|
17
|
+
import { IDexHelper } from '../../dex-helper';
|
|
18
|
+
import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
|
|
19
|
+
import PotAbi from '../../abi/maker-psm/pot.json';
|
|
20
|
+
import SavingsDaiAbi from '../../abi/sdai/SavingsDai.abi.json';
|
|
21
|
+
import { Interface } from 'ethers/lib/utils';
|
|
22
|
+
import { SDaiEventPool } from './sdai-pool';
|
|
23
|
+
import { BI_POWS } from '../../bigint-constants';
|
|
24
|
+
import { SDAI_DEPOSIT_GAS_COST, SDAI_REDEEM_GAS_COST } from './constants';
|
|
25
|
+
|
|
26
|
+
export class SDai extends SimpleExchange implements IDex<SDaiData, SDaiParams> {
|
|
27
|
+
readonly hasConstantPriceLargeAmounts = true;
|
|
28
|
+
readonly isFeeOnTransferSupported = false;
|
|
29
|
+
|
|
30
|
+
public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
|
|
31
|
+
getDexKeysWithNetwork(SDaiConfig);
|
|
32
|
+
|
|
33
|
+
public readonly eventPool: SDaiEventPool;
|
|
34
|
+
logger: Logger;
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
protected network: Network,
|
|
38
|
+
dexKey: string,
|
|
39
|
+
protected dexHelper: IDexHelper,
|
|
40
|
+
|
|
41
|
+
readonly daiAddress: string = SDaiConfig[dexKey][network].daiAddress,
|
|
42
|
+
readonly sdaiAddress: string = SDaiConfig[dexKey][network].sdaiAddress,
|
|
43
|
+
readonly potAddress: string = SDaiConfig[dexKey][network].potAddress,
|
|
44
|
+
|
|
45
|
+
protected adapters = Adapters[network] || {},
|
|
46
|
+
protected sdaiInterface = new Interface(SavingsDaiAbi),
|
|
47
|
+
protected potInterface = new Interface(PotAbi),
|
|
48
|
+
) {
|
|
49
|
+
super(dexHelper, dexKey);
|
|
50
|
+
this.logger = dexHelper.getLogger(dexKey);
|
|
51
|
+
this.eventPool = new SDaiEventPool(
|
|
52
|
+
this.dexKey,
|
|
53
|
+
dexHelper,
|
|
54
|
+
this.potAddress,
|
|
55
|
+
this.potInterface,
|
|
56
|
+
this.logger,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getAdapters(side: SwapSide): { name: string; index: number }[] | null {
|
|
61
|
+
return this.adapters[side] || null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
isSDai(tokenAddress: Address) {
|
|
65
|
+
return this.sdaiAddress.toLowerCase() === tokenAddress.toLowerCase();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
isDai(tokenAddress: Address) {
|
|
69
|
+
return this.daiAddress.toLowerCase() === tokenAddress.toLowerCase();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
isAppropriatePair(srcToken: Token, destToken: Token) {
|
|
73
|
+
return (
|
|
74
|
+
(this.isDai(srcToken.address) && this.isSDai(destToken.address)) ||
|
|
75
|
+
(this.isDai(destToken.address) && this.isSDai(srcToken.address))
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async initializePricing(blockNumber: number) {
|
|
80
|
+
await this.eventPool.initialize(blockNumber);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async getPoolIdentifiers(
|
|
84
|
+
srcToken: Token,
|
|
85
|
+
destToken: Token,
|
|
86
|
+
side: SwapSide,
|
|
87
|
+
blockNumber: number,
|
|
88
|
+
): Promise<string[]> {
|
|
89
|
+
return this.isAppropriatePair(srcToken, destToken)
|
|
90
|
+
? [`${this.dexKey}_${this.sdaiAddress}`]
|
|
91
|
+
: [];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async getPricesVolume(
|
|
95
|
+
srcToken: Token,
|
|
96
|
+
destToken: Token,
|
|
97
|
+
amounts: bigint[],
|
|
98
|
+
side: SwapSide,
|
|
99
|
+
blockNumber: number,
|
|
100
|
+
limitPools?: string[],
|
|
101
|
+
): Promise<null | ExchangePrices<SDaiData>> {
|
|
102
|
+
if (!this.isAppropriatePair(srcToken, destToken)) return null;
|
|
103
|
+
if (!this.eventPool.getState(blockNumber)) return null;
|
|
104
|
+
|
|
105
|
+
if (side === SwapSide.SELL) {
|
|
106
|
+
const calcSellFn = (blockNumber: number, amountIn: bigint) =>
|
|
107
|
+
this.isDai(srcToken.address)
|
|
108
|
+
? this.eventPool.convertToSDai(amountIn, blockNumber)
|
|
109
|
+
: this.eventPool.convertToDai(amountIn, blockNumber);
|
|
110
|
+
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
prices: amounts.map(amount => calcSellFn(blockNumber, amount)),
|
|
114
|
+
unit: calcSellFn(blockNumber, BI_POWS[18]),
|
|
115
|
+
gasCost: SDAI_DEPOSIT_GAS_COST,
|
|
116
|
+
exchange: this.dexKey,
|
|
117
|
+
data: { exchange: `${this.sdaiAddress}` },
|
|
118
|
+
poolAddresses: [`${this.sdaiAddress}`],
|
|
119
|
+
},
|
|
120
|
+
];
|
|
121
|
+
} else {
|
|
122
|
+
const calcBuyFn = (blockNumber: number, amountIn: bigint) =>
|
|
123
|
+
this.isDai(srcToken.address)
|
|
124
|
+
? this.eventPool.convertToDai(amountIn, blockNumber)
|
|
125
|
+
: this.eventPool.convertToSDai(amountIn, blockNumber);
|
|
126
|
+
|
|
127
|
+
return [
|
|
128
|
+
{
|
|
129
|
+
prices: amounts.map(amount => calcBuyFn(blockNumber, amount)),
|
|
130
|
+
unit: calcBuyFn(blockNumber, BI_POWS[18]),
|
|
131
|
+
gasCost: SDAI_REDEEM_GAS_COST,
|
|
132
|
+
exchange: this.dexKey,
|
|
133
|
+
data: { exchange: `${this.sdaiAddress}` },
|
|
134
|
+
poolAddresses: [`${this.sdaiAddress}`],
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Returns estimated gas cost of calldata for this DEX in multiSwap
|
|
141
|
+
getCalldataGasCost(poolPrices: PoolPrices<SDaiData>): number | number[] {
|
|
142
|
+
return CALLDATA_GAS_COST.DEX_NO_PAYLOAD;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async getTopPoolsForToken(
|
|
146
|
+
tokenAddress: Address,
|
|
147
|
+
limit: number,
|
|
148
|
+
): Promise<PoolLiquidity[]> {
|
|
149
|
+
if (!this.isDai(tokenAddress) && !this.isSDai(tokenAddress)) return [];
|
|
150
|
+
|
|
151
|
+
return [
|
|
152
|
+
{
|
|
153
|
+
exchange: this.dexKey,
|
|
154
|
+
address: this.sdaiAddress,
|
|
155
|
+
connectorTokens: [
|
|
156
|
+
{
|
|
157
|
+
decimals: 18,
|
|
158
|
+
address: this.isDai(tokenAddress)
|
|
159
|
+
? this.sdaiAddress
|
|
160
|
+
: this.daiAddress,
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
liquidityUSD: 1000000000, // Just returning a big number so this DEX will be preferred
|
|
164
|
+
},
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async getSimpleParam(
|
|
169
|
+
srcToken: string,
|
|
170
|
+
destToken: string,
|
|
171
|
+
srcAmount: string,
|
|
172
|
+
destAmount: string,
|
|
173
|
+
data: SDaiData,
|
|
174
|
+
side: SwapSide,
|
|
175
|
+
): Promise<SimpleExchangeParam> {
|
|
176
|
+
const isSell = side === SwapSide.SELL;
|
|
177
|
+
const { exchange } = data;
|
|
178
|
+
|
|
179
|
+
let swapData: string;
|
|
180
|
+
if (this.isDai(srcToken)) {
|
|
181
|
+
swapData = this.sdaiInterface.encodeFunctionData(
|
|
182
|
+
isSell ? SDaiFunctions.deposit : SDaiFunctions.mint,
|
|
183
|
+
[isSell ? srcAmount : destAmount, this.augustusAddress],
|
|
184
|
+
);
|
|
185
|
+
} else {
|
|
186
|
+
swapData = this.sdaiInterface.encodeFunctionData(
|
|
187
|
+
isSell ? SDaiFunctions.redeem : SDaiFunctions.withdraw,
|
|
188
|
+
[
|
|
189
|
+
isSell ? srcAmount : destAmount,
|
|
190
|
+
this.augustusAddress,
|
|
191
|
+
this.augustusAddress,
|
|
192
|
+
],
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return this.buildSimpleParamWithoutWETHConversion(
|
|
197
|
+
srcToken,
|
|
198
|
+
srcAmount,
|
|
199
|
+
destToken,
|
|
200
|
+
destAmount,
|
|
201
|
+
swapData,
|
|
202
|
+
exchange,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
getAdapterParam(
|
|
207
|
+
srcToken: string,
|
|
208
|
+
destToken: string,
|
|
209
|
+
srcAmount: string,
|
|
210
|
+
destAmount: string,
|
|
211
|
+
data: SDaiData,
|
|
212
|
+
side: SwapSide,
|
|
213
|
+
): AdapterExchangeParam {
|
|
214
|
+
const { exchange } = data;
|
|
215
|
+
|
|
216
|
+
const payload = this.abiCoder.encodeParameter(
|
|
217
|
+
{
|
|
218
|
+
ParentStruct: {
|
|
219
|
+
toStaked: 'bool',
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
toStaked: this.isDai(srcToken),
|
|
224
|
+
},
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
targetExchange: exchange,
|
|
229
|
+
payload,
|
|
230
|
+
networkFee: '0',
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Address } from '../../types';
|
|
2
|
+
|
|
3
|
+
export type SDaiData = { exchange: Address };
|
|
4
|
+
|
|
5
|
+
export type SDaiParams = {
|
|
6
|
+
sdaiAddress: Address;
|
|
7
|
+
daiAddress: Address;
|
|
8
|
+
potAddress: Address;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export enum SDaiFunctions {
|
|
12
|
+
deposit = 'deposit',
|
|
13
|
+
redeem = 'redeem',
|
|
14
|
+
withdraw = 'withdraw',
|
|
15
|
+
mint = 'mint',
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type SDaiPoolState = {
|
|
19
|
+
rho: string;
|
|
20
|
+
chi: string;
|
|
21
|
+
dsr: string;
|
|
22
|
+
live: boolean;
|
|
23
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Contract } from 'web3-eth-contract';
|
|
2
|
+
import { SDaiPoolState } from './types';
|
|
3
|
+
import { Interface, AbiCoder } from '@ethersproject/abi';
|
|
4
|
+
import { currentBigIntTimestampInS } from '../../utils';
|
|
5
|
+
|
|
6
|
+
const coder = new AbiCoder();
|
|
7
|
+
|
|
8
|
+
// - `dsr`: the Dai Savings Rate
|
|
9
|
+
// - `chi`: the Rate Accumulator
|
|
10
|
+
// - `rho`: time of last drip
|
|
11
|
+
export async function getOnChainState(
|
|
12
|
+
multiContract: Contract,
|
|
13
|
+
potAddress: string,
|
|
14
|
+
potInterface: Interface,
|
|
15
|
+
blockNumber: number | 'latest',
|
|
16
|
+
): Promise<SDaiPoolState> {
|
|
17
|
+
const data: { returnData: any[] } = await multiContract.methods
|
|
18
|
+
.aggregate([
|
|
19
|
+
{
|
|
20
|
+
target: potAddress,
|
|
21
|
+
callData: potInterface.encodeFunctionData('dsr', []),
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
target: potAddress,
|
|
25
|
+
callData: potInterface.encodeFunctionData('chi', []),
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
target: potAddress,
|
|
29
|
+
callData: potInterface.encodeFunctionData('rho', []),
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
target: potAddress,
|
|
33
|
+
callData: potInterface.encodeFunctionData('live', []),
|
|
34
|
+
},
|
|
35
|
+
])
|
|
36
|
+
.call({}, blockNumber);
|
|
37
|
+
|
|
38
|
+
const [dsr, chi, rho, live] = data.returnData.map(item =>
|
|
39
|
+
coder.decode(['uint256'], item)[0].toString(),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
live: !!live,
|
|
44
|
+
dsr,
|
|
45
|
+
chi,
|
|
46
|
+
rho,
|
|
47
|
+
};
|
|
48
|
+
}
|
package/tests/constants-e2e.ts
CHANGED
|
@@ -1096,7 +1096,7 @@ export const Holders: {
|
|
|
1096
1096
|
USDT: '0x8A446971dbB112f3be15bc38C14D44B94D9E94b9',
|
|
1097
1097
|
XAUT: '0xc4e161e8d8a4bc4ac762ab33a28bbac5474203d7',
|
|
1098
1098
|
R: '0xBfe4c9D3235475C138a61f62e9e72FaD94A3303b',
|
|
1099
|
-
sDAI: '
|
|
1099
|
+
sDAI: '0x4C612E3B15b96Ff9A6faED838F8d07d479a8dD4c',
|
|
1100
1100
|
CVX: '0x0aCA67Fa70B142A3b9bF2eD89A81B40ff85dACdC',
|
|
1101
1101
|
MIM: '0xa046a8660e66d178ee07ec97c585eeb6aa18c26c',
|
|
1102
1102
|
AnkETH: '0xF7260D4ADc48fEefd5a19a9Eb23f9747CeE15C92',
|
|
@@ -1271,7 +1271,7 @@ export const Holders: {
|
|
|
1271
1271
|
nETH: '0xcf2ef00e75558512ae735679ea5df62ad2056786',
|
|
1272
1272
|
avWETH: '0x92d78e32b990d10aeca0875dc5585f1a6f958179',
|
|
1273
1273
|
YUSD: '0x6c1a5ef2acde1fd2fc68def440d2c1eb35bae24a',
|
|
1274
|
-
BTCb: '
|
|
1274
|
+
BTCb: '0x4bb7f4c3d47C4b431cb0658F44287d52006fb506',
|
|
1275
1275
|
AMPL: '0xfcaA5ea7F8eb0631BcA72C345025C0A5a6D93f0E',
|
|
1276
1276
|
PHAR: '0x654296D56532f62B7d91d335791d3c364a9385b5',
|
|
1277
1277
|
},
|
package/.vscode/launch.json
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "0.2.0",
|
|
3
|
-
"configurations": [
|
|
4
|
-
{
|
|
5
|
-
"type": "node",
|
|
6
|
-
"request": "launch",
|
|
7
|
-
"name": "Current",
|
|
8
|
-
"program": "${file}",
|
|
9
|
-
"preLaunchTask": "npm: build",
|
|
10
|
-
"sourceMaps": true,
|
|
11
|
-
"smartStep": true,
|
|
12
|
-
"internalConsoleOptions": "openOnSessionStart",
|
|
13
|
-
"outFiles": ["${workspaceFolder}/build/**/*.js"]
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"type": "node",
|
|
17
|
-
"request": "launch",
|
|
18
|
-
"name": "Debug dex integration",
|
|
19
|
-
"program": "${workspaceFolder}/node_modules/ts-node/dist/bin.js",
|
|
20
|
-
"args": [
|
|
21
|
-
"--project",
|
|
22
|
-
"tsconfig.json",
|
|
23
|
-
// "${workspaceFolder}/src/dex/algebra/scripts/validate-state.ts",
|
|
24
|
-
"${workspaceFolder}/src/dex/camelot/camelot-pool-discovery.test.ts",
|
|
25
|
-
// "${workspaceFolder}/src/dex/solidly-v3/scripts/check-event-pool-event.ts",
|
|
26
|
-
// "${workspaceFolder}/scripts/dex-integration.ts",
|
|
27
|
-
"test",
|
|
28
|
-
"wombat"
|
|
29
|
-
],
|
|
30
|
-
"console": "integratedTerminal",
|
|
31
|
-
"internalConsoleOptions": "neverOpen",
|
|
32
|
-
"runtimeArgs": ["--nolazy"],
|
|
33
|
-
"sourceMaps": true,
|
|
34
|
-
"smartStep": true,
|
|
35
|
-
"skipFiles": ["<node_internals>/**"],
|
|
36
|
-
"cwd": "${workspaceFolder}"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"type": "node",
|
|
40
|
-
"name": "Jest file",
|
|
41
|
-
"request": "launch",
|
|
42
|
-
"program": "${workspaceFolder}/node_modules/jest/bin/jest.js",
|
|
43
|
-
// "program": "${workspaceFolder}/src/dex/camelot/scripts/validate-state.ts",
|
|
44
|
-
// "args": ["src/dex/balancer-v1/balancer-v1-e2e.test.ts"],
|
|
45
|
-
// "args": ["${relativeFile}"],
|
|
46
|
-
"args": ["${file}"],
|
|
47
|
-
"cwd": "${workspaceRoot}",
|
|
48
|
-
"console": "integratedTerminal",
|
|
49
|
-
"internalConsoleOptions": "neverOpen",
|
|
50
|
-
"sourceMaps": true
|
|
51
|
-
}
|
|
52
|
-
]
|
|
53
|
-
}
|
package/.vscode/settings.json
DELETED
package/.vscode/tasks.json
DELETED