FV-SOL-2-C3 Rounding

TLDR

Solidity rounds down in integer division, which can lead to small precision losses that add up over multiple calculations.

This is particularly problematic in contracts dealing with revenue sharing, staking, or rewards distribution, where precision is critical.

Game

In this contract, the allocateShare function calculates a recipient's share based on totalFunds, recipientShares, and totalShares

Look for uneven divisions.

// SPDX-License-Identifier: MIT
// Open me in VSCode and really think before opening the hints!
// Add @audit tags wherever suspicious
// Go to the solidity docs to complete missing knowledge of what's happening here
// Solve by drafting a fix!
pragma solidity ^0.8.0;

contract SharesCalculationGame {
    uint256 public totalShares;
    uint256 public totalFunds;

    mapping(address => uint256) public shares;

    constructor(uint256 _totalShares) {
        totalShares = _totalShares;
    }

    function depositFunds() public payable {
        totalFunds += msg.value;
    }

    function allocateShare(address recipient, uint256 recipientShares) public {
        require(recipientShares <= totalShares, "Not enough shares available");

        uint256 allocation = (totalFunds * recipientShares) / totalShares;
        require(allocation <= totalFunds, "Allocation exceeds funds");

        shares[recipient] += recipientShares;
        totalFunds -= allocation;

        (bool success, ) = payable(recipient).call{value: allocation}("");
        require(success, "Transfer failed");
    }
}

Last updated