Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Invalid

Precision Loss in BaseGauge Reward Rate Calculation

Summary

The BaseGauge contract's reward rate calculation suffers from precision loss due to integer division, resulting in users receiving slightly less rewards than intended over the reward period.

Vulnerability Detail

In the BaseGauge contract, the reward rate is calculated by dividing the reward amount by the period duration:

uint256 rewardRate = amount / periodDuration;

This integer division causes precision loss. When this rate is later used to distribute rewards over time, the total rewards distributed will be less than the original amount intended for distribution.

This has been demonstrated through testing:

const amount = ethers.parseEther("1000"); // 1000000000000000000000
const calculatedTotalRewards = rewardRate * periodDuration; // 999999999999999734400
// Difference of 265600 wei (0.0000000000000026560 ETH)

In this example with 1000 tokens, there is a loss of 265,600 wei. While small in this case, the precision loss scales with larger amounts and could be more significant with tokens of different decimals.

Impact

Medium. The precision loss leads to a systematic underpayment of rewards to users, though the impact per user is relatively small. This does not result in lost funds but rather in slightly reduced rewards compared to what was intended.

uint256 rewardRate = amount / periodDuration;

Test demonstrating the issue:

it("should show tokens lost due to precision issues", async () => {
const { baseGauge, rewardToken, owner } = await loadFixture(deployFixture);
// Amount to test with
const amount = ethers.parseEther("1000");
const periodDuration = 7 * 24 * 3600; // 7 days in seconds
await rewardToken.mint(await baseGauge.getAddress(), amount);
await baseGauge.notifyRewardAmount(amount);
const rewardRate = await baseGauge.rewardRate();
const calculatedTotalRewards = rewardRate * BigInt(periodDuration);
expect(calculatedTotalRewards).to.not.equal(amount);
});

Tool used

Manual Review

Recommendation

To mitigate this precision loss, implement fixed-point arithmetic by scaling up the reward rate calculation:

// Use a precision factor of 1e18
uint256 constant PRECISION = 1e18;
uint256 rewardRate = (amount * PRECISION) / periodDuration;

When distributing rewards, divide by the precision factor:
uint256 reward = (rewardRate * duration) / PRECISION;
This will ensure more accurate reward distribution and minimize precision losses.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.