import { parseUnits } from "viem"; import { useWaitForTransactionReceipt, useWriteContract } from "wagmi"; import { hoodquidityVaultsAbi } from "@/lib/abi/HoodquidityVaults"; import { ACTIVE_CHAIN_ID, getActiveDeployment, USD_DECIMALS } from "@/lib/contracts"; import { fmtUsd, fmtCountdown, fmtNum } from "@/lib/format"; import { campaignPoints, isGenesisLp } from "@/lib/points"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { CountUp } from "@/components/CountUp"; import type { CampaignState } from "@/hooks/useCampaigns"; import type { usePosition } from "@/hooks/useCampaigns"; type Position = NonNullable["position"]>; export function PositionPanel({ campaign, position, onSettled, }: { campaign: CampaignState; position: Position; onSettled: () => void; }) { const deployment = getActiveDeployment(); const { writeContract, data: txHash, isPending, reset } = useWriteContract(); const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash: txHash, }); if (isSuccess) { reset(); onSettled(); } const busy = isPending || isConfirming; const ended = campaign.status === "ended"; const id = BigInt(campaign.meta.campaignId); const exit = () => writeContract({ address: deployment.vaults, abi: hoodquidityVaultsAbi, functionName: "withdraw", args: [id, parseUnits(position.amountUsd.toString(), USD_DECIMALS)], chainId: ACTIVE_CHAIN_ID, }); const claim = () => writeContract({ address: deployment.vaults, abi: hoodquidityVaultsAbi, functionName: "claim", args: [id], chainId: ACTIVE_CHAIN_ID, }); return (
LP receipt
{isGenesisLp(position.lpIndex) && Genesis LP} {position.boosted && 1.5x boosted}
Deposited {fmtUsd(position.amountUsd, false)}
Vault share {campaign.tvlUsd > 0 ? `${((position.amountUsd / campaign.tvlUsd) * 100).toFixed(1)}%` : "0%"}
Rewards accrued {fmtUsd(position.pendingUsd, false)}
Rewards claimed {fmtUsd(position.claimedUsd, false)}
{position.stockAmount > 0 && (
Stock leg {position.stockAmount.toFixed(4)} {campaign.meta.symbol}
)}
Points fmtNum(Math.floor(n))} />
Full rewards unlock {ended ? "Unlocked" : fmtCountdown(campaign.end)}
{ended ? ( <> ) : ( )}
{!ended ? (

Early exit returns your principal minus a 0.1% fee. Accrued campaign rewards are forfeited and redistributed to remaining LPs.

) : (

Reward payouts carry a 10% platform fee. Points have no monetary value and feed future programs.

)}
); }