All articles
Smart Contracts·March 17, 2026·7 min read

Squads Multisig Timelocks for Live Trading Program Upgrades

A concrete Squads v4 setup for a squads multisig upgrade authority: timelock gating, deterministic buffer verification, and a guardian break-glass pause for live trading programs.

Your upgrade authority is the single most dangerous key in your entire stack. Whoever holds it can swap the bytecode behind your live trading program between one slot and the next, and every vault, position, and open order inherits the new logic instantly. A leaked or coerced upgrade authority isn't a bug — it's total loss. Squads v4 exists to make that key a committee instead of a person, and to put a clock between "approved" and "deployed" so a compromised committee still can't rug you in a single transaction.

This is the operational side of program governance: how to actually wire a Squads multisig as your upgrade authority, put a timelock gate in front of the BPF loader, and keep a break-glass path that works at 3 a.m. when a fill engine is misbehaving.

Why the upgrade authority is different from every other key

On Solana, an upgradeable program's bytecode lives in a ProgramData account, and exactly one authority can call bpf_loader_upgradeable::upgrade against it. There's no per-instruction gate, no rate limit, no built-in delay. The loader checks one thing: does the signer match the stored authority? If yes, the new ELF is written and the program is live at the next slot.

For a trading program that custodies user funds or runs strategy logic, that's the whole ballgame. Someone who controls the upgrade authority can insert a withdraw_all path, disable your risk checks, or redirect fees. This is precisely why treating the upgrade authority as a multisig-governed asset rather than a hot keypair is table stakes for anything holding size.

Setting up the Squads v4 multisig

Squads v4 gives you a program-derived multisig with configurable members, a threshold, and — critically for this — an optional per-member time_lock on the vault. The multisig itself is a PDA; proposals are accounts; execution is a two-phase create-then-execute flow.

Start by creating the multisig with a sane threshold. For a program authority, 2-of-3 is the floor and 3-of-5 is more defensible. Keep at least one member on a hardware signer and one on a fully cold, air-gapped key that never touches a hot machine.

# Create a 3-of-5 multisig with a 24h config time_lock (86400 seconds)
squads-cli multisig create \
  --members <memberA>,<memberB>,<memberC>,<memberD>,<memberE> \
  --threshold 3 \
  --time-lock 86400 \
  --config-authority none

Setting --config-authority none is deliberate. If you leave a config authority, that single key can change members and threshold and route around the whole scheme. Make the multisig govern itself so membership changes go through the same threshold and timelock as everything else.

Then transfer the program's upgrade authority to the multisig's vault PDA:

solana program set-upgrade-authority <PROGRAM_ID> \
  --new-upgrade-authority <MULTISIG_VAULT_PDA>

Verify with solana program show <PROGRAM_ID> that the authority is now the vault PDA and not any individual signer. If your design also uses PDAs to hold vault state, the same discipline about who can mutate what applies — the reasoning I laid out in the piece on PDA seed design for multi-vault trading programs carries directly over to authority accounts.

The timelock gate is where the real security lives

A threshold alone stops a single compromised key. It does not stop a coordinated compromise, a coerced quorum, or three members who all clicked the same phishing link. The timelock does.

With time_lock set, an approved proposal cannot execute until the delay elapses. Those hours are your detection window. You wire monitoring on the multisig's proposal accounts so any created upgrade proposal fires an alert:

  • A subscription on the multisig account plus proposal PDAs, decoding new Proposal accounts as they're created.
  • An alert that names the target program, the proposed buffer address, and the proposing member.
  • A verification step where an independent operator diffs the proposed buffer against the audited build.

The delay only helps if someone is watching during it. A 24-hour timelock with no monitoring is theater. Pick the delay to match your ops coverage: if you can guarantee eyes on alerts within an hour, 6–12 hours is workable; if coverage is thin, go to 48. The tradeoff is real — a longer lock means slower legitimate fixes, which matters when a market-structure change breaks your program.

Verifying the buffer before it can execute

Never approve an upgrade against a buffer you haven't independently reproduced. The flow:

  1. Build the program deterministically (anchor build --verifiable or solana-verify build).
  2. Compare the resulting hash to the deployed buffer with solana-verify get-program-hash against the buffer account.
  3. Only then does the second and third signer approve.

Making buffer verification a required, checklist-gated step is the single highest-leverage control here, and it's exactly the kind of thing a proper smart contract code review and audit should bake into your deploy runbook rather than leaving to memory.

Break-glass: what you do when the program is actively hurting users

Here's the tension nobody likes to talk about. A timelock that protects you from attackers also blocks you from stopping a live bug. If your matching logic starts mispricing fills or a rounding error is draining a vault, waiting 24 hours to ship a fix is unacceptable.

The answer is not "remove the timelock." It's a separate, narrow emergency path that pauses without upgrading.

Bake a pause flag into the program itself, gated by a guardian — a distinct, lower-threshold authority (say 2-of-3, or even a single hardware key held by an on-call engineer) that can only flip the program into a halted state. It cannot upgrade bytecode. It cannot move funds. It can only stop new instructions from processing.

#[account]
pub struct Config {
    pub upgrade_authority: Pubkey, // the Squads vault PDA
    pub guardian: Pubkey,          // fast pause key, no upgrade power
    pub paused: bool,
}

pub fn execute_trade(ctx: Context<ExecuteTrade>) -> Result<()> {
    require!(!ctx.accounts.config.paused, ErrorCode::ProgramPaused);
    // ... strategy logic
    Ok(())
}

Now your incident response splits cleanly. The guardian pauses in one transaction — instant. Then the real fix goes through the full multisig-plus-timelock flow with everyone watching, because you've already stopped the bleeding. The break-glass action is cheap and reversible; the dangerous action stays slow and scrutinized.

One gotcha: make sure paused is checked on every state-mutating instruction, including the ones you added last week. A pause flag that misses a code path is worse than none because it breeds false confidence. And if your program batches many legs into one transaction using address lookup tables for multi-leg execution, confirm the pause check sits ahead of the first leg, not buried after account resolution.

A few things that bite people

  • Rent and the buffer lifecycle. A failed or abandoned upgrade proposal leaves a funded buffer account. Clean these up; a stale buffer that later gets approved by accident is a live threat.
  • Member key rotation is a config change. Rotating a compromised member's key goes through the multisig's own threshold and config timelock. Plan for the case where the key you need to remove is one of your signers — you still need threshold minus that member to act.
  • Squads program upgrades. You're now depending on Squads' own program. Pin the version you audited and track their upgrade authority and governance too.
  • State layout across upgrades. If your new bytecode changes account layout, the timelock window is also when you confirm migration logic doesn't corrupt existing accounts — the same discipline the zero-copy account layout work demands, since a bad layout assumption survives an upgrade silently.

The pattern that holds up: multisig-owned upgrade authority with a real timelock, independent buffer verification as a hard gate, and a narrow guardian pause for emergencies. Threshold stops one bad key, the clock stops a bad quorum, and the pause stops a bad deploy — three different failures, three different controls.

If you're standing up governance for a program that already holds real positions, our team can design and pressure-test the whole authority-and-timelock setup with you through dedicated smart contract development.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#Squads Multisig#Solana#Upgrade Authority#Smart Contracts#Program Governance