Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

ERC4626 Share Price Inflation Through Direct Token Transfer Manipulation

Description

The ZlpVault, which implements ERC4626, is susceptible to inflation attacks where an attacker can manipulate the share price by directly transferring tokens to the vault before legitimate deposits occur.

The vulnerability exists in the share price calculation mechanism:

uint256 previewSharesOut = assetsIn.mulDiv(
IERC4626(vault.indexToken).totalSupply() + 10 ** decimalOffset,
totalAssetsMinusVaultDebt,
MathOpenZeppelin.Rounding.Floor
);

While the contract includes a decimal offset to prevent zero-division and initial share manipulation, this protection is insufficient against donation-based attacks.

The vault's fundamental security issue lies in its share price calculation mechanism, which fails to protect against manipulation through direct token transfers. When calculating shares, the contract uses total assets without any safeguards against artificial inflation, making it susceptible to price manipulation despite having deposit caps in place. The absence of virtual shares or minimum deposit requirements further compounds this vulnerability, allowing attackers to manipulate the share price by inflating the asset balance before legitimate users deposit. This creates a scenario where the relationship between assets and shares can be distorted, leading to potential value extraction from subsequent depositors.

The decimal offset protection, while appearing secure at first glance, fails to address sophisticated donation attacks due to its limited scope. An attacker can bypass this protection by first establishing a minimal legitimate position in the vault, then manipulating the share price through direct token transfers.

This manipulation works because once shares are in circulation, the fixed decimal offset becomes insignificant compared to the potential magnitude of donated tokens. When the attacker artificially inflates the vault's total assets while maintaining a minimal share supply, the share price calculation becomes severely distorted, effectively diluting the value of any subsequent deposits. This exploit capitalizes on the static nature of the decimal offset, which loses its protective properties once the vault is active.

Proof of Concept

Attack Sequence:

  1. Attacker transfers a minimal amount (e.g., 1 wei) of tokens to get initial shares

  2. Attacker directly transfers a large amount of tokens to the vault

  3. Share price becomes inflated due to increased total assets

  4. When victims deposit, they receive disproportionately few shares

  5. Attacker extracts value through their inflated share position

Recommended Fixes

  1. Implement minimum initial deposit requirement:

function deposit(uint256 assets, address receiver) public override onlyMarketMakingEngine returns (uint256) {
if (totalSupply() == 0 && assets < MINIMUM_INITIAL_DEPOSIT) {
revert InitialDepositTooLow();
}
// ... rest of function
}
  1. Add virtual shares to price calculations:

uint256 virtualSupply = totalSupply() + VIRTUAL_SHARES;
uint256 previewSharesOut = assetsIn.mulDiv(
virtualSupply,
totalAssetsMinusVaultDebt,
MathOpenZeppelin.Rounding.Floor
);
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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