Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
marshall2112 committed Dec 3, 2024
1 parent 444527c commit dff62c0
Show file tree
Hide file tree
Showing 26 changed files with 1,490 additions and 1,168 deletions.
3 changes: 2 additions & 1 deletion apps/dapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,6 @@
"typescript": "^5.5.4",
"vite": "^5.2.10",
"vite-plugin-svgr": "^4.2.0"
}
},
"packageManager": "[email protected]"
}
5 changes: 3 additions & 2 deletions apps/dapp/src/components/InputSelect/InputSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface SelectTempleDaoProps {
isSearchable?: boolean;
width?: CSS.Property.Width;
fontSize?: CSS.Property.FontSize;
fontWeight?: CSS.Property.FontWeight;
textAlign?: CSS.Property.TextAlign;
zIndex?: CSS.Property.ZIndex;
}
Expand Down Expand Up @@ -88,7 +89,7 @@ export const InputSelect = (props: SelectTempleDaoProps) => {
transition: theme.transitions.backgroundColor,
height: selectHeight,
borderBottom: `0.0625rem solid ${theme.palette.brand}`,
fontWeight: 'bold',
fontWeight: props.fontWeight ? props.fontWeight : 'bold',
fontSize: props.fontSize,
color: theme.palette.brandLight,
}),
Expand All @@ -101,7 +102,7 @@ export const InputSelect = (props: SelectTempleDaoProps) => {
transition: 'opacity 300ms',
textAlign: props.textAlign ?? 'center',
width: '100%',
fontWeight: 'bold',
fontWeight: props.fontWeight ? props.fontWeight : 'bold',
fontSize: props.fontSize ?? '1.25rem',
color: theme.palette.brandLight,
}),
Expand Down
7 changes: 7 additions & 0 deletions apps/dapp/src/components/Layouts/V2Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum V2DashboardLocPaths {
Trv = '/dapp/dashboard/treasuryreservesvault',
Borrow = '/dapp/borrow',
SpiceBazaar = '/dapp/spice',
Ohmage = '/dapp/ohmage',
Legacy = '/dapp/legacy',
}

Expand Down Expand Up @@ -70,6 +71,12 @@ const V2Layout = () => {
Logo: StoreFront,
selected: V2DashboardLocPaths.SpiceBazaar === loc.pathname,
},
{
label: 'Ohmage',
linkTo: V2DashboardLocPaths.Ohmage,
Logo: Candle,
selected: V2DashboardLocPaths.Ohmage === loc.pathname,
},
{
label: 'Legacy',
linkTo: V2DashboardLocPaths.Legacy,
Expand Down
21 changes: 11 additions & 10 deletions apps/dapp/src/components/Pages/Core/DappPages/Borrow/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
formatNumberFixedDecimals,
} from 'utils/formatter';
import { formatDailyDataPoints } from 'utils/charts';
import { fetchGenericSubgraph } from 'utils/subgraph';
import { queryTlcDailySnapshots, subgraphQuery } from 'utils/subgraph';
import IntervalToggler from 'components/Charts/IntervalToggler';
import env from 'constants/env';

