What is the logic behind token reflections?

I've noticed that a lot of tokens that implement reflections come from safemoon. And I was curious about how safemoon did reflections. I expected to find a for loop somewhere where they are adding to each account's balance, but I did not find anything like that. Instead I foud _rOwned and _tOwned. I kept researching and I came across RFI the contract that started reflections (correct me if I am wrong). But even still I did not really understand how the accounts recieve more tokens? I found their reflect function. (in safemoon its called deliver)

    function deliver(uint256 tAmount) public {
        address sender = _msgSender();
        require(!_isExcluded[sender], "Excluded addresses cannot call this function");
        (uint256 rAmount,,,,,) = _getValues(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _rTotal = _rTotal.sub(rAmount);
        _tFeeTotal = _tFeeTotal.add(tAmount);

But after finding this I only had more questions than anserws. Who is calling this function? Why is it not used anywhere in the source code? Another function I found that was just as confusing was reflectionFromToken()

    function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) {
        require(tAmount <= _tTotal, "Amount must be less than supply");
        if (!deductTransferFee) {
            (uint256 rAmount,,,,,) = _getValues(tAmount);
            return rAmount;
        } else {
            (,uint256 rTransferAmount,,,,) = _getValues(tAmount);
            return rTransferAmount;

Once again where is the function being called? What is it even for? Thanks for the help!

Does nobody know the answer?

The project is called reflect finance for a reason. The idea is instead of sending fees one by one in the t-space, updating the relative size between t-space and r-space is a lot easier. The balances in the t-space can be updated instantaneously without addtional transactions when balances in the r-space are reflected back to the t-space. t-space refers to the true space where all token balances are recorded. r-space is the reflected space where reflected balances and variables are being operated upon. The relative size between t-space and r-space plays the key role in the reflection idea.

Hi @maxaero,

Thanks for the response. One thing I still am trying to wrap my head around why an accounts balance when tested locally with Ganache, never changes the value of tokens unless specifically sent to that address. I understood the logic of reflections before, but now I understand it more thanks to you.

It is changing, but the reason you do not see changes is the fees are too small. The earning factor is T_t/(T_t-f_t). For a typical transaction of size 1000 tokens, this factor is roughly 1.000001. It takes 10000 such transactions to see a 1% increase. If you send too few tokens, due to rounding errors, you won't see any change.

Alright that makes sense. Let me do some more testing! Thanks again @maxaero !

1 Like