The ZlpVault contract's deposit cap mechanism can be bypassed through direct token transfers. The maxDeposit
function relies on ERC4626's totalAssets()
—which includes tokens sent directly to the vault—to enforce the deposit cap. This flaw allows an attacker to artificially inflate the vault's asset balance outside of the authorized deposit function, thereby blocking legitimate deposits.
Location: ZlpVault.sol
(approximately lines 89-108)
The core issue lies in the implementation of the maxDeposit
function:
Since totalAssets()
aggregates all tokens held by the vault, including those sent via plain transfers, an attacker can bypass proper deposit accounting by directly sending tokens to the vault. As demonstrated in our tests, this manipulation can completely block legitimate deposit attempts.
Deposit Blockage: An attacker can prevent further deposits by artificially inflating the vault's recorded asset balance.
Disruption: Legitimate users may have their deposits reverted, potentially forcing them to pay higher gas fees or wait until the malicious tokens are removed.
Protocol Integrity: The incorrect assumption in deposit cap enforcement could affect other protocol components relying on accurate asset tracking.
Initial Deposit & Direct Transfer Attack:
The deposit cap is set at 1000 USDC.
A legitimate deposit of 800 USDC yields maxDeposit
of 200 USDC.
An attacker then directly transfers 200 USDC, which makes totalAssets()
equal to 1000 USDC.
As a result, maxDeposit
returns 0, and subsequent deposit attempts revert (e.g., with a SlippageCheckFailed
error).
Repeated Small Direct Transfers:
Multiple small transfers can cumulatively deplete the available deposit capacity.
Precision Testing with Small Amounts:
Even very small transfers accurately reduce the available max deposit, highlighting the precision of this bypass.
These tests conclusively prove that direct token transfers can be used to bypass the intended deposit cap logic.
Separate Deposit Accounting:
Track payments made through the authorized deposit
function separately (e.g., using a totalDeposited
variable) and base maxDeposit
calculations on this value instead of totalAssets()
.
Example Fix:
Reject Direct Transfers:
Consider overriding ERC4626's asset handling functions to reject direct transfers that bypass proper deposit logic.
Enhanced Monitoring and Auditing:
Implement monitoring to detect abnormal increases in totalAssets()
and ensure vault operations reflect only legitimate deposits.
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.