Skip to content

Commit

Permalink
Feat/switch to implied rates (#735)
Browse files Browse the repository at this point in the history
* fix: adding spot rates to oracle registry

* fix: change fcash rate source

* fix: testing lend fixed borrow fixed

* fix: convert fcash

* fix: order details bugs
  • Loading branch information
jeffywu authored Apr 4, 2024
1 parent 6441c2a commit 445af8c
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 78 deletions.
4 changes: 2 additions & 2 deletions apps/localAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ const vaultsProxy = createProxyMiddleware(['/*/vaults'], {
changeOrigin: true,
});
const oraclesProxy = createProxyMiddleware(['/*/oracles'], {
target: 'https://registry-oracles-dev.notional-finance.workers.dev',
target: 'http://localhost:8890',
changeOrigin: true,
});
const exchangesProxy = createProxyMiddleware(['/*/exchanges'], {
target: 'https://registry-exchanges-dev.notional-finance.workers.dev',
changeOrigin: true,
});
const dataProxy = createProxyMiddleware(['/*/views/*'], {
target: 'http://localhost:8890',
target: 'https://data-dev.notional-finance.workers.dev',
changeOrigin: true,
});

Expand Down
2 changes: 1 addition & 1 deletion apps/serveLocalRegistry.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
yarn nx serve data --env dev --port 8890 &
yarn nx serve registry-oracles --port 8890 &
yarn node apps/localAPI.js
11 changes: 7 additions & 4 deletions packages/core-entities/src/.graphclient/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9048,7 +9048,9 @@ export type AllConfigurationByBlockQuery = { currencyConfigurations: Array<(
& { primaryBorrowCurrency: Pick<Token, 'id'>, secondaryBorrowCurrencies?: Maybe<Array<Pick<Token, 'id'>>> }
)>, _meta?: Maybe<{ block: Pick<_Block_, 'number'> }> };

export type AllOraclesQueryVariables = Exact<{ [key: string]: never; }>;
export type AllOraclesQueryVariables = Exact<{
skip: Scalars['Int'];
}>;


export type AllOraclesQuery = { oracles: Array<(
Expand Down Expand Up @@ -9597,10 +9599,11 @@ export const AllConfigurationByBlockDocument = gql`
}
` as unknown as DocumentNode<AllConfigurationByBlockQuery, AllConfigurationByBlockQueryVariables>;
export const AllOraclesDocument = gql`
query AllOracles {
query AllOracles($skip: Int!) {
oracles(
where: {oracleType_in: [Chainlink, fCashOracleRate, fCashSettlementRate, PrimeCashToUnderlyingExchangeRate, PrimeDebtToUnderlyingExchangeRate, VaultShareOracleRate, nTokenToUnderlyingExchangeRate], matured: false}
where: {oracleType_in: [Chainlink, fCashOracleRate, fCashSettlementRate, PrimeCashToUnderlyingExchangeRate, PrimeDebtToUnderlyingExchangeRate, VaultShareOracleRate, nTokenToUnderlyingExchangeRate, fCashSpotRate], matured: false}
first: 1000
skip: $skip
) {
id
lastUpdateBlockNumber
Expand Down Expand Up @@ -9965,7 +9968,7 @@ export function getSdk<C, E>(requester: Requester<C, E>) {
AllConfigurationByBlock(variables?: AllConfigurationByBlockQueryVariables, options?: C): Promise<AllConfigurationByBlockQuery> {
return requester<AllConfigurationByBlockQuery, AllConfigurationByBlockQueryVariables>(AllConfigurationByBlockDocument, variables, options) as Promise<AllConfigurationByBlockQuery>;
},
AllOracles(variables?: AllOraclesQueryVariables, options?: C): Promise<AllOraclesQuery> {
AllOracles(variables: AllOraclesQueryVariables, options?: C): Promise<AllOraclesQuery> {
return requester<AllOraclesQuery, AllOraclesQueryVariables>(AllOraclesDocument, variables, options) as Promise<AllOraclesQuery>;
},
AllOraclesByBlock(variables?: AllOraclesByBlockQueryVariables, options?: C): Promise<AllOraclesByBlockQuery> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { TokenBalance } from '../token-balance';
import { FiatKeys } from '../config/fiat-config';
import { fetchGraph, loadGraphClientDeferred } from '../server/server-registry';
import { parseTransaction } from './accounts/transaction-history';
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import { Transaction } from '../.graphclient';

const APY_ORACLES = [
Expand Down
18 changes: 12 additions & 6 deletions packages/core-entities/src/client/oracle-registry-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ interface Node {
type AdjList = Map<string, Map<string, Node>>;
const UNIT_RATE = 'UNIT_RATE';

// Can change this to fCashOracleRate to use oracle rates
const FCASH_RATE_SOURCE = 'fCashSpotRate';

export const PRICE_ORACLES = [
'sNOTE',
'Chainlink',
'fCashOracleRate',
FCASH_RATE_SOURCE,
'fCashSettlementRate',
'PrimeCashToUnderlyingExchangeRate',
'PrimeDebtToUnderlyingExchangeRate',
Expand Down Expand Up @@ -93,8 +96,11 @@ export class OracleRegistryClient extends ClientRegistry<OracleDefinition> {
// Only add whitelisted oracles to the adj list
if (!PRICE_ORACLES.includes(oracle.oracleType)) return;

if (oracle.oracleType === 'fCashOracleRate') {
// Suppress historical oracle rates
if (
oracle.oracleType === 'fCashOracleRate' ||
oracle.oracleAddress === 'fCashSpotRate'
) {
// Suppress historical fcash rates
const { maturity } = decodeERC1155Id(oracle.quote);
if (maturity < getNowSeconds()) return;
}
Expand Down Expand Up @@ -203,10 +209,10 @@ export class OracleRegistryClient extends ClientRegistry<OracleDefinition> {
network,
currencyId
);
// fCashOracleRate is from underlying => fCash id, settlement rates are from
// FCASH_RATE_SOURCE is from underlying => fCash id, settlement rates are from
// fCash id => prime cash
o = subjects
.get(`${underlying.id}:${base}:fCashOracleRate`)
.get(`${underlying.id}:${base}:${FCASH_RATE_SOURCE}`)
?.asObservable();
}
}
Expand All @@ -224,7 +230,7 @@ export class OracleRegistryClient extends ClientRegistry<OracleDefinition> {
if (!o) return null;

// fCash rates are interest rates so convert them to exchange rates in SCALAR_PRECISION here
if (o.oracleType === 'fCashOracleRate') {
if (o.oracleType === FCASH_RATE_SOURCE) {
// Adjustment is set to identity values if riskAdjusted is set to None.
const { interestAdjustment, maxDiscountFactor, oracleRateLimit } =
config.getInterestRiskAdjustment(o, node.inverted, riskAdjusted);
Expand Down
6 changes: 3 additions & 3 deletions packages/core-entities/src/queries/AllOracles.graphql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
query AllOracles {
query AllOracles($skip: Int!) {
oracles(where: { oracleType_in: [
Chainlink,
fCashOracleRate,
Expand All @@ -7,15 +7,15 @@ query AllOracles {
PrimeDebtToUnderlyingExchangeRate,
VaultShareOracleRate,
nTokenToUnderlyingExchangeRate
fCashSpotRate,
# NOT used in exchange rate path finding algorithm and excluded
# from the active query to reduce the amount of data stored in the
# oracle durable object storage.
# PrimeCashPremiumInterestRate,
# PrimeDebtPremiumInterestRate,
# fCashSpotRate,
# PrimeCashToUnderlyingOracleInterestRate,
# fCashToUnderlyingExchangeRate
], matured: false}, first: 1000) {
], matured: false}, first: 1000, skip: $skip) {
id
lastUpdateBlockNumber
lastUpdateTimestamp
Expand Down
4 changes: 3 additions & 1 deletion packages/core-entities/src/server/oracle-registry-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ export class OracleRegistryServer extends ServerRegistry<OracleDefinition> {
},
{
blockNumber,
}
skip: 0,
},
'oracles'
);
}

Expand Down
11 changes: 9 additions & 2 deletions packages/core-entities/src/server/server-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,16 @@ export abstract class ServerRegistry<T> extends BaseRegistry<T> {
network: Network,
query: TypedDocumentNode<R, V>,
transform: (r: R) => Record<string, T>,
variables?: V
variables?: V,
rootVariable?: string
): Promise<CacheSchema<T>> {
return fetchUsingGraph<T, R, V>(network, query, transform, variables);
return fetchUsingGraph<T, R, V>(
network,
query,
transform,
variables,
rootVariable
);
}

protected getProvider(network: Network) {
Expand Down
81 changes: 38 additions & 43 deletions packages/shared/notionable-hooks/src/use-summary.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {
TokenBalance,
TokenDefinition,
YieldData,
fCashMarket,
FiatKeys,
} from '@notional-finance/core-entities';
import {
Expand All @@ -12,12 +10,12 @@ import {
} from '@notional-finance/helpers';
import {
BaseTradeState,
TokenOption,
TradeState,
VaultTradeState,
} from '@notional-finance/notionable';
import {
RATE_DECIMALS,
RATE_PRECISION,
HEALTH_FACTOR_RISK_LEVELS,
} from '@notional-finance/util';
import {
Expand All @@ -26,7 +24,6 @@ import {
defineMessages,
useIntl,
} from 'react-intl';
import { useAllMarkets } from './use-market';
import { useFiat } from './use-user-settings';
import { colors } from '@notional-finance/styles';
import { useTheme } from '@mui/material';
Expand Down Expand Up @@ -72,9 +69,10 @@ const OrderDetailLabels = defineMessages({
function getOrderDetails(
b: TokenBalance,
realized: TokenBalance,
feeValue: TokenBalance,
intl: IntlShape,
isLeverageOrRoll: boolean,
yieldData: YieldData[]
options: TokenOption[] | undefined
): DetailItem[] {
const { title, caption } = formatTokenType(b.token);
const apyLabel =
Expand All @@ -89,14 +87,7 @@ function getOrderDetails(
b.tokenType === 'fCash' || b.tokenType === 'VaultShare'
? OrderDetailLabels.captionPrice
: OrderDetailLabels.price;
let apy: number;
if (b.tokenType === 'fCash') {
apy =
((fCashMarket.getImpliedInterestRate(realized, b) || 0) * 100) /
RATE_PRECISION;
} else {
apy = yieldData.find((y) => y.token.id === b.tokenId)?.totalAPY || 0;
}
const apy = options?.find((o) => o.token.id === b.tokenId)?.interestRate;

let valueLabel: MessageDescriptor;
switch (b.tokenType) {
Expand Down Expand Up @@ -125,7 +116,7 @@ function getOrderDetails(
throw Error('Unknown token type');
}

return [
const orderDetails = [
{
label: intl.formatMessage(valueLabel, { title, caption }),
value: {
Expand All @@ -143,32 +134,16 @@ function getOrderDetails(
},
{
label: intl.formatMessage(feeLabel, { title, caption }),
// Fee: diff between PV and realized cash
value: {
data: [
{
displayValue: realized
.abs()
displayValue: feeValue
.toUnderlying()
.sub(b.abs().toUnderlying())
.toDisplayStringWithSymbol(4, true),
},
],
},
},
{
// APY: for fCash look at implied rate, otherwise look at yield
label: intl.formatMessage(apyLabel, { title, caption }),
value: {
data: [
{
displayValue: `${formatNumberAsPercent(apy, 2)}`,
isNegative: apy < 0,
},
],
},
showOnExpand: true,
},
{
// Price: realized cash / total units
label: intl.formatMessage(priceLabel, { title, caption }),
Expand All @@ -187,20 +162,39 @@ function getOrderDetails(
showOnExpand: true,
},
];

if (apy !== undefined) {
orderDetails.push({
label: intl.formatMessage(apyLabel, { title, caption }),
value: {
data: [
{
displayValue: `${formatNumberAsPercent(apy, 2)}`,
isNegative: apy < 0,
},
],
},
showOnExpand: true,
});
}

return orderDetails;
}

export function useOrderDetails(state: BaseTradeState): OrderDetails {
const {
debtBalance,
debtFee,
collateralFee,
debtOptions,
collateralOptions,
collateralBalance,
netRealizedDebtBalance,
netRealizedCollateralBalance,
depositBalance,
tradeType,
selectedNetwork,
} = state;
const intl = useIntl();
const { nonLeveragedYields } = useAllMarkets(selectedNetwork);
const orderDetails: DetailItem[] = [];
// Only show positive values if one of the values is defined
const isLeverageOrRoll = !!debtBalance && !!collateralBalance;
Expand Down Expand Up @@ -232,9 +226,10 @@ export function useOrderDetails(state: BaseTradeState): OrderDetails {
...getOrderDetails(
balance.unwrapVaultToken(),
netRealizedDebtBalance,
debtFee?.toUnderlying() || netRealizedDebtBalance.copy(0),
intl,
isLeverageOrRoll,
nonLeveragedYields
debtOptions
)
);
}
Expand All @@ -245,9 +240,10 @@ export function useOrderDetails(state: BaseTradeState): OrderDetails {
...getOrderDetails(
collateralBalance.unwrapVaultToken(),
netRealizedCollateralBalance,
collateralFee?.toUnderlying() || netRealizedCollateralBalance.copy(0),
intl,
isLeverageOrRoll,
nonLeveragedYields
collateralOptions
)
);
}
Expand Down Expand Up @@ -408,6 +404,8 @@ export function useTradeSummary(state: VaultTradeState | TradeState) {
netDebtBalance,
debtBalance,
collateralBalance,
collateralFee,
debtFee,
tradeType,
inputsSatisfied,
calculationSuccess,
Expand Down Expand Up @@ -594,10 +592,9 @@ export function useTradeSummary(state: VaultTradeState | TradeState) {
} else if (isLeverageOrRoll) {
// Do not include roll vault position because the margin will be
// incorrectly included in the fee value
feeValue = collateralBalance
.toUnderlying()
.sub(depositBalance || TokenBalance.zero(underlying))
.add(debtBalance.toUnderlying());
feeValue = (collateralFee?.toUnderlying() || feeValue).add(
debtFee?.toUnderlying() || feeValue
);
} else if (
collateralBalance &&
depositBalance &&
Expand All @@ -606,15 +603,13 @@ export function useTradeSummary(state: VaultTradeState | TradeState) {
// we move the calculations into the observable so this is hidden
collateralBalance.currencyId === depositBalance.currencyId
) {
feeValue = depositBalance
.toUnderlying()
.sub(collateralBalance.toUnderlying());
feeValue = collateralFee?.toUnderlying() || feeValue;
} else if (
debtBalance &&
depositBalance &&
debtBalance.currencyId === depositBalance.currencyId
) {
feeValue = depositBalance.toUnderlying().sub(debtBalance.toUnderlying());
feeValue = debtFee?.toUnderlying() || feeValue;
}

summary.push({
Expand Down
Loading

0 comments on commit 445af8c

Please sign in to comment.