Skip to content
Open
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
2 changes: 1 addition & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const newsreader = Newsreader({
});

export const metadata: Metadata = {
title: "LBP Simulator | Balancer",
title: "Liquidity Bootstrapping Pools | Balancer",
description: "Simulate a LBP sale to understand price discovery.",
icons: {
icon: [
Expand Down
2 changes: 1 addition & 1 deletion components/layout/CommomQuestions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const QUESTIONS = [
"Yes. LBPs offer the flexibility to implement structured fixed price strategies over time, enabling teams to launch tokens in a more efficient and controlled manner.",
},
{
question: "I wanted to deploy a LBP on a EVM with no support. How can I proceed?",
question: "The chain I want to deploy on isn't supported yet. What are my options?",
answer:
"Contact our product and support team to learn more about new integrations and other issues.",
},
Expand Down
4 changes: 2 additions & 2 deletions components/layout/Insights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ const INSIGHTS = [
{
subtitle: "Invert the Mechanics",
paragraph:
"Reverse the standard logic by starting with high collateral weight (e.g., 90% DAI) to generate natural upward price pressure.",
"Start with high collateral weight (e.g., 90% DAI) to create natural upward price pressure as weights shift.",
Icon: RefreshCcw,
},
{
subtitle: "Passive Accumulation",
paragraph:
"Operate as an automated limit order where arbitrageurs are incentivized to fill your treasury organically as weights adjust.",
"Function as an automated limit order: arbitrageurs fill your treasury with collateral as pool weights shift, requiring no active management.",
Icon: Magnet,
},
{
Expand Down
12 changes: 6 additions & 6 deletions components/layout/KPI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,35 +79,35 @@ export function KPI() {
<div className="grid gap-12 rounded-[28px] bg-background/80 px-6 py-8 md:grid-cols-3 md:px-10 items-center justify-center">
<div className="flex flex-col items-center text-center gap-2">
<div className="text-sm uppercase tracking-[0.2em] text-muted-foreground">
Historical amount raised
Total Raised
</div>
<div className="text-4xl md:text-5xl font-semibold text-[#E6C8A3]">
{formatCurrency(raised)}
</div>
<div className="text-sm text-muted-foreground">
Liquidity bootstrapped through on-chain auctions.
Bootstrapped through on-chain auctions across all LBPs.
</div>
</div>
<div className="flex flex-col items-center text-center gap-2">
<div className="text-sm uppercase tracking-[0.2em] text-muted-foreground">
LBP pools created
LBPs Launched
</div>
<div className="text-4xl md:text-5xl font-semibold text-[#E6C8A3]">
{formatCount(pools)}
</div>
<div className="text-sm text-muted-foreground">
Verified launches across ecosystems and communities.
Completed launches across ecosystems and communities.
</div>
</div>
<div className="flex flex-col items-center text-center gap-2">
<div className="text-sm uppercase tracking-[0.2em] text-muted-foreground">
Single participants
Unique participants
</div>
<div className="text-4xl md:text-5xl font-semibold text-[#E6C8A3]">
{formatCount(participants)}
</div>
<div className="text-sm text-muted-foreground">
Unique participants across LBP launches.
Individual wallets that participated in LBP launches.
</div>
</div>
</div>
Expand Down
43 changes: 34 additions & 9 deletions components/layout/Live.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ export function Live() {
});

return points
.map((p, idx) => `${idx === 0 ? "M" : "L"} ${p.x.toFixed(2)} ${p.y.toFixed(2)}`)
.map(
(p, idx) =>
`${idx === 0 ? "M" : "L"} ${p.x.toFixed(2)} ${p.y.toFixed(2)}`,
)
.join(" ");
})();

Expand All @@ -51,11 +54,12 @@ export function Live() {
Live on Balancer
</p>
<h2 className="text-3xl md:text-4xl font-semibold tracking-tight">
Launch, divest, and buy back tokens, securely on-chain.
Launch, divest, and buy back tokens, all transparent.
</h2>
<p className="text-base md:text-lg text-[#171717]/70 dark:text-white/70 max-w-lg">
Launch with confidence using programmable LBP mechanics built for
fair price discovery and transparent allocation.
Built for fair price discovery and minimal market impact, whether
you're launching a token, executing a buyback, or divesting a
treasury position.
</p>
<div className="mt-4">
<Link href="/lbp-simulator">
Expand All @@ -80,16 +84,35 @@ export function Live() {
<div className="mt-4 flex-1 min-h-0 rounded-2xl border border-[#171717]/10 bg-white/40 p-3 dark:border-white/10 dark:bg-black/20">
<svg viewBox="0 0 100 60" className="h-full w-full">
<defs>
<linearGradient id="lbpStroke" x1="0%" y1="0%" x2="100%" y2="0%">
<linearGradient
id="lbpStroke"
x1="0%"
y1="0%"
x2="100%"
y2="0%"
>
<stop offset="0%" stopColor="#E6C8A3" stopOpacity="1" />
<stop offset="55%" stopColor="#E1B782" stopOpacity="1" />
<stop offset="100%" stopColor="#EADBC8" stopOpacity="1" />
<stop
offset="55%"
stopColor="#E1B782"
stopOpacity="1"
/>
<stop
offset="100%"
stopColor="#EADBC8"
stopOpacity="1"
/>
</linearGradient>
<clipPath id="elapsedClip">
<rect x="0" y="0" width={100 * progress} height="60" />
</clipPath>
<clipPath id="remainingClip">
<rect x={100 * progress} y="0" width={100 - 100 * progress} height="60" />
<rect
x={100 * progress}
y="0"
width={100 - 100 * progress}
height="60"
/>
</clipPath>
</defs>

Expand Down Expand Up @@ -138,7 +161,9 @@ export function Live() {
</div>
<div className="mt-4 flex items-center justify-between text-xs text-[#171717]/60 dark:text-white/60">
<span>Token price</span>
<span className="text-[#171717] dark:text-white">$1.50 USDC</span>
<span className="text-[#171717] dark:text-white">
$1.50 USDC
</span>
</div>
</div>
</div>
Expand Down
77 changes: 39 additions & 38 deletions components/layout/UseCases.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const SLIDES = [
slug: "buy-back",
title: "Buy Back",
description:
"Programmatic buy-backs with transparent price discovery and predictable liquidity.",
"Automated buybacks with transparent price discovery and controlled market impact.",
benefits: ["Market Stability", "Fair Pricing", "Transparent Execution"],
Icon: RefreshCcw,
caseStudy: {
Expand Down Expand Up @@ -49,7 +49,7 @@ const SLIDES = [
slug: "token-launches",
title: "Token Launches",
description:
"Fair price discovery for new tokens. Let the market find the right price through an LBP.",
"Let the market set the price. Fairly, transparently, and without bot interference.",
benefits: ["No Bot Sniping", "Deep Initial Liquidity", "Community Driven"],
Icon: Rocket,
caseStudy: {
Expand Down Expand Up @@ -81,7 +81,7 @@ const SLIDES = [
slug: "divestment",
title: "Investment & Divestment",
description:
"Gradual, market-driven divestment with configurable weights and transparent execution.",
"Gradually enter or exit positions with configurable parameters and minimal price impact.",
benefits: ["Minimal Price Impact", "Controlled Flow", "Verified Discovery"],
Icon: TrendingDown,
caseStudy: {
Expand Down Expand Up @@ -167,44 +167,46 @@ const UseCases = ({ activeIndex, onSelect, openCaseSlug }: UseCasesProps) => {
return url.toString();
}, []);

const animateDeck = useCallback((currentActiveIndex: number) => {
SLIDES.forEach((_, slideIndex) => {
const wrapper = wrapperRefs.current[slideIndex];
const card = cardRefs.current[slideIndex];
if (!wrapper || !card) return;
const animateDeck = useCallback(
(currentActiveIndex: number) => {
SLIDES.forEach((_, slideIndex) => {
const wrapper = wrapperRefs.current[slideIndex];
const card = cardRefs.current[slideIndex];
if (!wrapper || !card) return;

const position = getVisualPosition(slideIndex, currentActiveIndex);
const layout = CARD_LAYOUT[position];
const isFocused = position === 0;
const scale = isFocused ? 1.1 : 1;
const mobileOffsetY =
position === 0 ? -8 : position === 1 ? -28 : -48;
const translateX = isMobile ? 0 : layout.offsetX;
const translateY = isMobile ? mobileOffsetY : isFocused ? -18 : 0;
const rotate = isMobile ? 0 : layout.rotate;
const deckScale = isMobile ? 1 : scale;
const position = getVisualPosition(slideIndex, currentActiveIndex);
const layout = CARD_LAYOUT[position];
const isFocused = position === 0;
const scale = isFocused ? 1.1 : 1;
const mobileOffsetY = position === 0 ? -8 : position === 1 ? -28 : -48;
const translateX = isMobile ? 0 : layout.offsetX;
const translateY = isMobile ? mobileOffsetY : isFocused ? -18 : 0;
const rotate = isMobile ? 0 : layout.rotate;
const deckScale = isMobile ? 1 : scale;

animate(wrapper, {
translateX,
translateY,
rotate,
scale: deckScale,
duration: 420,
easing: "easeOutQuad",
});
animate(wrapper, {
translateX,
translateY,
rotate,
scale: deckScale,
duration: 420,
easing: "easeOutQuad",
});

// Set z-index immediately to prevent overlap issues during transition
wrapper.style.zIndex = (isFocused ? 40 : layout.baseZ).toString();
// Set z-index immediately to prevent overlap issues during transition
wrapper.style.zIndex = (isFocused ? 40 : layout.baseZ).toString();

animate(card, {
boxShadow: isFocused
? "0 24px 60px rgba(230, 200, 163, 0.35)"
: "0 18px 35px rgba(15, 23, 42, 0.2)",
duration: 420,
easing: "easeOutQuad",
animate(card, {
boxShadow: isFocused
? "0 24px 60px rgba(230, 200, 163, 0.35)"
: "0 18px 35px rgba(15, 23, 42, 0.2)",
duration: 420,
easing: "easeOutQuad",
});
});
});
}, [isMobile]);
},
[isMobile],
);

useEffect(() => {
// Initialize styles for all slides
Expand All @@ -216,8 +218,7 @@ const UseCases = ({ activeIndex, onSelect, openCaseSlug }: UseCasesProps) => {
const position = getVisualPosition(slideIndex, activeIndex);
const layout = CARD_LAYOUT[position];
const isFocused = position === 0;
const mobileOffsetY =
position === 0 ? -8 : position === 1 ? -28 : -48;
const mobileOffsetY = position === 0 ? -8 : position === 1 ? -28 : -48;
const translateX = isMobile ? 0 : layout.offsetX;
const translateY = isMobile ? mobileOffsetY : isFocused ? -18 : 0;
const rotate = isMobile ? 0 : layout.rotate;
Expand Down
4 changes: 2 additions & 2 deletions components/lbp-simulator/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function Hero() {
ref={subtitleRef}
className="text-lg md:text-xl text-muted-foreground max-w-2xl mb-8"
>
Programmable, on-chain price discovery for fair token launches, and more.
Programmable price discovery for token launches, buybacks, and treasury diversification. All on-chain.
</p>
<div className="flex flex-col sm:flex-row gap-4">
<Link
Expand Down Expand Up @@ -73,7 +73,7 @@ export function Hero() {
rel="noopener noreferrer"
onClick={trackReportDownload}
>
Get the 961 LBPs Analysis
Read the 961 LBPs Analysis
</a>
</Button>
</div>
Expand Down