Skip to content

Commit a207487

Browse files
committed
more improvements to pricing, with decimals more strictly defined
1 parent c23a021 commit a207487

File tree

2 files changed

+52
-17
lines changed

2 files changed

+52
-17
lines changed

src/main-test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ if (require.main === module) {
2020
process: async (ctx) => {
2121
// Validate that we're getting otoken rates the way we want to.
2222

23-
for (const pair of Object.keys(priceMap)) {
23+
for (const [pair, [getPrice, decimals]] of Object.entries(priceMap)) {
2424
const rate = await ensureExchangeRate(
2525
ctx,
2626
ctx.blocks[0],
2727
pair.split('_')[0] as CurrencySymbol,
2828
pair.split('_')[1] as CurrencySymbol,
2929
)
30-
console.log(`${pair} = ${Number(rate?.rate) / 1e18}`)
30+
console.log(`${pair} = ${Number(rate?.rate) / 10 ** decimals}`)
3131
}
3232

3333
process.exit(0)

src/shared/post-processors/exchange-rates/price-routing-mainnet.ts

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ export const getMainnetPrice = async (ctx: Context, height: number, base: Mainne
2525
base = translateMainnetSymbol(base)
2626
quote = translateMainnetSymbol(quote)
2727

28-
const getPrice = priceMap[`${base}_${quote}`]
29-
if (getPrice) {
28+
const priceEntry = priceMap[`${base}_${quote}`]
29+
if (priceEntry) {
30+
const [getPrice] = priceEntry
3031
return getPrice(ctx, height)
3132
}
3233
throw new Error(`No price for ${base}_${quote}`)
@@ -148,25 +149,46 @@ export const translateMainnetSymbol = (symbol: MainnetCurrency): MainnetCurrency
148149
return symbol
149150
}
150151

152+
export const derived = <Base extends MainnetCurrencySymbol, Quote extends MainnetCurrencySymbol>(
153+
base: Base,
154+
quote: Quote,
155+
connections: { base: MainnetCurrencySymbol; quote: MainnetCurrencySymbol }[],
156+
decimals: number = 18,
157+
) => {
158+
return twoWay(
159+
base,
160+
quote,
161+
async (ctx: Context, height: number) => {
162+
const baseExponent = 10n ** BigInt(decimals)
163+
const rates = await Promise.all(connections.map(({ base, quote }) => getMainnetPrice(ctx, height, base, quote)))
164+
return rates.reduce((acc, rate) => (acc * rate) / baseExponent, baseExponent)
165+
},
166+
decimals,
167+
)
168+
}
151169
export const invertRate = (rate: bigint, decimals = 18) => (rate > 0n ? 10n ** BigInt(2 * decimals) / rate : 0n)
152-
export const twoWay = <Base extends CurrencySymbol, Quote extends CurrencySymbol>(
170+
export const twoWay = <Base extends MainnetCurrencySymbol, Quote extends MainnetCurrencySymbol>(
153171
base: Base,
154172
quote: Quote,
155173
getPrice: (ctx: Context, height: number) => Promise<bigint>,
174+
decimals: number = 18,
156175
) =>
157176
({
158-
[`${base}_${quote}`]: async (ctx: Context, height: number) => getPrice(ctx, height),
159-
[`${quote}_${base}`]: async (ctx: Context, height: number) => getPrice(ctx, height).then(invertRate),
160-
}) as Record<`${Base}_${Quote}` | `${Quote}_${Base}`, (ctx: Context, height: number) => Promise<bigint>>
177+
[`${base}_${quote}`]: [async (ctx: Context, height: number) => getPrice(ctx, height), decimals],
178+
[`${quote}_${base}`]: [
179+
async (ctx: Context, height: number) => getPrice(ctx, height).then((rate) => invertRate(rate, decimals)),
180+
decimals,
181+
],
182+
}) as Record<`${Base}_${Quote}` | `${Quote}_${Base}`, [(ctx: Context, height: number) => Promise<bigint>, number]>
161183

162184
export const priceMap: Partial<
163-
Record<`${CurrencySymbol}_${CurrencySymbol}`, (ctx: Context, height: number) => Promise<bigint>>
185+
Record<`${CurrencySymbol}_${CurrencySymbol}`, [(ctx: Context, height: number) => Promise<bigint>, number]>
164186
> = {
165-
ETH_WETH: async () => 1_000_000_000_000_000_000n,
166-
WETH_ETH: async () => 1_000_000_000_000_000_000n,
167-
ETH_ETH: async () => 1_000_000_000_000_000_000n,
168-
ETH_OETH: getETHOETHPrice,
169-
OETH_ETH: getOETHETHPrice,
187+
ETH_WETH: [async () => 1_000_000_000_000_000_000n, 18],
188+
WETH_ETH: [async () => 1_000_000_000_000_000_000n, 18],
189+
ETH_ETH: [async () => 1_000_000_000_000_000_000n, 18],
190+
ETH_OETH: [getETHOETHPrice, 18],
191+
OETH_ETH: [getOETHETHPrice, 18],
170192
...twoWay('ETH', 'sfrxETH', getStakedFraxPrice),
171193
...twoWay('ETH', 'rETH', getRETHPrice),
172194
...twoWay('ETH', 'frxETH', getFrxEthPrice),
@@ -175,6 +197,19 @@ export const priceMap: Partial<
175197
...twoWay('OUSD', 'ETH', getPrice_OUSD_ETH),
176198
...twoWay('ETH', 'stETH', (ctx, height) => getOethOraclePrice(ctx, height, 'stETH')),
177199
...twoWay('OETH', 'USD', getPrice_OETH_USD),
178-
ETH_USD: (ctx, height) => getChainlinkPrice(ctx, height, 'ETH', 'USD'),
179-
// ...twoWay('ETH', 'USD', (ctx, height) => getChainlinkPrice(ctx, height, 'ETH', 'USD').then((p) => p * 10n ** 10n)),
180-
} as const
200+
...twoWay('ETH', 'USD', (ctx, height) => getChainlinkPrice(ctx, height, 'ETH', 'USD'), 8),
201+
...twoWay('DAI', 'USD', (ctx, height) => getChainlinkPrice(ctx, height, 'DAI', 'USD'), 8),
202+
...twoWay('USDC', 'USD', (ctx, height) => getChainlinkPrice(ctx, height, 'USDC', 'USD'), 8),
203+
...twoWay('USDT', 'USD', (ctx, height) => getChainlinkPrice(ctx, height, 'USDT', 'USD'), 8),
204+
...derived(
205+
'DAI',
206+
'ETH',
207+
[
208+
{ base: 'DAI', quote: 'USD' },
209+
{ base: 'USD', quote: 'ETH' },
210+
],
211+
8,
212+
),
213+
...twoWay('USDC', 'ETH', (ctx, height) => getChainlinkPrice(ctx, height, 'USDC', 'ETH')),
214+
...twoWay('USDT', 'ETH', (ctx, height) => getChainlinkPrice(ctx, height, 'USDT', 'ETH')),
215+
}

0 commit comments

Comments
 (0)