Midas Capital HAY/BUSD LP Empty-Market Rounding Exploit (2023-06-17)

  • Name: Midas Capital HAY/BUSD LP empty-market rounding exploit
  • Date: 2023-06-17
  • Protocol: Midas Capital
  • Chain: BNB Smart Chain
  • Category: empty-market exchange-rate inflation / precision-loss redemption / isolated-pool lending drain
  • Loss: about 600k gross exploit value)
  • Summary: The attacker targeted Midas Capital’s BNB Chain isolated Ankr/Helio pool and specifically its HAY/BUSD Thena-LP lending market. Even after post-Hundred awareness and patching, the market could still be driven back into an attacker-ownable dust-supply state instead of preserving a durable non-burnable floor. The attacker first reduced the market’s cToken supply to just 1001 wei, then donated redeemed LP tokens back into the market and later donated another roughly 259,826.61 HAY/BUSD LP tokens so those 1001 wei of cTokens represented roughly $519k of collateral on paper. With that inflated exchange rate, the attacker borrowed pool assets, unwound temporary ANKR collateral, and then exploited rounding in the redemption math: withdrawing about 519.13 LP tokens should have required burning 1.998 wei of cTokens, but integer truncation rounded the burn down to 1 wei. They looped the same chip-away redemption pattern and finished with self-liquidation steps to seize and redeem the remaining inflated collateral.
  • Trigger / entry point:
    • The exploited market was the HAY/BUSD LP-token market at 0xf8527dc5611b589cbb365acacaac0d1dc70b25cb inside Midas’s permissionless isolated pool for Ankr / Helio assets on BNB Chain.
    • Midas had already tried to patch the post-Hundred empty-market issue, but its later workaround for very low-denomination LP assets left a path where a tiny residual cToken supply could still be inflated into meaningful collateral.
    • The attack used a dedicated helper contract at 0xd2094b870D80Cfb7DaDa4893aD0030d642CA9f72 (named borrower in Midas’s postmortem) plus a root attack contract at 0xc40119c7269a5fa813d878bf83d14e3462fc8fde.
  • Root cause:
    • The HAY/BUSD market could be driven down to a microscopic cToken supply (1001 wei) while still remaining valid collateral.
    • More specifically, Midas’s post-Hundred mitigation did not create a durable, runtime-surviving supply floor; under production flows the market could still return to an attacker-ownable denominator small enough for one actor to redefine exchange-rate meaning.
    • Direct LP-token donations changed the market’s asset base without minting new cTokens, so the exchange rate for the remaining 1001 wei of supply became abnormally large.
    • Redemption math truncated in the attacker’s favor: an economically necessary burn of 1.998 wei was rounded down to 1 wei.
    • Midas’s risk controls limited some borrow paths, but the attacker found a route around ankrBNB debt ceilings by combining flash-loaned ANKR collateral, separate helper contracts, and borrow / resupply steps.
  • Exploit path:
    1. In the main exploit transaction 0x1ebc03f0f2257c275f4990b4130e6c3e451125aa98ee8bbde8aba5dc0320c659, the attacker used the root contract 0xc40119c7269a5fa813d878bf83d14e3462fc8fde and helper borrower contract 0xd2094b870D80Cfb7DaDa4893aD0030d642CA9f72.
    2. They minted and supplied 21,184 HAY/BUSD LP tokens, then redeemed almost the entire cToken position, leaving only 1001 wei of market cTokens outstanding.
    3. They donated the redeemed 21,184 LP tokens back into the market and transferred the residual 1001 wei cToken position into the helper contract so that the helper controlled essentially the whole remaining cToken supply.
    4. Using flash-loaned ANKR as temporary collateral, they borrowed about $25k of HAY and 1,148 ankrBNB from the pool, swapping the ankrBNB into BUSD.
    5. Combining those borrowed assets with their own funds, they minted about 259,826.61 additional HAY/BUSD LP tokens worth roughly $519k and donated those LP tokens directly into the market.
    6. With the exchange rate now inflated, the attacker borrowed a bit more ANKR to cover flash-loan fees, then redeemed the temporary ANKR collateral back out, leaving roughly $519k of paper collateral against about $320k of debt.
    7. The key cash-out step was redeeming about 519.13 LP tokens from the market. That amount economically corresponded to 1.998 wei out of the 1001 wei total cToken supply, but the protocol rounded the required burn down to 1 wei.
    8. After the flash-loan-heavy first phase, the attacker kept looping the same pattern: add LP collateral worth roughly 1 wei of cTokens, then withdraw LP collateral worth roughly 1.998 wei, repeatedly extracting value from rounding.
    9. Once the remaining damaged LP collateral fell to roughly $30k, the attacker used about 90.9 of the 115 supplied ankrBNB to self-liquidate, seize the residual LP collateral, and redeem what was left.
  • What the attacker needed to be true:
    • The HAY/BUSD market had to be attacker-dominated, with cToken supply reducible to a tiny nonzero amount.
    • Direct LP-token donations had to flow into exchange-rate math without minting matching cTokens.
    • Redemption math had to round down in the attacker’s favor at microscopic supply values.
    • The isolated pool needed enough real borrowable assets that inflated LP collateral could be monetized before prices normalized.
    • The attacker needed a way around the pool’s intended debt ceilings, which they found through the ANKR / ankrBNB collateral route and helper-contract choreography.
  • Technical anatomy worth remembering:
    • This was a close cousin of the Hundred Finance exploit, but not a literal copy. Midas’s postmortem is useful because it shows how a fork can patch the obvious zero-supply version yet still leave a low-denomination LP-token variant alive.
    • The crucial number to remember is not just 1001 wei; it is the 1.998 wei -> 1 wei redemption truncation that turned exchange-rate inflation into extractable value.
    • The exploit also shows how isolated-pool risk controls can fail compositionally: debt ceilings on one borrow path are weaker than they look if another collateral route lets the attacker recreate the same exposure indirectly.
    • The liquidation cleanup step is worth preserving too. Midas was not only an exchange-rate-and-rounding bug; the attacker could still be the economically relevant liquidator at the end, so the protocol’s own liquidation incentives helped sweep the residual inflated collateral instead of letting an outside rescuer neutralize it.
    • LP-token collateral adds another layer of fragility because the donated underlying was itself a wrapped claim on external pool assets rather than a plain ERC-20 balance.
  • Representative transactions and artifacts:
    • Main exploit tx: 0x1ebc03f0f2257c275f4990b4130e6c3e451125aa98ee8bbde8aba5dc0320c659
    • Attacker EOA reported by public analyses: 0x4b92cc3452ef1e37528470495b86d3f976470734
    • Root attack contract: 0xc40119c7269a5fa813d878bf83d14e3462fc8fde
    • Borrower helper contract: 0xd2094b870D80Cfb7DaDa4893aD0030d642CA9f72
    • Vulnerable HAY/BUSD market: 0xf8527dc5611b589cbb365acacaac0d1dc70b25cb
  • Response / mitigation:
    • Midas paused the protocol, published a postmortem, and pointed to a final fix in commit b82dcf81c4e78d43100b53ed70201be0143bc713.
    • The team also said the incident pushed them away from the permissionless isolated-pool design toward a more permissioned structure with whitelisted users and tiered pools.
    • The postmortem is notable because it documents not just the bug, but the failed partial fix that had been added immediately after Hundred and then relaxed for low-denomination LP assets.
    • The sharper design lesson is that we patched the zero-supply version was not enough if runtime behavior could still compress the denominator back into a state where one actor owned the market’s accounting meaning.

