Hi, I'm seeing an unexpected big change in the share:asset conversion rate when an ERC-4626 vault is emptied and refilled. When the vault is first created, the share:asset ratio is 1:1 and the vault has no share nor assets. When I run through a series of deposits and donations (explained below), then empty the vault and refill it, I'm seeing the share:asset conversion jump to 1:2.
I'm wondering is this expected behaviour, or do I need to protect the vault against storing tiny amounts of asset when shares is zero. For example if the vault shares ever drops to zero then the vault could burn any tiny asset values remaining.
Example
- Assume a vault using OZ v5.02 and the standard ERC-4626 contract. All values are default, there are no fees.
- The vault is for an asset called ASSET which has 6 decimals.
- An investor puts in 800_000 ASSET, gets back 800_000 SHARE.
- The vault earns +10% more ASSET, so 80_000 ASSETS gets donated in.
- The vault now has 880_000 ASSET and 800_000 SHARE.
- Investor wants to cash out, they want to convert all their shares to assets.
- They call vault.redeem(800_000 SHARE);
- They get back 879_999 ASSET, and 1 ASSET remains in the vault. The fact they get not all assets is due to rounding inside the calculation in _convertToAssets. This makes sense I think because the vault must never have too little assets, so rounding is done in favour of the vault.
- The vault now has 1 ASSET and 0 SHARE. It is empty of shares, but still has 1 ASSET.
- The investor decides to re-invest in the vault. They take 800_000 ASSET and deposit it.
- This time they get back 400_000 SHARE! Why is this? It is because the vault calculates the "share per asset" as floor of [ totalAssets + 1 / totalSupply (ie total shares) + 1 ] assets per share. This calculation becomes floor [ 1 + 1 / 0 + 1 ] = 2.