Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update interest rate strategies + move terminology from collateral to branch #809

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
22 changes: 11 additions & 11 deletions frontend/app/src/comps/About/About.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,38 +33,38 @@ const ENV_EXCLUDE: Set<keyof typeof env> = new Set([
// - contracts: main contracts (CONTRACT_*)
// - branches: branches contracts (in COLLATERAL_CONTRACTS)
function getEnvGroups() {
const config = { ...env };
const envConfig = { ...env };

const contracts: Record<string, string> = {};

for (const [key, value] of Object.entries(env) as Entries<typeof env>) {
if (key.startsWith("CONTRACT_")) {
contracts[key.replace("CONTRACT_", "")] = String(value);
delete config[key];
delete envConfig[key];
continue;
}
}

const branches: {
collIndex: number;
branchId: number;
symbol: string;
contracts: [string, string][];
}[] = [];

for (const { collIndex, symbol, contracts } of config.COLLATERAL_CONTRACTS) {
for (const { branchId, symbol, contracts } of envConfig.BRANCHES) {
branches.push({
collIndex,
branchId,
symbol,
contracts: Object
.entries(contracts)
.map(([name, address]) => [name, address]),
});
}

delete config["COLLATERAL_CONTRACTS" as keyof typeof config];
delete envConfig["COLLATERAL_CONTRACTS" as keyof typeof envConfig];

const configFinal = Object.fromEntries(
Object.entries(config)
const envConfigFinal = Object.fromEntries(
Object.entries(envConfig)
.filter(([key]) => !ENV_EXCLUDE.has(key as keyof typeof env))
.map(([key, value]) => {
if (key === "CHAIN_BLOCK_EXPLORER") {
Expand All @@ -79,7 +79,7 @@ function getEnvGroups() {
}),
);

return { config: configFinal, contracts, branches };
return { config: envConfigFinal, contracts, branches };
}

const AboutContext = createContext<{
Expand Down Expand Up @@ -279,9 +279,9 @@ export function About({ children }: { children: ReactNode }) {
}
entries={envGroups.contracts}
/>
{envGroups.branches.map(({ collIndex, symbol, contracts }) => (
{envGroups.branches.map(({ branchId, symbol, contracts }) => (
<AboutTable
key={collIndex}
key={branchId}
title={`Branch contracts: ${symbol}`}
entries={Object.fromEntries(contracts)}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CollIndex, PositionEarn } from "@/src/types";
import type { BranchId, PositionEarn } from "@/src/types";
import type { ReactNode } from "react";

import { Amount } from "@/src/comps/Amount/Amount";
Expand All @@ -11,22 +11,22 @@ import * as dn from "dnum";
import Link from "next/link";

export function EarnPositionSummary({
collIndex,
branchId,
prevEarnPosition,
earnPosition,
linkToScreen,
title,
txPreviewMode,
}: {
collIndex: CollIndex;
branchId: BranchId;
prevEarnPosition?: PositionEarn | null;
earnPosition: PositionEarn | null;
linkToScreen?: boolean;
title?: ReactNode;
txPreviewMode?: boolean;
}) {
const collToken = getCollToken(collIndex);
const earnPool = useEarnPool(collIndex);
const collToken = getCollToken(branchId);
const earnPool = useEarnPool(branchId);

const { totalDeposited: totalPoolDeposit } = earnPool.data;

Expand Down
189 changes: 189 additions & 0 deletions frontend/app/src/comps/InterestRateField/DelegateBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import type { Delegate } from "@/src/types";

import { Amount } from "@/src/comps/Amount/Amount";
import { fmtnum, formatRedemptionRisk } from "@/src/formatting";
import { getRedemptionRisk } from "@/src/liquity-math";
import { riskLevelToStatusMode } from "@/src/uikit-utils";
import { css } from "@/styled-system/css";
import { Button, IconCopy, StatusDot, TextButton } from "@liquity2/uikit";
import { MiniChart } from "./MiniChart";
import { ShadowBox } from "./ShadowBox";

export function DelegateBox({
delegate,
onSelect,
selectLabel = "Select",
}: {
delegate: Delegate;
onSelect: (delegate: Delegate) => void;
selectLabel: string;
}) {
const delegationRisk = getRedemptionRisk(delegate.interestRate);
return (
<ShadowBox key={delegate.id}>
<section
key={delegate.name}
className={css({
display: "flex",
flexDirection: "column",
alignItems: "center",
padding: "8px 16px",
})}
>
<div
className={css({
display: "flex",
flexDirection: "column",
width: "100%",
paddingBottom: 12,
borderBottom: "1px solid token(colors.borderSoft)",
})}
>
<div
className={css({
display: "flex",
justifyContent: "space-between",
alignItems: "center",
width: "100%",
fontSize: 20,
fontWeight: 500,
userSelect: "none",
})}
>
<h1 title={`${delegate.name} (${delegate.address})`}>
{delegate.name}
</h1>
<div
className={css({
display: "flex",
gap: 6,
alignItems: "center",
})}
>
<MiniChart />
{fmtnum(delegate.interestRate, "pct1z")}%
</div>
</div>
<div
className={css({
display: "flex",
justifyContent: "space-between",
width: "100%",
fontSize: 14,
color: "content",
})}
>
<div
className={css({
display: "flex",
gap: 8,
alignItems: "center",
})}
>
<Amount
value={delegate.boldAmount}
format="compact"
suffix=" BOLD"
/>
</div>
<div
className={css({
display: "flex",
gap: 8,
alignItems: "center",
})}
>
<StatusDot mode={riskLevelToStatusMode(delegationRisk)} />
{formatRedemptionRisk(delegationRisk)}
</div>
</div>
</div>
<div
className={css({
display: "flex",
flexDirection: "column",
width: "100%",
paddingTop: 12,
fontSize: 14,
paddingBottom: 12,
borderBottom: "1px solid token(colors.borderSoft)",
})}
>
<div
className={css({
display: "flex",
justifyContent: "space-between",
width: "100%",
fontSize: 14,
color: "content",
})}
>
<div>Interest rate range</div>
<div>
{fmtnum(delegate.interestRateChange[0], "pct2")}
<span>-</span>
{fmtnum(delegate.interestRateChange[1], "pct2")}%
</div>
</div>
{delegate.fee && (
<div
className={css({
display: "flex",
justifyContent: "space-between",
width: "100%",
fontSize: 14,
color: "content",
})}
>
<div>
Fees <abbr title="per annum">p.a.</abbr>
</div>
<div title={`${fmtnum(delegate.fee, "pctfull")}%`}>
{fmtnum(delegate.fee, { digits: 4, scale: 100 })}%
</div>
</div>
)}
</div>
<div
className={css({
display: "flex",
justifyContent: "space-between",
width: "100%",
paddingTop: 16,
paddingBottom: 8,
fontSize: 14,
})}
>
<div
className={css({
display: "flex",
gap: 8,
})}
>
<TextButton
label={
<>
Copy address
<IconCopy size={16} />
</>
}
className={css({
fontSize: 14,
})}
/>
</div>
<div>
<Button
label={selectLabel}
mode="primary"
size="small"
onClick={() => {
onSelect(delegate);
}}
/>
</div>
</div>
</section>
</ShadowBox>
);
}
Loading