Mappings rOwned and tOwned

Hi Zeppelins…

In many contracts there are two different mappings for in hold addresses. The tOwned is clear to me, they are all the accounts that they hold but … What is the function of rOwned?

mapping (address => uint256) private _rOwned;
  mapping (address => uint256) private _tOwned;

An example contract that has it like this:

rOwned is the balance with reflective fees

could you explain me more about the reflection?

thanks @FreezyEx . Why is in a different map?

These fees do not have to reach in the total balance of the holders?

the reflection fee is a commission of each transaction that is distributed to all token holders.
It is a kind of passive staking.
This is to reward the holding attitude.

thanks @Cainuriel
by the way, what is this function?

function _reflectFee(uint256 rFee, uint256 tFee) private {
        _rTotal = _rTotal.sub(rFee);
        _tFeeTotal = _tFeeTotal.add(tFee);
    }

here what is rTotal?
tTotal is total supply. right? but I don’t understand rTotal.

uint256 private _rTotal = (MAX - (MAX % _tTotal));

Good cuestion.

I’m studying the contract along with you. And this would be for another thread.

Obviously it is related to supply, but I am not very clear what it intends.

  uint256 private constant MAX = ~uint256(0);
  uint256 private _tTotal = 1000000000 * 10**18;
  uint256 private _rTotal = (MAX - (MAX % _tTotal));


What can be deduced from the _reflectfee function is that it separates the fee to be returned to all holders from the other fees. It is striking that you subtract the amount of return.

if you have any idea, plz let me know about the rToal

@Cainuriel any update with this topic my friend? I'm also studying the code, and very interested in understanding this.

I'm going to answer from memory because now I don't have the code in front of it.

the rtotal is a kind of percentage with which the redistribution of reflective fees is established.

When an account is excluded from rewards, it only uses the tOwned as you can see in the contracts in which this rFee is implemented.

But if the account has rewards, update both balances.

Since the distribution of the fee is proportional to the holder percentage of the account.

Whoever has more, receives more from the reward fee.

And for this to work, it is necessary to know what percentage the holder of the total supply has.

I just answered what I discovered from memory. If it is not clear replicate me and we look better at the code when it is in front of me.

That make sense: tOwned is the "stake/participation" of each holder, and rOwned the corresponding balance according to their stake...

But if you take a look to _transferStandard function, you won't see any updates in tOwned. That is pretty confusing,

function _transferStandard(address sender, address recipient, uint256 tAmount) private {
     (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getValues(tAmount);
     _rOwned[sender] = _rOwned[sender].sub(rAmount);
     _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
     _takeLiquidity(tLiquidity);
     _reflectFee(rFee, tFee);
     emit Transfer(sender, recipient, tTransferAmount);
 }

Because a standard transaction is not exempt from the rewards fee.

The other methods for transaction do check if it is excluded:
_transferFromExcluded, _transferToExcluded, _transferBothExcluded

Notice how when we exclude someone from the rewards we use the classic mapping of holders.

	function excludeFromReward(address account) public onlyOwner {
		require(!_isExcludedFromReward[account], "Account is already excluded");
		if(_rOwned[account] > 0) {
			_tOwned[account] = tokenFromReflection(_rOwned[account]);
		}
		_isExcludedFromReward[account] = true;
		_excludedFromReward.push(account);
	}

This is the bigest number that can be generated as a bignumber on the blockchain 115792089237316195423570985008687907853269984665640564039457584007913129639935. And, in relation to it, a proportion is established with the total supply. Thus, without having to do many calculations, a proportional bignumber will be obtained that will be equal to the percentage of each owner with excellent precision.

The ratios of the accounts are marketed here:

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

But what is the purpose of maintan a tOwned mapping with the balance of excluded addresses (the owner and the contract itself)?

I'm also confused with _reflectFee function, that is executed in every transfer function, which reduces _rTotal amount (kind of token burn?).

_tFeeTotal is getting bigger, but is never used to share fees between holders, it just grows and grows proportionally to token transfers, due to to _reflectFee function. But what for?

function _reflectFee(uint256 rFee, uint256 tFee) private {
    _rTotal = _rTotal.sub(rFee);
    _tFeeTotal = _tFeeTotal.add(tFee);
}

you will also see it like this:

function _HODLrFee(uint256 rHODLrFee, uint256 tHODLrFee) private {
		_rTotal = _rTotal.sub(rHODLrFee);
		_tHODLrRewardsTotal = _tHODLrRewardsTotal.add(tHODLrFee);
	}

_tFeeTotal it is not more than the total registry of commissions distributed. To know how much has been distributed.

And what is the purpose of maintan a tOwned mapping with the balance of excluded addresses (the owner and the contract itself)?

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.

2 Likes