HopeLend hETHWBTC Empty-Market liquidityIndex Exploit (2023-10-18)
- Name: HopeLend hETHWBTC empty-market liquidityIndex exploit
- Date: 2023-10-18
- Protocol: HopeLend / Hope.money
- Chain: Ethereum
- Category: empty-market liquidityIndex inflation / precision-loss burn / cross-market lending drain
- Loss: about 526 ETH (roughly 835K at the time)
- Summary: HopeLend left its
hETHWBTCreserve effectively uninitialized for about 73 days, with no real outside liquidity, so an old listing had drifted back into an effectively fresh market. The exploit path combined two Aave-style accounting failures inside that empty reserve. First, the attacker deposited2,000 WBTC, then used HopeLend flash loans to concentrate roughly1.26 WBTCof LP fee income per loop into a nearly nonexistenthETHWBTCsupply, pushing the reserveliquidityIndexfrom the normal1e27scale to about7,560,000,001e27. That made a single1e-8unit ofhETHWBTCappear to be worth about75.6 WBTC, which HopeLend then accepted as collateral against the rest of the protocol. Second, after draining other markets, the attacker usedrayDivtruncation in the burn path to withdraw113.4 WBTCwhile burning only one1e-8hToken unit instead of the nearly2e-8units economic reality required. A generalized frontrunner copied the exploit from the mempool, landed the profitable transaction first, and paid a massive validator bribe out of the proceeds. - Trigger / entry point:
- HopeLend’s
hETHWBTCreserve at0x25126F207Db7dC427415eA640ce0187767403907existed but had essentially zero live liquidity, so the first meaningful attacker could dominate the entire reserve state. - The core lending pool at
0xc74b72bbf904bac9fac880303922fc76a69f0bb4used Aave-styleliquidityIndexaccounting, where flash-loan LP fees increase supplier value pro rata. - Because only a dust amount of
hETHWBTCremained after the attacker burned almost all supply, each later flash-loan fee update moved the index by an absurd amount. - HopeLend still treated the manipulated
hETHWBTCas valid collateral for borrowing WETH, USDT, USDC, HOPE, and stHOPE from sibling markets.
- HopeLend’s
- Root cause:
- HopeLend allowed an effectively empty reserve to remain live and collateral-relevant, so a single attacker could monopolize
liquidityIndexgrowth. - More specifically, the protocol treated
old reserveas if it still meantmature reserve, instead of reclassifyinghETHWBTCas effectively fresh again once real supplier breadth had collapsed and the next meaningful actor could redefine the market’s accounting. - Flash-loan fee accounting assumed a healthy supplier base; in an empty reserve, the LP-fee mechanism became a way to print collateral value for the only remaining hToken holder.
- The burn path used
rayDivfloor rounding, which became catastrophic once WBTC’s 8-decimal granularity and the extremeliquidityIndexmade the economically correct burn amount just under2minimum hToken units. - In short: a dormant empty market, unrevoked cross-market solvency authority, fee-driven
liquidityIndexinflation, and attacker-favorable burn truncation formed one exploit pipeline.
- HopeLend allowed an effectively empty reserve to remain live and collateral-relevant, so a single attacker could monopolize
- Exploit path:
- An original searcher identified the bug and prepared an attack contract in block
18377039, but a generalized frontrunner monitoring the mempool copied the exploit and ultimately captured the profitable execution in block18377042. - The exploit sourced
2,300 WBTCvia an Aave flash loan, then deposited2,000 WBTCinto HopeLend’s emptyhETHWBTCreserve to mint2,000 hETHWBTC. - The attacker next took a
2,000 WBTCHopeLend flash loan from the same reserve, transferred that2,000 WBTCdirectly back into the reserve contract, and then withdrew1,999.99999999 WBTC, leaving only0.00000001 hETHWBTCoutstanding. - That tiny remaining hToken balance was the key setup. Each
2,000 WBTCflash loan generated about1.26 WBTCof LP fees for suppliers (0.09%fee times the LP share), and with only1e-8 hETHWBTCleft, those fees were effectively credited to a single dust unit. - By repeating the flash-loan loop roughly 60 times, the attacker pushed
liquidityIndexto about7,560,000,001e27, so the remaining1e-8 hETHWBTCread as collateral worth about75.6 WBTC. - Using that fake collateral value, the attacker borrowed assets from HopeLend’s other pools, including about
175.4 WETH,145,522.220985 USDT,123,406 USDC,844,282 HOPE, and220,617 stHOPE, which were later swapped into more liquid assets. - The cash-out phase then exploited burn truncation. After depositing
151.20000002 WBTC, the attacker received0.00000002 hETHWBTC; withdrawing113.4 WBTCshould have burned about0.000000019999999998 hETHWBTC, butrayDivfloor rounding burned only0.00000001. - With one minimum hToken unit preserved, the attacker could loop
75.60000001 WBTCdeposits against113.4 WBTCwithdrawals, producing roughly37.8 WBTCof value per cycle until the initial Aave flash loan was repaid and the rest of the stolen assets remained as profit.
- An original searcher identified the bug and prepared an attack contract in block
- What the attacker needed to be true:
- The
hETHWBTCreserve had to stay effectively empty, with no real supplier base to dilute fee accrual. - HopeLend flash loans had to charge fees that flowed back into the same reserve’s
liquidityIndex. - The protocol had to accept inflated
hETHWBTCvalue as real collateral against deeper-liquidity sibling markets. - Burn math had to round down in favor of the user once the correct burn amount was just under
2minimum hToken units. - The attacker needed enough external flash liquidity to set up the initial WBTC position and complete the loop in one block.
- The
- Technical anatomy worth remembering:
- This was the dormant-reserve cousin of Radiant’s fresh-market exploit. Both are Aave-style empty-market attacks where
liquidityIndex, not exchange rate, is the printable variable. - The critical setup step was not only the flash loan; it was the deliberate reduction of hToken supply to a single
1e-8WBTC-denominated unit before fee accrual started compounding. - WBTC’s 8-decimal granularity mattered. The bug became monetizable because the economically correct burn amount landed just below
2minimal hToken units, so flooring it to1created a huge gap. - The mempool twist matters too: the profitable transaction was not necessarily executed by the original discoverer, but by a frontrunner who copied the exploit and paid about
263 ETHas validator bribe to secure ordering.
- This was the dormant-reserve cousin of Radiant’s fresh-market exploit. Both are Aave-style empty-market attacks where
Three reserve-authority promotions this incident collapsed
-
An old reserve was still treated as if age itself meant economic maturity
hETHWBTChad existed for about 73 days, but that only proved the reserve was old and reachable.- It did not prove the reserve still had a healthy supplier denominator or that the next meaningful actor could no longer define what reserve-side fee income meant.
- HopeLend effectively let
listed for monthsstand in formature enough to keep full collateral authorityeven after the market had drifted back toward attacker-ownable dust.
-
That attacker-owned dust denominator was still promoted into canonical supplier-side solvency truth
- Once the attacker compressed supply down to
0.00000001 hETHWBTC, the reserve’s next unit of flash-loan fee income no longer looked like ordinary shared supplier yield. - It looked like authorship over
liquidityIndexitself, because one dust unit now captured almost the entire next increment of reserve-side value. - The dangerous promotion was accepting
the reserve can still publish a supplier balanceas if it already impliedthat published balance still deserves ordinary accounting trust under a healthy denominator.
- Once the attacker compressed supply down to
-
That published supplier-side truth still inherited immediate cross-market reserve-spending authority
- The manipulated
scaledBalance * liquidityIndexoutput did not stay local to the dormant WBTC reserve. - HopeLend still let that printed mark fund real borrowing from WETH, USDT, USDC, HOPE, and stHOPE markets, and later let burn truncation turn the same distorted state into under-burned WBTC withdrawals.
- In other words,
old reserve exists,that reserve may still publish trustworthy supplier value, andsibling markets must already spend against that valuewere collapsed into one joined state transition.
- The manipulated
- Representative transactions and artifacts:
- Successful exploit tx:
0x1a7ee0a7efc70ed7429edef069a1dd001fbff378748d91f17ab1876dc6d10392 - Original searcher / attempted attacker:
0x1F23eb80f0c16758E4A55D48097c343bD20Be56f - Profitable frontrunner EOA:
0xa8bbb3742f299b183190a9b079f1c0db8924145b - Post-exploit fund recipient used in negotiations:
0x9a9122Ef3C4B33cAe7902EDFCD5F5a486792Bc3A - HopeLend lending pool:
0xc74b72bbf904bac9fac880303922fc76a69f0bb4 hETHWBTCreserve / hToken:0x25126F207Db7dC427415eA640ce0187767403907- Additional cash-out helper contract:
0x5a63e21ebded06dbfcb7271fbcef13c9f0844e74
- Successful exploit tx:
- Response / mitigation:
- Hope.money negotiated with the address controlling the recovered proceeds, ultimately moving most of the funds into a Gnosis Safe after allowing the frontrunner to keep a small bounty.
- The incident highlighted that Aave-style forks need the same empty-market hygiene as Compound forks: unused reserves cannot stay live and collateral-relevant just because their steady-state math looks familiar.
- It also reinforced that precision testing has to include extreme empty-market states and low-decimal assets like WBTC, not only normal-scale balances.
- The deeper lifecycle lesson is that a dormant reserve needs an explicit path to lose collateral authority once it becomes attacker-ownable again; historical listing age is not a substitute for current breadth.
Pattern tags
- supplier-index-inflation
- empty-market-exchange-rate-inflation
- fresh-market-initialization-failure
- The preserved shape is sharper than generic
flash-loan fee bug in an old Aave fork: HopeLend let a long-listed reserve fall back into an attacker-ownable opening denominator, let flash-loan premiums compound intoliquidityIndexover that dust supply, and then let the printed supplier-side mark become immediate cross-market borrow power. - This was also a clean
old reserve != mature reservefailure. HopeLend’s problem was not just thathETHWBTCwas empty; it was that the protocol never reclassified that empty state as economically equivalent to a fresh market again.
Why the exploit worked
- HopeLend let an old WBTC reserve keep full collateral authority after it had already drifted back into an effectively fresh state. Once the attacker reduced
hETHWBTCsupply to a single1e-8unit, the reserve no longer had a meaningful outside supplier base; it had one actor deciding what the next unit of fee income would mean. - In that state, flash-loan premiums stopped behaving like neutral protocol revenue and became solvency authorship. The reserve’s own
liquidityIndexmachinery turned repeated2,000 WBTCflash-loan fees into collateral value for the only remaining dust supplier, without any external oracle failure. - The
rayDivburn truncation then completed the cash-out path rather than standing alone. Without the under-burn, HopeLend would still have had a fake-collateral problem but a harder time converting it back into withdrawable WBTC; without the empty-market setup, the same rounding loss would have been economically small. The exploit paid because dormant-reserve lifecycle failure, fee-socialized index inflation, and low-decimal burn rounding lined up in one pipeline. - Downstream borrowing imposed no second distrust boundary. A reserve that had become first-actor-capturable again was still allowed to define borrow power for WETH, USDT, USDC, HOPE, and stHOPE, even after
liquidityIndexgrowth had become impossible under any healthy supplier distribution. - The preserved design lesson is therefore broader than
watch empty Aave markets: reserve lifecycle, supplier-index socialization, burn arithmetic, and cross-market collateral admission were one security object, and HopeLend split them apart.
Detection and audit pivots
- Ask the lifecycle question directly: what onchain fact proves an old reserve is still economically mature, and what demotes it back into quarantine if supplier breadth later collapses toward dust? If the answer is only
this market has existed for months, the control does not exist. - Reconstruct the entire supplier-value publication path: flash-loan premium routing,
liquidityIndex, hToken burn math, collateral factor, and sibling-market borrow checks should all tell one coherent story before a low-liquidity reserve can matter system-wide. - Simulate the exact dust state that made HopeLend exploitable: one
1e-8WBTC-denominated hToken unit, repeated same-reserve flash loans, and withdrawals under extreme index values. If the exploit only appears when the reserve becomes effectively empty again, the test harness still has to cover that state. - Treat low-decimal assets as adversarial when paired with rebasing supplier indexes. WBTC-sized minimum units make
1.99999999versus1hToken burns economically catastrophic in a way 18-decimal assets may not reveal during casual review. - Look for a downstream distrust boundary. Can a dormant reserve remain listed while collateral factor stays
0, flash loans stay off, or debt caps stay too small for one printed mark to drain sibling pools? If not, the protocol is still trusting old listings more than live supplier reality.
Failure-prevention checklist
- Reclassify dormant reserves as effectively fresh when supplier breadth or scaled supply collapses toward attacker-ownable dust. A 73-day-old market with one meaningful supplier should not retain the same collateral authority as a deep reserve.
- Keep same-reserve flash-loan premiums from socializing into
liquidityIndexwhile the denominator is thin. Route those fees to treasury, a pending bucket, or a quarantined reserve state until supplier breadth is healthy enough to deserve ordinary yield treatment. - Separate reserve reachability from cross-market solvency authority. A dormant market can stay visible or even deposit-open while collateral factor remains
0, flash loans stay off, and debt caps stay too small for one printed mark to drain sibling pools. - Make burn math safe at pathological index values and low-decimal asset granularities. If the economically correct burn is
~1.99999999minimum hToken units, the protocol still needs to consume enough supplier state that the withdrawal cannot mint value. - Add explicit denominator-health and impossible-growth checks: one meaningful supplier, microscopic hToken supply, or
liquidityIndexgrowth that only makes sense if one wallet owns the next unit of fee accrual should freeze or de-collateralize the reserve automatically. - Re-test empty-market behavior after launch, not only at launch. A reserve that later drifts back into dust supply should lose the same privileges a fresh reserve lacks instead of inheriting trust forever.
- Put blast-radius controls under the market anyway: isolated mode, per-reserve debt caps, correlated-borrow suppression, and fast pauses should stop one WBTC reserve from turning fee-index fiction into protocol-wide WETH and stablecoin bad debt.
- Treat mempool visibility as part of the risk model for atomic drain paths. If one profitable transaction can be copied and bribed into the block by a generalized frontrunner, emergency responses must assume the first visible exploit may not be the only one.
Audit prompts
- What exact reserve state proves
hETHWBTCis still mature today rather than merely old, and what onchain condition forces it back into quarantine if suppliers later redeem toward dust? - Can the same reserve both generate attacker-controlled flash-loan premiums and immediately socialize them over a denominator that one actor effectively owns?
- Which paths keep flash loans, collateral factor, liquidation thresholds, and sibling-market borrow caps live even when the reserve has only one meaningful supplier?
- At extreme
liquidityIndexvalues and WBTC-sized minimum units, how many hToken units should a withdrawal burn economically, and where does floor rounding let the protocol destroy less supplier state than the withdrawal consumes? - If a reserve has been dormant for months, what prevents
old listingfrom silently standing in foreconomically mature collateral objectduring governance review, monitoring, and automated controls? - What automated production signal would have caught HopeLend before cross-market drains began: one-address supplier concentration, impossible index growth, flash-loan fees accruing into a dust reserve, or a dust hToken balance suddenly gaining tens of WBTC of collateral value?
- Can the reserve stay locally observable while downstream trust stays off, or does every listed reserve automatically inherit collateral authority whether or not its denominator is still healthy?
- If the exploit path becomes visible in the mempool, what pause, cap, or deny path can still stop copied transactions from draining the same reserve before the next block is sealed?
Lessons that should already be standard
- Old reserves can become fresh-market bugs again. Historical listing age is not a substitute for current supplier breadth.
- Flash-loan premiums are not neutral income in a dust reserve. When one actor both generates and captures them, the protocol is letting that actor print collateral.
- Low-decimal assets turn
tiny precision issueinto treasury policy. Once one1e-8hToken unit can represent meaningful WBTC, floor rounding is part of solvency design. - Downstream borrowing is where empty-market accounting lies become real losses. A dormant side reserve should not get immediate line-of-sight to deep sibling liquidity without another distrust boundary.
- Lifecycle controls have to survive runtime drift, not just launch day. A market that becomes attacker-ownable months later still needs launch-grade skepticism.
- Mempool competition does not reduce exploit severity; it often increases it. Atomic solvency bugs should be modeled as publicly copyable once one exploiter demonstrates the path.
Why this incident matters
- HopeLend broadens the empty-market corpus with a non-launch-window Aave-style example: not a brand-new reserve like Radiant, but a stale and unused one that had become effectively fresh again while still remaining economically live.
- It preserves the exact mechanics of fee-concentrated
liquidityIndexinflation in an empty reserve, which is the Aave-family analog of direct donation inflation in Compound-style forks. - It also sharpens the lifecycle lesson preserved by the empty-market cluster:
market still existsandmarket still deserves cross-market solvency authorityare different claims. - It is also a clean reminder that solver and MEV dynamics are part of exploit reality: once an exploit is publicly visible in the mempool, whoever controls ordering may become the actual thief.
Internal linkages
- Closest recurring pattern: supplier-index-inflation.
- Broader empty-market family: empty-market-exchange-rate-inflation.
- Launch-window and effective-freshness framing: fresh-market-initialization-failure.
- Positive-design companion: effective-freshness-reclassification-and-dormant-market-quarantine — the sharper lifecycle follow-up is why a dormant WBTC reserve that had drifted back into a first-actor-capturable state was still allowed to define cross-market solvency instead of being reclassified, quarantined, or treated with launch-style skepticism again.
- Positive-design companion: bootstrap-state-irreversibility-and-supply-floor-design — the denominator-side follow-up is why a reserve should not be able to slide all the way back into attacker-ownable dust while still retaining full cross-market authority.
- Positive-design companions: fresh-market-seeding-and-activation-discipline and collateral-admission-lag-and-borrow-side-quarantine — the sharper design follow-up is why a low-breadth reserve needs both a durable floor and a still-binding downstream quarantine before it can matter system-wide.
- Positive-design companion: supplier-denominator-integrity-and-thin-market-fee-socialization — useful when the sharper follow-up is exactly why same-reserve flash-loan premiums should not have been allowed to socialize over a dust WBTC denominator at all.
- Useful contrast: radiant-capital-native-usdc-empty-market-liquidityindex-exploit-2024-01-02 — same Aave-style
liquidityIndexfamily, but with a fresh reserve instead of a dormant one. - Useful contrast: starlay-finance-acala-usdc-empty-market-liquidityindex-exploit-2024-02-08 — another Aave-style empty-market case where public evidence was sparse but the lifecycle lesson was the same: admitted reserve is not the same thing as mature collateral object.
- Adjacent pattern: solvency-check-bypass.
Control surface
-
The decisive leverage sat in dormant-reserve reclassification, flash-loan fee routing into
liquidityIndex, minimal-unit hToken supply, burn rounding, and collateral admission across the rest of the lending system. -
HopeLend did not fail because flash loans exist. It failed because an almost-empty WBTC reserve was allowed to convert fee income and integer truncation into protocol-wide borrow power.
-
The lifecycle mistake was upstream of the arithmetic: once
hETHWBTChad become economically first-actor-capturable again, the protocol never downgraded it fromold listingback tofresh-dangerous collateral object. -
Sources:
- https://www.certik.com/blog/hopelend-incident-analysis
- https://lunaray.medium.com/deep-dive-into-hopelend-hack-5962e8b55d3f
- https://www.quillaudits.com/blog/hack-analysis/hopelend-835k-exploit
- https://blog.solidityscan.com/hope-money-hack-analysis-d3ecd7006daf/
- https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/past/2023/README.md
- https://etherscan.io/tx/0x1a7ee0a7efc70ed7429edef069a1dd001fbff378748d91f17ab1876dc6d10392
-
Last reviewed: 2026-08-04 UTC