BonqDAO WALBT Tellor instant-price manipulation (2023-02-01)

  • Name: BonqDAO WALBT Tellor instant-price manipulation
  • Date: 2023-02-01
  • Protocol: BonqDAO
  • Chain: Polygon
  • Category: oracle manipulation / disputable-oracle misuse / instant-price consumption / undercollateralized stablecoin mint / liquidation abuse
  • Loss: roughly $120M nominally across BEUR and WALBT at manipulated marks, but realized damage was far lower because the attacker could not exit anywhere near those fake prices; BonqDAO’s own post-incident report estimated total realized USD losses around $1.85M across WALBT liquidations, drained Uniswap liquidity, and later trove redemptions, while AllianceBlock separately framed the ALBT-side damage at roughly $1.6M
  • Summary: BonqDAO let WALBT collateral be priced from the latest TellorFlex report through its custom TellorPriceFeed and ConvertedPriceFeed, instead of waiting out Tellor’s dispute window. Bonq’s own post-incident writeup was unusually concrete about the adapter mistake: the feed used getCurrentValue where a delayed getDataBefore(..., block.timestamp - 20 minutes) style read was needed, effectively making the oracle user-writable for the cost of staking 10 TRB. The attacker first reported an absurdly high WALBT price, opened a near-dust trove with 0.1 WALBT, and minted 100,000,000 BEUR against that fake collateral value. In a second transaction they reported an absurdly low WALBT price, pushed other WALBT troves into liquidation, iterated through the trove list to liquidate them, then used Bonq’s shared CommunityLiquidationPool debt-and-collateral mechanics to accumulate about 113.8M WALBT into their own trove, repay the inherited debt with a fraction of the freshly minted BEUR, and withdraw the collateral. The important preserved lesson is not just bad oracle: Bonq treated a slashable-but-disputable report as immediate collateral truth, so a cheap self-published Tellor update became both mint authority and liquidation authority.
  • Trigger / entry point:
    • Bonq’s WALBT/BEUR troves depended on a ConvertedPriceFeed that read a custom Tellor-fed WALBT/USD price and divided it by a Chainlink EUR/USD feed to get WALBT value in euro terms.
    • The custom TellorPriceFeed consumed TellorFlex data through getCurrentValue, meaning it used the newest submission immediately.
    • Tellor’s design assumes submitted values can be challenged and slashed during a dispute window; Bonq skipped that protection and promoted the fresh report straight into collateral valuation.
    • Because Bonq used the same price feed for trove health and liquidation decisions, one attacker-controlled Tellor report could first overvalue their own collateral and then undervalue everyone else’s.
  • Root cause:
    • Bonq integrated Tellor as if latest reported value meant safe oracle value, ignoring the fact that Tellor’s security model depends on delayed consumption and dispute resolution.
    • The cost to print a false price was tiny relative to the value Bonq would honor: the attacker only needed to stake 10 TRB per submission, fully rational when the protocol would mint tens of millions of BEUR against the fabricated price.
    • Bonq also let liquidation logic consume the same manipulated price immediately, so the oracle failure did not stop at fake borrowing power; it also created a mass-liquidation path against other WALBT troves.
    • The exploit therefore combined two solvency failures in sequence: fake-collateral minting followed by collateral seizure via false underpricing.
  • Exploit path:
    1. The attacker funded Polygon address 0xcacf2d28b2a5309e099f0c6e8c60ec3ddf656642 and interacted with the Bonq contracts around 18:29-18:31 UTC.
    2. In the first phase, they staked 10 TRB into TellorFlex and submitted a false price of exactly 5,000,000 USD per WALBT.
    3. With that fabricated price live immediately, they created a first WALBT trove, deposited only 0.1 WALBT, recorded the collateral, and borrowed 100,000,000 BEUR.
    4. In the same first phase they also opened a second WALBT trove and deposited about 13.25973256272339977 WALBT, not to borrow immediately, but to position themselves as both firstTrove() and lastTrove() in Bonq’s collateral-ratio ordering.
    5. In the second phase, using another Tellor submission address, they staked another 10 TRB and reported the opposite fake price: 0.0000001 USD per WALBT.
    6. That instant underpricing pushed WALBT-backed troves across the protocol into liquidatable territory.
    7. The attacker then traversed the trove list through firstTrove, lastTrove, and nextTrove, checked whether each trove contained WALBT collateral and non-zero debt, and liquidated qualifying troves one by one.
    8. Bonq’s liquidation flow routed collateral and debt through the CommunityLiquidationPool, so the liquidated WALBT and associated debt could be claimed into the attacker’s prepared trove through the claimCollateralAndDebt path.
    9. Once the iterative liquidation pass was done, the attacker repaid only about 1,341,461 BEUR into their second trove to clear the inherited debt stack.
    10. They then called decreaseCollateral() and extracted roughly 113,813,998 WALBT from the trove, alongside the still-massive BEUR minted in the first phase.
    11. The attacker dumped part of the loot for ETH and DAI, but market depth was too thin to realize anything close to the nominal manipulated value.
  • What the attacker needed to be true:
    • Bonq had to consume a freshly submitted Tellor value without delay or dispute-window enforcement.
    • The staking/slashing cost for a malicious Tellor submission had to be negligible relative to the protocol value unlocked by one fake price.
    • Bonq had to use the same manipulated oracle for both borrowing power and liquidation eligibility.
    • Trove ordering and liquidation-pool accounting had to let the attacker iterate the WALBT trove set and consolidate seized collateral into their own prepared trove.
  • Technical anatomy worth remembering:
    • This was not the usual buy thin collateral on a DEX, then borrow oracle-manipulation pattern. The attacker did not need to drag a market; they simply wrote the oracle input through a permissionless but disputable reporting system that Bonq consumed too early.
    • The exploit had a clean two-stage structure: first print debt by overpricing your own collateral, then seize others’ collateral by underpricing theirs.
    • The second trove mattered because Bonq’s troves were sorted by collateralization ratio. The attacker arranged the ordering so they could traverse and liquidate the WALBT trove set deterministically, while preserving their own sink trove for debt and collateral accumulation.
    • The economic lesson is sharp: if an oracle’s trust model says wait for disputes, then using latest value directly is equivalent to handing collateral policy to whoever can most cheaply post and forfeit a report bond.
    • Bonq therefore belongs in the oracle-manipulation corpus, but specifically in the immediate consumption of a disputable oracle branch rather than the AMM-TWAP or thin-orderbook branches.
  • Representative transactions and addresses:
    • Attacker address: 0xcacf2d28b2a5309e099f0c6e8c60ec3ddf656642
    • Example attack transaction: 0x31957ecc43774d19f54d9968e95c69c882468b46860f921668f2c55fadd51b19
    • Attacked Bonq contract highlighted in incident reporting: 0x8f55d884cad66b79e1a131f6bcb0e66f4fd84d5b
    • First attacker trove noted by Omniscia: 0x4248FD3E2c055a02117eB13De4276170003ca295
    • Second attacker trove noted by Omniscia: 0x5343c5d0af82b89DF164A9e829A7102c4edB5402
  • Response / mitigation:
    • Bonq paused the protocol after the incident and publicly attributed the exploit to a bug in its Tellor price-feed implementation.
    • Bonq’s own report also recorded an operational miss after initial notification: although the team intended to stop trove redemptions, redemptions were not actually halted in time, so the attacker or opportunistic third parties used BEUR to redeem collateral from additional non-WALBT troves and deepen realized losses.
    • AllianceBlock emphasized that the fault sat in Bonq’s oracle integration rather than in AllianceBlock’s own token contracts, then froze bridge activity, coordinated exchange halts, and later replaced ALBT with a new token distribution.
    • The real mitigation lesson is to respect the oracle’s trust model: disputable-report systems need explicit delay, dispute-window checks, and conservative risk caps before their values become borrow power or liquidation triggers.

