0xacfba7ce…4082·#25,798,770·view on Etherscan
ecoration:none;transition:border-color .15s}
.marq-i:hover{border-color:var(--pri)}
.marq-i b{font-weight:600}
.marq-i span{color:var(--mut);font-variant-numeric:tabular-nums}
/* -------------------------------------------------------------- activity */
.acty{display:flex;flex-direction:column}
.act{display:flex;align-items:center;gap:.85rem;padding:.8rem 0;border-bottom:1px solid var(--line)}
.act:last-child{border-bottom:0}
.act .ico{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;
flex:0 0 auto;border-radius:.6rem}
.act .who{min-width:0;flex:1}
.act .who b{display:block;font-size:.875rem;font-weight:600}
.act .who span{display:block;font-size:.75rem;color:var(--mut);overflow:hidden;
text-overflow:ellipsis;white-space:nowrap}
.act .amt{text-align:right;flex:0 0 auto}
.act .amt b{display:block;font-size:.8125rem;font-weight:600;font-variant-numeric:tabular-nums}
.act .amt span{display:block;font-size:.75rem;color:var(--mut)}
.act a{color:var(--mut);flex:0 0 auto;display:inline-flex;align-items:center;
justify-content:center;width:1.75rem;height:1.75rem;margin-right:-.35rem}
.act a:hover{color:var(--pri)}
.split-2{display:grid;gap:1.25rem;margin-top:1.75rem}
@media(min-width:1024px){.split-2{grid-template-columns:2fr 1fr;gap:1.5rem;align-items:start}}
.stale{font-size:.75rem;color:var(--mut)}
/* ---------------------------------------------------------------- modal */
.modal{position:fixed;inset:0;z-index:40;background:#0000008c;display:flex;
align-items:center;justify-content:center;padding:1rem}
.modal .card{width:100%;max-width:22rem;padding:1.5rem}
.wrow{display:flex;align-items:center;gap:.75rem;width:100%;padding:.75rem .85rem;margin:.35rem 0;
border:1px solid var(--line);border-radius:var(--r);background:transparent;color:var(--fg);
font:inherit;font-weight:600;cursor:pointer;transition:background .15s}
.wrow:hover{background:var(--sunk)}
.wrow img{width:1.5rem;height:1.5rem;border-radius:.35rem}
.wrow .wki{width:1.5rem;height:1.5rem;flex:0 0 auto;line-height:0}
.wrow .wki svg{width:100%;height:100%}
#wcQR svg{width:100%;height:auto;background:#fff;border-radius:.6rem;display:block}
</style>
<header class="bar"><div class="wrap">
<a class="brand" href="#top">
<svg viewBox="0 0 24 24" aria-hidden="true"><g fill="currentColor"><path d="M20.5 2.5C21.6 11 17.5 18 11 21.5 10 13 14 6 20.5 2.5Z"/><path d="M2.2 8.5C7.6 9.8 10.6 14.4 10.9 21.4 5.6 20.1 2.5 15.5 2.2 8.5Z"/></g></svg>
<span>Firstfruits</span>
</a>
<nav class="nav">
<a href="#vault">Dashboard</a>
<a href="#causes">Causes</a>
<a href="#how">How it works</a>
</nav>
<div class="trail">
<button class="chip" id="connect"><span class="bal" id="chipBal"></span><b id="chipAddr">Connect Wallet</b></button>
<button class="icon-btn" id="node" title="Read node" aria-label="Read node"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c2.5 2.7 2.5 15.3 0 18M12 3c-2.5 2.7-2.5 15.3 0 18"/></svg></button>
<button class="icon-btn" id="theme" title="Switch theme" aria-label="Switch theme"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg></button>
</div>
</div></header>
<main id="top">
<!-- ------------------------------------------------------------------ HERO -->
<div class="hero"><div class="wrap"><div class="hero-grid">
<div>
<span class="badge">
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160"><defs><style> .rp-c1 { mask: url(#rp-mask); } .rp-c2 { fill: url(#rp-linear-gradient-3); } .rp-c3 { fill: url(#rp-linear-gradient-2); } .rp-c4 { fill: url(#rp-linear-gradient); } .rp-c5 { fill: #fff; } </style><linearGradient id="rp-linear-gradient" x1="1023.49" y1="-10427.81" x2="1134.36" y2="-10538.68" gradientTransform="translate(1158.93 -10403.25) rotate(-180)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f2681d"/><stop offset="1" stop-color="#f89863"/></linearGradient><linearGradient id="rp-linear-gradient-2" x1="-1320.91" y1="-116.53" x2="-1180.26" y2="-116.53" gradientTransform="translate(1046.7 -721.9) rotate(-45)" xlink:href="#linear-gradient"/><linearGradient id="rp-linear-gradient-3" x1="-13.5" y1="174.98" x2="163.35" y2="-1.86" gradientTransform="translate(83.15 -27.63) rotate(45)" gradientUnits="userSpaceOnUse"><stop offset=".11" stop-color="#000"/><stop offset=".13" stop-color="#050505"/><stop offset=".15" stop-color="#131313"/><stop offset=".18" stop-color="#2c2c2c"/><stop offset=".21" stop-color="#4e4e4e"/><stop offset=".24" stop-color="#7a7a7a"/><stop offset=".27" stop-color="#afafaf"/><stop offset=".3" stop-color="#ededed"/><stop offset=".31" stop-color="#fff"/><stop offset=".41" stop-color="#fff"/><stop offset=".75" stop-color="#fff"/><stop offset=".81" stop-color="#fff"/><stop offset=".82" stop-color="#f7f7f7"/><stop offset=".83" stop-color="#e3e3e3"/><stop offset=".85" stop-color="#c1c1c1"/><stop offset=".87" stop-color="#939393"/><stop offset=".88" stop-color="#585858"/><stop offset=".9" stop-color="#101010"/><stop offset=".91" stop-color="#000"/></linearGradient><mask id="rp-mask" x="-220.31" y="-220.31" width="600.61" height="600.61" maskUnits="userSpaceOnUse"><g><rect class="rp-c2" x="-50.12" y="31.18" width="250.09" height="110.77" transform="translate(-39.26 78.33) rotate(-45)"/><g><path class="rp-c5" d="M80,265.31c-102.18,0-185.31-83.13-185.31-185.31S-22.18-105.31,80-105.31,265.31-22.18,265.31,80s-83.13,185.31-185.31,185.31Z"/><path d="M80,9.69c38.83,0,70.31,31.48,70.31,70.31s-31.48,70.31-70.31,70.31S9.69,118.83,9.69,80,41.17,9.69,80,9.69M80-220.31c-40.44,0-79.79,7.97-116.96,23.69-35.79,15.14-67.88,36.76-95.39,64.26-27.51,27.51-49.13,59.6-64.26,95.39-15.72,37.17-23.69,76.52-23.69,116.96s7.97,79.79,23.69,116.96c15.14,35.79,36.76,67.88,64.26,95.39,27.51,27.51,59.6,49.13,95.39,64.26,37.17,15.72,76.52,23.69,116.96,23.69s79.79-7.97,116.96-23.69c35.79-15.14,67.88-36.76,95.39-64.26s49.13-59.6,64.26-95.39c15.72-37.17,23.69-76.52,23.69-116.96s-7.97-79.79-23.69-116.96c-15.14-35.79-36.76-67.88-64.26-95.39-27.51-27.51-59.6-49.13-95.39-64.26-37.17-15.72-76.52-23.69-116.96-23.69h0Z"/></g></g></mask></defs><g id="rp-Logomark"><g id="rp-Logo_BG"><circle class="rp-c4" cx="80" cy="80" r="78.4"/><path id="rp-bg" class="rp-c3" d="M80,9.67c-38.84,0-70.33,31.48-70.33,70.33,0,35.42,26.19,64.73,60.28,69.6,1.32.2,2.66.35,4.02.46,1.33.12,2.67.19,4.02.23.67.02,1.34.03,2.01.03s1.34,0,2.01-.03c1.35-.03,2.69-.11,4.02-.23,1.35-.11,2.69-.26,4.02-.45,34.08-4.87,60.28-34.18,60.28-69.61,0-38.85-31.49-70.33-70.33-70.33Z"/></g><g class="rp-c1"><path id="rp-Logo_Rocket" class="rp-c5" d="M59.68,108.85l-24.96,24.96c1.03.88,2.09,1.72,3.16,2.52l24.64-24.64-2.84-2.84ZM48.31,97.48l-24.63,24.63c.79,1.07,1.64,2.13,2.52,3.17l24.96-24.95-2.84-2.84ZM59.59,97.57l-30.72,30.72c.46.49.93.97,1.4,1.44s.96.94,1.44,1.4l30.72-30.72-2.84-2.84ZM115.23,44.78c-4.53-1.24-10.26-.38-16.2,2.3-5.25,2.36-10.66,6.14-15.54,11.15-2.2,2.25-4.15,4.61-5.83,7l-9.59,1.17-10.69,13.83,10.05,2.6c-.57,2.29-.84,4.5-.8,6.55l-2.53,3.29,3.25,3.25,3.28-2.52c2.06.04,4.26-.23,6.55-.8l2.6,10.05,13.81-10.68,1.16-9.6c2.4-1.69,4.77-3.64,7.03-5.85,5.01-4.89,8.8-10.31,11.16-15.57,2.67-5.93,3.52-11.66,2.29-16.18ZM96.09,72.78c-3.02,3.02-7.45,3.49-9.9,1.04-2.44-2.44-1.98-6.88,1.04-9.9,3.01-3.01,7.45-3.48,9.89-1.03,2.44,2.44,1.98,6.88-1.03,9.89Z"/></g></g></svg>
<span style="font-size:1.0625rem">Built with rETH</span>
</span>
<h1 class="big">Stake ETH.<br><span class="accent">Give what grows.</span></h1>
<p class="lead">Firstfruits is a charitable-giving vault. Stake ETH, earn staking yield via rETH, and the yield is routed to causes you care about. Your principal stays yours and is withdrawable anytime.</p>
<div class="ctas">
<a href="#vault" class="btn btn-lg">Stake ETH Now →</a>
<a href="#causes" class="btn btn-lg">Explore Causes</a>
</div>
<div class="feats">
<div class="feat"><span class="ico i-blue"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/></svg></span>
<div><p>Principal always yours</p><p>Withdraw your ETH anytime.</p></div></div>
<div class="feat"><span class="ico i-green"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.5-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7Z"/></svg></span>
<div><p>Powered by rETH</p><p>Secure liquid staking.</p></div></div>
<div class="feat"><span class="ico i-amber"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/></svg></span>
<div><p>Give automatically</p><p>Yield routed based on your splits.</p></div></div>
</div>
</div>
<div class="card ov">
<div class="ov-hd"><h2>Vault Overview</h2><span class="mut" style="font-size:.75rem" id="blockAt"></span></div>
<div class="tvl">
<div style="display:flex;justify-content:space-between;align-items:baseline;gap:.75rem">
<p class="mut" style="font-size:.875rem">Total Value Locked</p>
<span class="delta hide" id="sDelta"></span>
</div>
<div class="big"><b id="sTvl">…</b><span class="sym">Ξ</span><span class="usd" id="sTvlUsd"></span></div>
<div id="readPick" class="hide">
<p class="hint" style="margin-top:.75rem">No wallet found. This page reads Ethereum
directly — pick a node to read from, or set your own with the globe icon.
Nothing is contacted until you choose. A read node sees your IP address and
what you look up; it never sees a key, and nothing you sign passes through it.</p>
<div class="acts" id="readOpts"></div>
</div>
<svg class="spark hide" id="spark" viewBox="0 0 300 80" preserveAspectRatio="none" aria-hidden="true">
<defs><linearGradient id="sparkfill" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="currentColor" stop-opacity=".28"/>
<stop offset="100%" stop-color="currentColor" stop-opacity="0"/>
</linearGradient></defs>
<path class="fl" id="sparkFill" d=""/><path class="ln" id="sparkLine" d=""/>
</svg>
</div>
<div class="tiles">
<div class="tile"><span>Total Causes</span><b id="sCauses">…</b></div>
<div class="tile"><span>Total Patrons</span><b id="sPatrons">…</b></div>
<div class="tile"><span>Total Yield Donated</span><b id="sGiven">…<span class="usd" id="sGivenUsd"></span></b></div>
<div class="tile"><span>Current rETH APY</span><b id="sApy">…</b></div>
</div>
<a href="#vault" class="btn btn-block btn-lg" style="margin-top:1.5rem">Manage Vault</a>
</div>
</div></div></div>
<!-- --------------------------------------------------------------- MARQUEE -->
<div class="marq"><div class="marq-in" id="marq"></div></div>
<!-- ----------------------------------------------------------- MANAGE VAULT -->
<section id="vault"><div class="wrap">
<h2 class="sec-h">Manage Vault</h2>
<p class="sec-sub">Reads and writes the vault contract directly, from your own wallet.</p>
<div class="manage">
<div class="card pane">
<div class="tabs">
<button id="tGive" class="on">Stake</button>
<button id="tWd">Withdraw</button>
<button id="tNew">New cause</button>
</div>
<div id="pGive">
<div class="field">
<div class="field-hd"><span class="lbl">Stake</span><span id="balLbl"></span></div>
<div class="field-row">
<input id="amt" type="text" inputmode="decimal" placeholder="0" autocomplete="off">
<select id="asset"><option value="eth">ETH</option><option value="reth">rETH</option></select>
<button class="btn btn-sm" id="max">MAX</button>
</div>
<p class="hint" id="amtNote"></p>
</div>
<div class="field">
<div class="field-hd"><span class="lbl">Designate the yield</span><span id="bpsLeft"></span></div>
<div id="splits"></div>
<div class="bar-track"><i id="bpsBar" style="width:0"></i></div>
<div class="field-row"><button class="btn btn-sm" id="addSplit">+ Cause</button>
<span class="hint" id="splitNote" style="margin:0"></span></div>
</div>
<button class="btn btn-pri btn-block btn-lg" id="doGive" style="margin-top:1rem">Connect wallet</button>
<p class="hint">Your principal stays withdrawable. Only the rETH appreciation above your principal is routed to the causes you name; anything left undesignated accrues to your bank.</p>
</div>
<div id="pWd" class="hide">
<div class="field">
<div class="field-hd"><span class="lbl">Withdraw principal</span><span id="wMax"></span></div>
<div class="field-row">
<input id="wAmt" type="text" inputmode="decimal" placeholder="0" autocomplete="off">
<select id="wAsset"><option value="eth">as ETH</option><option value="reth">as rETH</option></select>
<button class="btn btn-sm" id="wMaxBtn">MAX</button>
</div>
</div>
<button class="btn btn-pri btn-block btn-lg" id="doWithdraw" style="margin-top:1rem">Withdraw</button>
<p class="hint">Withdrawing settles your pending yield first, so your causes are paid before your principal leaves. MAX asks the contract for its own maximum rather than the number shown, so a harvest landing in between cannot make it stale.</p>
</div>
<div id="pNew" class="hide">
<input class="tin" id="czName" placeholder="Name" maxlength="120" autocomplete="off">
<input class="tin" id="czRecip" placeholder="Recipient — 0x address, or a .wei / .gwei / .eth name" style="margin-top:.6rem" autocomplete="off">
<input class="tin" id="czOwner" placeholder="Owner — address or name. Blank = you" style="margin-top:.6rem" autocomplete="off">
<p class="hint" id="czResolved"></p>
<button class="btn btn-pri btn-block btn-lg" id="doCreate" style="margin-top:1rem">Create cause</button>
<p class="hint">Causes are permissionless: anyone may create one, and the name is fixed at creation. The owner manages the recipient and the active flag; claimed yield only ever goes to the recipient.</p>
</div>
<p id="stat"></p>
</div>
<div class="card pane">
<div class="ov-hd" style="padding-bottom:1rem;margin-bottom:.5rem"><h2>Your Position</h2></div>
<div id="posBody">
<div class="rowline"><span>Withdrawable principal</span><b id="pPrincipal">—</b></div>
<div class="rowline"><span>rETH held for you</span><b id="pReth">—</b></div>
<div class="rowline"><span>Pending yield</span><b id="pPending">—</b></div>
<div class="rowline"><span>Banked, undesignated</span><b id="pBank">—</b></div>
<div class="rowline"><span>Your designation</span><b id="curSplitSum">—</b></div>
<p class="hint" id="curSplits"></p>
<div class="acts">
<button class="btn btn-sm" id="doHarvest">Harvest</button>
<button class="btn btn-sm" id="doBank">Bank → ETH</button>
<button class="btn btn-sm" id="doBankR">Bank → rETH</button>
</div>
<p class="hint">Harvest settles yield accrued so far and routes it by your designation. It is permissionless — anyone may harvest for anyone, and it pays the same causes either way.</p>
</div>
<p class="pos-empty" id="posEmpty">Connect a wallet to see your position.</p>
</div>
</div>
</div></section>
<!-- ------------------------------------------------- HOW IT WORKS + ACTIVITY -->
<section><div class="wrap"><div class="split-2">
<div class="card pane" id="how">
<h2 class="sec-h">How Firstfruits Works</h2>
<div class="steps">
<div class="step"><span class="ico"><svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3h12l4 6-10 12L2 9Z"/><path d="M11 3 8 9l4 12 4-12-3-6"/><path d="M2 9h20"/></svg></span>
<div><p>1. Deposit</p><p>Deposit ETH or rETH into the vault.</p></div></div>
<div class="arrow"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m13 6 6 6-6 6"/></svg></div>
<div class="step"><span class="ico"><svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.5-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7Z"/></svg></span>
<div><p>2. Earn</p><p>ETH is staked, which returns rETH to the vault.</p></div></div>
<div class="arrow"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m13 6 6 6-6 6"/></svg></div>
<div class="step"><span class="ico"><svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg></span>
<div><p>3. Yield</p><p>rETH appreciates over time, generating staking yield.</p></div></div>
<div class="arrow"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m13 6 6 6-6 6"/></svg></div>
<div class="step"><span class="ico"><svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/></svg></span>
<div><p>4. Give</p><p>Yield is routed t