新零售是指个人、企业以互联网为依托,通过运用大数据、人工智能等先进技术手段并运用心理学知识,对商品的生产、流通与销售过程进行升级改造,进而重塑业态结构与生态圈,并对线上服务、线下体验以及现代物流进行深度融合的零售新模式。
“新零售”模式打破了线上和线下之前的各自封闭状态,线上线下得以相互融合、取长补短且相互依赖,线上更多履行交易与支付的职能,线下通常作为筛选与体验的平台,高效物流则将线上线下相连接并与其共同作用形成商业闭环。在“新零售”模式下,消费者可以任意畅游在智能、高效、快捷、平价、愉悦的购物环境之中,购物体验获得大幅提升,年轻群体对消费升级的强烈意愿也由此得到较好满足。
//this low-level function should be called from a contract which performs important safety checks
//这个低级函数应该从执行重要安全检查的合约中调用
function mint(address to)external lock returns(uint liquidity){
(uint112 _reserve0,uint112 _reserve1,)=getReserves();//gas savings
//合约里两种token的当前的balance
uint balance0=IERC20(token0).balanceOf(address(this));
uint balance1=IERC20(token1).balanceOf(address(this));
//获得当前balance和上一次缓存的余额的差值
//因为balance是动态变化的,reserve是静态变化的
uint amount0=balance0.sub(_reserve0);
uint amount1=balance1.sub(_reserve1);
//计算手续费
bool feeOn=_mintFee(_reserve0,_reserve1);
//gas节省,必须在此处定义,因为totalSupply可以在_mintFee中更新
//totalSupply是pair的凭证
uint _totalSupply=totalSupply;//gas savings,must be defined here since totalSupply can update in _mintFee
if(_totalSupply==0){
//第一次铸币,也就是第一次注入流动性,值为根号k减去MINIMUM_LIQUIDITY,防止数据溢出
liquidity=Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
//把MINIMUM_LIQUIDITY赋给地址0,永久锁住
_mint(address(0),MINIMUM_LIQUIDITY);//permanently lock the first MINIMUM_LIQUIDITY tokens
}else{
//计算增量的token占总池子的比例,作为新铸币的数量
//木桶法则,按最少的来,按当前投入的占池子总的比例增发
liquidity=Math.min(amount0.mul(_totalSupply)/_reserve0,amount1.mul(_totalSupply)/_reserve1);
}
require(liquidity>0,'UniswapV2:INSUFFICIENT_LIQUIDITY_MINTED');
//铸币,修改to的token数量及totalsupply
//给to地址发凭证,同时pair合约的totalSupply增发同等的凭证
_mint(to,liquidity);
//更新时间加权平均价格
_update(balance0,balance1,_reserve0,_reserve1);
if(feeOn)kLast=uint(reserve0).mul(reserve1);//reserve0 and reserve1 are up-to-date
emit Mint(msg.sender,amount0,amount1);
}
//this low-level function should be called from a contract which performs important safety checks
function burn(address to)external lock returns(uint amount0,uint amount1){
(uint112 _reserve0,uint112 _reserve1,)=getReserves();//gas savings
address _token0=token0;//gas savings
address _token1=token1;//gas savings
uint balance0=IERC20(_token0).balanceOf(address(this));
uint balance1=IERC20(_token1).balanceOf(address(this));
uint liquidity=balanceOf[address(this)];
bool feeOn=_mintFee(_reserve0,_reserve1);
uint _totalSupply=totalSupply;//gas savings,must be defined here since totalSupply can update in _mintFee
//计算返回的amount0/1
amount0=liquidity.mul(balance0)/_totalSupply;//using balances ensures pro-rata distribution
amount1=liquidity.mul(balance1)/_totalSupply;//using balances ensures pro-rata distribution
require(amount0>0&&amount1>0,'UniswapV2:INSUFFICIENT_LIQUIDITY_BURNED');
_burn(address(this),liquidity);
//_token0/1给to转amount0/1
_safeTransfer(_token0,to,amount0);
_safeTransfer(_token1,to,amount1);
//获取转账后的balance
balance0=IERC20(_token0).balanceOf(address(this));
balance1=IERC20(_token1).balanceOf(address(this));
//更新reserve0,reserve1和时间戳
_update(balance0,balance1,_reserve0,_reserve1);
if(feeOn)kLast=uint(reserve0).mul(reserve1);//reserve0 and reserve1 are up-to-date
emit Burn(msg.sender,amount0,amount1,to);
}
//this low-level function should be called from a contract which performs important safety checks
//交易函数
//可以是token0-->token1,
//也可以是token1-->token0
//但参数中:amount0Out和amount1Out中有一个值是0
function swap(
uint amount0Out,
uint amount1Out,
address to,
bytes calldata data
)external lock
{
require(amount0Out>0||amount1Out>0,'UniswapV2:INSUFFICIENT_OUTPUT_AMOUNT');
(uint112 _reserve0,uint112 _reserve1,)=getReserves();//gas savings
require(amount0Out<_reserve0&&amount1Out<_reserve1,'UniswapV2:INSUFFICIENT_LIQUIDITY');
uint balance0;
uint balance1;
{//scope for _token{0,1},avoids stack too deep errors
address _token0=token0;
address _token1=token1;
require(to!=_token0&&to!=_token1,'UniswapV2:INVALID_TO');
//划转操作
if(amount0Out>0)_safeTransfer(_token0,to,amount0Out);//optimistically transfer tokens
if(amount1Out>0)_safeTransfer(_token1,to,amount1Out);//optimistically transfer tokens
if(data.length>0)IUniswapV2Callee(to).uniswapV2Call(msg.sender,amount0Out,amount1Out,data);
balance0=IERC20(_token0).balanceOf(address(this));
balance1=IERC20(_token1).balanceOf(address(this));
}
uint amount0In=balance0>_reserve0-amount0Out?balance0-(_reserve0-amount0Out):0;
uint amount1In=balance1>_reserve1-amount1Out?balance1-(_reserve1-amount1Out):0;
require(amount0In>0||amount1In>0,'UniswapV2:INSUFFICIENT_INPUT_AMOUNT');
{//scope for reserve{0,1}Adjusted,avoids stack too deep errors
//防止数据溢出校验
uint balance0Adjusted=balance0.mul(1000).sub(amount0In.mul(3));
uint balance1Adjusted=balance1.mul(1000).sub(amount1In.mul(3));
require(balance0Adjusted.mul(balance1Adjusted)>=uint(_reserve0).mul(_reserve1).mul(1000**2),'UniswapV2:K');
}
//更新
_update(balance0,balance1,_reserve0,_reserve1);
emit Swap(msg.sender,amount0In,amount1In,amount0Out,amount1Out,to);
}
//force balances to match reserves
//强制balance以匹配储备
function skim(address to)external lock{
address _token0=token0;//gas savings
address _token1=token1;//gas savings
_safeTransfer(_token0,to,IERC20(_token0).balanceOf(address(this)).sub(reserve0));
_safeTransfer(_token1,to,IERC20(_token1).balanceOf(address(this)).sub(reserve1));
}
//force reserves to match balances
//强制储备以匹配balance
function sync()external lock{
_update(IERC20(token0).balanceOf(address(this)),IERC20(token1).balanceOf(address(this)),reserve0,reserve1);
}
}