Three denominator-authority promotions the partial fix still collapsed

  1. The market could still fall back into attacker-owned denominator state under ordinary runtime flow

    • The important failure was not that the post-Hundred patch was absent. It was that the surviving runtime path still let the attacker reduce HAY/BUSD cToken supply to 1001 wei, which was economically close to letting one actor define what the next meaningful LP-token balance increase would mean.
    • That is the deeper partial fix failed lesson: a launch-time or edge-case patch does not help if the live market can still re-enter the same attacker-owned denominator regime after redeems, low-denomination handling, or helper-contract choreography.
  2. Donated LP inventory was still promoted into local collateral truth

    • Once the denominator was microscopic, direct HAY/BUSD LP donations stopped being passive inventory and became exchange-rate authorship.
    • Midas still let those off-path LP-token transfers flow into the market’s exchange-rate meaning without minting proportional new cTokens, so the helper’s 1001 wei position became a local collateral printer rather than a residual dust claim.
  3. That locally printed mark still retained enough borrowing and endgame authority to cash out

    • The pool did not keep a second distrust boundary between this market can publish a local exchange rate and this market may now back meaningful debt and liquidation value.
    • That is why the attacker could bridge the printed LP mark into real pool borrowing, then finish the extraction through the 1.998 wei -> 1 wei redemption truncation and attacker-controlled self-liquidation.

The durable lesson is that the market is thin again, off-path LP inventory can redefine exchange-rate meaning, and that printed meaning is still borrowable and liquidatable elsewhere in the pool are three separate promotions. Midas’s partial fix did not keep them separate.

