Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: high
Valid

Decimal Mismatch in Deposit Cap Check Leads to Incorrect Maximum Deposit Calculations

Summary

The maxDeposit function in ZlpVault.sol contains a critical decimal mismatch when comparing depositCap (18 decimals) with totalAssets() (asset decimals). This leads to incorrect calculation of the maximum deposit amount, potentially causing various issues with deposits depending on the scenario.

Vulnerability Details

This is the maxDeposit implementation:

function maxDeposit(address) public view override returns (uint256 maxAssets) {
// load the zlp vault storage pointer
ZlpVaultStorage storage zlpVaultStorage = _getZlpVaultStorage();
// cache the market making engine contract
IMarketMakingEngine marketMakingEngine = IMarketMakingEngine(zlpVaultStorage.marketMakingEngine);
// get the vault's deposit cap
@> uint128 depositCap = marketMakingEngine.getDepositCap(zlpVaultStorage.vaultId);//@audit check decimals
// cache the vault's total assets
@> uint256 totalAssetsCached = totalAssets();
// underflow check here would be redundant
unchecked {
maxAssets = depositCap > totalAssetsCached ? depositCap - totalAssetsCached : 0;
}
}

The totalAssets() function, inherited from ERC4626, returns the total amount of underlying assets in the vault using the asset's native decimals (e.g., 6 for USDC).

However, depositCap is maintained in 18 decimals. This has been confirmed by the sponsors in the discord:
discord-image

This presents an issue when vault's asset decimals != 18.

Example Scenario (USDC - 6 decimals):

  1. Deposit Cap: 1,000,000 USDC

  2. In 18 decimals: 1,000,000 * 10^18 = 1e24

  3. Current total assets: 900,000 USDC

  4. In 6 decimals: 900,000 * 10^6 = 9e11

In maxDeposit:

maxAssets = depositCap > totalAssetsCached ? depositCap - totalAssetsCached : 0;
// 1e24 > 9e11 = true
// maxAssets = 1e24 - 9e11 ≈ 1e24

The function returns a massive number (~1e24) as the maximum deposit amount, which is incorrect as it should be 100,000 USDC (1e11 in 6 decimals).

Impact

Function returns incorrect maximum deposit amounts that are much larger than intended making it impossible for the contract to properly enforce deposit caps

Tools Used

Manual Review

Recommendations

Normalize the decimals before comparison in maxDeposit

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

`totalAssets()` is not properly scaled to ZAROS precision

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!