LOW severity: Protocol will leak value to users due to rounding in `RebasingLibrary`. **Description:** Protocols should always round against users in favor of the protocol. `RebasingLibrary` uses "rounding to nearest" method which leaks value to users:

**Impact:** The rounding helps users in both directions:
* When depositing: Users might get 1 extra share
* When withdrawing:...

Vulnerable code:
// In convertTokensToShares
return (_tokens * DECIMALS_FACTOR + _rebasingMultiplier / 2) / _rebasingMultiplier;
                                 // ^^^^^^^^^^^^^^^^^^^^
                                 // This rounds to nearest

// In convertSharesToTokens
return (_shares * _rebasingMultiplier + DECIMALS_FACTOR / 2) / DECIMALS_FACTOR;
                                     // ^^^^^^^^^^^^^^^^^^^^
                                     // This also rounds to nearest

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

import "forge-std/Test.sol";
import "../contracts/rebasing/RebasingLibrary.sol";

contract RebasingRoundingTest is Test {
    using RebasingLibrary for *;

    function testRoundingInconsistency() public {
        // Setup: multiplier = 1.5e18 (1.5x rebasing)
        uint256 multiplier = 1.5e18;
        uint8 decimals = 18;

        // Test 1: Convert 1 token to shares and back
        uint256 initialTokens = 1e18;

        // Convert tokens to shares
        uint256 shares = RebasingLibrary.convertTokensToShares(
            initialTokens,
            multiplier,
            decimals
        );

        // Convert shares back to tokens
        uint256 finalTokens = RebasingLibrary.convertSharesToTokens(
            shares,
            multiplier,
            decimals
        );

        console.log("Initial tokens:", initialTokens);
        console.log("Shares received:", shares);
        console.log("Final tokens:", finalTokens);

        // This should fail if there's inconsistency
        assertEq(initialTokens, finalTokens, "Rounding inconsistency detected");
    }

    function testAccumulatedRoundingErrors() public {
        uint256 multiplier = 1.7e18; // Non-round multiplier
        uint8 decimals = 18;

        uint256 totalSharesIssued;
        uint256 totalTokensIn;

        // Simulate 1000 small deposits
        for(uint i = 0; i < 1000; i++) {
            // Each user deposits a small odd amount
            uint256 tokens = 1e15 + i; // 0.001 tokens + i wei

            uint256 shares = RebasingLibrary.convertTokensToShares(
                tokens,
                multiplier,
                decimals
            );

            totalTokensIn += tokens;
            totalSharesIssued += shares;
        }

        // Now convert total shares back to tokens
        uint256 totalTokensOut = RebasingLibrary.convertSharesToTokens(
            totalSharesIssued,
            multiplier,
            decimals
        );

        console.log("Total tokens in:", totalTokensIn);
        console.log("Total tokens out:", totalTokensOut);
        console.log("Difference:", totalTokensOut > totalTokensIn ?
            totalTokensOut - totalTokensIn : totalTokensIn - totalTokensOut);

        // Check if protocol lost tokens
        if(totalTokensOut > totalTokensIn) {
            console.log("Protocol LOST tokens due to rounding!");
        }
    }
}