Three disputable-oracle authority promotions this incident collapsed

1. A permissionless Tellor report for WALBT could still be authored cheaply

  • The first true fact in the system was only that TellorFlex still allowed a reporter willing to post the required bond to publish a fresh WALBT/USD value.
  • Bonq’s own incident report preserved the local asymmetry cleanly: the attacker only needed to stake 10 TRB to publish a new value, first an absurdly high WALBT price and later an absurdly low one.
  • At that stage nothing about the report should have implied safe collateral truth; it only meant a disputable report now exists inside Tellor's challengeable window.

2. Bonq still promoted that freshest report into canonical trove-side collateral truth

  • The decisive second promotion sat inside Bonq’s adapter layer, not inside Tellor itself. Bonq’s own post-incident writeup said the vulnerable line used getCurrentValue() where getDataBefore(..., block.timestamp - 20 minutes) should have been used.
  • That meant Bonq skipped the entire local staging step that Tellor’s dispute model assumes. A freshly posted report was treated as if it had already matured into money-good WALBT collateral truth for ConvertedPriceFeed, trove collateral-ratio ordering, borrow capacity, and liquidation checks.
  • This is the sharp reusable split the note should preserve: some report exists and that report is now the canonical solvency number for this market were different promotions, but Bonq collapsed them into one read.

