On March 15, 2026, Venus Protocol — one of BNB Chain's largest lending platforms — suffered a $3.7 million exploit that left $2.15 million in bad debt. The attacker didn't use a flash loan. They didn't exploit a zero-day. They used a vulnerability that Compound-fork auditors have flagged for years — and executed it with the patience of a sniper who spent nine months setting up the shot.
This is how supply cap donation attacks work, why they keep catching protocols off-guard, and what every lending protocol deploying low-liquidity collateral assets needs to fix.
The Setup: Nine Months of Patience
Most DeFi exploits happen in a single transaction block. This one started in June 2025.
The attacker, operating from address 0x1a35…6231, began quietly accumulating THENA (THE) tokens. Over nine months, they amassed approximately 14.5 million THE — roughly 84% of the token's circulating supply designated within Venus's supply cap.
The initial funding? 7,400 ETH funneled through Tornado Cash. That's roughly $15-20 million in operational capital, deployed with the kind of operational security that suggests this wasn't their first rodeo.
Attacker Timeline:
June 2025 → First THE token purchases begin
June-Feb → Slow accumulation across DEXs (avoiding detection)
March 15 → Supply cap bypass + price manipulation loop
March 15-16 → Asset drainage and exit
Key insight: Most on-chain monitoring tools are tuned to detect sudden large movements. A nine-month accumulation campaign across multiple wallets flies under the radar of standard whale-watching alerts.
The Core Vulnerability: Supply Cap Bypass via Direct Transfer
Venus Protocol, like most Compound-forked lending protocols, enforces supply caps to limit exposure to individual assets. The supply cap for THE was set to prevent exactly this kind of concentration risk.
The problem? The supply cap was only enforced on the mint function.
Here's the conceptual vulnerability:
// Simplified — what the vulnerable code path looks like
function mint(uint mintAmount) external returns (uint) {
// ✅ Supply cap check happens here
require(totalSupply + mintAmount <= supplyCap, "supply cap exceeded");
// Transfer tokens from user
underlying.transferFrom(msg.sender, address(this), mintAmount);
// Mint cTokens
_mint(msg.sender, cTokenAmount);
}
The attacker bypassed this entirely by directly transferring THE tokens to the vTHE contract address — a technique known as a "donation attack":
// What the attacker did instead:
// 1. Direct ERC-20 transfer (no mint function call)
IERC20(THE).transfer(address(vTHE), amount);
// This increases the contract's underlying balance
// WITHOUT triggering the supply cap check
// 2. The exchange rate calculation uses the contract's
// actual token balance:
// exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply
//
// By donating tokens, totalCash increases
// This inflates the exchange rate for existing cToken holders
The result: the attacker built a 53.2 million THE collateral position — nearly 3.7x the intended supply cap limit.
The Price Manipulation Loop
With an oversized collateral position established, the attacker initiated a cyclical manipulation strategy:
┌──────────────────────────────────────────────┐
│ │
│ 1. Deposit THE as collateral on Venus │
│ ↓ │
│ 2. Borrow liquid assets (BTCB, CAKE, BNB) │
│ ↓ │
│ 3. Use borrowed assets to buy more THE │
│ ↓ │
│ 4. THE price rises due to thin liquidity │
│ ↓ │
│ 5. TWAP oracle updates to higher price │
│ ↓ │
│ 6. Collateral value increases │
│ ↓ │
│ 7. Can borrow even more → back to step 2 │
│ │
└──────────────────────────────────────────────┘
The THE token price was pushed from approximately $0.27 to nearly $5 — an 18x increase driven almost entirely by the attacker's own buying pressure against thin DEX liquidity.
This is why the TWAP (Time-Weighted Average Price) oracle, which is designed to resist flash loan manipulation, still failed here: a TWAP oracle protects against instantaneous price spikes, but it's defenseless against sustained manipulation over multiple blocks.
The Drain
With massively inflated collateral, the attacker systematically borrowed:
| Asset | Amount | Approximate Value |
|---|---|---|
| BTCB (Wrapped Bitcoin) | ~20 BTC | ~$1.6M |
| CAKE | ~1.5M tokens | ~$800K |
| BNB | ~200 BNB | ~$120K |
| USDC | ~1.58M | $1.58M |
Total extracted: ~$3.7M
After the attacker stopped buying THE, its price collapsed back to ~$0.24. The leftover THE collateral was worth far less than the outstanding loans, creating $2.15M in bad debt — losses that the protocol (and ultimately its users) must absorb.
Why This Keeps Happening: The Compound Fork Supply Cap Problem
This isn't a novel attack. The supply cap bypass via direct transfer has been documented in security audits going back to 2022. Here's why it persists:
1. The Exchange Rate Assumption
Compound-style protocols calculate exchange rates using the contract's actual token balance:
function exchangeRateStored() public view returns (uint) {
uint totalCash = getCashPrior(); // Uses balanceOf(address(this))
uint totalBorrows = totalBorrowsCurrent();
uint totalReserves = totalReserves;
return (totalCash + totalBorrows - totalReserves) * 1e18 / totalSupply;
}
function getCashPrior() internal view returns (uint) {
// This is the problem — it reads actual balance,
// which includes "donated" tokens
return underlying.balanceOf(address(this));
}
Any token directly transferred to the contract inflates totalCash, which inflates the exchange rate, which inflates the effective collateral value.
2. Supply Cap Enforcement Gap
The supply cap check in mint() prevents users from minting new cTokens beyond the cap, but doesn't prevent the underlying balance from growing through direct transfers. The cap guards the front door while leaving the back door wide open.
3. Low-Liquidity Asset Risk Compounding
When you combine:
- A bypassable supply cap
- A low-liquidity underlying asset
- A TWAP oracle that can be manipulated over time
- Sufficient capital to corner the market
You get a protocol-draining exploit that's almost deterministic if you have the patience and capital.
Defensive Patterns: How to Actually Fix This
Pattern 1: Track Internal Balances
Don't rely on balanceOf(address(this)) for exchange rate calculations. Maintain an internal accounting variable:
uint256 private _internalBalance;
function _updateInternalBalance(uint256 amount, bool isDeposit) internal {
if (isDeposit) {
_internalBalance += amount;
} else {
_internalBalance -= amount;
}
}
function getCashPrior() internal view returns (uint) {
// Use tracked balance, not actual balance
return _internalBalance;
}
This is exactly how Aave V3 and Compound V3 (Comet) handle it — they track deposits through internal state rather than reading raw balances.
Pattern 2: Supply Cap on Collateral Value, Not Just Minting
Enforce caps on the total value of collateral, not just the supply:
function checkCollateralCap(address asset) internal view {
uint256 totalCollateralValue = getCollateralValue(asset);
require(
totalCollateralValue <= collateralValueCap[asset],
"collateral value cap exceeded"
);
}
Pattern 3: Liquidity-Aware Collateral Factors
Dynamically adjust collateral factors based on on-chain liquidity:
function getEffectiveCollateralFactor(address asset) public view returns (uint) {
uint256 baselineCF = collateralFactor[asset];
uint256 onChainLiquidity = getOnChainLiquidity(asset);
uint256 totalSupplied = getTotalSupplied(asset);
// If supplied amount exceeds safe % of liquidity, reduce CF
uint256 utilizationRatio = totalSupplied * 1e18 / onChainLiquidity;
if (utilizationRatio > SAFE_THRESHOLD) {
// Linear decrease — aggressive positions get lower CF
return baselineCF * SAFE_THRESHOLD / utilizationRatio;
}
return baselineCF;
}
Pattern 4: Concentration Limits Per Account
Even if supply caps hold globally, a single account controlling 84% of supplied collateral should trigger circuit breakers:
modifier checkConcentration(address account, address asset) {
_;
uint256 accountShare = accountCollateral[account][asset] * 1e18
/ totalCollateral[asset];
require(accountShare <= MAX_CONCENTRATION, "concentration limit exceeded");
}
Pattern 5: Anomaly Detection for Slow Accumulations
This attack took nine months. On-chain monitoring should flag:
- Single-entity accumulation above X% of a token's supply cap
- Collateral positions that exceed N% of total market liquidity
- TWAP deviations that correlate with large deposit activity
Tools like Forta, OpenZeppelin Defender, or custom monitoring bots can detect these patterns in real-time.
The Bigger Picture: Lending Protocol Risk Taxonomy
The Venus exploit fits a pattern I call the "Collateral Weaponization" attack class:
| Attack Vector | Example | Core Issue |
|---|---|---|
| Flash loan oracle manipulation | Mango Markets ($114M, 2022) | Spot price oracle |
| Supply cap bypass + slow manipulation | Venus Protocol ($3.7M, 2026) | Supply cap enforcement gap |
| Vault inflation / donation | ERC-4626 first-depositor attacks | Exchange rate manipulation |
| Governance token accumulation | Beanstalk ($182M, 2022) | Flash loan voting |
All of these share a common root: the protocol treats a manipulable number (price, exchange rate, vote count) as trustworthy input for high-value decisions (lending, liquidation, governance).
Takeaways
Supply caps are security theater if they only guard
mint(). Direct transfers must be accounted for in exchange rate calculations.TWAP oracles don't protect against sustained manipulation. If an attacker has enough capital and patience, they can move a TWAP just as effectively as a spot price — it just takes longer.
Low-liquidity collateral is a ticking time bomb. Any asset where a single actor can meaningfully move the price should have stricter guardrails: lower collateral factors, concentration limits, and liquidity-aware caps.
Nine months of patience > one block of flash loans. The future of DeFi exploits isn't getting faster — it's getting slower and more methodical. Your monitoring needs to match.
Compound V2-style accounting is a known risk. If your protocol still uses
balanceOf(address(this))for exchange rates, you are vulnerable. Migrate to internal balance tracking.
The Venus team has paused THE markets and zeroed collateral factors on six additional low-liquidity assets. But the bad debt remains. For every protocol running a Compound V2 fork with low-liquidity collateral: audit your supply cap enforcement today, not tomorrow.
This analysis is based on publicly available on-chain data and incident reports. For detailed transaction traces, see the attacker address 0x1a35…6231 on BscScan.
Top comments (0)