NewGet Polystrat: trade Polymarket on autopilot around the clock while you do something elseNew Polystrat agent: trades Polymarket on autopilot while you do something elsePolystrat
Olas Registries Updated, Thanks to Immunefi Whitehat

Olas Registries Updated, Thanks to Immunefi Whitehat

16-Jun-26

TL;DR

A whitehat researcher responsibly disclosed a vulnerability in the Olas registries through the Olas Immunefi program that, under specific conditions, could have let an attacker take over a service's recovery-enabled Safe and drain it.

No user funds were lost.

A fix has been shipped that is designed to enforce a one-to-one binding between a service and its multisig, deployed across Ethereum and all supported Layer 2 (L2) networks via on-chain DAO governance vote. The binding for the existing fleet has been back-filled, and the previously demonstrated attack chain no longer succeeds at the binding step. The change is public in autonolas-registries PR #307.

Background

Every Olas service is operated by a Gnosis Safe (Safe) multisig — see the Olas service lifecycle docs for how a service is created, deployed and torn down. Services that opt into recovery deploy their Agent Safe with a Recovery Module enabled, which is designed to let the service owner regain control of the Agent Safe if any of the Agent Safe's signer keys (the agent operator keys) is lost — by calling recoverAccess(serviceId). In the Pearl context — Olas's onchain agent operator — that service owner is the user's Master Safe: a separate Safe owned by the user, distinct from the Agent Safe that the running agent signs from. Pearl's recovery flow is designed to let the user's Master Safe call recoverAccess to reclaim signing authority over the Agent Safe when the operator key is rotated, evicted or lost.

A service also has a defined lifecycle: it can be deployed, then terminated and unbonded, which returns it to pre-registration while the registry keeps a pointer to its existing Agent Safe. This is by design — it lets an operator re-activate a service later without redeploying its Safe. The Safe, and any funds in it, persist.

The issue

The two facts above combined into a takeover path. A service in pre-registration with a recovery-enabled Safe is, in effect, a funded Safe with a "parked" owner. The missing guard was this: the service manager did not enforce that a given multisig could only ever belong to one service.

Using the same-address multisig adapter (a legitimate tool that lets a service adopt an existing Safe), an unprivileged attacker could:

  1. create their own service and register the victim Safe's (currently unused) owners as its agent instances;
  2. "deploy" their service onto the victim's existing Safe — the adapter's checks pass because the owners and threshold genuinely match;
  3. terminate, unbond, and call recoverAccess — becoming the sole owner of the Safe and draining it.

Impact

At the time of disclosure, the directly-drainable exposure was ≈ $11.4k across 227 service Safes, overwhelmingly affecting the Gnosis agent fleet (ordinary funded agent Safes holding mostly stablecoin — no single large target; a long tail with a median around $30). Importantly, none of these were ever drained: the only on-chain outflows observed were legitimate owners sweeping their own Safes. The standing risk was the parked, funded fleet, which the issue could have turned into an attacker's payday — so the fix was treated as high-priority.

The fix

The service manager now records a canonical binding the first time a service deploys its multisig, and refuses to move a Safe that already belongs to a different service:

  • deploy(...) writes mapMultisigServiceIds[multisig] = serviceId on first claim, reverts MultisigAlreadyBound if the multisig is already owned by another service, and releases the old binding on a genuine move (no-op on a same-address redeploy).
  • A permissionless, idempotent bindMultisig(uint256[]) is designed to let anyone record the binding for already-deployed services without a redeploy — closing that door on the existing fleet.

The same-address takeover sequence fails at step 2: the attacker's deploy(...) reverts MultisigAlreadyBound because the victim Safe is already bound to its real service.

Rollout

  • The fixed implementation was deployed and activated behind the upgradeable service-manager proxy on Ethereum and all supported L2 networks (Gnosis, Polygon, Arbitrum, Optimism, Base, Celo) via an on-chain DAO proposal, plus Mode via a separate maintenance upgrade. The in-scope networks were on the fixed code within about half an hour of execution.
  • The permissionless back-fill was then run across the existing service fleet on each in-scope chain. An on-chain audit at the time of writing recorded 0 unbound — each deployed service multisig was claimed by its rightful service.

Verification

  • A unit test reproduces the full attacker flow and asserts deploy(...) reverts MultisigAlreadyBound, while separate tests confirm legitimate recovery and re-deployment still work.
  • A fork-based reproduction against real (now-bound) on-chain state confirms the same: the attacker can set everything up, but the binding step reverts.

Responsible disclosure

Thank you to the researcher who reported this through the Olas Immunefi program and worked through the remediation process. Responsible disclosure like this is what strengthens the protocol for everyone. If you believe you've found a vulnerability in Olas, please report it through Immunefi.

What users need to do

No action needed. The fix is live across the in-scope networks and the existing fleet has been bound to its services. No funds were lost, and no action is required from operators or users.