Bulkhead Docs
Documentation

Limits that belong to the program, not the admin.

Bulkhead holds a Solana protocol's vaults. Your own deposit always comes back at once. Everything else leaves at most 2% an hour and 5% a day, even with the admin keys stolen.

Start

Quickstart#

Pick the tier that fits where your program is today. Both run on devnet now.

TierForWhat it holds
Tier 1 · VaultNew launchesThe protocol's token accounts. Every payout goes through it.
Tier 0 · FloorAny programThe program's upgrade key. No code changes.

Check any upgradeable program from the command line:

terminal · devnet
$ floor check Hrb9…x2Qe
loader      v3 upgradeable
authority   Floor PDA
delay       72h · vetoable
abort       binary ready

Rerun every number on the landing page with one command:

terminal
$ ./scripts/check.sh
6.9M cases where Rust and Python agree exactly.
Concepts

Backed and unbacked#

The protocol decides who gets paid. Bulkhead decides how fast. Every payout is sorted into one of two lanes before it leaves the vault.

PayoutLaneSpeed
Own deposit backBackedInstant, always
Borrow against listed collateralBackedInstant
Repay, then withdrawBackedInstant
Admin withdrawalUnbackedRate-limited
Bonus payoutUnbackedRate-limited
Borrow against unlisted collateralUnbackedRate-limited
Why

Normal users never touch the limiter. Only money that isn't provably theirs waits.

Concepts

Rate limits#

The unbacked lane releases at most 2% of the vault an hour and 5% a day. These limits live in the program, so stealing the admin keys doesn't raise them.

Modelled loss if a guardian freezes the vault after the first unbacked payout:

Freeze withinMost that can leave
2 minutes~2%
1 hour4%
24 hours10%
Note

Tightening a limit is instant. Loosening one is a proposal that waits 72 hours and any guardian can veto it.

Concepts

Tickets and the queue#

When an unbacked payout exceeds what the hour allows, the rest becomes a public ticket. Tickets are paid in order as capacity returns. Anyone can see them, and guardians can cancel them while they wait.

Concepts

Guardians#

People or bots you choose. They can freeze, cancel, extend, veto and abort.

  • They can stop money. They can never move it or choose who receives it.
  • A freeze lasts up to 24 hours per call and only delays unbacked payouts.
  • Only live guardians count. Unfreezing needs a live quorum.
  • No guardian can block anyone's own deposit.
Tier 0

Floor: upgrade delay#

Floor holds the program's upgrade key. Every upgrade waits 72 hours in public and can be vetoed. One guardian can stop the program in one transaction by swapping in an abort binary: every instruction fails and funds stay untouched until quorum restores it.

Propose

The upgrade buffer is frozen and published with its proposal time.

Wait 72 hours

The delay is a constant in the code. Any guardian can veto during the window.

Execute or abort

If no one vetoes, the upgrade lands. In an emergency, one guardian swaps in the abort binary.

Build

Integration#

About 40 lines. Three moves: hand over custody, route every move, seal.

Hand over custody

Move the protocol's token accounts under the Bulkhead vault.

Route every move

Replace direct transfers with a release call. Your program still picks the recipient.

Seal

Hand the upgrade key to Floor so the routing itself can't be removed quietly.

harbor/src/withdraw.rs
// the protocol picks who; Bulkhead decides how fast
bulkhead::cpi::release(
    CpiContext::new_with_signer(
        ctx.accounts.bulkhead.to_account_info(),
        Release { vault, ledger, owner, to, .. },
        signer,
    ),
    amount,
)?; // backed: paid now · unbacked: limited

See the full example in the repository docs.

Build

Constants#

NameValueMeaning
G1 hourly2%Unbacked outflow per hour
G1 daily5%Unbacked outflow per day
G4 delay72hWait before loosening or upgrading
Freeze≤ 24hLongest a single guardian freeze lasts
Trust

Security model#

Bulkhead buys time. People still have to use that time.

  • It doesn't detect attacks, protect user wallets, protect AMM pools or run an oracle.
  • Biggest risk: a bug in Bulkhead itself. Every rule is stated three ways and checked on millions of cases.
  • Before mainnet: audits, TVL caps, then burning Bulkhead's own upgrade key.
Status

Not audited yet. Runs on devnet, open source under Apache-2.0. SECURITY.md lists what is unaudited.

Trust

FAQ#

Isn't this just a rate limiter?

Drift had a rate limiter; the admin controlled it. Bulkhead's limit sits outside the admin's reach, and it tells your own deposit apart from someone else's money.

Does it slow normal users down?

No. Deposits, withdrawals of your own funds and ordinary borrows never touch the limiter.

What if a guardian is malicious?

It can delay unbacked payouts for up to 24 hours per freeze. It can't move funds, choose a recipient or block anyone's own deposit.

Bulkhead · Apache-2.0Edit these docs on GitHub