Skip to content
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
9 changes: 9 additions & 0 deletions app/api/dao-overview/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ async function readLightchainOverview(pub: Pub) {
rawSupplyWei != null && votableWei != null && (rawSupplyWei as bigint) > (votableWei as bigint)
? (rawSupplyWei as bigint) - (votableWei as bigint)
: null;
// Castable = votable minus LCAI held by protocol contracts that can't vote
// (Treasury + FeePool). votes == balance on the precompile, so their balances
// are their (non-castable) voting power.
const nonCastableWei = treasuryWei + feePoolWei;
const castableWei =
votableWei != null && (votableWei as bigint) > nonCastableWei ? (votableWei as bigint) - nonCastableWei : null;
return {
treasuryWei: treasuryWei.toString(),
feePoolWei: feePoolWei.toString(),
Expand All @@ -164,6 +170,9 @@ async function readLightchainOverview(pub: Pub) {
// The actual quorum threshold + the staked-excluded base it applies to.
quorumWei: quorumWei != null ? (quorumWei as bigint).toString() : null,
votableSupplyWei: votableWei != null ? (votableWei as bigint).toString() : null,
// Castable = votable minus the non-votable contract holdings (Treasury/FeePool).
castableSupplyWei: castableWei != null ? castableWei.toString() : null,
nonCastableWei: nonCastableWei.toString(),
rawSupplyWei: rawSupplyWei != null ? (rawSupplyWei as bigint).toString() : null,
stakeExcludedWei: stakeExcludedWei != null ? stakeExcludedWei.toString() : null,
stakeExcludedFromQuorum: true as boolean,
Expand Down
19 changes: 15 additions & 4 deletions app/build/dao/treasury-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,37 @@ interface Overview {
rawSupplyWei?: string | null;
stakeExcludedWei?: string | null;
holderCount?: number | null;
// Votable minus non-votable contract holdings (Treasury/FeePool) = castable.
castableSupplyWei?: string | null;
nonCastableWei?: string | null;
schedule?: Schedule;
error?: string;
}

const VOTE_SYMBOL: Record<DaoChain, string> = { ethereum: "LCAIB", lightchain: "LCAI" };

/** LightChain voting-power summary: votable sum, accounts, staked-excluded. */
/** LightChain voting-power summary: castable vs votable, staked-excluded, accounts. */
function VotingPowerLine({ chain, data }: { chain: DaoChain; data: Overview }) {
if (!data.votableSupplyWei) return null;
const sym = VOTE_SYMBOL[chain];
const votable = formatLcaiWei(BigInt(data.votableSupplyWei), 0);
// Castable = votable minus the Treasury/FeePool (contracts that can't vote).
const castable = data.castableSupplyWei ? formatLcaiWei(BigInt(data.castableSupplyWei), 0) : null;
const nonCastable = data.nonCastableWei && BigInt(data.nonCastableWei) > 0n ? formatLcaiWei(BigInt(data.nonCastableWei), 0) : null;
const accounts = data.holderCount != null ? `~${data.holderCount.toLocaleString()} accounts` : null;
const excluded = data.stakeExcludedWei && BigInt(data.stakeExcludedWei) > 0n
? `${formatLcaiWei(BigInt(data.stakeExcludedWei), 0)} ${sym} staked (excluded from quorum)`
? `${formatLcaiWei(BigInt(data.stakeExcludedWei), 0)} ${sym} staked (excluded)`
: null;
return (
<p className="px-1 text-[11px] leading-relaxed text-content-soft">
<span className="font-medium text-content-default">Voting power:</span> {votable} {sym} votable
{accounts ? <> across <span className="text-content-default">{accounts}</span></> : null}
<span className="font-medium text-content-default">Voting power:</span>{" "}
{castable ? (
<><span className="text-content-default">{castable} {sym} castable</span> of {votable} votable{nonCastable ? <> ({nonCastable} in the treasury, non-votable)</> : null}</>
) : (
<>{votable} {sym} votable</>
)}
{excluded ? <> · {excluded}</> : null}
{accounts ? <> · {accounts}</> : null}
</p>
);
}
Expand Down
Loading