3. That published collateral truth still inherited immediate BEUR mint and liquidation authority

  • Bonq did not merely cache the fresh report for observation. It still honored the first forged mark to let 0.1 WALBT back 100,000,000 BEUR, then honored the second forged mark to push the rest of the WALBT trove set into liquidation.
  • Bonq’s own writeup recorded the downstream blast radius plainly: 32 WALBT troves holding 114,672,328.11 WALBT were liquidated, and the attacker’s prepared debt-free trove could absorb that collateral through the CommunityLiquidationPool flow before selective repayment and withdrawal.
  • That is the design ladder worth keeping visible: a cheap disputable report can be posted, Bonq promotes it into canonical collateral truth immediately, and that accepted truth still deserves live mint, liquidation, and collateral-withdraw authority were three different authority promotions, and the exploit worked because Bonq treated them as one.

Pattern tags

  • oracle-manipulation
  • Immediate consumption of a permissionless disputable oracle report: Bonq’s custom TellorPriceFeed treated TellorFlex getCurrentValue() as if latest report already meant safe collateral truth
  • One cheap report first created fake mint authority and a second cheap report then created protocol-wide liquidation authority against the same collateral type
  • Trove-order steering plus CommunityLiquidationPool debt carryover let false underpricing become collateral consolidation instead of merely isolated liquidations

Why the exploit worked

  • Omniscia’s postmortem makes the decisive adapter mistake unusually explicit: Bonq’s ConvertedPriceFeed consumed the WALBT leg through a custom TellorPriceFeed that called TellorFlex::getCurrentValue(), so the protocol skipped the delay that Tellor’s slash-and-dispute model expects before a reported value is treated as trustworthy. Bonq therefore promoted latest report directly into both trove-health and liquidation math.
  • The economic asymmetry was extreme. The attacker only needed to risk 10 TRB per malicious submission, while the protocol was willing to honor that submission as enough evidence to mint 100,000,000 BEUR against 0.1 WALBT and later to repriced the rest of the WALBT trove set into forced-liquidation territory. A slashable bond is not a meaningful oracle defense if the value unlocked by one false report dwarfs the bond.
  • Bonq reused the same manipulated oracle surface for both sides of the balance sheet. The first false report overvalued the attacker’s own collateral and printed undercollateralized BEUR; the second false report undervalued everyone else’s WALBT collateral and turned liquidation logic into a collateral-seizure path. The protocol did not distinguish fresh report observed from price safe enough to mint against or price safe enough to liquidate against.
  • The liquidation machinery amplified the oracle failure. By arranging their two troves at opposite ends of Bonq’s collateral-ratio ordering, then iterating the WALBT trove set while CommunityLiquidationPool debt and collateral rolled forward to the next claimant, the attacker converted false liquidations into one sink trove that could later be cleaned up with a relatively small BEUR repayment and drained via decreaseCollateral().
  • The preserved lesson is therefore sharper than Tellor bad or oracle bug: Bonq failed to stage oracle trust. A permissionless disputable report became immediate solvency authority before any dispute window, risk cap, or market-local quarantine narrowed what that report was allowed to do.

Detection and audit pivots

  • For any slashable or disputable oracle network, write down the exact rule by which a report graduates from latest submission to collateral truth. If the adapter reads a freshest-value function like getCurrentValue() straight into borrowing or liquidation logic, the protocol is probably trusting the wrong stage of the oracle lifecycle.
  • Compare the maximum value one oracle update can unlock against the bond, slash, or staking cost required to post a malicious report. If one false submission can mint tens of millions or trigger mass liquidations while the reporter only risks a tiny bond, the oracle is economically writable no matter how good the dispute system looks on paper.
  • Review whether the same feed can simultaneously create mint authority, liquidation authority, and debt-socialization authority. Bonq shows that an adapter bug is more dangerous when one manipulated mark affects both over-borrowing and forced collateral redistribution.
  • Trace liquidation-pool and queueing mechanics after a false price lands. Ask not only can bad liquidations happen? but can an attacker consolidate the seized collateral and inherited debt into a prepared sink position, repay selectively, and withdraw the rest as if the liquidations were legitimate?
  • Treat permissive ordering and traversal helpers as part of the oracle exploit surface when liquidations are price-driven. If attackers can shape where their own troves sit in the ordered set, they may also be able to script who absorbs shared debt and who receives the liquidated collateral once a false price is accepted.

