14

Looking at all the latest shitcoins' Smart Contract code on Binance Smart Chain, there's a lot of common,recurring themes because most of each project's code is mostly copy-pasted. The code is also completely uncommented, which makes it a pain to understand what's what.

Most of these contacts use two different types of variables for their internal token calculations, 1 called t and one called r. For example, on TrustPad's smart contract (available here: bscscan link):

    mapping(address => uint256) private _rOwned;
    mapping(address => uint256) private _tOwned;
    mapping(address => mapping(address => uint256)) private _allowances;
uint256 private constant MAX = ~uint256(0);
uint256 private constant _tTotal = 100 * (10 ** 6) * (10 ** 9);
uint256 private _rTotal = (MAX - (MAX % _tTotal));
uint256 private _tFeeTotal;
uint256 private _tFeePercent = 2;

Anybody got any idea what the r and t mean, and why they maintain _tOwned and _rOwned, _tTotal and _rTotal, etc?

Dimitris Sfounis
  • 348
  • 2
  • 10
  • Same question (though no answers): https://ethereum.stackexchange.com/questions/97782/why-do-some-contracts-use-multiple-balance-and-supply-variables – Richard Horrocks May 09 '21 at 09:24
  • 1
    Haven't looked into it, but probably something along the lines of "Automatic x% Distribution to Holders and Burn on Each Transaction"... – Richard Horrocks May 09 '21 at 09:26
  • 1
    @RichardHorrocks You're right that it has something to do with the mehcanic most of these coins called "reflection to holders", which incidentally starts with an r, but what's the t they also maintain for variables? t for tax? No idea! – Dimitris Sfounis May 09 '21 at 09:28

3 Answers3

16

It' a bit of an algorithm, or really just some math, to to the balance of an account. Instead of using the default "tokenSupply".

Constants

Fee is 1% (assuming no burn, just a general 1% fee)

tTotal is totalSupply and literally never changes rTotal starts at 127366483000000 and continuously subtracts or adds currentRate

Example:

You buy 100 Token as tAmount

>>>

Current Totals: rTotal = 127366483000000 tTotal = 10000

currentRate = rTotal / tTotal = 12736648300

Formula to get amount you will receive > rTransferAmount = [rAmount] - [rFee] [rAmount] = tAmount * currentRate > 1273664830000 = 100 * 12736648300 [rFee] = tFee * currrentRate > 127366483 = .01 * 12736648300

>>> 1273537463517 = [rAmount] - [rFee] = rTransferAmount

rTotal is updated to = rTotal - rTransferAmount

balanceOf():

= rAmount / currentRate >

rAmount[me] is rAmount rAmount = 1273537463517 currentRate = 12735374635.17

Balance: 100

...Someone else makes a transfer from x0 supply to buy 100 Tokens

rTotal = 126092945536483 tTotal = 10000

currentRate = rTotal / tTotal = 12609294553.6483

Formula to get amount you will receive > rTransferAmount = [rAmount] - [rFee] rAmount = tAmount * currentRate > 1260929455364.83 = 100 * 12609294553.6483 rFee = tFee * currrentRate > 126092945.536483 = .01 * 12609294553.6483

>>> rTransferAmount = 1260803362419.293517

They now have 100

...Now check [me] balance after previous purchase

balanceOf():

= rAmount / currentRate

rAmount[me] is rAmount rAmount = 1273537463517 currentRate = 12609294553.6483

Balance: 100.9998979799010304029995929297

...Now lets buy 100 more directly after checking balance ...this is the next transaction after the previous one

rTotal = 124832142174063.706483 tTotal = 10000

currentRate = rTotal / tTotal = 12483214217.4063706483

Formula to get amount you will receive > rTransferAmount = [rAmount] - [rFee] rAmount = tAmount * currentRate > 1248321421740.63706483 = 100 * 12483214217.4063706483 rFee = tFee * currrentRate > 124832142.174063706483 = .01 * 12483214217.4063706483

