1、Safemoon原理
Safemoon是一种通缩分红token,通缩指的是每次转账都会收取一定手续费,这些手续费会直接销毁,进而导致总量的通缩。分红指的是,用户的余额会随着其他用户转账而增加。
Safemoon的基本原理用一个比喻来说就是,将一块固定蛋糕(_tTotal)分给总量会变化的盘子中(_rTotal),每次转账都会打碎一部分盘子,这样剩余盘子分到的蛋糕就变多了。
2、 数据结构
mapping (address => uint256) private _rOwned;
mapping (address => uint256) private _tOwned;
mapping (address => mapping (address => uint256)) private _allowances;
mapping (address => bool) private _isExcludedFromFee;
mapping (address => bool) private _isExcluded;
address[] private _excluded;
uint256 private constant MAX = ~uint256(0);
uint256 private _tTotal = 1000000000 * 10**6 * 10**9;
uint256 private _rTotal = (MAX - (MAX % _tTotal));
uint256 private _tFeeTotal;
string private _name = "SafeMoon";
string private _symbol = "SAFEMOON";
uint8 private _decimals = 9;
uint256 public _taxFee = 5;
uint256 private _previousTaxFee = _taxFee;
uint256 public _liquidityFee = 5;
uint256 private _previousLiquidityFee = _liquidityFee;
IUniswapV2Router02 public immutable uniswapV2Router;
address public immutable uniswapV2Pair;
bool inSwapAndLiquify;
bool public swapAndLiquifyEnabled = true;
uint256 public _maxTxAmount = 5000000 * 10**6 * 10**9;
uint256 private numTokensSellToAddToLiquidity = 500000 * 10**6 * 10**9;
_tTotal:对外展示的币总量,为1000000000 * 10**6 * 10**9,可以看出是总的蛋糕
_rTotal:是内部实际的币总量,为2^256-(2^256%_tTotal),是一个很大的数,可以看出是盘子的数量
_rOwned : 用户内部持有的实际币数量,可以看成是每个用户拥有的盘子数量
_tOwned :只用于非分红用户的转账,可以看成是一个帮助类
_allowances:类似于ERC20的allowance,指用户授权某些账户的可使用额度
_isExcludedFromFee:账户白名单,用来判断是否需要转账手续费
_isExcluded:账户黑名单,用来判断是否参与分红,默认所有用户都会参与分红
_excluded:黑名单数组
_tFeeTotal:收取的手续费,可以看成是打碎了多少盘子,但是不影响总蛋糕_tTotal
_name:代币名称
_symbol:代币代码
_decimals:代币精度
_taxFee:转账收取的手续费,这部分手续费会直接销毁,进而导致_rTotal减少,也就是总量的通缩。
_previousTaxFee:上一次设置的手续费,是个历史记录
_liquidityFee:转账收取的流动性手续费,这部分手续费会添加到uniswap的交易对里
_previousLiquidityFee:上一次设置的手续费,是个历史记录
uniswapV2Router:uniswap的路由器,用于添加流动性
uniswapV2Pair:在uniswap的创建的SafeMoon-ETH交易对
inSwapAndLiquify:用于lockTheSwap这个modifier,用来加锁的
swapAndLiquifyEnabled:开关,要不要将流动性手续费添加到uniswap的交易对里
_maxTxAmount:每次转账最多可转多少代币
numTokensSellToAddToLiquidity:当累积的流动性手续费大于这个值得时候,才会去uniswap添加流动性
3、构造函数
constructor () public {
_rOwned[_msgSender()] = _rTotal;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F);
// Create a uniswap pair for this new token
uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(address(this), _uniswapV2Router.WETH());
// set the rest of the contract variables
uniswapV2Router = _uniswapV2Router;
//exclude owner