The _getAccruedYieldPrivate
function contains a critical vulnerability in its yield calculation logic due to unhandled token decimal mismatches and improper accounting of aToken
balances. This allows attackers to manipulate yield calculations and steal funds.
The function calculates "accrued yield" as aTokenBalance - wTokenSupply
without accounting for differences in token decimals or isolating protocol-earned aTokens
from external sources.
Decimal Mismatch:
aToken
(Aave) and wToken
(protocol) may use different decimals (e.g., aToken=18 vs. wToken=6).
Example: 1 aToken (1e18 units)
vs. 1 wToken (1e6 units)
are treated as equal in raw values, causing 1000x+ miscalculations.
Incorrect aToken Inclusion:
Any aTokens
sent to the contract (e.g., via direct transfer) are counted as yield. Attackers can artificially inflate aTokenBalance
to withdraw unauthorized funds.
Assumption Violation:
The code assumes aTokenBalance >= wTokenSupply
except for rounding errors. With decimal mismatches, aTokenBalance
could be smaller than wTokenSupply
even when yield exists, returning 0
erroneously.
High Severity: Attackers can:
Drain funds by donating aTokens
to manipulate yield calculations.
Exploit decimal mismatches to claim excess yield.
Cause denial-of-service by forcing 0
yield returns.
Financial Loss: Users lose deposited collateral due to incorrect yield distribution.
Reputational Risk: Protocol becomes untrustworthy due to fund mismanagement.
Manual Code Review
Decimal Normalization:
Isolate Protocol-Earned aTokens:
Track aTokens
minted through user deposits in a state variable:
Use _protocolATokenBalances[_collateralToken]
instead of direct balanceOf
checks.
Add Safety Checks:
Reject Direct aToken Transfers:
Implement a blackhole address for unexpected aToken
transfers or use a dedicated vault to isolate yield-bearing assets.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.