hats-finance / Velvet-Capital-0x0bb0c08fd9eeaf190064f4c66f11d18182961f77

Core smart contracts of Velvet Capital
Other
0 stars 1 forks source link

Token Decimal Handling Issue in _multiTokenWithdrawal #109

Open hats-bug-reporter[bot] opened 2 months ago

hats-bug-reporter[bot] commented 2 months ago

Github username: @olaoyesalem Twitter username: salthegeek1 Submission hash (on-chain): 0x2122410e3f5dd82a172841c7e603cdd2ff03dba5a87f1f8fcb168e5047c79735 Severity: high

Description: Description\ The _multiTokenWithdrawal function in the smart contract has a potential vulnerability related to handling tokens with different decimal places, particularly tokens like USDC which have 6 decimal places. The current implementation assumes that all tokens operate with 18 decimals, which can lead to discrepancies in calculations and incorrect withdrawal amounts.

Vulnerability Details: In the function _multiTokenWithdrawal, the line:

uint256 tokenBalance = _getTokenBalanceOf(_token, vault);

retrieves the balance of the token from the vault. This value is then used to calculate the proportional amount of tokens to return to the user based on the burned portfolio tokens. The calculation:

tokenBalance = (tokenBalance * _portfolioTokenAmount) / totalSupplyPortfolio;

implicitly assumes that tokenBalance is in 18 decimals. However, if _token is USDC (which has 6 decimals), tokenBalance will be significantly smaller in magnitude compared to tokens with 18 decimals. This can cause significant discrepancies in the calculated withdrawal amounts.

Impact This vulnerability can lead to users receiving incorrect amounts of tokens during withdrawals. Specifically, users could receive much less than they are entitled to, undermining trust in the protocol and potentially causing financial loss.

Attachments

  1. Proof of Concept (PoC) File

  2. Revised Code File (Optional) Add this to the code

uint256 tokenBalance = _getTokenBalanceOf(_token, vault); uint8 decimals = _getTokenDecimals(_token); if (decimals < 18) { tokenBalance = tokenBalance * 10(18 - decimals); } else if (decimals > 18) { tokenBalance = tokenBalance / 10(decimals - 18); }

langnavina97 commented 2 months ago

The current calculation is suitable for all types of decimals because _portfolioTokenAmount / totalSupplyPortfolio results in a percentage, such as 20% of a token balance. The number of decimals the token has is not relevant. @olaoyesalem