The ZlpVault
contract enforces a deposit cap using the totalAssets()
function within maxDeposit()
. However, totalAssets()
includes all assets held by the contract, even those sent externally without going through the deposit()
function. An attacker can exploit this by artificially inflating totalAssets()
via direct asset transfers, reaching the deposit cap and preventing legitimate users from depositing. This results in a Denial-of-Service (DoS) attack on the vault.
The problematic logic exists in the maxDeposit()
function:
The issue arises because totalAssets()
is used to calculate the deposit limit. The function totalAssets()
is inherited from ERC4626Upgradeable and is likely implemented as:
Since totalAssets()
includes all tokens held by the contract, an attacker can artificially inflate this value by sending tokens directly to the vault. When totalAssets()
reaches depositCap
, maxDeposit()
will return 0
, blocking all new deposits.
Denial-of-Service (DoS) Attack: Attackers can disrupt normal vault operations by preventing deposits.
Liquidity Lock: If deposits are required for further vault operations the protocol’s functionality is severely impacted.
Manual
ERC4626 Standard Review
Instead of relying on totalAssets()
, maintain a separate state variable to track deposited funds:
Introduce a function to remove externally sent assets and transfer them to the protocol treasury:
Instead of outright blocking deposits, allow excess funds but introduce an emergency withdrawal mechanism.
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.