safemoon分红机制原理解析
在社区里提问了这个问题,自己做个总结
https://cn.etherscan.com/address/0xcd7492db29e2ab436e819b249452ee1bbdf52214#code
每一笔转账都会触发分红,但是分红不会触发转账,只是修改一个系数,即修改每个用户的占比。 在别人进行转账时,用户的rOwned不变,系数currentRate变小,实际余额变大。
我觉得需要理解的一点是:在用户转账成功后,还未分红的时候,用户的_rOwned占比即为分红后的占比
。
假设用户所有转账即为分红 _tTotal = 100,_rTotal = 10000 _rOwned[A] = 7000,_rOwned[B] = 2000,_rOwned[C] = 1000 用户B发起转账交易1000,即1000用做被分红。
常规分红计算
_rOwned[A] = 70 + 70/90*10 = 700/9
_rOwned[B] = 10 + 10/90*10 = 100/9
_rOwned[C] = 10 + 10/90*10 = 100/9
占比分红
_rOwned[A] = 7000/9000*100 = 700/9
_rOwned[B] = 1000/9000*100 = 100/9
_rOwned[C] = 1000/9000*100 = 100/9
contract SMI is Context, IERC20, Ownable {
mapping (address => uint256) private _rOwned;
mapping (address => uint256) private _tOwned;
uint256 private constant MAX = ~uint256(0); //最大值
uint256 private constant _tTotal = 100000 * 10**6 * 10**9; // 实际总量
uint256 private _rTotal = (MAX - (MAX % _tTotal)); // 映射的总量
function balanceOf(address account) public view override returns (uint256) {
if (_isExcluded[account]) return _tOwned[account]; //不参与分红的用户
return tokenFromReflection(_rOwned[account]);//参与分红的用户
}
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);
}
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 < _excluded.length; i++) {
if (_rOwned[_excluded[i]] > rSupply || _tOwned[_excluded[i]] > tSupply) return (_rTotal, _tTotal);
rSupply = rSupply.sub(_rOwned[_excluded[i]]);
tSupply = tSupply.sub(_tOwned[_excluded[i]]);
}
if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal);
return (rSupply, tSupply);
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!