What does Reflect.Finance code do: _rTotal = (MAX - (MAX % totalSupplyOfToken));

Because when it is included, you are now using the variable, _rOwned[account] to track the amount they own.

Check out what happens when you excludeFromReward. The reverse happens. You are now using _tOwned when it is excluded.

    function excludeFromReward(address account) public onlyOwner() {
        // require(account != 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, 'We can not exclude Uniswap router.');
        require(!_isExcluded[account], "Account is already excluded");
        if(_rOwned[account] > 0) {
            _tOwned[account] = tokenFromReflection(_rOwned[account]);
        }
        _isExcluded[account] = true;
        _excluded.push(account);
    }

    function includeInReward(address account) external onlyOwner() {
        require(_isExcluded[account], "Account is already excluded");
        for (uint256 i = 0; i < _excluded.length; i++) {
            if (_excluded[i] == account) {
                _excluded[i] = _excluded[_excluded.length - 1];
                _tOwned[account] = 0;
                _isExcluded[account] = false;
                _excluded.pop();
                break;
            }
        }
    }

Hi Tsushima - thanks for the reply. i did check the excludedFromReward and if you notice what happens is that the code is doing the following:

function excludeFromReward(address account) public onlyOwner() {
        // if the account excluded equals false carry on - else throw error
        require(!_isExcluded[account], "Account is already excluded");
        // if the rewards owned is greater then zero - set the tokens owned to the tokens from reflection
        // using the current rate of reflection.
        if(_rOwned[account] > 0) {
            _tOwned[account] = tokenFromReflection(_rOwned[account]);
        }
        // exclude the account from future token reflections
        _isExcluded[account] = true;
        // remove the account from the excluded array 
        _excluded.push(account);
    }

this looks correct as now _tOwned tracks the tokens owned by the account and it has been removed from _rOwned.

Anyways it looks like it works - I just thought from comments above that _tOwned would always reflect the actual tokens owned without reflections.

2 Likes


this is the behavior on the graph for the f(x) = ( any_number - ( any_number % x))

I couldn’t imagine any real advantage in using this strategy, just more spending on gas.

2 Likes

Actually, the MAX number is fine.

Take a look at the function tokenFromReflection which transforms the balance to balanceOf

Balance is calculated by the rAmount / currentRate, which currentRate is calculated by _rTotal/_tTotal (suppose that there are no exclude addresses available)

However, _rTotal will be reduced by the fee whenever a transaction is made. That why the user’s balance keeps increasing.

For the question of this topic, I think just for rounding the number more beautify.
115792089237316195423570985008687907853269984665640564039457580000000000000000/10000000000000000 would be much human friendly than 115792089237316195423570985008687907853269984665640564039457584007913129639935/10000000000000000

3 Likes

@Yoshiko
After doing a little bit of math, I think I started to see somthing.

rTotal = MAX - (MAX % tTotal )
    = MAX - (MAX - Q * tTotal)
    = Q * tTotal (Q ∈ ℕ , 1 <=Q<=MAX)
0 <= MAX % tTotal < tTotal
0 <= MAX - Q * tTotal < tTotal
-MAX <= -Q * tTotal < tTotal - MAX
MAX - tTotal < Q * tTotal <= MAX
MAX - tTotal < rTotal <= MAX

rTotal is a multiple of tTotal. Q is equal to the return value from _getRate().
MAX can be any number since it gets cancelled out. However, in order to avoid MAX - tTotal from becoming negative, they just chose the biggest number that solidity can provide.

1 Like

I suggest you see this article in Stack Exchange.

1 Like

I wrote a technical whitepaper for Reflect.
Check it out:

3 Likes

Does rTotal matter in the calculations?

Yes.
Read my paper and you'll understand

You paper does include it in your formulas but didn't explain why it is included. Curious if a large rTotal or a small rTotal would change the performance of the mechanism. It would be great if it is made more clear.

TL;DR

  • The whole purpose of t values and r values is to create a deflationary mechanism.
  • rTotal is tTotal in r values.
  • Most numbers in Solidity is uint256 so it shouldn't change the performance
  • The initial rTotal is between MAX-tTotal and MAX. MAX can be any number above tTotal but many tokens choose the biggest number that Solidity provides.

It is a new concept, it is not easy to explain in simple english.

1 Like

This article seems to be deleted.
Do you have the pdf file?

Sorry, the article was withdrawn for confidentiality reasons. There are great alternative posts on this forum doing a great job explaining RFI.

1 Like

Hey!
I found this article. I hope it helps :wink:
_rTotal

And what is the purpose of tOwned and excluded accounts ?
I see that by default excluded accounts are 2: The contract's itself and the owner's account.

Is it just to avoid the creator (owner) and the contract itself receive rewards, in order to give more to token holders?

thank you for the great explanation, what I don't understand is why you subtract _rFee from _rTotal?

Because when you decrese _rFee to _rTotal (divisor) each rOwned[address] balance gets bigger, in order to give rewards from the transaction fee, because currentRate (the divisor obtained from _getRate() function) is getting smaller.

Take a look at how transfer fee rewards are shared and obtained from balanceOf(address) function trough tokenFromReflection(rAmount) function => rAmount.div(currentRate):

function _getRate() private view returns(uint256) {
       (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
       return rSupply.div(tSupply);
   }

function balanceOf(address account) public view override returns (uint256) {
    if (_isExcluded[account]) return _tOwned[account];
    return tokenFromReflection(_rOwned[account]);//=> rAmount/currentRate
}

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);
}

Well _rTotal is simply Total Reflections and _rOwned refers to number of reflection a user owns.
think of this way:
we could set initial _rTotal to 100 to represent 100%
and if your _rOwned value is 10, you own 10% of total reflections.
in the constructor method you see after deployment of the contract, the whole reflections are transfered to the owner of the contract.

_rOwned[_msgSender()] = _rTotal;

using 100 as total reflection has a problem: solidity only supports integers and doesn't support floating point numbers, so we gotta somehow do it another way

If i am right, the reason they set _rTotal to a huge number is to make reflection very accurate and support as much floating points as possible (if i am wrong, correct me), so if you own something like 0.00812301283120398912312836% of reflections, it should work accurately.

I hope i could explain it in a simple way

1 Like

You are a f*cking hero, dude!

Guys, why do they assign rTotal, but emit another value tTotal? Thx in advance!

constructor () public {
_rOwned[_msgSender()] = _rTotal;
emit Transfer(address(0), _msgSender(), _tTotal);
}