Donation Attacks on Compound-Fork Lending Protocols: Dissecting the Venus Protocol THE Exploit
These articles are AI-generated summaries. Please check the original sources for full details.
Donation Attacks on Compound-Fork Lending Protocols: Dissecting the Venus Protocol THE Exploit
Venus Protocol on BNB Chain was drained of approximately $3.7 million on March 15, 2026. The attacker spent nine months accumulating 84% of the THE token supply cap before bypassing deposit mechanisms to inflate the vToken exchange rate.
Why This Matters
The persistence of donation attacks highlights a critical gap between the legacy architecture of Compound V2 forks and modern security requirements. While Compound V2 was revolutionary in 2020, its reliance on raw balanceOf() calls for accounting creates a vulnerability where direct ERC-20 transfers bypass high-level logic like supply caps and minting restrictions, leading to over $230 million in cumulative historical losses across the ecosystem.
Key Insights
- Attacker accumulated 14.5 million THE tokens over nine months (June 2025 - March 2026) to avoid triggering price alerts.
- Direct token transfers to the vTHE contract inflated the exchange rate from approximately 1.03 to 3.17 without increasing the cToken supply.
- Historical losses from this vulnerability class include Hundred Finance ($7.4M in 2022) and Euler Finance ($197M in 2023).
- Compound V3 (Comet) and Aave V3 mitigate this risk by using internal scaled balance accounting rather than raw token balances.
- The attack was amplified by an oracle feedback loop where borrowed funds were used to manipulate thin-market spot prices.
Working Examples
Vulnerable Compound V2 exchange rate logic using raw balanceOf() which includes ‘donated’ tokens.
function getCashPrior() internal view returns (uint) {
return IERC20(underlying).balanceOf(address(this));
}
function exchangeRateStored() public view returns (uint) {
uint _totalSupply = totalSupply;
if (_totalSupply == 0) return initialExchangeRateMantissa;
uint totalCash = getCashPrior();
uint exchangeRate = (totalCash + totalBorrows - totalReserves) * 1e18 / _totalSupply;
return exchangeRate;
}
Defense via internal accounting: tracking deposits and withdrawals manually to ignore direct transfers.
uint256 internal _totalCash;
function getCashPrior() internal view returns (uint) {
return _totalCash;
}
function mintInternal(uint mintAmount) internal {
_totalCash += mintAmount;
}
function redeemInternal(uint redeemAmount) internal {
_totalCash -= redeemAmount;
}
Practical Applications
- Protocol teams should implement donation detection by routing unexpected balance increases to ‘totalReserves’ instead of the exchange rate numerator.
- Risk engines should dynamically scale collateral factors based on on-chain liquidity to prevent thin-market manipulation.
- Auditors must verify that supply caps are enforced at the balance level rather than just within the mint() function entry point.
References:
Continue reading
Next article
Build Your First MCP Server in 10 Minutes with TypeScript
Related Content
Securing the npm Supply Chain: Lessons from the 2026 Axios Attack
The 2026 Axios supply chain attack compromised 83 million weekly downloads by exploiting legacy tokens to bypass SLSA provenance attestations.
Hardening CI/CD Pipelines Against Zero-Day Supply Chain Attacks
Two supply chain attacks targeting GitHub Actions and npm dependencies hit CI/CD pipelines in March 2026, highlighting critical vulnerabilities in mutable tags.
Secure P2P Data Streaming for Multi-Agent AI Swarms via Pilot Protocol
Stream structured server anomalies from GCP to LangChain orchestrators using Pilot Protocol's virtual port 1000, bypassing firewalls without public ports.