Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
47 changes: 38 additions & 9 deletions src/lib/components/blocks/dashboard/GluonStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import BigNumber from "bignumber.js";
import { motion, AnimatePresence } from "framer-motion";
import GauIcon from "@/lib/components/icons/GauIcon";
import GaucIcon from "@/lib/components/icons/GaucIcon";
import { protocolConfig } from "@/lib/config/protocol";

interface GluonStats {
ergPrice: number | null;
Expand Down Expand Up @@ -305,11 +306,32 @@ export function GluonStats() {

{/* Token Grid - Responsive */}
<div className="mb-6 grid grid-cols-1 gap-4 md:grid-cols-3">
{renderStatCard("Gram of Gold", "Gold (from Oracle)", stats.goldPrice, <Scale className="h-8 w-8 text-yellow-700" />, "ERG", 0.1)}
{renderStatCard(
protocolConfig.ui.labels.goldPriceTitle,
protocolConfig.ui.labels.goldPriceSubtitle,
stats.goldKgPrice,
<Scale className="h-8 w-8 text-yellow-700" />,
"ERG",
0.1
)}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

{renderStatCard("GAU", "Gold Pegged Token", stats.gauPrice, <GauIcon className="h-8 w-8" />, "ERG", 0.2)}
{renderStatCard(
protocolConfig.tokens.neutron.ticker,
protocolConfig.ui.labels.neutronSubtitle,
stats.gauPrice,
<GauIcon className="h-8 w-8" />,
"ERG",
0.2
)}

{renderStatCard("GAUC", "Leveraged Yield Token", stats.gaucPrice, <GaucIcon className="h-8 w-8" />, "ERG", 0.3)}
{renderStatCard(
protocolConfig.tokens.proton.ticker,
protocolConfig.ui.labels.protonSubtitle,
stats.gaucPrice,
<GaucIcon className="h-8 w-8" />,
"ERG",
0.3
)}
</div>

{/* Stats */}
Expand Down Expand Up @@ -360,25 +382,29 @@ export function GluonStats() {
<div className="text-2xl font-bold text-foreground">
{isLoading ? <Skeleton className="mx-auto h-8 w-16" /> : hasError ? "—" : nanoErgsToErgs(protocolMetrics.volume14Day.neutronsToProtons).toFixed(2)}
</div>
<div className="text-sm text-muted-foreground">14d GAU to GAUC Volume (ERG)</div>
<div className="text-sm text-muted-foreground">
14d {protocolConfig.tokens.neutron.ticker} to {protocolConfig.tokens.proton.ticker} Volume (ERG)
</div>
</div>
<div className="space-y-2">
<div className="text-2xl font-bold text-foreground">
{isLoading ? <Skeleton className="mx-auto h-8 w-16" /> : hasError ? "—" : nanoErgsToErgs(protocolMetrics.volume14Day.protonsToNeutrons).toFixed(2)}
</div>
<div className="text-sm text-muted-foreground">14d GAUC to GAU Volume (ERG)</div>
<div className="text-sm text-muted-foreground">
14d {protocolConfig.tokens.proton.ticker} to {protocolConfig.tokens.neutron.ticker} Volume (ERG)
</div>
</div>
<div className="space-y-2">
<div className="text-2xl font-bold text-foreground">
{isLoading ? <Skeleton className="mx-auto h-8 w-16" /> : hasError ? "—" : convertFromDecimals(protocolMetrics.circulatingSupply.neutrons).toFixed(2)}
</div>
<div className="text-sm text-muted-foreground">GAU Supply</div>
<div className="text-sm text-muted-foreground">{protocolConfig.ui.labels.neutronSupplyLabel}</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we could use the neutron ticker from config and then " Supply". Then we wouldn't need to define neutronSupplyLabel.

</div>
<div className="space-y-2">
<div className="text-2xl font-bold text-foreground">
{isLoading ? <Skeleton className="mx-auto h-8 w-16" /> : hasError ? "—" : convertFromDecimals(protocolMetrics.circulatingSupply.protons).toFixed(2)}
</div>
<div className="text-sm text-muted-foreground">GAUC Supply</div>
<div className="text-sm text-muted-foreground">{protocolConfig.ui.labels.protonSupplyLabel}</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too, for protons.

</div>
</div>
</Card>
Expand Down Expand Up @@ -434,8 +460,11 @@ export function GluonStats() {
transition={{ duration: 0.3 }}
className="text-center"
>
<div className="mb-1 text-4xl font-bold text-foreground">{hasError ? "—" : stats.priceCrashCushion ? Math.round(+stats.priceCrashCushion) : "—" }%</div>
<div className="text-sm font-medium text-muted-foreground">{renderTooltip("Price Crash Cushion", "Maximum drop in the price of ERG w.r.t. Gold that can be tolerated for GAU to remain pegged to Gold. When 0%, GAU depegs to prevent bank runs and maintain non-zero GAUC price.")}</div>
<div className="text-4xl font-bold text-foreground mb-1">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that, in this code block, some recent changes that iIhad committed are being erased.

Are you sure that you are working on the latest version of the main branch? Remember to always pull and synchronize your branch.

{hasError ? '—' : stats.reserveRatio ? Math.round(- (100 / (100 - stats.reserveRatio)) * 100)/100 : '—'}x <br />
</div>
<div className="font-medium text-sm text-muted-foreground">Current {protocolConfig.tokens.proton.ticker} Leverage</div>

Comment thread
coderabbitai[bot] marked this conversation as resolved.
</motion.div>
)}
</AnimatePresence>
Expand Down
13 changes: 7 additions & 6 deletions src/lib/components/blocks/dashboard/MyStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import BigNumber from "bignumber.js";
import ErgIcon from "@/lib/components/icons/ErgIcon";
import GauIcon from "@/lib/components/icons/GauIcon";
import GaucIcon from "@/lib/components/icons/GaucIcon";
import { protocolConfig } from "@/lib/config/protocol";

interface WalletStats {
ergBalance: string;
Expand Down Expand Up @@ -197,16 +198,16 @@ export function MyStats() {
case "GAU":
return {
icon: <GauIcon className="h-7 w-7" />,
name: "GAU",
symbol: "GAU",
fullName: "Gold Pegged",
name: protocolConfig.tokens.neutron.ticker,
symbol: protocolConfig.tokens.neutron.ticker,
fullName: protocolConfig.ui.labels.neutronSubtitle,
};
case "GAUC":
return {
icon: <GaucIcon className="h-7 w-7" />,
name: "GAUC",
symbol: "GAUC",
fullName: "Collateral",
name: protocolConfig.tokens.proton.ticker,
symbol: protocolConfig.tokens.proton.ticker,
fullName: protocolConfig.ui.labels.protonSubtitle,
};
}
};
Expand Down
49 changes: 21 additions & 28 deletions src/lib/components/blocks/home/Features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import GaucIcon from "@/lib/components/icons/GaucIcon";
import { useRef, forwardRef, useState, useEffect } from "react";
import { cn } from "@/lib/utils/utils";
import { motion } from "framer-motion";
import { protocolConfig } from "@/lib/config/protocol";

const Circle = forwardRef<HTMLDivElement, { className?: string; children?: React.ReactNode }>(({ className, children }, ref) => {
return (
Expand Down Expand Up @@ -177,49 +178,45 @@ export const Features = () => (
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.4, duration: 0.5 }}
>
Gluon Mechanics
{protocolConfig.ui.mechanics.overviewTitle}
</motion.h2>
<motion.p
className="z-20 max-w-lg text-left text-lg leading-relaxed tracking-tight text-muted-foreground"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.5, duration: 0.5 }}
>
Get exposure to Gold with GAU.
<br />
GAU is the stablecoin pegged to 1g of Gold.
<br />
<br />
Get leveraged volatility and yield with GAUC.
<br />
GAUC tokenizes the reserve surplus.
<br />
<br />
Both GAU and GAUC are fully backed by ERG.
{protocolConfig.ui.mechanics.overviewBody.map((line, idx) => (
<span key={idx}>
{line}
<br />
{idx === 1 || idx === 3 ? <br /> : null}
</span>
))}
</motion.p>
</div>
</div>
<div className="grid grid-cols-1 items-start gap-6 sm:grid-cols-3 lg:grid-cols-1 lg:pl-6">
{[
{
icon: Maximize2,
title: "Fission",
description: "Splits $ERG tokens into $GAU stable tokeons and $GAUC volatile tokeons",
title: protocolConfig.ui.mechanics.actions.fission.title,
description: protocolConfig.ui.mechanics.actions.fission.description,
},
{
icon: Minimize2,
title: "Fusion",
description: "Merges $GAU stable tokeons and $GAUC volatile tokeons into $ERG tokens",
title: protocolConfig.ui.mechanics.actions.fusion.title,
description: protocolConfig.ui.mechanics.actions.fusion.description,
},
{
icon: Repeat,
title: "Transmute to Gold",
description: "Transmutes $GAUC volatile tokeons into $GAU stable tokeons",
title: protocolConfig.ui.mechanics.actions.transmuteToPeg.title,
description: protocolConfig.ui.mechanics.actions.transmuteToPeg.description,
},
{
icon: Repeat,
title: "Transmute from Gold",
description: "Transmutes $GAU stable tokeons into $GAUC volatile tokeons",
title: protocolConfig.ui.mechanics.actions.transmuteFromPeg.title,
description: protocolConfig.ui.mechanics.actions.transmuteFromPeg.description,
},
].map((item, index) => (
<motion.div
Expand All @@ -245,17 +242,13 @@ export const Features = () => (
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.4, duration: 0.5 }}
>
{/* Fission: ERG -> GAU + GAUC */}
<TokenFlow title="Fission" fromTokens={["ERG"]} toTokens={["GAU", "GAUC"]} />
<TokenFlow title={protocolConfig.ui.mechanics.actions.fission.title} fromTokens={["ERG"]} toTokens={["GAU", "GAUC"]} />

{/* Fusion: GAU + GAUC -> ERG */}
<TokenFlow title="Fusion" fromTokens={["GAU", "GAUC"]} toTokens={["ERG"]} reverse={false} />
<TokenFlow title={protocolConfig.ui.mechanics.actions.fusion.title} fromTokens={["GAU", "GAUC"]} toTokens={["ERG"]} reverse={false} />

{/* Transmute To Gold: GAUC -> GAU */}
<TokenFlow title="Transmute To Gold" fromTokens={["GAUC"]} toTokens={["GAU"]} />
<TokenFlow title={protocolConfig.ui.mechanics.actions.transmuteToPeg.title} fromTokens={["GAUC"]} toTokens={["GAU"]} />

{/* Transmute From Gold: GAU -> GAUC */}
<TokenFlow title="Transmute From Gold" fromTokens={["GAU"]} toTokens={["GAUC"]} reverse={false} />
<TokenFlow title={protocolConfig.ui.mechanics.actions.transmuteFromPeg.title} fromTokens={["GAU"]} toTokens={["GAUC"]} reverse={false} />
</motion.div>
</CardSpotlight>
</motion.div>
Expand Down
6 changes: 4 additions & 2 deletions src/lib/components/blocks/home/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Button } from "@/lib/components/ui/button";
import { useRouter } from "next/navigation";
import { HeroText } from "../../ui/hero-text";
import { motion } from "framer-motion";
import { protocolConfig } from "@/lib/config/protocol";

export default function Hero() {
const router = useRouter();
Expand All @@ -21,8 +22,9 @@ export default function Hero() {

<motion.div className="mx-auto mt-5 max-w-3xl" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.4, duration: 0.6 }}>
<p className="text-xl text-muted-foreground">
Trade and transact with digital gold-pegged tokens. <br />
Secured by the Ergo blockchain and its decentralized gold price oracle.
{protocolConfig.ui.hero.tagline}
<br />
{protocolConfig.ui.hero.subTagline}
</p>
</motion.div>

Expand Down
3 changes: 2 additions & 1 deletion src/lib/components/layout/BottomNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { cn } from "@/lib/utils/utils";
import { useMediaQuery } from "usehooks-ts";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
import { protocolConfig } from "@/lib/config/protocol";

const socialLinks = [
{
Expand All @@ -20,7 +21,7 @@ const socialLinks = [
iconDark: "/logo/Discord-White.svg",
},
{
href: "https://t.me/GluonGold",
href: `https://t.me/${protocolConfig.ui.labels.telegramHandle}`,
label: "Telegram",
iconLight: "/logo/Telegram-Black.svg",
iconDark: "/logo/Telegram-White.svg",
Expand Down
12 changes: 7 additions & 5 deletions src/lib/components/layout/SEO.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Head from "next/head";
import { protocolConfig } from "@/lib/config/protocol";

interface SEOProps {
title?: string;
Expand All @@ -10,11 +11,12 @@ interface SEOProps {
}

export function SEO({
title = "Gluon Gold | Gold-Pegged Stablecoin on the Ergo Blockchain",
description = "Gluon Gold on Ergo is a fully autonomous stablecoin based on the novel Gluon Stablecoin Protocol, pegged to Gold, backed by the ERG cryptocurrency and running in a fully decentralized manner on the Ergo blockchain. Mint, swap and trade gold-pegged stable tokens or leveraged yield tokens according to your stability or volatility needs.",
keywords = "Blockchain, Cryptocurrency, Stablecoin, DeFi, Decentralized Finance, Digital Assets, Tokens, Gold, Gluon, Stability, GAU, CAUC, Gold-Pegged Stablecoin, Gold-Pegged Token, Crypto-Backed Stablecoin",
image = "/logo/gluon.png",
url = "https://www.gluon.gold/",
title = protocolConfig.seo.defaultTitle,
description = protocolConfig.seo.defaultDescription,
keywords = protocolConfig.seo.defaultKeywords,
image = protocolConfig.seo.defaultImage,
url = protocolConfig.seo.defaultUrl,

type = "website",
}: SEOProps) {
const siteTitle = title.includes("Gluon") ? title : `${title} | Gluon`;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/components/layout/TopNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { cn } from "@/lib/utils/utils";
import { useRouter } from "next/router";
import { WalletConnector } from "../blockchain/connector/WalletConnector";
import { useTheme } from "next-themes";
import { protocolConfig } from "@/lib/config/protocol";

const navItems = [
{ href: "/reactor", label: "Reactor" },
Expand Down Expand Up @@ -54,7 +55,7 @@ export function TopNavbar() {
<div className="flex items-center">
<Link href="/" className="flex items-center">
<Image src={theme === "dark" ? "/logo/gluon.png" : "/logo/gluon-light.png"} alt="Gluon Logo" width={28} height={28} priority />
{isDesktop && <p className="ml-2 font-sans text-2xl font-medium">GLUON GOLD</p>}
{isDesktop && <p className="ml-2 font-sans text-2xl font-medium">{protocolConfig.ui.labels.navbarTitle}</p>}
</Link>
</div>

Expand Down
6 changes: 5 additions & 1 deletion src/lib/components/ui/hero-text.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { useEffect, useMemo, useState } from "react";
import { motion } from "framer-motion";
import { protocolConfig } from "@/lib/config/protocol";

function HeroText() {
const [titleNumber, setTitleNumber] = useState(0);
const titles = useMemo(() => ["Decentralized", "Autonomous", "Permissionless", "Transparent", "Fully Crypto Backed", "Gold-Pegged"], []);
const titles = useMemo(
() => ["Decentralized", "Autonomous", "Permissionless", "Transparent", "Fully Crypto Backed", protocolConfig.peg.adjective],
[]
);

useEffect(() => {
const timeoutId = setTimeout(() => {
Expand Down
83 changes: 83 additions & 0 deletions src/lib/config/protocol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
export const protocolConfig = {
peg: {
asset: "Gold",
adjective: "gold-pegged",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
description: "digital gold-pegged tokens",
},
tokens: {
/**
* Neutron = stable token in the Gluon protocol.
* For the current deployment this corresponds to GAU.
*/
neutron: {
ticker: "GAU",
name: "Gluon Gold",
shortDescription: "Stable token pegged to 1g of Gold.",
},
/**
* Proton = volatile token in the Gluon protocol.
* For the current deployment this corresponds to GAUC.
*/
proton: {
ticker: "GAUC",
name: "Gluon Gold Certificate",
shortDescription: "Volatile token that tokenizes the reserve surplus.",
},
},
seo: {
defaultTitle: "Gluon | Gold Protocol on Ergo",
defaultDescription:
"Gluon is a decentralized finance protocol on Ergo blockchain that enables users to trade, swap, and manage gold-backed tokens.",
defaultKeywords: "Gluon, Ergo, DeFi, Blockchain, Cryptocurrency, Gold-backed tokens, GAU, GAUC, Digital Assets",
defaultUrl: "https://www.gluon.gold/",
defaultImage: "/logo/gluon.png",
},
ui: {
hero: {
tagline: "Trade and transact with digital gold-pegged tokens.",
subTagline: "Secured by the Ergo blockchain and its decentralized gold price oracle.",
},
labels: {
navbarTitle: "GLUON GOLD",
telegramHandle: "GluonGold",
goldPriceTitle: "1 kg of Gold",
goldPriceSubtitle: "Oracle Gold Price",
neutronSubtitle: "Gold Pegged Token",
protonSubtitle: "Leveraged Yield Token",
neutronSupplyLabel: "GAU Supply",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my other comment. Lines 47 adn 48 can be removed.

protonSupplyLabel: "GAUC Supply",
},
mechanics: {
overviewTitle: "Gluon Mechanics",
overviewBody: [
"Get exposure to Gold with GAU.",
"GAU is the stablecoin pegged to 1g of Gold.",
"Get leveraged volatility and yield with GAUC.",
"GAUC tokenizes the reserve surplus.",
"Both GAU and GAUC are fully backed by ERG.",
],
actions: {
fission: {
title: "Fission",
description: "Splits $ERG tokens into $GAU stable tokens and $GAUC volatile tokens.",
},
fusion: {
title: "Fusion",
description: "Merges $GAU stable tokens and $GAUC volatile tokens into $ERG tokens.",
},
transmuteToPeg: {
title: "Transmute To Gold",
description: "Transmutes $GAUC volatile tokens into $GAU stable tokens.",
},
transmuteFromPeg: {
title: "Transmute From Gold",
description: "Transmutes $GAU stable tokens into $GAUC volatile tokens.",
},
},
},
},
} as const;

export type ProtocolConfig = typeof protocolConfig;