SafeMath Dangers calculating percent in smart contract

I'm making a fund manager using solidity and I'd like to calculate the percentage, however I'm wonder whether the use of safeMath is actually incorrect.

``````using SafeMath for uint256;
uint256 percent = 5
function managePayment(uint256 payment)
amountToSplit = payment.mul(percent).div(100);
}
``````

In this case, I'm limiting myself to 1/5 of the max supply otherwise multiply will throw when calculating the percent, is there a better approach to doing this, (Granted I could avoid using safe math, if I validate the percentage is less than 100) However, I'd like to avoid this approach

Since solidity 0.8 you dont' need safe math for that. The compiler will inject checking sequences to automatically throw if overflow occurs. (This problem was removed since OP is aware of that)

Update: According to the comment, looks like OP wants to calculate multiplying with the result larger than `uint256` and then the division will take back the intermediate result down to `uint256`. The `safeMath` library or overflow prevention are not designed for that. You need to implement or use some library that can represent higher bitwidth (e.g. `uint512`). After searching for a while I think Openzeppellin already have similar library for you, look at `function mulDiv(uint256 x, uint256 y, uint256 denominator)` source code. Hence the code below will be safe to use:

``````pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol";
contract Test {
uint256 percent = 10;
function managePayment(uint256 payment) public view returns(uint256){
return  Math.mulDiv(payment, percent, 100);
}
}
``````

Input: `2**255` = 57896044618658097711785492504343953926634992332820282019728792003956564819968

Output: `2**255/10` = 5789604461865809771178549250434395392663499233282028201972879200395656481996

You can also choose rounding direction : `Math.mulDiv(payment, percent, 100, Math.Rounding.Up);`

Output: `2**255/10` = 5789604461865809771178549250434395392663499233282028201972879200395656481997

• You have to make sure it wont happen. If you allow unsafe overflow it will be like this, for example payment = 2^255, numerator = 2 : `payment*numerator = 2^256 = 0`. `payment*numerator/denom = 0/100 = 0;` How can you get the correct result with overflow ? Jan 1, 2023 at 4:14