OAK — OnChain Attack Knowledge

Worked example · 2020-06

Bancor v0.6 upgrade pool-drain exploit — Ethereum — 2020-06-18

Loss
approximately $460K (~12.5 ETH + ~229K USDT + smaller amounts of other tokens drained from the Bancor USDT liquidity pool). Funds were returned in full by the white-hat researcher who discovered and reported the vulnerability and temporarily extracted the funds to demonstrate impact.
OAK Techniques observed
OAK-T9.004 (Access-Control Misconfiguration — the newly deployed BancorConverter v0.6 contract contained a logic bug in its reserve-balance validation that allowed a caller to drain the USDT and ETH reserves of an affected pool through a crafted conversion-path call, effectively treating the pool's reserves as withdrawable by any caller). OAK-T16.006 (Timelock-Free Protocol Upgrade Execution — broadly construed; the upgrade from v0.5 to v0.6 was deployed without a governance-delay period; the vulnerability was introduced into a live production pool without a community-review or security-audit window between deployment and activation).
Attribution
pseudonymous The individual who discovered the vulnerability — a security researcher operating within the Bancor ecosystem — extracted the vulnerable-pool funds as a white-hat action to prevent malicious exploitation, then returned the funds to Bancor after the vulnerability was confirmed and patched.
Key teaching point
The Bancor June 2020 upgrade bug is the canonical worked example of a production contract-upgrade introducing a pool-drain vulnerability — distinct from the July 2018 Bancor hot-wallet compromise (which was a T11.001 operator-side custody breach). The incident illustrates the structural hazard of a timelock-free smart-contract upgrade on a live AMM pool: the upgrade silently invalidates an invariant that had held for the pool's entire pre-upgrade lifetime (that only depositors can withdraw their pro-rata share of reserves), and the absence of a timelock means there is no window for external researchers or the community to detect the invariance violation before the pool is exposed.

Summary

Bancor is a decentralised automated-market-maker (AMM) protocol on Ethereum that pre-dates Uniswap and pioneered the "liquidity pool with a reserve-based pricing formula" model. In June 2020, Bancor deployed a v0.6 upgrade to its smart contracts, replacing the existing BancorConverter contract with new code that introduced additional features, including a new fee model and an expanded set of conversion functions.

A security researcher (acting as a white-hat) discovered a logic error in the v0.6 BancorConverter contract within hours of deployment. The bug was in the reserve-balance accounting logic: under specific conditions, the contract's internal reserve-tracking state could diverge from the actual token balances held by the contract, allowing a caller to craft a conversion path that would transfer more tokens out of the pool than the conversion's input amount should have permitted — effectively draining the pool's USDT and ETH reserves.

The researcher demonstrated the vulnerability by extracting approximately 12.5 ETH and ~229K USDT from the USDT pool, then promptly reported the bug to the Bancor team. The extraction was a white-hat action — the researcher held the funds temporarily to prove impact and prevent a malicious actor from discovering and exploiting the same vulnerability. After Bancor confirmed the bug and deployed a fix (v0.6.1), the researcher returned all extracted funds.

The affected pool was the only pool using the v0.6 BancorConverter contract at the time; all other Bancor pools remained on v0.5, which was not vulnerable. Bancor's rapid response — pausing the v0.6 converter, fixing the reserve-accounting logic, and deploying the patched v0.6.1 contract — limited the exposure to the USDT pool only. The incident drew a sharp contrast with the July 2018 Bancor hot-wallet compromise (~$12.5M in ETH, BNT, and other tokens via a compromised operator endpoint — a T11.001 case), demonstrating the two structurally distinct attack surfaces at Bancor: custody-layer (2018) vs. smart-contract-upgrade-layer (2020).

Timeline (UTC)

When Event OAK ref
2020-06-18 ~08:00 Bancor deploys v0.6 BancorConverter contract upgrade; USDT pool migrated to the new converter T16.006 (timelock-free upgrade deployment)
2020-06-18 ~12:00 White-hat researcher discovers reserve-accounting logic bug in v0.6 converter; extracts ~12.5 ETH + ~229K USDT to demonstrate impact T9.004 (access-control / reserve-validation failure)
2020-06-18 ~12:30 Researcher reports vulnerability to Bancor; Bancor team pauses v0.6 converter (defender response)
2020-06-18 ~18:00 Bancor confirms root cause: reserve-balance state divergence under crafted conversion-path calls (forensic analysis)
2020-06-19 Bancor deploys patched v0.6.1 contract; researcher returns all extracted funds (remediation + fund return)
2020-06-20 Bancor publishes post-mortem; all funds returned and accounted for (post-mortem)

Realised extraction

Zero net loss. Approximately $460K was temporarily extracted by the white-hat researcher as a proof-of-impact demonstration; all funds were returned within 24 hours after the vulnerability was patched.

Distinction from 2018-07 Bancor exchange compromise

The July 2018 Bancor incident (~$12.5M via a compromised operator hot-wallet endpoint) is documented at examples/2018-07-bancor.md and is classified under OAK-T11.001 (Third-Party Signing-Vendor Compromise / Operator-Signing-Infrastructure Compromise): the attacker compromised Bancor's hot-wallet signing surface and drained the exchange's custody wallets. The June 2020 upgrade vulnerability is a structurally distinct event: it targeted the smart-contract layer (a logic bug in a production upgrade of the AMM converter), not the custody layer. The two Bancor incidents illustrate the dual-attack-surface shape that protocols with both custody operations and on-chain smart contracts must defend against.

T9.004 classification

The v0.6 BancorConverter vulnerability is classified under OAK-T9.004 (Access-Control Misconfiguration) because the core failure mode was a missing invariance check: the contract's withdraw or convert path did not validate that the caller's claimed output amount was bounded by the pool's actual reserve balance as tracked by the contract's internal accounting. The access-control failure is not a missing onlyOwner guard but a state-consistency failure — the contract permitted a state transition (token outflow) that violated the invariant the contract was designed to enforce (outflow <= caller's pro-rata reserve share). This is the same T9.004 structural sub-shape as the Uranium Finance migration-bug drain (April 2021, BSC) and the Concentric Finance multisig-signer-device compromise (January 2024, Arbitrum), all of which share the property that the contract believed it was in a valid state but an external caller could induce an inconsistent one.

T16.006 cross-classification

The upgrade from v0.5 to v0.6 was deployed by the Bancor contract owner without a governance timelock — the production pool was migrated to the new converter contract immediately upon deployment. The absence of a timelock meant that external researchers, auditors, and the community had no window to review the new converter's reserve-accounting logic before the pool's funds were exposed. The structural T16.006 pre-condition — a single-owner upgrade deployed directly to production without a mandatory delay — is the enabling context for the T9.004 reserve-accounting bug. This classification aligns Bancor June 2020 with the 2020-2021 DeFi timelock-free-upgrade cohort (documented at examples/2020-2021-defi-timelock-free-upgrade-cohort.md).

Public references

  • Bancor, "Bancor Post-Mortem — June 2020 v0.6 Upgrade Vulnerability," June 20, 2020
  • PeckShield, "Bancor v0.6 Converter Vulnerability Analysis," June 18, 2020
  • The Block, "Bancor Smart Contract Bug Exposes User Funds," June 18, 2020
  • Bancor v0.6 contract changelog and v0.6.1 patch notes (bancor.network)

Techniques demonstrated (2)