Decimal Offset

The _decimalsOffset() value in OpenZeppelin's ERC4626 that scales virtual shares; defaults to 0 (no protection) and must be overridden.

The decimal offset is the integer returned by OpenZeppelin's _decimalsOffset() function in its ERC4626 base contract. It controls how many virtual shares the vault mints per unit of underlying asset: the conversion math uses 10**offset virtual shares. A larger offset makes the vault's share unit smaller and the inflation attack exponentially more expensive to execute.

The default-zero trap

The single most important fact about the decimal offset is that its base implementation returns 0. An offset of 0 leaves only the +1 virtual asset, which provides almost no protection against a well-funded or flash-loaned attacker. Teams routinely inherit OpenZeppelin's ERC4626 believing they are protected, without overriding _decimalsOffset() — inheriting the interface of the defense with none of its strength.

Choosing a value

1function _decimalsOffset() internal view virtual override returns (uint8) {
2 return 6; // 3 is a practical floor; 6+ for high-value assets
3}

A common range is 3 to 6 or higher. The offset should be large enough that donating enough underlying to move the price per share costs more than any depositor's balance an attacker could steal. Higher offsets increase the virtual-share dilution slightly, so the value is a security-versus-yield trade-off chosen per asset.

Need expert guidance on Decimal Offset?

Our team at Zealynx has deep expertise in blockchain security and DeFi protocols. Whether you need an audit or consultation, we're here to help.

Get a Quote