Understand that if you are excluded from receiving rewards, your balance must be saved but it must not be in the supply to receive the proportional tokens. no have the next computation:
I explain it to you in my way that maybe it is not the best. Probably another more expert user can give you a clearer explanation.
As I was saying, there are two totals. One for when rewards are not received, and another for when they are received.
the rtotal is calculated with the tTotal modulus of the largest number that can be calculated on the blockchain.
MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935
tTotal: 1000000000000000000000000000
total supply
MOD: 564,039,457,584,007,913,129,639,935
rTotal: 115,792,089,237,316,195,423,570,985,008,687,907,853,269,984,665,640,000,000,000,000,000,000,000,000,000
If now we want to know the balance of someone who has 1% of the supply. We will have to check first if the account receives rewards. Otherwise:
function balanceOf(address account) public view override returns (uint256) {
if (_isExcludedFromReward[account]) return _tOwned[account];
return tokenFromReflection(_rOwned[account]);
}
If you are excluded from rewards you will have a typical balance of the tokens. 10,000,000 in the example.
In case they receive the rewards we must calculate with tokenFromreFlection:
function tokenFromReflection(uint256 rAmount) public view returns(uint256) {
require(rAmount <= _rTotal, "Amount must be less than total reflections");
uint256 currentRate = _getRate();
return rAmount.div(currentRate);
}
To know the proportion that corresponds to it, we will have to know the current ratio and divide the balance that corresponds to the holder in rOwner in it.
function _getRate() private view returns(uint256) {
(uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
return rSupply.div(tSupply);
}
function _getCurrentSupply() private view returns(uint256, uint256) {
uint256 rSupply = _rTotal;
uint256 tSupply = _tTotal;
for (uint256 i = 0; i < _excludedFromReward.length; i++) {
if (_rOwned[_excludedFromReward[i]] > rSupply || _tOwned[_excludedFromReward[i]] > tSupply)
return (_rTotal, _tTotal);
rSupply = rSupply.sub(_rOwned[_excludedFromReward[i]]);
tSupply = tSupply.sub(_tOwned[_excludedFromReward[i]]);
}
if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal);
return (rSupply, tSupply);
}
We calculate the supplys with getCurrentSupply.
tTotal: 1000000000000000000000000000
rTotal: 115,792,089,237,316,195,423,570,985,008,687,907,853,269,984,665,640,000,000,000,000,000,000,000,000,000
Suppose no one is excluded from receiving rewards. otherwise we would have to subtract each account from each supply This subtraction of accounts can cause the rtotal to be less than the rTotal divided by the tTotal.
result = 115,792,089,237,316,195,423,570,985,008,687,907,853,269,984,665,640
that if you look at it, it is not more than the rTotal without its 28 decimal zeros.
In that case we must return the totals.
returned the supplys we return the division in our case '' result
''
to which we will divide the rAmount:
There are a function called reflectionFromToken
that gives you the value of a tAmount in rAmount. For example, 1000 tokens, in a tAmount equals a the next rAmount: 113711137695680841163648566827223238325825765381503000
And if we also want to deduct the fees, it will also calculate it for you. with the same tAmount we get:
104614246680026373870556681481045379259759704150982760
the rAmount of 1% of the supply in this example equals the following::1137109521662255110447877802345051140201043838440900000000
With these bignumbers we can calculate with greater precision the amount to be distributed to each holder in proportion to its volume. Imagine the hassle of distributing small amounts to thousands of accounts. With this we solve the problem.
With this system we only have to discount the accounts excluded from receiving rewards and only subtract the commission from the rTotal in each transaction. Incredible gas savings.
This is my modest contribution but I am sure that another more illustrated zeppellin could better explain this computation to you.