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.