• Blockchain
  • Swissborg
  • Vulnerability
  • Cryptocurrency
  • Exploit

MPC Doesn’t Save You From Your Private API

MPC removes single-key risk, but offchain transaction builders and policy APIs can still tell distributed signers to authorize the wrong operation.

Published byOKcontract Labs5 min read
MPC Doesn’t Save You From Your Private API

MPC removes single‑key risk, but it doesn’t remove the need to tell signers what to sign and when. Most custodial stacks route those decisions through off‑chain services: transaction builders, policy engines, withdrawal whitelists, “earn” strategy managers, and internal dashboards. Compromise any of those private APIs and you can often coerce the MPC signer to do the wrong thing — with perfectly valid signatures.

What follows: a factual recap of SwissBorg’s incident, other real events that rhyme, and a practical path that moves the trust boundary on‑chain — where timelocks, roles, and watchers can veto bad changes before funds move.

SwissBorg Kiln API Incident

What happened on September 8–9, 2025:

  • Loss & scope. ~192.6–193k SOL (~$41–42M) was drained from wallets tied to SwissBorg’s SOL Earn program. SwissBorg said a partner’s API was compromised, affecting <1% of users and ~2% of total assets, and pledged recovery.
  • Kiln’s role. Kiln, SwissBorg’s staking partner, disabled its transaction crafting API and dashboard during incident response; its public status page points directly to that API layer.
  • Onchain footprint. Independent onchain analysts on Reddit showed that stake withdraw authorities on certain Solana stake accounts were changed days before the main drain, hidden among benign‑looking operations (e.g., an unstake). That primed later withdrawals to attacker‑controlled addresses.
  • Context & coverage. Third‑party reporting from CoinDesk, Cointelegraph, and others corroborated the partner‑API compromise narrative.

The key point: nothing about the Ed25519 curves or threshold math failed. The control surface that tells signers what to sign was subverted.

Why private APIs are the real key

MPC guarantees that no single device can produce a signature. It does not guarantee that a signature request was a) policy‑compliant, b) user‑intended, c) or the only thing bundled in a transaction. In many stacks:

  • A transaction‑crafting service builds messages.
  • A policy engine says “OK” based on stored rules.
  • A submitter sends signing sessions to the MPC cluster.

Compromise credentials, CI/CD, or the dashboard for any of those, and you can enqueue legitimate‑looking requests which pass policy and get valid signatures. That is the “API as the new key” problem.

Other real incidents that rhyme

  • Bybit’s ".4–".5B cold‑wallet theft (Feb 21, 2025). Signers were tricked into approving a transaction that changed the Safe proxy implementation, after which attacker functions swept assets. This wasn’t a curve break; it was UI / transaction‑construction deception against the approval workflow. Deep write‑ups from NCC Group, Elliptic, Cointelegraph, and security vendors align on the mechanics.
  • BitGo “Zero‑Proof” TSS vulnerability (disclosed 2023). Fireblocks demonstrated a bug in BitGo’s TSS for Ethereum where a single interaction could exfiltrate a private key share, and verified exploitation via the BitGo REST API and backend, bypassing admin and transaction policies. BitGo mitigated after disclosure. This shows how API‑exposed cryptography can collapse policy guarantees if the implementation is flawed.
  • BitForge class of MPC bugs (disclosed 2023). Fireblocks found vulnerabilities in popular GG‑18/GG‑20/Lindell‑17 threshold ECDSA implementations affecting multiple providers; major vendors shipped patches. No public mass thefts were confirmed, but it proved MPC code can be vulnerable — and when paired with service APIs, the blast radius is large, as reported by CoinDesk.
  • **CoinsPaid hot‑wallet drain (2023).** A social‑engineering‑led breach of internal systems let attackers push legitimate‑looking withdrawal requests through payment infrastructure, draining ~$37M. Again: back‑office/API abuse, not crypto‑primitives failure.

Pattern: attackers don’t need to “break MPC.” They target the policy + transaction API that decides intent.

Move the trust boundary onchain

The alternative is to hold assets in smart‑contract accounts whose control plane lives onchain. That lets you encode changes to powers, beneficiaries, or spend limits into state transitions that the whole world can observe and front‑run with defenses.

Concrete building blocks:

  1. Account abstraction smart accounts (ERC‑4337). Make the account itself enforce arbitrary verification logic, spend limits, and modules. Use a separate EntryPoint and UserOperation flow; add policy in the account, not an off‑chain server.
  2. Timelocks for dangerous actions. Route upgrades, owner changes, or beneficiary/whitelist edits through a TimelockController or a Safe Delay/Timelock module, so there’s a queued period to review and cancel.
  3. On‑chain roles/whitelists with parameter scoping. You can use onchain workflows such as Zodiac Roles Modifier to permit only specific function selectors on specific targets with argument constraints and value caps.
  4. Many eyes, many pagers. Subscribe multiple independent alerting stacks to the same contracts — Alchemy Webhooks/Notify, Blocknative mempool monitors, Tenderly Alerts/Webhooks/Web3 Actions, QuickNode webhooks. If a timelocked change appears, several services can page human signers or automated vetoers.
  5. Veto and cancel paths. Use the Safe Delay module’s invalidation or a governance timelock’s cancel role so designated guardians can halt a queued operation during its delay window.

Practical checklist for teams using MPC today

  • Put every policy change behind an onchain timelock with a canceler role; treat whitelists/beneficiaries as contract state, not DB rows. See OpenZeppelin Docs.
  • Move high‑value flows to smart‑contract accounts with parameter‑scoped permissions (e.g., Zodiac Roles) rather than a blanket “allowed address.”
  • Require a two‑man rule for turning off delays or modifying roles; and subscribe at least two independent alerting providers to the same events, such as Alchemy.
  • Treat transaction‑crafting and policy services as Tier‑0. Hardware‑back them, isolate their networks, pin image digests, and rotate credentials with out‑of‑band attestation.
  • Bake in transaction simulation and spec conformance checks on the client. If the built call deviates from the spec, fail closed.
  • Regularly rehearse veto drills: simulate a malicious role change, ensure alerts fire, and verify a cancel transaction lands before the timelock expires.

What we’re building at OKcontract

The weak link often isn’t custody — it’s the interface that composes calls. Vitalik outlined this plainly in his wallet essay: “the weakest link in a user’s security is often the dapp,” because websites can be swapped or hijacked and trick users into signing the wrong thing. That’s exactly the link we remove.

When you want defense in depth, you have to think about UI + spec + chain. Don’t trust runtime web UIs. Generate transactions from a formal interaction spec and verify onchain that the spec‑conformant call is what’s being queued. That’s exactly what we provide:

  • Formal interaction specs. OKcontract defines a DSL (λscript) to specify interactions precisely — targets, selectors, parameter shapes, slippage bounds, and invariants — then compiles that to generated UI and to a runtime that produces deterministic transactions from user inputs.
  • On‑chain control plane. The spec ties into on‑chain timelocks and roles so that any change to who can do what must be queued, observable, and subject to veto by designated guardians watching through multiple alert providers. See OpenZeppelin Docs.

_Related context: Vitalik mentioned OKcontract on stage at EthCC 2025 — see X post_

Closing thought

SwissBorg’s loss wasn’t a referendum on MPC math. It was another case where the instruction path to the signer got bent. If your control plane is a private API, that API is your key. Move that control plane onchain, wrap it in timelocks and roles, and let many eyes watch it with independent pagers. That’s how you turn “we trust our off‑chain service” into “we trust code, with time to stop it.”

Originally published on Medium.

Related reading