# Rebasing tokenomics

I have the following variables where all values are multiplied by 1e18 to represent fixed-point numbers on the EVM:

``````uint totalShares = 100;
uint sharesAlice = 20;
uint sharesBob = 30;
uint sharesCharlie = 50;
uint undervalue = n; //invariant

function getNum(uint shares_) public returns(uint) {
return shares_.mulDiv(n, totalShares);
}
``````

I have now the following statement that derives from the snippet above, proven to be true:

``````getNum(totalShares) != getNum(sharesAlice) + getNum(sharesBob) + getNum(sharesCharlie);
``````

Why is this statement true and how can I make it not true (meaning that both values in the statement are equal?

I think it has something to do with rounding errors and the limit that 18 decimals place into irrational numbers. If this is true, my main question would be then how do I brake that statement (aka make both values equal)?

Thanks!

• What's the value of n? Nov 30, 2023 at 6:08
• It's indifferent. What matters is that it's a constant value that never changes. @ZartajAfser Nov 30, 2023 at 10:37
• That's why I am asking. It might be the reason for rounding up of integers and returning true for the above statement. Nov 30, 2023 at 10:59
• More than the reason, I'm looking for the solution. I think that the issue is the rounding, but I'd like to turn that statement into false. And one of the constraints of the operation is the invariant, that doesn't change. @ZartajAfser Nov 30, 2023 at 18:41
• Mate, as long as you don't find the reason for the error, how are you supposed to solve that error? Dec 1, 2023 at 4:10

The reason I asked for the value of n is because it is the only part affecting your code. I tried implementing the same logic and guess what, I found out that when I gave `undervalue` a value of `1 ether` it returned false for the statement, and when I gave it a random value of `12345` it returned true as in your case.

`1 ether` and `12345` are just examples, what I meant was when the value of `underValue` is something ending with zeroes then it doesn't round up the output.

The value of `undervalue` determines the value of bool because the rest of everything is fine.

Here is the code I used, you can try it out on remix:

``````contract abc {
uint256 totalShares = 100;
uint256 sharesAlice = 20;
uint256 sharesBob = 30;
uint256 sharesCharlie = 50;
uint256 undervalue = 12345; //Try with this value and then 1 ether.

function getNum(uint256 shares_) public view returns (uint256) {
return mulDiv(shares_, undervalue, totalShares);
}

function mulDiv(
uint256 a,
uint256 b,
uint256 c
) internal pure returns (uint256) {
return (a * b) / c;
}

function compare() external view returns (bool) {
return
getNum(totalShares) !=
getNum(sharesAlice) + getNum(sharesBob) + getNum(sharesCharlie);
}
}
``````