hats-finance / StakeWise-0xd91cd6ed6c9a112fdc112b1a3c66e47697f522cd

Liquid staking protocol for Ethereum
Other
0 stars 0 forks source link

sharesToBurn in _redeemOsToken should round up but didn't #138

Open hats-bug-reporter[bot] opened 1 year ago

hats-bug-reporter[bot] commented 1 year ago

Github username: @turvec Submission hash (on-chain): 0x392287e70d2ea5e3d056d33b89cef08d00f2c6d6b270fc5c766c401f0394d11d Severity: low

Description: Description\ sharesToBurn in _redeemOsToken should round up but didn't which favor the users and not the vault itself in both redeemOsToken and liquidateOsToken calls, causing VaultOsToken.sol to not be ERC4626-compliant

Attack Scenario\

Attachments

  1. Proof of Concept (PoC) File

according to EIP-4626- Vault, implementers should be aware of the need for specific, ๐จ๐ฉ๐ฉ๐จ๐ฌ๐ข๐ง๐  ๐ซ๐จ๐ฎ๐ง๐๐ข๐ง๐  ๐๐ข๐ซ๐ž๐œ๐ญ๐ข๐จ๐ง๐ฌ across the different mutable and view methods, as it is considered most secure to favor the Vault itself during calculations over its users:

https://eips.ethereum.org/EIPS/eip-4626 https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC4626.sol#L229

However in the implementation of _redeemOsToken() which is called in both redeemOsToken and liquidateOsToken.

    uint256 sharesToBurn = convertToShares(receivedAssets);

the function calculates the user shares to burn but instead of using the internal _convertToShares, it call the public convertToShares() which Rounds Down by default

   function convertToShares(uint256 assets) public view override returns (uint256 shares) {
    return _convertToShares(assets, Math.Rounding.Down);
  }

and then burn user shares using the Rounded Down value

     _burnShares(owner, sharesToBurn);
  1. Revised Code File (Optional)

An easy fix is to change this line of code:

    uint256 sharesToBurn = convertToShares(receivedAssets);

to this:

    uint256 sharesToBurn = _convertToShares(receivedAssets, Math.Rounding.Up);
tsudmi commented 1 year ago

We're not following the ERC-4626 standard here, except we use some of the function names from there.

turvec commented 1 year ago

Hi @tsudmi I agree, There are no strict requirements to be EIP-4626 compliant hence the low. However, it's in terms of liquidity tokens and Vault always takes a bit less. ensuring it remains secure and doesn't run out of tokens is what the revised code provides.