Pattern tags

  • Core recurring pattern: empty-market-exchange-rate-inflation.
  • Monetization endgame: self-liquidation-monetization.
  • The preserved shape is sharper than generic rounding bug or generic donation attack: Midas kept a post-Hundred LP-collateral market live even though production flows could still rewind its denominator back to 1001 wei, let direct LP donations redefine exchange-rate meaning over that attacker-owned dust supply, and then let the same attacker use liquidation as the final extraction rail once the borrow leg was already in place.
  • This is also a strong partial mitigation that never became a durable runtime floor case. The dangerous state was not a pristine zero-supply market anymore; it was a supposedly patched market whose low-denomination LP handling still let one actor own the denominator again.

Why the exploit worked

  • Midas’s first response to Hundred had recognized the family, but the later low-denomination LP workaround quietly reopened the same economic state. The protocol no longer needed literal zero supply; it only needed a denominator small enough that one actor could cheaply decide what the next LP donation meant.
  • In that state, the donated HAY/BUSD LP tokens stopped being passive pool inventory and became solvency authorship. The market read those donated LP balances into exchange-rate math without minting new cTokens, so the helper contract’s 1001 wei position became a collateral printer rather than a residual dust claim.
  • The borrow-side controls were not independent enough from the manipulated collateral path. Debt ceilings on one route looked conservative in isolation, but the attacker could still use flash-loaned ANKR, helper-contract choreography, and the ankrBNB leg to reconstruct meaningful borrowing against the printed LP collateral.
  • The rounding bug completed the cash-out path rather than standing alone. Without the exchange-rate inflation over 1001 wei of supply, the 1.998 -> 1 wei burn error would have stayed small; without the truncation, the printed LP collateral would have been much harder to recover into withdrawable value. The exploit only paid because tiny-supply state, donation-sensitive exchange-rate accounting, borrow-path composition, and attacker-controlled liquidation all lined up.
  • The liquidation finale matters because it shows the protocol never regained an independent cleanup actor. Once the same attacker controlled the unhealthy borrower, the collateral printer, and the liquidator capital, liquidation incentives stopped being a defense and became the last monetization step.

Detection and audit pivots

  • Reconstruct the exact post-Hundred patch path, not only the final exploit trace: what low-denomination LP edge case broke the original fix, what replacement logic was introduced days later, and what runtime state could still compress cToken supply back toward attacker-ownable dust?
  • Force direct LP-token donations into a thin collateral market during testing. If donated LP inventory can raise exchange rate faster than the protocol mints matching cTokens or quarantines the market, the supposed fix is only a launch-time patch, not a durable runtime defense.
  • Simulate redemption math at the real denominator that matters here, not only totalSupply == 0. Midas shows why 1001 wei, 1.998 wei, and other low-denomination residual states are the production-relevant adversarial inputs.
  • Audit borrow caps as a composition problem. If one collateral route is tightly capped but another asset can be flash-loaned, re-supplied, or helper-routed to recreate the same economic exposure, then the cap is weaker than its parameter table suggests.
  • Ask who still controls liquidation in the damaged state. If the same actor can manufacture unhealthy collateral, own the debt position, and arrive with the liquidator capital, liquidation no longer acts as an external correction mechanism.
  • Treat LP-token collateral as a two-layer trust boundary: not only is the cToken market safe?, but also does the protocol understand how the donated LP claim's denomination, liquidity, and accounting semantics change low-supply exchange-rate behavior?

Failure-prevention checklist

  • Make the denominator floor durable at runtime, not just at deployment. If a market is supposed to be protected against the Hundred family, ordinary mint / redeem / donate flows must never be able to drive totalSupply or equivalent supplier state back into attacker-ownable dust like 1001 wei.
  • Treat low-denomination LP assets as an adversarial precision environment, not as a reason to relax the floor. If share precision, exchange-rate scaling, or asset decimals make the original defense awkward, redesign the accounting boundary instead of re-opening the dust-state exploit path.
  • Keep direct LP donations from becoming immediate collateral truth. Unsolicited LP-token balance increases should mint proportional claims, route into quarantined surplus accounting, or stay excluded from exchange-rate inputs until the protocol can prove the new value is safely owned.
  • Test the exact adversarial denominator that production can reach. The meaningful regression case here is not only totalSupply == 0, but 1001 wei, 1.998 wei should burn, and other low-decimal residual states that a helper contract can actually manufacture.
  • Audit risk limits compositionally across correlated assets and helper routes. A cap on one borrow path is not a defense if flash-loaned ANKR, ankrBNB recycling, or side-contract choreography can recreate the same economic exposure.
  • Do not assume liquidation remains an external cleanup mechanism after solvency is attacker-authored. If the same actor can create the bad collateral, keep the debt alive, and arrive as liquidator, the protocol needs stronger borrower/liquidator separation or narrower endgame powers.
  • Add automatic degraded-mode triggers for dust supply, abnormal exchange-rate jumps, and impossible LP-collateral growth. If a market re-enters an effectively fresh state, collateral utility and borrowing powers should shrink before operators even start incident response.