>>> rTransferAmount = 1248196589598.463001123517

We now take our previous rAmount and add the rTransferAmount to update our rAmount

> rOwned[me] = rOwned[me] + rTransferAmount > 2521734053115.463001123517 = 1273537463517 + 1248196589598.463001123517

...Now check [me] balance after previous purchase

balanceOf():

= rAmount / currentRate

rAmount[me] is rAmount rAmount = 2521734053115.463001123517 currentRate = 12483214217.4063706483

Balance: 202.00999591909607202719956134358

... now lets sell 100

rTotal = 123583945584465.243481876483 tTotal = 10000

currentRate = rTotal / tTotal = 12358394558.4465243481876483

Formula to get amount you will receive > rTransferAmount = [rAmount] - [rFee] rAmount = tAmount * currentRate > 1235839455844.65243481876483 = 100 * 12358394558.4465243481876483 rFee = tFee * currrentRate > 123583945.584465243481876483 = .01 * 12358394558.4465243481876483

>>> rTransferAmount = 1235715871899.067969575282953517

We now take our previous rAmount and add the rTransferAmount to update our rAmount

(we are subtracting because we are selling)

> rOwned[me] = rOwned[me] - rTransferAmount > 1286018181216.395031548234046483 = 2521734053115.463001123517 - 1235715871899.067969575282953517

rTotal is updated to = rTotal - rTransferAmount 122348229712566.17551230120004648 = 123583945584465.243481876483 - 1235715871899.067969575282953517

...Now check [me] balance after previous purchase

balanceOf():

= rAmount / currentRate

rAmount[me] is rAmount rAmount = 1286018181216.395031548234046483 currentRate = 12358394558.4465243481876483

Balance: 104.06029481697096470326753341015

Example assumes a 1% fee with reflect and nothing else. Usually there is a fee that reflects and burns

Bob Linux
  • 338
  • 4
  • 7
  • 3
    Thanks for this answer, friend. Any reason you started rTotal at 127366483000000? – Dimitris Sfounis May 14 '21 at 08:35
  • @DimitrisSfounis rTotal is fixed & pre-determined constant _rTotal = (MAX - (MAX % _tTotal)); – hack3r-0m May 22 '21 at 18:05
  • 2
    @bob-linux: if you buy 100 token, and the total fee is 1%....and I think you will get 99 token in the end...am I correct? and when you calculate the balance, it seems that you don't care about how many token holders out there... why? – mc-tor Jul 17 '21 at 09:57
  • I also have some doubts and there is not too much information on the internet. I think that is also because all of these coins are a clone of a previous one with same code, so the variable names are spread across all repos. – Alexander Herranz Nov 04 '21 at 22:24
  • 1
    Not exactly true: _rTotal is always decreasing in order to divide less between holders. – Alexander Herranz Nov 14 '21 at 03:04
  • "Not exactly true: _rTotal is always decreasing in order to divide less between holders." I forget this post, but i do believe you were right. it is always decreasing- i think – Bob Linux Nov 21 '23 at 06:58
3

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 in comments), so if you own something like 0.00812301283120398912312836% of reflections, it should work accurately.

I hope i could explain it in a simple way

Amin
  • 131
  • 2
1

tTotal, which belongs to t-space, represents tokens in circulation or total supply of a token. On the other hand, rTotal, which belongs to r-space, is a reflected value of tTotal. The term “reflected” cannot be easily explained in words but one interpretation of rTotal is token supply in reserve.

tAmount: token amount that sender pays/transfers including tFee  • tFee: transfer fee (note: 10% was chosen arbitrarily)  • tTransferAmount: tokens that will get transferred to recipient  • tOwned[user]: User’s balance represented in t-space (only used by non-stakers)  • rOwned[user]: User’s balance represented in r-space

https://reflect-contract-doc.netlify.app/

Legion
  • 41
  • 3