Every smart contract developer knows that floating-point numbers don't exist in Solidity or Cairo. We use integers. But knowing it and feeling the consequences are two different things.
In my recent security research on a Starknet staking protocol, I implemented a vulnerability that is so simple, yet so devastating: The "Division Before Multiplication" Bug.
The Vulnerable LogicImagine a standard staking reward formula. You want to calculate the reward increase based on time, a reward rate, and the total supply of staked tokens. To maintain precision, we use a multiplier (like $10^{18}$).Here is the line of code that caused the "ghost rewards" issue:
// ⚠️ VULNERABLE CODE
let reward_increase = (duration * rate) / supply * 1_000_000_000_000_000_000;
At first glance, it looks fine. We calculate the rate per time, divide by supply, and scale it up. Wrong.
Why It BreaksIn integer-based languages like Cairo, division is performed first. If (duration * rate) is smaller than supply, the result of the division is exactly 0.Even if you multiply that 0 by a quintillion ($10^{18}$), it remains 0. The rewards for your users simply vanish into the void.
Proving the Flaw (PoC)
To confirm this, I wrote a Proof of Concept using Starknet Foundry (snforge). I simulated a "Whale" entering the pool with a large supply, making the denominator huge.
[test]
fn test_math_precision_loss() {
let duration: u256 = 100;
let rate: u256 = 10000;
let supply: u256 = 1_000_000_000_000_000_000_000; // 1000 tokens
let precision: u256 = 1_000_000_000_000_000_000;
// Result: (1,000,000 / 10^21) = 0. Then 0 * 10^18 = 0
let reward_increase = (duration * rate) / supply * precision;
assert(reward_increase == 0, 'BUG_STILL_EXISTS');
}
The test passed, meaning the rewards were indeed lost.
The Fix
The rule is simple: Always multiply before you divide. By reordering the operations, we keep the numbers large before the division "chops off" the precision.
// ✅ SECURE CODE
let reward_increase = (duration * rate * 1_000_000_000_000_000_000) / supply;
With this fix, even small rewards are captured and distributed correctly.
Conclusion
Precision loss is a silent killer in DeFi. One misplaced set of parentheses or a wrong order of operations can lead to frozen funds or broken incentives.
You can check out my full audit and the PoC code on my GitHub: rdin777/starknet-staking_audit1

Top comments (0)