Skip to content

Commit 3c99dc8

Browse files
committed
feat: load reserve data from on chain
1 parent 7f6f023 commit 3c99dc8

File tree

6 files changed

+179
-15
lines changed

6 files changed

+179
-15
lines changed

apps/indexer/eslint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export default [
2020
],
2121
},
2222
],
23+
'@typescript-eslint/no-unused-vars': 'warn',
2324
},
2425
languageOptions: {
2526
parser: await import('jsonc-eslint-parser'),

apps/indexer/src/app/routes/_chain/routes.ts

Lines changed: 162 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,73 @@
1-
import { and, asc, eq, gte } from 'drizzle-orm';
1+
import { Decimal } from '@sovryn/slayer-shared';
2+
import { and, asc, eq, gte, inArray } from 'drizzle-orm';
23
import { FastifyInstance, FastifyRequest } from 'fastify';
34
import { ZodTypeProvider } from 'fastify-type-provider-zod';
45
import { client } from '../../../database/client';
56
import { tTokens } from '../../../database/schema';
6-
import { tTokensSelectors } from '../../../database/selectors';
7+
import { TTokenSelected, tTokensSelectors } from '../../../database/selectors';
78
import {
89
fetchPoolList,
910
fetchPoolReserves,
1011
} from '../../../libs/loaders/money-market';
1112
import { paginationResponse, paginationSchema } from '../../../libs/pagination';
13+
import { areAddressesEqual } from '../../../libs/utils/helpers';
14+
15+
interface ReserveDataHumanized {
16+
originalId: number;
17+
id: string;
18+
underlyingAsset: string;
19+
20+
token: TTokenSelected;
21+
22+
name: string;
23+
symbol: string;
24+
decimals: number;
25+
baseLTVasCollateral: string;
26+
reserveLiquidationThreshold: string;
27+
reserveLiquidationBonus: string;
28+
reserveFactor: string;
29+
usageAsCollateralEnabled: boolean;
30+
borrowingEnabled: boolean;
31+
isActive: boolean;
32+
isFrozen: boolean;
33+
liquidityIndex: string;
34+
variableBorrowIndex: string;
35+
liquidityRate: string;
36+
variableBorrowRate: string;
37+
lastUpdateTimestamp: number;
38+
aTokenAddress: string;
39+
variableDebtTokenAddress: string;
40+
interestRateStrategyAddress: string;
41+
availableLiquidity: string;
42+
totalScaledVariableDebt: string;
43+
priceInMarketReferenceCurrency: string;
44+
priceOracle: string;
45+
variableRateSlope1: string;
46+
variableRateSlope2: string;
47+
baseVariableBorrowRate: string;
48+
optimalUsageRatio: string;
49+
// v3 only
50+
isPaused: boolean;
51+
isSiloedBorrowing: boolean;
52+
accruedToTreasury: string;
53+
unbacked: string;
54+
isolationModeTotalDebt: string;
55+
flashLoanEnabled: boolean;
56+
debtCeiling: string;
57+
debtCeilingDecimals: number;
58+
borrowCap: string;
59+
supplyCap: string;
60+
borrowableInIsolation: boolean;
61+
virtualAccActive: boolean;
62+
virtualUnderlyingBalance: string;
63+
}
64+
65+
interface PoolBaseCurrencyHumanized {
66+
marketReferenceCurrencyDecimals: number;
67+
marketReferenceCurrencyPriceInUsd: string;
68+
networkBaseTokenPriceInUsd: string;
69+
networkBaseTokenPriceDecimals: number;
70+
}
1271

1372
export default async function (fastify: FastifyInstance) {
1473
fastify.get('/', async (req) => {
@@ -73,6 +132,9 @@ export default async function (fastify: FastifyInstance) {
73132
schema: {
74133
querystring: paginationSchema,
75134
},
135+
// config: {
136+
// cache: true,
137+
// },
76138
},
77139
async (req: FastifyRequest<{ Params: { pool: string } }>, reply) => {
78140
const pools = await fetchPoolList(req.chain.chainId);
@@ -84,20 +146,106 @@ export default async function (fastify: FastifyInstance) {
84146
return reply.notFound('Pool not found');
85147
}
86148

87-
const reserves = await fetchPoolReserves(req.chain.chainId, pool);
149+
const { 0: reservesRaw, 1: poolBaseCurrencyRaw } =
150+
await fetchPoolReserves(req.chain.chainId, pool);
151+
152+
const tokens = await client.query.tTokens.findMany({
153+
columns: tTokensSelectors.columns,
154+
where: and(
155+
eq(tTokens.chainId, req.chain.chainId),
156+
inArray(
157+
tTokens.address,
158+
reservesRaw.map((i) => i.underlyingAsset.toLowerCase()),
159+
),
160+
),
161+
});
162+
163+
const reservesData: Partial<ReserveDataHumanized>[] = reservesRaw.map(
164+
(reserveRaw, index) => {
165+
// const virtualUnderlyingBalance =
166+
// reserveRaw.virtualUnderlyingBalance.toString();
167+
// const { virtualAccActive } = reserveRaw;
168+
return {
169+
originalId: index,
170+
id: `!!${req.chain.chainId}-${reserveRaw.underlyingAsset}-${pool.address}`.toLowerCase(),
171+
underlyingAsset: reserveRaw.underlyingAsset.toLowerCase(),
172+
173+
token: tokens.find((t) =>
174+
areAddressesEqual(t.address, reserveRaw.underlyingAsset),
175+
),
176+
177+
name: reserveRaw.name,
178+
// symbol: ammSymbolMap[reserveRaw.underlyingAsset.toLowerCase()]
179+
// ? ammSymbolMap[reserveRaw.underlyingAsset.toLowerCase()]
180+
// : reserveRaw.symbol,
181+
decimals: reserveRaw.decimals.toNumber(),
182+
baseLTVasCollateral: reserveRaw.baseLTVasCollateral.toString(),
183+
reserveLiquidationThreshold:
184+
reserveRaw.reserveLiquidationThreshold.toString(),
185+
reserveLiquidationBonus:
186+
reserveRaw.reserveLiquidationBonus.toString(),
187+
reserveFactor: reserveRaw.reserveFactor.toString(),
188+
usageAsCollateralEnabled: reserveRaw.usageAsCollateralEnabled,
189+
borrowingEnabled: reserveRaw.borrowingEnabled,
190+
isActive: reserveRaw.isActive,
191+
isFrozen: reserveRaw.isFrozen,
192+
liquidityIndex: reserveRaw.liquidityIndex.toString(),
193+
variableBorrowIndex: reserveRaw.variableBorrowIndex.toString(),
194+
liquidityRate: reserveRaw.liquidityRate.toString(),
195+
variableBorrowRate: reserveRaw.variableBorrowRate.toString(),
196+
lastUpdateTimestamp: reserveRaw.lastUpdateTimestamp,
197+
aTokenAddress: reserveRaw.aTokenAddress.toString(),
198+
variableDebtTokenAddress:
199+
reserveRaw.variableDebtTokenAddress.toString(),
200+
interestRateStrategyAddress:
201+
reserveRaw.interestRateStrategyAddress.toString(),
202+
availableLiquidity: Decimal.from(
203+
reserveRaw.availableLiquidity,
204+
reserveRaw.decimals.toNumber(),
205+
).toString(),
206+
// availableLiquidity: reserveRaw.availableLiquidity.toString(),
207+
totalScaledVariableDebt:
208+
reserveRaw.totalScaledVariableDebt.toString(),
209+
priceInMarketReferenceCurrency:
210+
reserveRaw.priceInMarketReferenceCurrency.toString(),
211+
// priceOracle: reserveRaw.priceOracle,
212+
variableRateSlope1: reserveRaw.variableRateSlope1.toString(),
213+
variableRateSlope2: reserveRaw.variableRateSlope2.toString(),
214+
// baseVariableBorrowRate:
215+
// reserveRaw.baseVariableBorrowRate.toString(),
216+
// optimalUsageRatio: reserveRaw.optimalUsageRatio.toString(),
217+
// new fields
218+
// isPaused: reserveRaw.isPaused,
219+
// debtCeiling: reserveRaw.debtCeiling.toString(),
220+
// borrowCap: reserveRaw.borrowCap.toString(),
221+
// supplyCap: reserveRaw.supplyCap.toString(),
222+
// borrowableInIsolation: reserveRaw.borrowableInIsolation,
223+
// accruedToTreasury: reserveRaw.accruedToTreasury.toString(),
224+
// unbacked: reserveRaw.unbacked.toString(),
225+
// isolationModeTotalDebt:
226+
// reserveRaw.isolationModeTotalDebt.toString(),
227+
// debtCeilingDecimals: reserveRaw.debtCeilingDecimals.toNumber(),
228+
// isSiloedBorrowing: reserveRaw.isSiloedBorrowing,
229+
// flashLoanEnabled: reserveRaw.flashLoanEnabled,
230+
// virtualAccActive,
231+
// virtualUnderlyingBalance,
232+
};
233+
},
234+
);
88235

89-
return { data: reserves };
236+
const baseCurrencyData: PoolBaseCurrencyHumanized = {
237+
// this is to get the decimals from the unit so 1e18 = string length of 19 - 1 to get the number of 0
238+
marketReferenceCurrencyDecimals:
239+
poolBaseCurrencyRaw.marketReferenceCurrencyUnit.toString().length - 1,
240+
marketReferenceCurrencyPriceInUsd:
241+
poolBaseCurrencyRaw.marketReferenceCurrencyPriceInUsd.toString(),
242+
networkBaseTokenPriceInUsd:
243+
poolBaseCurrencyRaw.networkBaseTokenPriceInUsd.toString(),
244+
networkBaseTokenPriceDecimals:
245+
poolBaseCurrencyRaw.networkBaseTokenPriceDecimals,
246+
};
90247

91-
// const tokens = await client.query.tTokens.findMany({
92-
// columns: tTokensSelectors.columns,
93-
// where: and(
94-
// eq(tTokens.chainId, req.chain.chainId),
95-
// inArray(
96-
// tTokens.address,
97-
// items.map((i) => i.underlyingAsset),
98-
// ),
99-
// ),
100-
// });
248+
return { data: { reservesData, baseCurrencyData } };
101249

102250
// return {
103251
// data: items

apps/indexer/src/database/selectors.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { tTokens } from './schema';
1+
import { TToken, tTokens } from './schema';
22

33
export const tTokensSelectors = {
44
columns: {
@@ -16,3 +16,8 @@ export const tTokensSelectors = {
1616
logoUrl: tTokens.logoUrl,
1717
},
1818
} as const;
19+
20+
export type TTokenSelected = Pick<
21+
TToken,
22+
keyof typeof tTokensSelectors.columns
23+
>;

apps/indexer/src/libs/shims.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
declare global {
22
interface BigInt {
33
toJSON(): string;
4+
toNumber(): number;
45
}
56
}
67

78
BigInt.prototype.toJSON = function () {
89
return this.toString();
910
};
11+
12+
BigInt.prototype.toNumber = function () {
13+
return Number(this);
14+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export const areAddressesEqual = (
2+
address1: string,
3+
address2: string,
4+
): boolean => address1.toLowerCase() === address2.toLowerCase();

eslint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export default [
3030
],
3131
'@typescript-eslint/no-non-null-assertion': 'off',
3232
'@typescript-eslint/no-explicit-any': 'warn',
33+
'@typescript-eslint/no-unused-vars': 'warn',
3334
'no-constant-binary-expression': 'off',
3435
'no-restricted-syntax': [
3536
'error',

0 commit comments

Comments
 (0)