0VIX vGHST Donation / Oracle Self-Liquidation Exploit (2023-04-28)
- Name: 0VIX vGHST donation / oracle self-liquidation exploit
- Date: 2023-04-28
- Protocol: 0VIX
- Chain: Polygon PoS
- Category: donation / share-price manipulation / oracle manipulation / self-liquidation monetization / lending bad-debt extraction
- Loss: about $2M
- Summary: 0VIX listed Aavegotchi’s
vGHSTwrapper through anovGHSTCompound-style market and priced it with a customVGHSTOraclethat simply multiplied the ChainlinkGHST / USDfeed byvGHST.convertVGHST(1e18). But Aavegotchi’svGHSTwrapper computedconvertVGHST()fromtotalGHST(address(this)) / totalSupply(), so directGHSTtransfers into the wrapper increased assets-per-share without minting newvGHST. The attacker used flash loans to build a two-contract position: the main contract borrowed most liquid assets from 0VIX, while a helper contract postedUSDCcollateral and loop-borrowedvGHST. After directly donating about1.656M GHSTto thevGHSTcontract, the printedconvertVGHST()rate made the helper’svGHSTdebt far more expensive on paper. The main contract then liquidated that helper debt, seizedoUSDCcollateral at the inflated mark, redeemed theovGHSTit had accumulated earlier, unwound the borrowed assets, and exited with roughly $2M. - Trigger / entry point:
- 0VIX did not price
ovGHSTfrom an external market oracle alone. Its customVGHSTOraclereadvGHST.convertVGHST(1 ether)from the wrapper contract at0x51195e21BDaE8722B29919db56d95Ef51FaecA6Cand multiplied that live conversion rate by the Chainlink GHST feed. - Aavegotchi’s
vGHSTwrapper itself treated each share asshare * totalGHST(address(this)) / totalSupply(). BecausetotalGHST(address(this))included GHST sitting in the contract, a raw token transfer into the wrapper increasedconvertVGHST()immediately even though no new shares were minted. - 0VIX accepted that live, attacker-changeable wrapper exchange rate as lending and liquidation truth.
- The protocol also allowed the same economic actor to control both the underwater borrower and the liquidator through separate contracts.
- 0VIX did not price
- Root cause:
- 0VIX treated a wrapper’s spot
assets / sharesexchange rate as a trustworthy oracle even though one actor could increaseassetsvia direct donation. - The protocol therefore converted normal wrapper accounting into a printable collateral and debt price.
- Because liquidation math honored the same manipulated mark, the attacker did not only create false insolvency; they also captured the liquidation bonus themselves.
- In practice, the system fused three brittle assumptions: that
convertVGHST()could not jump violently inside one transaction, that wrapper exchange-rate truth was safe to use as a lending oracle, and that liquidators would be economically independent from the borrower they were rescuing.
- 0VIX treated a wrapper’s spot
- Exploit path:
- In the main exploit transaction
0x10f2c28f5d6cd8d7b56210b4d5e0cece27e45a30808cd3d3443c05d4275bb008, the attacker assembled flash-loaned working capital across Aave v3, Aave v2, and Balancer: about1.95M GHST,24.5M USDC, and6.15M USDTin aggregate. - The main attack contract entered Aavegotchi’s wrapper with about
294,000 GHST, receivedvGHST, deposited itsUSDTinto 0VIX’soUSDTmarket, entered that market in the Comptroller, and borrowed out most of the remaining liquid assets across 0VIX’s live pools. - The attacker then transferred about
24.5M USDCplus its currentvGHSTbalance to a helper contract. - The helper minted
oUSDC, entered 0VIX with that USDC collateral, borrowed all availablevGHSTfrom theovGHSTmarket, and then loopedovGHST.mint(vGHSTAmount)plusovGHST.borrow(vGHSTAmount)about 24 times to build a large leveragedvGHSTdebt position. - The helper sent the resulting
ovGHSTcTokens and residualvGHSTback to the main attack contract, then borrowed additionalUSDTand about720,000 USDC, leaving the helper heavily exposed to any increase in the oracle price ofvGHST. - With the two-contract structure in place, the main contract directly transferred about
1,656,000 GHSTto thevGHSTwrapper contract. No newvGHSTshares were minted, buttotalGHST(address(this))rose immediately, soconvertVGHST(1e18)and therefore 0VIX’sVGHSTOracleprice both jumped. - That price jump made the helper’s borrowed
vGHSTfar more expensive relative to itsUSDCcollateral, pushing the helper into liquidatable territory. - The main attack contract then used the
vGHSTit controlled to callovGHST.liquidateBorrow(helper, ...)repeatedly, seized the helper’soUSDCcollateral, and also redeemed theovGHSTposition it had accumulated earlier for underlyingvGHST. - After capturing the seized
USDCand unwinding the redeemed and previously borrowed assets into stronger tokens, the attacker repaid the flash loans, bridged funds toward Ethereum, and netted roughly $2M.
- In the main exploit transaction
- What the attacker needed to be true:
- 0VIX had to read
vGHST.convertVGHST()live, with no haircut, donation filter, delayed update, or cap on how much one block could move the wrapper-derived price. - Direct
GHSTtransfers into the wrapper had to affecttotalGHST(address(this))and thereforeconvertVGHST()immediately. - 0VIX needed enough remaining liquidity in
USDC,USDT,WETH,WBTC,MATICX,stMATIC, and related markets for the first borrowing leg to matter economically. - The protocol had to let the same attacker control both the insolvent borrower and the liquidator, so the liquidation incentive stayed inside the attack bundle.
- Liquidations and cToken transfers had to remain live long enough for the attacker to seize
oUSDCcollateral and redeem theovGHSTposition before operators paused the system.
- 0VIX had to read
- Technical anatomy worth remembering:
- This was not mainly a thin-spot
GHSTpump. The decisive print happened inside the wrapper exchange-rate path:VGHSTOracleaskedconvertVGHST(1e18), andconvertVGHST()trusted raw wrapper-held GHST. - Some secondary descriptions say the attacker
deposited vGHST into the oracle contract; the more precise description is that they donatedGHSTdirectly into thevGHSTwrapper, and the oracle then honestly read the manipulated wrapper state. - 0VIX is a useful bridge case between donation-share-price-manipulation and oracle-manipulation. The oracle itself was not externally spoofed; it truthfully published a wrapper exchange rate the attacker could print.
- It is also a strong self-liquidation-monetization case: the attacker created the insolvency and then captured the liquidation discount against their own helper account.
- The exploit shows how a wrapper-share oracle can be dangerous even when the wrapper is non-empty and widely integrated. The key question is not whether
convertToAssetsworks as designed, but whether a lending protocol should honor it as same-block solvency truth.
- This was not mainly a thin-spot
- Representative transactions and addresses:
- Main exploit tx:
0x10f2c28f5d6cd8d7b56210b4d5e0cece27e45a30808cd3d3443c05d4275bb008 - Attacker address highlighted in public reports:
0x702ef63881b5241ffb412199547bcd0c6910a970 - Vulnerable
vGHSTwrapper:0x51195e21BDaE8722B29919db56d95Ef51FaecA6C - 0VIX
VGHSTOracle:0xBEF0a2A4885EA5Df895047F49c202525B73DCc68 - 0VIX
ovGHSTmarket:0xE053A4014b50666ED388ab8CbB18D5834de0aB12 - 0VIX
oUSDTmarket:0x1372c34acC14F1E8644C72Dad82E3a21C211729f - 0VIX
oUSDCmarket:0xEBb865Bf286e6eA8aBf5ac97e1b56A76530F3fBe - 0VIX Comptroller / Unitroller:
0x8849f1a0cB6b5D6076aB150546EddEe193754F1C
- Main exploit tx:
- Response / mitigation:
- 0VIX publicly paused its Polygon PoS and zkEVM markets while investigating, including minting, transfers, and liquidations.
- Public reporting after the incident described negotiations with the attacker and at least partial return of funds, though the exploit still stands as a material oracle and liquidation-design failure.
- The immediate technical lesson was to delist or heavily constrain wrapper assets whose exchange rate can move from direct donations or other same-block balance changes.
- More generally, Compound-style markets should not treat wrapper
convertToAssetsmath as money-good collateral truth unless the integration explicitly hardens against donation-sensitive accounting and attacker-controlled self-liquidation.
Why this incident matters
- 0VIX preserves a clean
wrapper exchange-rate oracle + self-liquidationvariant that is distinct from thin-spot pumps like Moola and from non-liquidation donation cases like some early ERC-4626 inflation exploits. - It broadens the donation/share-price corpus with an Aavegotchi-specific wrapper case where the dangerous state lived in a custom
convertVGHST()function rather than in a canonical ERC-4626 vault. - It is also a good reminder that once a manipulable wrapper price is admitted into lending math, liquidation can become the payout rail rather than the defense.
- The preserved healthy boundary was not only
price the wrapper better, buta donation-sensitive wrapper ratio becoming locally readable is still not the same thing as that ratio becoming canonical lending truth and then same-bundle liquidation authority against stronger collateral.
Three wrapper-oracle promotions this incident collapsed
-
Aavegotchi
vGHSTwrapper state changed- The attacker’s direct donation of about
1.656M GHSTinto thevGHSTwrapper raisedtotalGHST(address(this))without minting offsettingvGHSTshares, soconvertVGHST(1e18)jumped immediately. - That only proved the wrapper’s local accounting state had moved. It did not yet mean the new ratio deserved to become lending-solvency truth for 0VIX.
- The attacker’s direct donation of about
-
0VIX promoted that wrapper-local ratio into canonical solvency truth
VGHSTOraclemultiplied the trusted ChainlinkGHST / USDfeed by liveconvertVGHST()output and treated the result as the authoritativeovGHSTprice for debt valuation and liquidation eligibility.- This was the decisive false promotion: a donation-authorable wrapper mark stopped being just
Aavegotchi wrapper accountingand became0VIX's canonical answer about what vGHST debt and collateral were worth.
-
The attacker spent against that published truth through self-liquidation
- Once the helper account’s
vGHSTdebt repriced upward, the main account could liquidate it, seizeoUSDCcollateral at the manipulated mark, redeem accumulatedovGHST, and unwind back into stronger assets. - This is where the printable wrapper rate became realized reserve loss. The manipulated mark did not merely distort paper health factors; it inherited immediate liquidation and redemption authority against live 0VIX liquidity.
- Once the helper account’s
Pattern tags:
- Direct donation / share-price manipulation against a wrapper-specific exchange-rate oracle.
- Wrapper-derived solvency failure where debt pricing and liquidation math both trusted the same attacker-printable
convertVGHST()output. - Self-liquidation monetization: the same economic actor controlled the underwater borrower and the liquidator through separate contracts.
- Design companions: vault-share-truth-security-object, liquidator-independence-assumptions, and collateral-admission-lag-and-borrow-side-quarantine.
Why the exploit worked
- 0VIX’s custom
VGHSTOraclemultiplied a trusted GHST feed by a live wrapper conversion function that could be moved with a direct donation intovGHST. - A raw GHST transfer increased
vGHST’s numerator-side backing without minting new shares, so the oracle faithfully published attacker-authored wrapper state. - The two-contract position let the attacker create the unhealthy borrower themselves, then capture the liquidation discount on the other side instead of leaving that value for an independent keeper.
- 0VIX treated the manipulated wrapper rate as immediate debt and liquidation truth, and retained enough liquid collateral elsewhere in the system for the seized
oUSDCand borrowed assets to cash out into real value.
Detection and audit pivots
- Search for custom wrapper oracles that multiply a base asset feed by
convertToAssets,pricePerShare,exchangeRate, or protocol-specific wrapper math read live from another contract. - Ask whether direct transfers into the wrapper, staking recipient changes, or other off-path balance increases can move that conversion function without share issuance.
- Model borrower and liquidator as one adversary. If a helper account can be made unhealthy by the same actor who later liquidates it, the liquidation bonus is part of the exploit surface.
- Check whether a sudden wrapper-rate jump on the borrowed asset side can force liquidations against stronger collateral before any cap, pause, or delayed-mark mechanism reacts.
- Review whether listed wrapper assets can simultaneously serve as price inputs, debt assets, and liquidation ammunition across sibling accounts.
Failure-prevention checklist
- Do not compose a trusted base-asset feed with a live wrapper conversion function unless the wrapper’s numerator-side backing is donation-neutral or otherwise explicitly recognized through hardened accounting rails.
- Haircut, cap, or quarantine wrapper-derived price moves before they become borrow, liquidation, or seize authority; a same-block
convertToAssetsjump should not become immediate solvency truth. - Treat raw balance changes into wrappers as hostile by default. If direct donations, rescue transfers, reward top-ups, or staking-recipient changes can move share value, require explicit recognition rather than ambient balance reads.
- Review borrowed-asset listings as well as collateral listings. A manipulable wrapper price can be monetized by making debt expensive on paper and then liquidating stronger collateral, not only by over-borrowing against the wrapper itself.
- Enforce bounded-loss controls around wrapper integrations: borrow caps, isolated listings, delayed collateral enablement, liquidation throttles, and fast pause paths should all assume the wrapper exchange rate may be attacker-authored.
- Make self-liquidation assumptions explicit. If the same actor can cheaply control borrower and liquidator accounts through helper contracts, the liquidation incentive is part of the attack surface and should be constrained accordingly.
- Rehearse the
wrapper rate jumps 2x-10x in one transactioncase in borrow, health-factor, and liquidation simulations. If the protocol’s answer is justthat should not happen, the integration is incomplete.
Audit prompts
- What exact function defines wrapper truth here:
convertToAssets,pricePerShare,exchangeRateStored, a rebasingbalanceOf, or a protocol-specific wrapper helper likeconvertVGHST()? - Can a raw token transfer into the wrapper move that function without minting new wrapper shares or triggering a reviewable accounting-recognition step?
- Does the protocol ever multiply a trusted external feed by an attacker-movable wrapper ratio and then call the result an oracle?
- If the wrapper mark spikes inside one block, which downstream paths trust it immediately: borrowing power, liquidation eligibility, seize math, redeem math, or reserve accounting?
- Can the same economic actor create the unhealthy borrower and then capture the liquidation bonus through a helper account, alternate wallet, or router-mediated path?
- Are borrow caps, isolation rules, or collateral factors calibrated to the possibility that the wrapper’s exchange rate is locally printable even when the base asset’s own oracle is sound?
- What blast-radius limit stops a wrapper-mark anomaly from turning into systemwide stablecoin or blue-chip collateral extraction before governance or operators can react?
- If the wrapper is kept for product reasons, what independent sanity bound proves that one unit of wrapper debt or collateral cannot outrun plausible underlying earnings by an attacker-sized multiple in one transaction?
Lessons that should already be standard
- A wrapper exchange rate is an oracle the moment lending or liquidation code honors it as money-good truth.
The oracle read the contract honestlyis not a defense when the contract state being read was attacker-authored through an ambient balance change.- Borrow-side pricing can be just as dangerous as collateral-side pricing. Making debt suddenly expensive on paper can be enough to unlock liquidation-based cash-out against stronger collateral.
- Liquidation discounts are not protective by default. Once borrower and liquidator independence disappears, the liquidation bonus becomes attacker revenue.
- Wrapper integrations should be reviewed as joint accounting-and-market-structure decisions, not as simple token listings. The dangerous question is not just
is GHST priced correctly?butwho is allowed to define vGHST share truth this block? - Same-block solvency trust in
convertToAssets-style math is a design choice, not a neutral convenience. If a wrapper can be donated into, harvested into, or otherwise topped up off-path, immediate trust is usually too generous.
Internal linkages
- Core recurring pattern: donation-share-price-manipulation.
- Adjacent parent pattern: oracle-manipulation.
- Key monetization rail: self-liquidation-monetization.
- Useful comparison case: oracle manipulation exploit (2022-12-10) — another
wrapper exchange rate priced as collateral truthcase, but without 0VIX’s cleaner attacker-controlled liquidation leg. - Useful comparison case: Venus ZKsync wUSDM donation exchange-rate exploit (2025-02-27) — another exchange-rate inflation case where attacker-controlled liquidation, not just borrowing, was the monetization path.
Control surface
-
The decisive leverage sat in 0VIX’s custom
VGHSTOracle, AavegotchivGHSTaccounting that let direct donations changeconvertVGHST()without minting shares, and liquidation rules that let the same attacker own both the borrower and liquidator sides of the trade. -
0VIX did not merely list a volatile asset. It treated a printable wrapper exchange rate as immediate debt and collateral truth, then paid the attacker to liquidate the bad state they had just manufactured.
-
Sources:
- https://github.com/0Vix/0vix-contracts/blob/main/oracles/vGHSTOracle.sol
- https://polygonscan.com/address/0x51195e21bdae8722b29919db56d95ef51faeca6c#code
- https://polygonscan.com/tx/0x10f2c28f5d6cd8d7b56210b4d5e0cece27e45a30808cd3d3443c05d4275bb008
- https://raw.githubusercontent.com/SunWeb3Sec/DeFiHackLabs/main/src/test/2023-04/0vix_exp.sol
- https://quillaudits.medium.com/decoding-ovix-protocols-2-million-exploit-quillaudits-92befc250e7c
- https://blog.solidityscan.com/ovix-protocol-hack-analysis-oracle-price-manipulation-4bd2755ea85e/
- https://decrypt.co/138262/polygon-lending-protocol-0vix-pauses-protocol-exploit
-
Last reviewed: 2026-08-02 UTC