georgits
high
Users may experience loss of funds.
In USSD.sol, mintForToken()
calls calculateMint()
to calculate how many tokens the user should receive. The problem is the return value of calculateMint()
can be subject to significant loss of precision due to multiplication occurring after division.
If calculateMint()
returns 0 the user will lose tokenAmount
of token
.
https://github.com/sherlock-audit/2023-05-USSD/blob/main/ussd-contracts/contracts/USSD.sol#L151-L173
function mintForToken(
address token,
uint256 tokenAmount,
address to
) public returns (uint256 stableCoinAmount) {
require(hasCollateralMint(token), "unsupported token");
IERC20Upgradeable(token).safeTransferFrom(
msg.sender,
address(this),
tokenAmount
);
stableCoinAmount = calculateMint(token, tokenAmount);
_mint(to, stableCoinAmount);
emit Mint(msg.sender, to, token, tokenAmount, stableCoinAmount);
}
/// @dev Return how much STABLECOIN does user receive for AMOUNT of asset
function calculateMint(address _token, uint256 _amount) public view returns (uint256 stableCoinAmount) {
uint256 assetPrice = collateral[getCollateralIndex(_token)].oracle.getPriceUSD();
return (((assetPrice * _amount) / 1e18) * (10 ** decimals())) / (10 ** IERC20MetadataUpgradeable(_token).decimals());
}
Manual Review
Perform multiplication before division in calculateMint()
and add a check if stableCoinAmount
is equal to 0 before minting new tokens in mintForToken()
.