Audit prompts

  • What exact production path can compress this market back from a supposedly protected state into 1001 wei or another attacker-ownable denominator, and why is that path still reachable after the original fix?
  • Which low-denomination LP edge case motivated the post-Hundred workaround, and did that workaround preserve the security invariant or only preserve usability?
  • When LP tokens are transferred directly into the market, which variables become larger immediately: raw balance, getCash(), exchange rate, collateral mark, borrow power? Where is unsolicited inventory supposed to stop becoming solvency truth?
  • At the real adversarial state Midas hit, how many cToken wei should redeeming 519.13 LP tokens burn economically, and where does floor division still let 1.998 wei collapse to 1 wei?
  • Are debt ceilings and borrow caps enforced on economic exposure or only on one local asset route? What correlated collateral path, helper contract, or flash-loan sequence lets the attacker reconstruct the forbidden exposure anyway?
  • If the market becomes unhealthy under attacker-authored collateral, who is realistically expected to liquidate it? An independent keeper with fresh capital, or the same attacker who already controls the borrower, the collateral printer, and the liquidation ammunition?
  • What invariant proves that every increase in supplier-side collateral value came from a matched claim-issuance path rather than from an attacker-controlled denominator plus donated LP inventory?

Lessons that should already be standard

  • A partial fix that still allows production flows to recreate the dangerous denominator is not a fix. We handled the obvious zero-supply case is not enough if 1001 wei is still economically equivalent to attacker owns the market's meaning.
  • Low-denomination collateral is not a special case that deserves weaker security boundaries. It is usually the exact place where precision, exchange-rate, and dust-state assumptions need to be stricter.
  • LP collateral does not make empty-market inflation gentler. It adds another abstraction layer whose own denomination, redemption semantics, and liquidity profile can amplify the damage once exchange-rate math is already attacker-authored.
  • Risk limits are path-dependent. A parameter table that looks conservative on one asset is not a real defense if correlated assets, flash loans, or helper contracts can rebuild the same leverage off-path.
  • Liquidation is not automatically independent cleanup. Once the same actor can stay economically present on both sides of the unhealthy position, liquidation incentives can become the last extraction rail rather than the rescue mechanism.
  • Empty-market inflation and rounding bugs are one joined failure family. The rounding edge matters because the denominator was already attacker-owned; the denominator matters because the protocol still let the attacker cash that lie out through borrowing and redemption.

Why this incident matters

  • Midas is a strong follow-on case for the empty-market / rounding-loss family because it shows the same exploit logic adapting to LP-token collateral and a partially patched fork.
  • It preserves a useful second-wave lesson: once a bug family becomes public, the next failures often come from incomplete mitigations rather than from total ignorance.
  • It also sharpens the positive-design target behind the cluster: a protective floor only counts if production redemption, migration, and low-denomination runtime paths cannot erode the market back into attacker-ownable dust supply.
  • It is also a reminder that isolated-pool architecture contains blast radius, but does not remove the need for market-seeding, exchange-rate, and rounding hardening inside each pool.

Internal linkages

  • Core recurring pattern: empty-market-exchange-rate-inflation.
  • Monetization lens: self-liquidation-monetization — Midas is a useful cousin where the main borrow drain came from exchange-rate inflation and truncation, then self-liquidation helped sweep the remaining inflated collateral.
  • Positive-design companion: bootstrap-state-irreversibility-and-supply-floor-design — the sharper lifecycle follow-up is why a market that supposedly had already been patched could still be driven back into attacker-ownable dust supply under ordinary runtime flows.
  • Positive-design companion: unexpected-balance-quarantine-and-explicit-recognition-discipline — the sharper reserve-boundary question is why directly donated HAY/BUSD LP inventory was still allowed to become exchange-rate-relevant collateral truth instead of staying quarantined until explicitly recognized.
  • Positive-design companion: collateral-admission-lag-and-borrow-side-quarantine — the sharper downstream question is why a market that had fallen back into a dust-denominator state was still allowed to turn that locally printed LP mark into live borrow authority inside the pool.
  • Positive-design companion: borrower-separation discipline — the useful follow-up question is why the protocol’s endgame still assumed liquidation was a cleanup tool rather than an attacker-owned final extraction rail once the same actor controlled the unhealthy account and the liquidator capital.
  • Adjacent pattern: donation-share-price-manipulation.

Control surface