Skip to main content

Divide before multiply

Description

In Rust, the order of operations can influence the precision of the result, especially in integer arithmetic. Performing a division operation before a multiplication can lead to a loss of precision as division between integers might return zero. This issue can have serious consequences in programs such as smart contracts where numerical precision is critical.

Exploit Scenario

Consider the following Soroban contract:


pub fn split_profit(percentage: u64, total_profit: u64) -> u64 {
(percentage / 100) * total_profit
}

In this contract, the split_profit function divides the percentage by 100 before multiplying it with total_profit. This could lead to a loss of precision if percentage is less than 100 as the division would return 0. This could lead to incorrect calculations and potential financial loss in a real-world smart contract.

The vulnerable code example can be found here.

Remediation

Reverse the order of operations to ensure multiplication occurs before division.


pub fn split_profit(&self, percentage: u64, total_profit: u64) -> u64 {
(percentage * total_profit) / 100
}

The remediated code example can be found here.

References

Rust documentation: Integer Division