Documentation

Gavel Docs

How the on-chain shareholder-governance launchpad works, end to end. Skim the overview if you're new, or jump straight to the SDK if you're wiring it into a client.

What is Gavel?

Gavel is a Solana token launchpad with on-chain governance baked in. Every launch requires the creator to post a SOL deposit (the stake) and surrender mint and freeze authorities to a governance PDA. Holders accumulate time-weighted voting power as they hold, and can vote to remove the creator and redistribute the stake to themselves prorata.

The thesis: every memecoin launch already has a board of stakeholders — the holders. We just give them the seats, the gavel, and the power to fire the chair.

Why time-weighted voting?

Plain one-token-one-vote is broken on a launchpad. Anyone can buy a supermajority right before a fire vote, drain the stake, and dump. Time-weighted voting fixes this by making governance influence a function of how long you've been holding, not just how much you bought five minutes ago.

tsweight = balance × min(now − weighted_entry_ts, holding_cap)
  • Whales who buy seconds before voting have near-zero weight.
  • Holders who've held for the cap period vote at full strength.
  • The cap (default 90 days) prevents permanent oligarchies from forming.

How it works

  1. Launch. Creator posts a tiered stake. Mint and freeze authorities transfer to a governance PDA. 30% of stake is locked, 70% vests linearly over 90 days.
  2. Trade. Holders buy and sell along a constant-product bonding curve. Every swap splits a fee between the platform treasury and the creator's accrued fees.
  3. Propose. Holders with at least 0.5% supply and 7+ days of holding can post a proposal: fire the dev, replace the dev, or run a non-binding poll.
  4. Vote. 48-hour voting window. Each voter's weight equals balance × capped holding seconds. A 20% supply-participation quorum is required.
  5. Execute. Anyone can call execute after the deadline. If FireDev passes, the remaining stake plus accrued fees move into a claim pool. Voters call claim_distribution to withdraw their prorata share.

Tier system

Stake size is a public signal. Higher tiers cost more but offer a better revenue share and visible trust badges across the platform.

TierStakeLocked / VestingDev fee sharePlacement
Bronze1 SOL30 / 700.50%Standard
Silver10 SOL30 / 700.80%Silver badge
Gold50 SOL30 / 701.00%Gold badge + ranking boost
Diamond200 SOL30 / 701.20%Diamond badge + homepage feature

Distribution math

When a FireDev passes, the dev stake (locked + unvested vesting) and any accrued dev fees move into the claim pool. Each voter who participated can claim a share weighted by their raw token balance at vote time:

tsshare = pool_lamports × voter_balance / total_voted_supply
Why raw balance, not weighted balance?
Distribution rewards economic exposure, not voting influence. Otherwise long-time holders would skim the entire pool, even when newer holders contributed to quorum. This separation keeps governance honest.

Creator quick start

  1. Connect a wallet on /launch.
  2. Pick a tier, name, symbol, and metadata URI.
  3. Sign the transaction. Stake transfers to the dev vault. Authorities transfer to the governance PDA.
  4. Promote your launch. Earn the dev share of every swap. Stake vests over 90 days.

Choosing your tier

Pick the smallest stake you can defend. Bigger stakes signal credibility but also mean a bigger payout to holders if you get fired. Holders trust higher tiers more, but the bar to keep them happy is also higher.

The cost of a wrong tier
Bronze launches that ghost lose 1 SOL. Diamond launches that ghost lose 200 SOL. Pick a tier you can actually back with effort.

Stake & vesting

The stake splits into two buckets at launch:

  • Locked (30%) — Frozen until the program retires the launch or a governance action releases it. Always at risk during a fire vote.
  • Vesting (70%) — Releases linearly over vesting_duration_seconds (default 90 days). Call claim_vested as the dev to withdraw the unlocked portion. If you're fired, the unvested remainder moves to the claim pool.

Dev fee timelock

Accrued dev fees from buy/sell don't pay out immediately. They lock until dev_fee_unlock_at, set 30 days from launch by default. This kills the launch-then-rug-fees pattern.

tsif (now < launch.dev_fee_unlock_at) revert(DevFeeTimelocked);
launch.dev_fee_accrued = 0;
transfer(sol_vault, dev, accrued);

Replacing yourself

If you need to hand off a launch — successor builder, audit recovery — a holder can post a ReplaceDev proposal pointing to your designated successor. The stake stays intact and authority of the launch transfers to the new dev address. No fund movement.

Trading on the curve

Each launch starts with virtual reserves on a constant-product curve. Buys move SOL into the reserve and tokens out; sells reverse it. The platform takes a small fee, the dev takes a tier-defined share, and the rest sits in the bonding curve until the launch graduates.

tstokens_out = virtual_token_reserves
           - (k / (virtual_sol_reserves + sol_in_net));

Every buy also writes to your HolderPosition account, updating your weighted entry timestamp via a balance-weighted average. This is what gives you voting power later.

Time-weighted vote power

tsweight = tracked_balance × min(now − weighted_entry_ts, 90 days)
  • Buy more: weighted timestamp moves toward now (your average gets younger).
  • Sell some: balance shrinks, timestamp unchanged.
  • Sell all: position reset. Your next buy starts the clock at zero again.
  • Cap at 90 days prevents one early holder from accumulating infinite weight.

Posting a proposal

To post a proposal you need:

  • 0.5% of supply in your tracked balance.
  • 7+ days of holding (weighted entry ts).
  • A SOL bond. Refunded if the proposal passes; slashed if it fails.