Failure-prevention checklist

  • Do not let permissionless disputable-oracle submissions become immediate borrow or liquidation truth. If the network’s security model depends on a slash / dispute window, the adapter must enforce that staging locally instead of reading getCurrentValue() straight into solvency math.
  • Size local credit authority against the cost to publish a bad report, not only against the nominal quality of the oracle brand. A 10 TRB bond should never unlock 100,000,000 BEUR of mint capacity or protocol-wide liquidation authority.
  • Separate fresh report observed from safe enough to mint, safe enough to liquidate, and safe enough to socialize debt. A disputable feed may be usable for monitoring or UI display before it is allowed to move solvency-critical state.
  • Add market-local clamps for impossible price jumps, mint caps, and liquidation throttles so one absurd report cannot immediately traverse the full price -> trove health -> liquidation -> debt carryover -> collateral withdrawal path.
  • Treat shared-liquidity liquidation pools as part of oracle blast-radius design. If one false price can force many troves through the same debt-and-collateral bucket, the downstream pool needs tighter claimant rules, caps, or pause hooks.
  • Keep thin or partner-provided collateral under tighter borrow-side quarantine than blue-chip collateral, especially when the pricing path is custom and unaudited. Bonq’s WALBT market should have assumed adapter risk was part of collateral risk.
  • Ensure new oracle adapters inherit the same review and rollout gates as core borrowing code. Omniscia’s public note matters here because the exploited ConvertedPriceFeed, ChainlinkPriceFeed, and TellorPriceFeed path was outside the earlier audit scope.
  • Preserve emergency de-recognition paths for collateral types whose oracle trust model degrades. If the protocol cannot quickly stop fresh borrowing and liquidation on one market, a disputed-report bug becomes protocol-wide balance-sheet authority.

Audit prompts

  • What exact function turns a disputable or slashable oracle report into collateral truth here, and where is the dispute-window or finality rule enforced: inside the oracle network, inside the adapter, or nowhere?
  • If a reporter risks only the posted bond, how much borrowing power, liquidation authority, or debt-socialization authority does one malicious submission unlock at current market parameters?
  • Does the same feed simultaneously govern minting, liquidation eligibility, liquidation ordering, and collateral redistribution? If so, what independent brake survives when that single feed fails?
  • Can an attacker open one preparation position under an inflated price, a second sink position under a different ordering state, then traverse the market and consolidate liquidated collateral plus debt into their own trove as Bonq allowed?
  • What local sanity checks reject impossible moves before debt is issued or liquidations begin: absolute price bands, percent-change clamps, delayed activation, borrow caps, or none?
  • Are custom oracle adapters, converted-price helpers, and partner-collateral feeds forced through the same audit and change-management path as the base lending engine, or can unaudited adapter glue silently acquire mint authority?
  • If the oracle becomes disputable-but-not-final, which actions narrow automatically: UI display only, no new borrowing, no liquidations, capped redemptions, or full pause?
  • How would governance justify the largest allowed mint and liquidation blast radius if the freshest report for this market were wrong for one dispute window?

Lessons that should already be standard

  • Latest report is not the same object as safe collateral truth when the oracle network explicitly expects disputes and slashing to clean bad submissions out later.
  • Oracle-bond economics matter as much as oracle-code correctness. If the cost to lie is tiny relative to the value the protocol will honor, the feed is economically writable at the point of consumption.
  • Liquidation logic is another oracle consumer, not just a cleanup path after borrowing. Bonq lost money twice because the same bad report first printed BEUR and then rewrote who owned WALBT collateral.
  • Shared liquidation pools and debt-carryover mechanics are balance-sheet amplifiers. Once a false price can push many positions through them, the protocol needs stronger distrust than liquidation is permissionless and should just work.
  • Partner or custom oracle adapters deserve first-class review. A protocol can have battle-tested trove math and still hand solvency authority to a few lines of unaudited price-adapter glue.
  • Degraded oracle trust should narrow permissions before it changes balances. Fresh, disputable, or low-confidence values may still be useful signals, but they should not automatically authorize minting or collateral seizure.
  • Stablecoin systems need explicit issuance brakes even when they think the oracle is externalized. If one false report can overissue the liability and only later reveal that the collateral was fictional, the balance-sheet check happened in the wrong order.
  • Trove ordering, queue traversal, and claimCollateralAndDebt-style helpers are part of exploit design once the oracle can be falsified. Price-manipulation review should follow the full seizure-and-consolidation path, not stop at the initial bad report.

Why this incident matters

  • It preserves a mechanically distinct oracle-manipulation branch that the corpus otherwise underweights: not AMM reserve distortion, not TWAP dragging, and not perp mark manipulation, but instant acceptance of a permissionless disputable oracle report.
  • It is also a good stablecoin-design warning. Bonq let a cheap false report mint BEUR against dust collateral and then let a second false report reshuffle who owned the WALBT collateral base.
  • The incident makes a broader point about oracle composition: using a good EUR/USD feed downstream does not help if the upstream asset feed is effectively attacker-authored at the moment you read it.

Internal linkages

Control surface

  • The leverage sat in Bonq’s custom Tellor adapter, the decision to consume getCurrentValue immediately, trove-order traversal, and liquidation-pool accounting that let false price reports become both mint rights and seizure rights.
  • Bonq did not merely have a noisy oracle. It delegated solvency-critical timing to the cheapest party willing to post a slashable false report before anyone could dispute it.

Sources

Last reviewed

  • 2026-08-04 UTC