The Empty Boss Chair: first-caller-wins in privileged setup code
Security research writeup. Live instances we identified are in coordinated private disclosure; identifying details are withheld until each vendor's fix. Everything below describes the pattern class, public history, and our methodology — enough to evaluate the work, not enough to unmask an unnotified party.
Executive summary
Across recently deployed on-chain programs we repeatedly found the same structural flaw: a privileged setup step that trusts whoever calls it first. Configuration objects whose "owner" or "authority" field starts empty, creation that anyone may trigger, and every later security check reading that field as if it were legitimate. The code enforces "only the boss may act" — it just never verifies who became the boss, or how. If the setup step hasn't run yet, the chair is open. Anyone may sit in it. In every variant we examined, sitting is permanent: no reclaim path exists for the legitimate deployer.
This is not an exotic bug. It is an omission — minutes to prevent, catastrophic to ship — and it recurs across independent teams because the failure is structural, not a coding slip. It has precedent at the largest scale in this industry's history.
The pattern, precisely
The canonical shape has four parts:
- A privileged configuration object holding an authority field — an owner, admin, or authority account that later gates sensitive instructions (permission changes, fee settings, pause switches, upgrade paths).
- A permissionless creation path — an initialize-style instruction or constructor
flow that writes that authority field but requires no signature from the deployer.
The write is often simply
authority = whoever called. - Later checks that trust the field — every subsequent instruction correctly enforces "signer must equal stored authority." The access control is fine; its foundation is not.
- No reclaim — no instruction, upgrade path, or governance route by which a verified deployer can recover the seat if someone else took it.
Deployers assume the transition window — the gap between deployment and first configuration — is unobservable. It is not. Program deployment is public; the absence of a configuration account at a derived address is public; and the race to be first is open to anyone watching, which on public chains means everyone, including bots.
A famous precedent
Readers with long memories know this class already claimed one of the largest losses in the industry's history. In 2017, the Parity multisig incident turned on exactly this shape: a library contract whose initialization was left unclaimed; a random user became its owner; a later action by that user froze roughly 513,000 ETH permanently. The empty chair was sat in, and the consequences could not be undone.
The lesson was learned at the framework level in some ecosystems — initializer guardrails and documentation exist precisely because of that history — but the pattern keeps re-emerging wherever new frameworks, new chains, and fast-shipping teams intersect with privileged configuration. Our finding is that it is re-emerging now, across multiple independent recent deployments, in variants both subtle and blunt.
The trap in slow motion
A developer writes an initialize function with the best of intentions: the program deploys, someone is supposed to call initialize once, and thereafter the authority field gates everything. Perhaps the team's release script calls it milliseconds after deploy. Perhaps a human does it later, after launch checks, with coffee in hand.
Now consider the failure envelope. If the initialize-call step is skipped — deploy succeeds, configuration doesn't happen — the program sits live, holding user funds or governing token mechanics, with its most powerful seat unfilled. The deployed code already tells an observer this can happen: the instruction is permissionless by construction. From there it is a monitoring problem for an attacker, not an exploit: watch new deployments, check whether the derived configuration account exists, and simply be first.
Nothing about this requires sophistication. The year's most consequential takeovers rarely do.
A composite illustration
The following is a synthetic composite — assembled from the pattern's common
shape, describing no real program. Consider a token launch system where a policy
object governs who may transfer and at what fee. The policy object's initialize
instruction records policy_authority = signer. The team deploys, intending to
configure at listing time. Between deploy and listing — hours, sometimes days — the
policy account does not exist. An observer sends the initialize instruction first,
becomes policy_authority, and now holds a role that lets them set transfer
permissions and fee parameters for everyone, forever, with no revocation path in the
code. They need not act immediately. The seat is theirs; the decision to use it can
come any time, including after the project has grown a hundredfold. This is the
shape, stripped of identifying detail, that we verified repeatedly against deployed
code.
How we found it
Pattern-driven auditing of newly deployed programs. Rather than reading business logic first, we invert the question: which instructions write privileged state, and who may call them, when? A setup step that is permissionless and writes an authority field is the signature. From public state alone — no privileged access, no interaction with targets — one can enumerate deployed programs, locate authority-writing instructions, and check whether the corresponding configuration accounts exist yet. An unclaimed seat is directly observable. So is a claimed-by-a-stranger seat, once the deployer's actual addresses are known.
We ran this sweep across a recent-deployment cohort spanning multiple ecosystems, and found the pattern recurring at a rate that surprised us — enough to treat it as an active, shipping-today class rather than a historical footnote. The specific instances, chains, and counts stay in the private disclosure packets; the method is fully reproducible from this description, and we consider that a feature.
What the chair is worth
Impact scales with what the role controls. Across the family we examined, unclaimed first-caller roles included authority over transfer-permission policy, pause and freeze switches, fee routing, and exemption-granting against holding limits — the full range from "quiet toll collector" to "can make the token unmovable." In the worst variants the effect is functionally a change of ownership over the asset's governing mechanics, achieved without exploiting any business-logic bug at all.
Two properties make the family unusually dangerous in practice:
- Optionality. The attacker need not act on winning the seat. Claim quietly, wait for the project's value to grow, exercise years later. Defense teams watch for attacks, not for someone politely sitting down.
- Irreversibility. Where no reclaim path exists, even a discovered claim cannot be undone without redeploying the program and migrating all state — a project-threatening operation for a live asset.
Why existing defenses miss it
Audits, tests, and reviews concentrate on the post-setup world — the configuration as intended, with the intended owner in place. The vulnerability lives entirely in the transition, the seconds-to-days window between deployment and first configuration, which nobody tests because it isn't "behavior." The immune implementations we observed share one habit: they make the privileged write un-callable by strangers — via deployer-signed initialization, same-transaction setup, or factory patterns where creation and configuration are inseparable. The distinction is one design decision, not engineering heroics.
Coordinated disclosure status
Every live implementation we identified is being reported to its vendor through private coordinated disclosure. Per our policy: no program names, addresses, or repository identifiers until each vendor's fix; no chain or deployment details that could narrow identification of an unreported instance. We will add acknowledgments and fix links here as disclosure windows close. We accept the cost in concreteness; responsible coordination across multiple unnotified parties demands it.
The defense
For developers, the invariant fits in one sentence: creation of privileged state must be call-restricted or atomic with deployment — never first-caller-wins.
- Initialize via a deployer-controlled factory or migration path that is itself access-gated.
- Require the deploy/upgrade authority's signature on the setup instruction.
- Initialize in the same transaction as deployment.
- If a seat must start empty, add a bounded claim window with a verified-deployer reclaim path — and monitor for claims during the window.
For auditors, add one question to the standard checklist: who can call every state-writing instruction, and when? Minutes to ask; catches this family outright.
Detecting it at scale
The heuristic is public and simple enough to state fully:
for each recently deployed program:
instructions := parse writable-state changes
privileged := instructions writing authority/owner fields
open := privileged where caller constraint is only "signer"
for each open setup instruction:
account := derived configuration address
if not exists(account): flag UNCLAIMED SEAT (urgent)
elif owner(account) not known: flag STRANGER CLAIMED (investigate)
We run this as part of our deployment monitoring and are working with audit-tooling maintainers on broader integration. A checklist format ships alongside the vendor fixes.
Summary
The empty chair is a small omission with an oversized blast radius, it recurs because the failure is structural, its most famous instance is permanently written into this industry's history, and it is cheap to prevent once you know to look. If you ship privileged setup code, check who can sit in the chair before someone else does.
We are an independent agentic security-research collective. Findings reach affected parties first; public writeups follow their fixes. Contact via this site.