Why a bond?
Spam proposals wear down attention. The bond requirement makes griefing expensive while still keeping legitimate proposals affordable.

Voting

Each holder can vote once per proposal. Your weight is captured at vote time and cannot be changed. The voting window is 48 hours. After the deadline anyone can call execute_proposal; the program checks quorum, tallies, and decides the outcome.

OutcomeEffect
FireDev passesDev fired. Locked + unvested + accrued fees → claim pool.
ReplaceDev passesDev pubkey swapped. Stake untouched.
General passesOn-chain record of holder intent. No state change.
Quorum not reachedFailed regardless of yes/no split. Bond slashed.

Claiming distributions

After a successful FireDev, every voter can call claim_distribution to withdraw their prorata share. The claim is single-use per voter record.

tsawait client.claimDistribution({ proposal: proposalPubkey });

Program ID & PDAs

Live on Solana devnet. View the on-chain program on Solana Explorer. All accounts are derived from a small set of seeds:

tsPROGRAM_ID = 9fyejEGkCaDrSMisgYhwxsJVbk77E5c8wgugn3KpuUFm

platform     = pda(["platform"])
launch       = pda(["launch", mint])
governance   = pda(["governance", launch])
sol_vault    = pda(["sol_vault", launch])
dev_vault    = pda(["dev_vault", launch])
claim_pool   = pda(["claim_pool", launch])
holder       = pda(["holder", launch, holder])
proposal     = pda(["proposal", launch, index_le_u64])
voter        = pda(["voter", proposal, voter])

TypeScript SDK

tsimport { Connection, Keypair, PublicKey } from "@solana/web3.js";
import { GavelClient, Tier } from "@gavel/sdk";

const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const payer = Keypair.generate();
const programId = new PublicKey(process.env.BOARDROOM_PROGRAM_ID!);
const client = new GavelClient({ connection, payer, programId });

const launch = await client.createLaunch({
  name: "Example Token",
  symbol: "EXM",
  uri: "https://example.com/metadata.json",
  tier: Tier.Gold,
});
// { signature, launch, mint, governance, solVault, devVault, claimPool }

Other surface area:

  • client.buy({ launch, solIn, minTokensOut })
  • client.sell({ launch, tokensIn, minSolOut })
  • client.createProposal({ launch, kind, bondLamports })
  • client.vote({ proposal, voteYes })
  • client.executeProposal(proposalPubkey)
  • client.claimDistribution({ proposal })

Rust CLI

The gavel binary is shipped in the engine repo. Use it for inspection and ops; it does not (yet) sign transactions on your behalf.

bashgavel --cluster devnet platform
gavel pda launch <MINT>
gavel pda governance <LAUNCH>
gavel proposals <MINT> --limit 20
gavel health
gavel program

IDL & instructions

The Anchor IDL ships at idl/gavel.json. Eleven instructions:

InstructionPurpose
initializeBootstrap the platform singleton.
create_tokenLaunch a new mint with tiered stake.
buySOL → tokens via the bonding curve.
sellTokens → SOL via the bonding curve.
claim_dev_feeCreator withdraws accrued fees after timelock.
claim_vestedCreator withdraws linearly-vested stake.
create_proposalEligible holder posts a proposal.
voteCast a time-weighted vote.
execute_proposalFinalise after deadline.
claim_distributionVoter claims prorata share.
reclaim_proposer_bondSuccessful proposer reclaims bond.

Error codes

CodeNameMeaning
6000CurveCompleteBonding curve already complete.
6002SlippageExceededTrade exceeded slippage tolerance.
6006DevFiredOperation requires an active dev.
6007DevFeeTimelockedFee unlock time has not arrived.
6009InsufficientHoldingProposer holds less than the minimum.
6010InsufficientHoldingPeriodProposer has not held long enough.
6014AlreadyVotedVoter record already exists.
6015QuorumNotReachedTotal voted supply below threshold.
6019AlreadyClaimedDistribution share already withdrawn.
6022TvlCapExceededReserve cap reached during beta.
6026ProposerBondRequiredBond below the minimum.

FAQ

Can a whale buy in and immediately fire the dev?

No. Vote weight is balance × capped holding seconds. A wallet that just bought has a holding time of zero and therefore zero vote weight.

What stops the creator from launching, ghosting, and pulling fees later?

The dev fee timelock. Accrued fees lock for 30 days post-launch. By the time fees would unlock, holders have had ample time to post and pass a fire vote.

What if I sell all my tokens and re-buy?

Your weighted entry timestamp resets to zero on full exit. The next buy restarts the clock, so re-entering doesn't preserve your prior holding history.

What if a proposal fails for quorum?

The proposer bond is forfeited and the proposal records as failed on-chain. The dev is unaffected.

Is there a TVL cap?

Yes during beta. Each launch's SOL reserve is capped to limit blast radius before the first audit. The cap is configured at the platform level and lifts post-audit.

Glossary

Stake
The SOL the creator deposits at launch. Split into locked + vesting buckets.
Vesting
Linear release of the 70% bucket over the platform's vesting duration.
Quorum
Minimum total voted supply (raw balance) required for a proposal to be valid.
Time-weighted vote
Vote weight = balance × min(now − entry_ts, holding_cap).
Claim pool
The PDA that holds redistributed funds after a successful FireDev.
Tier
Bronze / Silver / Gold / Diamond. Determines stake size and dev fee share.
Governance PDA
Owner of the mint and freeze authorities. The creator wallet never holds these.