Expand Down Expand Up @@ -50,17 +50,18 @@ export const TlcChart = () => {

useEffect(() => {
const fetchMetrics = async () => {
const { data } = await fetchGenericSubgraph<any>(
const response = await subgraphQuery(
env.subgraph.templeV2,
`{
tlcDailySnapshots(orderBy: timestamp, orderDirection: desc) {
timestamp
utilRatio
interestYield
}
}`
queryTlcDailySnapshots()
);

setMetrics(
response.tlcDailySnapshots.map((r) => ({
timestamp: parseFloat(r.timestamp),
utilRatio: parseFloat(r.utilRatio),
interestYield: parseFloat(r.interestYield),
}))
);
setMetrics(data.tlcDailySnapshots);
};
fetchMetrics();
}, []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import { formatTimestampedChartData } from 'utils/charts';
import useV2StrategySnapshotData, {
StrategyTokenField,
V2SnapshotMetric,
V2StrategySnapshot,
} from '../hooks/use-dashboardv2-daily-snapshots';
import {
ALL_STRATEGIES,
DashboardData,
isTRVDashboard,
StrategyKey,
} from '../DashboardConfig';
import { V2StrategySnapshot } from 'utils/subgraph';

type XAxisTickFormatter = (timestamp: number) => string;

Expand Down Expand Up @@ -181,12 +182,16 @@ const V2StrategyMetricsChart: React.FC<{

const filteredDaily =
dailyMetrics
?.filter((m) => chartStrategyNames.includes(m.strategy.name))
?.filter((m) =>
chartStrategyNames.includes(m.strategy.name as StrategyKey)
)
.sort((a, b) => parseInt(a.timestamp) - parseInt(b.timestamp)) ?? [];

const filteredHourly =
hourlyMetrics
?.filter((m) => chartStrategyNames.includes(m.strategy.name))
?.filter((m) =>
chartStrategyNames.includes(m.strategy.name as StrategyKey)
)
.sort((a, b) => parseInt(a.timestamp) - parseInt(b.timestamp)) ?? [];

// if we are rendering chart for only one strategy we can use data as is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const Dashboards: DashboardData[] = [
title: 'TRV',
path: 'treasuryreservesvault',
description:
'Treasury Reserves Vault (TRV) coordinates and manages the flow of capital for current Treasury allocations. When funding and management parameters are approved for a Strategy, the TRV will transfer funds e.g. DAI and issue corresponding debt to the Strategy borrower. The current equity of the Strategy is discounted by the loan principal and accrued interest benchmarked to the prevailing rate of the current Base Strategy for the borrowed token.',
'Treasury Reserves Vault (TRV) is the central clearinghouse for the Temple Treasury and critical coordinator for current Treasury Strategy allocations. When funding and management parameters are approved for a Strategy, the TRV will transfer funds and issue corresponding debt to the Strategy borrower. The current equity of the Strategy is discounted by the loan principal and accrued interest benchmarked to the prevailing rate of the current Base Strategy for the borrowed token.',
contractLink: `${env.etherscan}/address/${env.contracts.treasuryReservesVault}`,
},
{
Expand All @@ -47,7 +47,7 @@ export const Dashboards: DashboardData[] = [
title: 'RAMOS',
path: 'ramos',
description:
'Ramos is the automated market operations (AMO) manager that supplies liquidity to the TEMPLE/DAI pool on the Balancer Exchange platform. A bot manages the contract to support TEMPLE trading, reduce price volatility, and earn farming rewards.',
'Ramos is the automated market operations (AMO) manager that supplies liquidity to the TEMPLE/DAI pool on the Balancer DEX. A bot manages the contract to support TEMPLE trading, reduce price volatility, and earn farming rewards.',
contractLink: `${env.etherscan}/address/${env.contracts.strategies.ramosStrategy}`,
},
{
Expand All @@ -56,7 +56,7 @@ export const Dashboards: DashboardData[] = [
title: 'TLC',
path: 'tlc',
description:
'Temple Loving Care (also known as Temple Line of Credit) offers DAI lending for users who supply TEMPLE token as collateral. The value of the collateral is not determined by the current $TEMPLE spot price on the Balancer DEX but by the current Treasury Price Index (TPI). Users may borrow up to 75% loan-to-value (LTV) with the liquidation LTV set to 80%. There are no origination fees and users can withdraw their collateral at any time by repaying the DAI loan. TLC interest rate is a variable APR that is dependent on Debt Ceiling Utilisation. Any accrued interest will increase LTV over time. Borrowers can expect the APR to be set no lower than the prevailing APR for the Treasury DAI Base Strategy. <a target="_blank" href="https://templedao.medium.com/he-who-controls-the-spice-controls-the-universe-bae5fb92bd43">Click here</a> to learn more about Temple Loving Care.',
'Temple Loving Care (also known as Temple Line of Credit) offers DAI lending for users who supply TEMPLE as collateral. The TLC will use the current Treasury Price Index (TPI) Oracle to determine the collateral value of TEMPLE. Users may borrow up to 85% loan-to-value (LTV) with the TEMPLE liquidation LTV set to 90%. There are no origination fees and users can withdraw their TEMPLE at any time by repaying the DAI loan. The TLC interest rate is set to a fixed rate that will be periodically updated to 2X the yield from the current Treasury Base Strategy e.g. sDAI. <a target="_blank" href="https://templedao.medium.com/he-who-controls-the-spice-controls-the-universe-bae5fb92bd43">Click here</a> to learn more about Temple Loving Care.',
contractLink: `${env.etherscan}/address/${env.contracts.strategies.tlcStrategy}`,
},
{
Expand All @@ -65,7 +65,7 @@ export const Dashboards: DashboardData[] = [
title: 'TEMPLE BASE',
path: 'templebase',
description:
'Temple Base strategy is the source of automated market operations (AMO) TEMPLE tokens in the Treasury framework. The TRV facilitates the withdrawal of newly minted TEMPLE tokens from and the issuance of TEMPLE debt to the Temple Base strategy. These TEMPLE tokens will be borrowed by a Treasury Strategy such as Ramos to generate returns. Once these tokens are repaid to the TRV, they will be deposited to the Temple Base strategy to be burned. From the perspective of the TRV, positive returns will be realized when TEMPLE flows to the Temple Base strategy is net positive.',
'TEMPLE Base strategy is the funding source for TEMPLE tokens for automated market operations (AMO) in the Treasury framework. The TRV facilitates the withdrawal of newly minted TEMPLE tokens from and the issuance of TEMPLE debt to the TEMPLE Base strategy. These TEMPLE tokens will be borrowed by a Treasury Strategy such as Ramos to generate returns. Once these tokens are repaid to the TRV, they will be deposited to the TEMPLE Base strategy to be burned. Positive returns will be realized when TEMPLE flows to the TEMPLE Base strategy is net positive.',
contractLink: `${env.etherscan}/address/${env.contracts.strategies.templeStrategy}`,
},
{
Expand All @@ -74,7 +74,7 @@ export const Dashboards: DashboardData[] = [
title: 'DSR BASE',
path: 'dsrbase',
description:
'Idle capital in the Treasury Reserves Vault (TRV) that is not currently deployed to a Strategy borrower will be automatically directed to a Base Strategy to earn yield. Currently, the Base Strategy is set to the Dai Savings Rate (DSR) which makes DAI the base currency of the TRV. The current rate of return for DSR Base also serves as the benchmark interest rate for the Treasury Strategy that borrows DAI from the TRV.',
'Idle reserve capital in the TRV that is not currently borrowed by a Strategy Borrower will be automatically directed to a Base Strategy to earn yield. The TRV Base Strategy is currently set to the Dai Savings Rate (DSR) or sDAI. The current rate of return for the Base Strategy also serves as the performance benchmark or "risk-free" interest rate for Treasury Strategies.',
contractLink: `${env.etherscan}/address/${env.contracts.strategies.dsrBaseStrategy}`,
},
{
Expand All @@ -83,7 +83,7 @@ export const Dashboards: DashboardData[] = [
title: 'TEMPLO MAYOR',
path: 'templomayor',
description:
'Templo Mayor is an Gnosis Safe Omnibus strategy. An Omnibus Strategy utilises the same bookkeeping structure and approval process, but may entail several related holdings or sub-positions that are managed as a whole. For instance, deposits into different but similar or co-dependent vaults on the same platform or different platforms may be consolidated into one Omnibus Gnosis Safe. Seed allocations of a target risk profile may also be consolidated into an Omnibus Strategy to reduce the noise. Therefore an Omnibus Strategy may provide additional operational efficiency and allow Stakeholders to evaluate a series of related deployments as one composite position rather than as singletons.',
'Templo Mayor is an Gnosis Safe Omnibus Strategy that is particularly useful when full automation is not feasible. An Omnibus Strategy utilises the same bookkeeping structure and approval process as the automated Temple v2 Strategies, but may entail several related holdings or sub-positions that are managed holistically. For instance, deposits into different but similar or co-dependent vaults on the same platform or different platforms may be consolidated into one Omnibus Gnosis Safe. Partner seed allocations of a target risk profile may also be consolidated into an Omnibus Strategy to derisk any particular project. An Omnibus Strategy may provide additional operational efficiency and allow Stakeholders to evaluate a series of related deployments as one composite position rather than as singletons.',
contractLink: `${env.etherscan}/address/${env.contracts.strategies.temploMayorGnosisStrategy}`,
},
{
Expand All @@ -92,7 +92,7 @@ export const Dashboards: DashboardData[] = [
title: 'FOHMO',
path: 'fohmo',
description:
'FOHMO is a strategy that aims to maintain a maxed looped position in OHM',
'FOHMO is a strategy that aims to maintain a maximally looped position in OHM',
contractLink: `${env.etherscan}/address/${env.contracts.strategies.fohmoGnosisStrategy}`,
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import { queryMinTablet } from 'styles/breakpoints';
import env from 'constants/env';
import linkSvg from 'assets/icons/link.svg?react';
import { formatNumberWithCommas } from 'utils/formatter';
import { DashboardData, Dashboards, isTRVDashboard } from '../DashboardConfig';
import {
DashboardData,
Dashboards,
isTRVDashboard,
StrategyKey,
} from '../DashboardConfig';

type Props = {
dashboardData: DashboardData;
Expand Down Expand Up @@ -271,8 +276,8 @@ const TxnHistoryTable = (props: Props) => {
const timeOnly = format(new Date(Number(tx.timestamp) * 1000), 'H:mm:ss');
return {
date: isBiggerThanTablet ? datetime : dateOnly,
type: tx.name,
strategy: tx.strategy.name,
type: tx.name as TxType,
strategy: tx.strategy.name as StrategyKey,
token: tx.token.symbol,
amount: amountFmt,
txHash: tx.hash,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { useQuery } from '@tanstack/react-query';
import env from 'constants/env';
import { getQueryKey } from 'utils/react-query-helpers';
import { SubGraphResponse } from 'hooks/core/types';
import { fetchGenericSubgraph } from 'utils/subgraph';
import { StrategyKey } from '../DashboardConfig';
import {
queryStrategyDailySnapshots,
queryStrategyHourlySnapshots,
subgraphQuery,
V2StrategySnapshot,
} from 'utils/subgraph';

const V2SnapshotMetrics = [
'totalMarketValueUSD',
Expand All @@ -30,38 +33,12 @@ const STRATEGY_TOKEN_FIELDS = [

export type StrategyTokenField = (typeof STRATEGY_TOKEN_FIELDS)[number];

const QUERIED_FIELDS = `
strategy{
name
}
timeframe
timestamp
${V2SnapshotMetrics.join('\n')}
strategyTokens{
${STRATEGY_TOKEN_FIELDS.join('\n')}
}
`;

export type V2StrategySnapshot = {
timestamp: string;
timeframe: string;
strategy: { name: StrategyKey };
strategyTokens: { [key in (typeof STRATEGY_TOKEN_FIELDS)[number]]: string }[];
} & { [key in V2SnapshotMetric]: string };

export function isV2SnapshotMetric(
key?: string | null
): key is V2SnapshotMetric {
return V2SnapshotMetrics.some((m) => m === key);
}

type FetchV2StrategyDailySnapshotResponse = SubGraphResponse<{
strategyDailySnapshots: V2StrategySnapshot[];
}>;
type FetchV2StrategyHourlySnapshotResponse = SubGraphResponse<{
strategyHourlySnapshots: V2StrategySnapshot[];
}>;

const ONE_DAY_ONE_HOUR_MS = 25 * 60 * 60 * 1000;
const ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;

Expand All @@ -73,22 +50,17 @@ async function fetchStrategyHourlySnapshots() {
).toString();
// if # of strategies * 24 > 1000 we would be missing data
// but we shouldnt be getting anywhere close to that
const query = `
query {
strategyHourlySnapshots(first: ${itemsPerPage},
orderBy: timestamp,
orderDirection: asc,
where: {timestamp_gt: ${since}}
) {
${QUERIED_FIELDS}
}
}`;
const resp =
await fetchGenericSubgraph<FetchV2StrategyHourlySnapshotResponse>(
env.subgraph.templeV2Balances,
query
);
return resp?.data?.strategyHourlySnapshots ?? [];
const resp = await subgraphQuery(
env.subgraph.templeV2Balances,
queryStrategyHourlySnapshots(
V2SnapshotMetrics,
STRATEGY_TOKEN_FIELDS,
itemsPerPage,
since
)
);

return resp.strategyHourlySnapshots;
}

async function fetchStrategyDailySnapshots() {
Expand All @@ -99,26 +71,19 @@ async function fetchStrategyDailySnapshots() {
const MAX_PAGE_SIZE = 1000; // current max page size
let skip = 0;
while (true) {
const query = `
query {
strategyDailySnapshots(first: ${MAX_PAGE_SIZE},
orderBy: timestamp,
orderDirection: asc,
where: {timestamp_gt: ${since}}
skip: ${skip}) {
${QUERIED_FIELDS}
}
}`;
const page =
await fetchGenericSubgraph<FetchV2StrategyDailySnapshotResponse>(
env.subgraph.templeV2Balances,
query
);
const itemsOnPage = page.data?.strategyDailySnapshots.length ?? 0;
if (page.data) {
result.push(...page.data.strategyDailySnapshots);
skip += itemsOnPage;
}
const page = await subgraphQuery(
env.subgraph.templeV2Balances,
queryStrategyDailySnapshots(
V2SnapshotMetrics,
STRATEGY_TOKEN_FIELDS,
MAX_PAGE_SIZE,
since,
skip
)
);
const itemsOnPage = page.strategyDailySnapshots.length ?? 0;
result.push(...page.strategyDailySnapshots);
skip += itemsOnPage;
if (itemsOnPage < MAX_PAGE_SIZE) {
break;
}
Expand Down
Loading

0 comments on commit dff62c0

Please sign in to comment.