Skip to main content
Sigvex

Vault Rounding Remediation

How to protect ERC-4626 vaults from share-price rounding abuse and first-depositor inflation attacks.

Vault Rounding Remediation

Overview

Related Detector: Vault Rounding

Tokenized vaults (ERC-4626) convert between assets and shares with integer division, so rounding direction decides who absorbs the truncated remainder. If conversions round in the user’s favour, a depositor can extract value; and an empty vault is vulnerable to the classic inflation attack, where the first depositor mints one wei-share, donates assets directly to the vault to inflate the share price, and makes later deposits round down to zero shares. Remediation combines correct rounding direction with an inflation defence.

Before (Vulnerable)

// Rounds shares up on deposit and assets up on withdraw — both favour the user.
// Empty-vault share price is unprotected, enabling the inflation attack.
function deposit(uint256 assets) external returns (uint256 shares) {
    shares = totalSupply == 0 ? assets : (assets * totalSupply + totalAssets - 1) / totalAssets;
    _mint(msg.sender, shares);
}

After (Fixed — round against the user, add virtual shares)

// Round shares DOWN on deposit / mint fewer; round assets DOWN on redeem.
// Virtual shares and assets (a constant offset) make the empty-vault price
// impossible to inflate to a meaningful ratio.
uint256 private constant VIRTUAL = 1e3;

function convertToShares(uint256 assets) public view returns (uint256) {
    return (assets * (totalSupply + VIRTUAL)) / (totalAssets + 1);   // floor division
}

The most robust option is to inherit a reviewed ERC-4626 implementation (OpenZeppelin’s uses the virtual-shares approach) rather than hand-rolling the conversion math. Optionally seed the vault with a small first deposit at deployment so it is never empty.

Common Mistakes

  • Rounding both deposit and withdraw in the user’s favour, so every round trip leaks a wei to the caller.
  • Adding a minimum-deposit check but leaving the empty-vault share price inflatable.
  • Copying mulDiv with Rounding.Up where Rounding.Down is required for the protocol-favouring direction.

References