The First Thing I Check When I See Division in Solidity
If you’ve spent time auditing smart contracts, you’ve probably noticed something. Division isn’t scary. But it deserves attention.
The First Thing I Check When I See Division in Solidity
If you’ve spent time auditing smart contracts, you’ve probably noticed something. Division isn’t scary. But it deserves attention.
Whenever I see a line like this:
shares = assets * totalShares / totalAssets;
I don’t immediately think about math. I ask myself one question.
“What gets lost here?”
That single question has led to countless precision bugs across DeFi.
Solidity Doesn’t Understand Fractions
One thing that surprises beginners is that solidity has no idea what 1.5 means. It only stores whole numbers. So if we write:
uint256 result = 3 / 2;
the answer isn’t 1.5 , It’s simply 1. The 0.5 doesn’t get rounded. It doesn’t get stored somewhere. It just disappears. Once you understand that, precision bugs become much easier to spot.
This Is What I Actually Look For
When I see division during an audit, I don’t start calculating numbers. I start asking questions.
Can this division round down?
Who benefits if it does?
Can someone repeat this many times?
Those three questions usually tell me whether I should investigate further. For example:
uint256 reward = userStake * rewardPool / totalStake;
Looks harmless. But imagine this:
userStake = 3
rewardPool = 100
totalStake = 8
The real answer is 37.5, but solidity gives 37. Some unit disappears. Now imagine thousands of users doing this every day. Where do all those missing pieces go? That’s the question worth answering.
Precision Bugs Usually Hide Here
After reviewing enough code, you start seeing patterns. Whenever I find expressions like these, I slow down.
amount * price / totalSupply
shares * assets / totalShares
reward * userBalance / totalBalance
None of these are bugs by themselves. They’re just places where rounding can change who wins and who loses.
Here’s How I Try to Break It
Instead of staring at the code, I give it awkward numbers, not nice numbers. Numbers that don’t divide cleanly. For example:
3 / 2
5 / 3
7 / 4
100 / 9
If everything divides perfectly, you’re not really testing the edge cases. Precision bugs usually show up when there is a remainder.
Proving the Bug
Once I suspect rounding matters, I try to prove it with a simple Foundry test. For example:
function test_precisionLoss() public {
uint256 reward = 3 * 100 / 8;
assertEq(reward, 37);
}
The important part isn’t the assertion. It’s comparing what solidity returned with what you expected mathematically. If that missing value affects balances, shares, rewards, or withdrawals, you’ve found something worth investigating.
Preventing It
Most precision bugs aren’t fixed by adding more checks. They’re fixed by changing the order of operations.
Instead of:
amount / total * price;
Do:
amount * price / total;
Multiplying first preserves more precision before division removes the remainder. Sometimes that’s enough. Sometimes you also need proper rounding functions depending on whether users or the protocol should benefit from rounding.
My Precision Bug Checklist
While auditing a contract, these are the questions I ask.
- Is there a division?
- Can a remainder be discarded?
- Who gains from the rounding?
- Can this happen repeatedly?
- Does the protocol account for the lost precision?
However, theory is the easy part.
Next time, we’ll hunt down a real precision bug from a public audit contest and walk through the exact thought process that turned a suspicious line of code into a valid finding.
메타데이터
- post_id
- cb4e19619ebd
- slug
- the-first-thing-i-check-when-i-see-division-in-solidity-cb4e19619ebd
- url
- https://coinsbench.com/the-first-thing-i-check-when-i-see-division-in-solidity-cb4e19619ebd
- canonical_url
- https://coinsbench.com/the-first-thing-i-check-when-i-see-division-in-solidity-cb4e19619ebd
- author_url
- https://medium.com/@stephennwebor
- status
- ok
- fetched_at
- 2026-07-09 04:10:03