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

Add rewards for linena rseth #1490

Merged
merged 2 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions apps/hyperdrive-trading/src/base/assertNever.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Helper function for exhaustive checks of discriminated unions.
* https://basarat.gitbooks.io/typescript/docs/types/discriminated-unions.html
*
* @example
*
* type A = {type: 'a'};
* type B = {type: 'b'};
* type Union = A | B;
*
* function doSomething(arg: Union) {
* if (arg.type === 'a') {
* return something;
* }
*
* if (arg.type === 'b') {
* return somethingElse;
* }
*
* // TS will error if there are other types in the union
* // Will throw an Error when called at runtime.
* // Use `assertNever(arg, true)` instead to fail silently.
* return assertNever(arg);
* }
*/ export function assertNever(value: never, noThrow?: boolean): never {
if (noThrow) {
return value;
}

throw new Error(
`Unhandled discriminated union member: ${JSON.stringify(value)}`,
);
}
70 changes: 45 additions & 25 deletions apps/hyperdrive-trading/src/ui/rewards/RewardsTooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { findHyperdriveConfig } from "@hyperdrive/appconfig";
import { appConfig, findHyperdriveConfig } from "@hyperdrive/appconfig";
import * as Tooltip from "@radix-ui/react-tooltip";
import { PropsWithChildren, ReactNode } from "react";
import { assertNever } from "src/base/assertNever";
import { useAppConfig } from "src/ui/appconfig/useAppConfig";
import { useRewards } from "src/ui/rewards/useRewards";
import { Address } from "viem";
Expand Down Expand Up @@ -40,36 +41,55 @@ export function RewardsTooltip({
sideOffset={5}
collisionPadding={12}
>
<div className="p- flex justify-between border-b border-neutral-content/30 p-3">
<div className="flex justify-between border-b border-neutral-content/30 p-3">
<p className="gradient-text text-lg">Rewards</p>
</div>

{rewards?.map((reward) => {
if (reward.id === "MorphoFlatRate") {
return (
<div
key={reward.id}
className="flex items-center justify-between border-b border-neutral-content/30 p-3 [&:nth-last-child(2)]:border-none"
>
<div className="flex items-center gap-1">
<img
src="https://cdn.morpho.org/assets/logos/morpho.svg"
alt="Morpho logo"
className="h-4"
/>
{reward.name}
</div>
switch (reward.id) {
case "MorphoFlatRate":
return (
<div
key={reward.id}
className="flex items-center justify-between border-b border-neutral-content/30 p-3 [&:nth-last-child(2)]:border-none"
>
<div className="flex items-center gap-1">
<img
src={appConfig.protocols.morpho.iconUrl}
alt="Morpho logo"
className="h-4"
/>
{reward.name}
</div>

<div className="grid justify-items-end">
<p className="flex items-center gap-1">
+{reward.amount}
</p>
<p className="text-2xs text-neutral-content">
per $1000 / yr
</p>
<div className="grid justify-items-end">
<p className="flex items-center gap-1">
+{reward.amount}
</p>
<p className="text-2xs text-neutral-content">
per $1000 / yr
</p>
</div>
</div>
);
case "LineaLXPL":
return (
<div
key={reward.id}
className="flex flex-col items-start justify-start gap-2 border-b border-neutral-content/30 p-3 [&:nth-last-child(2)]:border-none"
>
<div className="flex items-center gap-4">
<img
src={appConfig.chains[hyperdrive.chainId].iconUrl}
alt="KelpDAO logo"
className="h-8"
/>
<p>This pool is eligible for LXP-L rewards.</p>
</div>
</div>
</div>
);
);
default:
assertNever(reward.id);
}
})}
</Tooltip.Content>
Expand Down
61 changes: 42 additions & 19 deletions apps/hyperdrive-trading/src/ui/rewards/useRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { HyperdriveConfig } from "@hyperdrive/appconfig";
import { usePoolInfo } from "src/ui/hyperdrive/hooks/usePoolInfo";
import { usePresentValue } from "src/ui/hyperdrive/hooks/usePresentValue";
import { Address } from "viem";
import { mainnet } from "viem/chains";
import { linea, mainnet } from "viem/chains";

// TODO @cashd: Move to AppConfig
// https://github.com/delvtech/hyperdrive-frontend/issues/1341
Expand All @@ -17,19 +17,24 @@ const eligibleMarketsForMorphoRewards: Record<number, Address[]> = {
],
};

const eligibleMarketsForLineaRewards: Record<number, Address[]> = {
[linea.id]: [
// 182d KelpDAO rsETH
"0xB56e0Bf37c4747AbbC3aA9B8084B0d9b9A336777",
],
};

// Source: https://docs.morpho.org/rewards/concepts/programs
const MorphoFlatRatePerDay = 1.45e-4;
const MorphoFlatRatePerYear = parseFixed(MorphoFlatRatePerDay * 365 * 1000);

type RewardType = "MorphoFlatRate";
type RewardType = "MorphoFlatRate" | "LineaLXPL";

type UseRewardsReturn =
| {
id: RewardType;
name: string;
amount: string;
}[]
| undefined;
type Reward = {
id: RewardType;
name: string;
amount: string;
};

function getWeightMorpho(
poolConfig: PoolConfig,
Expand All @@ -56,7 +61,7 @@ function getWeightMorpho(
export function useRewards(
hyperdrive: HyperdriveConfig,
positionType: "short" | "lp",
): UseRewardsReturn {
): Reward[] | undefined {
const { poolInfo } = usePoolInfo({
chainId: hyperdrive.chainId,
hyperdriveAddress: hyperdrive.address,
Expand All @@ -66,6 +71,9 @@ export function useRewards(
hyperdriveAddress: hyperdrive.address,
});

const rewards = [];

// Add any morpho rewards for this market
if (
eligibleMarketsForMorphoRewards[hyperdrive.chainId]?.includes(
hyperdrive.address,
Expand All @@ -80,14 +88,29 @@ export function useRewards(
),
);

return [
{
id: "MorphoFlatRate",
name: "MORPHO",
amount: morphoRate.format({
decimals: 2,
}),
},
];
const morphoReward: Reward = {
id: "MorphoFlatRate",
name: "MORPHO",
amount: morphoRate.format({
decimals: 2,
}),
};
rewards.push(morphoReward);
}

// Add any linea rewards for this market
if (
eligibleMarketsForLineaRewards[hyperdrive.chainId]?.includes(
hyperdrive.address,
)
) {
const lineaReward: Reward = {
id: "LineaLXPL",
name: "LXPL",
amount: "1",
};
rewards.push(lineaReward);
}

return rewards;
}
Loading