TOKE:从技术角度解析:为什么通缩机制的代币易受攻击_RES

作者:EoceneResearch

概述

在区块链上具有通缩机制的代币最近经常受到攻击。本文将讨论并分析代币令牌受到攻击的原因,并给出相应的防御方案。

在代币中实现通缩机制通常有两种方式,一种是燃烧机制,另一种是反射机制。下面我们将分析这两种实现方式可能存在的问题。

燃烧机制

通常,具有燃烧机制的代币将在其_transfer函数中实现燃烧的逻辑。有时候会存在发送者承担手续费的情况。在这种情况下,接收方收到的代币数量不会发生变化,但发送方需要支付更多代币,因为其需要承担手续费。下面是一个简单的例子:

function_transfer(addresssender,addressrecipient,uint256amount)internalvirtualreturns(bool){

require(_balances>=amount,"ERC20:transferamountexceedsbalance");

require(sender!=address(0),"ERC20:transferfromthezeroaddress");

require(recipient!=address(0),"ERC20:transfertothezeroaddress");

burnFee=amount*burnFeeRate;

_balances-=amount;

_burn(sender,burnFee);

_balances+=amount;

}

然后我们讨论这种情况下可能存在的风险。

如果单看代币合约,我们会发现这种写法其实没有什么问题,但是区块链中有很多复杂的情况,需要我们考虑很多方面。

Velo实验室副董事Beam:解读Velo收购Interstellar背后布局:金色财经报道,3月17日下午16:00,金色财经与欧易OKEx联合举办“金色财经对话Beam:解读Velo收购Interstellar背后布局“,邀请Velo 实验室副董事长 Tridbodi Arunanondchai(Beam)作为嘉宾讲述背后故事。

在直播中,Beam表示,Velo的目标是建立一个赋能传统银行商业并将其与最新的中心化和去中心化商业相链接的桥梁。

在谈及本次收购的原因时,Beam解释道,Velo与Stellar有着共同的目标和愿景,并且双方在能力上互相补充互相赋能。Interstellar团队在提供更快、更低廉以及更稳定的给予Stellar网络的跨境支付方案中有着极深厚的经验。因此彼此的融合是一个非常自然的选择。这次合并将使其成为行业里更强、更有影响力的团队。[2021/3/18 18:56:33]

通常,为了让代币有价格,项目方会在Uniswap、Pancakeswap等去中心化交易所为代币添加流动性。

其中,在Uniswap中,有一个函数skim,它会将流动性池中两种代币的余额和储备金的差值转移给调用方,以平衡余额和储备金:

functionskim(addressto)externallock{

address_token0=token0;//gassavings

address_token1=token1;//gassavings

_safeTransfer(_token0,to,IERC20(_token0).balanceOf(address(this)).sub(reserve0));

_safeTransfer(_token1,to,IERC20(_token1).balanceOf(address(this)).sub(reserve1));

动态 | 加密资产机构加大对软件开发商投入,以通过算法解读市场情绪:据cointelegraph消息,随着近期比特币波动性的加剧,加密资产管理公司和对冲基金正在加大对软件开发商的投入,以通过算法研究解读市场情绪。帮助他们解释和利用市场情绪信号,获得更高的收益。[2019/7/17]

}

此时发送方变成了流动性池,当调用_transfer时,流动性池中的代币将被部分销毁,导致代币价格部分上涨。

攻击者利用此特性将代币直接转入流动性池中,然后调用skim函数转出,然后多次重复此操作,导致流动性池中大量代币被燃烧,价格也随之飙升,最后卖出代币获利。

一个真实的攻击案例,winnerdoge(WDOGE)?:

function_transfer(addresssender,addressrecipient,uint256amount)internalvirtualreturns(bool){

require(_balances.amount>=amount,"ERC20:transferamountexceedsbalance");

require(sender!=address(0),"ERC20:transferfromthezeroaddress");

require(recipient!=address(0),"ERC20:transfertothezeroaddress");

if(block.timestamp>=openingTime&&block.timestamp<=closingTime)

{

_balances.amount-=amount;

_balances.amount+=amount;

分析 | 币安中签解读:最新中签率显示持仓逐步分散 机构投资者或有一定撤离:据TokenGazer观察BNB最新的中签信息,TokenGazer猜测机构投资者可能已经有一定程度撤离。

本次elrond中签率仅为11.07%,大幅度低于one的30%和matic的58%;

总签数10833,共计锁定978.5万BNB,约占BNB总体供应的10%,远远高于之前锁定2%左右的量,说明BNB的持仓已经有了一定程度的分散。

而币安自6月中宣布在9月隔离美国用户后出现较大幅度的跌幅,时间点上和本次Launchpad抽签时间段重合,可能说明机构投资者对监管有所顾虑已经出现一定程度撤离。[2019/7/2]

emitTransfer(sender,recipient,amount);

}

else

{

uint256onePercent=findOnePercent(amount);

uint256tokensToBurn=onePercent*4;

uint256tokensToRedistribute=onePercent*4;

uint256toFeeWallet=onePercent*1;

uint256todev=onePercent*1;

uint256tokensToTransfer=amount-tokensToBurn-tokensToRedistribute-toFeeWallet-todev;

?

_balances.amount-=amount;

_balances.amount+=tokensToTransfer;

_balances.amount+=toFeeWallet;

金色财经独家分析 巨人转让区块链相关股份的两种解读:被投资公司盈利能力反映在巨人公司的投资损益项,盈利能力存在风险会直接对其财务报表产生风险,而这正是股东看重的地方。巨人公司出售OKC股份,从因“不确定性”而“保护投资者”理由解释合理充分,转让对价2850万美元占2%左右比例并不高,董事会在其职权范围内作出决定也不用劳烦整个股东大会,巨人也按照程序做了相同的关联方解释,资产并未被低估贱卖,完全符合要求。

然而“不确定性”却存在两种解读。如果解释为风险,史玉柱等自然展现了担当与无私;如果解释为潜在收益,那么OKC成功转型带来的利润巨人公司的广大股东也是享受不到的。旁人并不知道史玉柱和董事会的想法,但至少,此次减少“区块链”相关的股权,并不能说明OKC或区块链概念的利空。如果真是巨大风险,就没必要卖给“利益相关方”了,解释为史玉柱与股东会的“分歧”更为准确。而且值得注意的是,OKC是从经营币到搞区块链“实业”,更符合政策,有理由是个正向消息。[2018/3/24]

_balances.amount+=todev;

if(!_balances.exists){

_balanceOwners.push(recipient);

_balances.exists=true;

}

redistribute(sender,tokensToRedistribute);

_burn(sender,tokensToBurn);

emitTransfer(sender,recipient,tokensToTransfer);

}

returntrue;

}

在WDOGE合约的_transfer函数中,当block.timestamp>closingTime时,进入else循环。在代码第21行中,转账金额从发送方的余额中扣除,在代码第31行中,发送方又被燃烧了tokensToBurn数量的代币。攻击者利用这种手续费的机制,通过上述的攻击方式窃取流动性池中的所有价值代币(WBNB)。

反射机制

在反射机制中,用户每次交易都会收取手续费,用于奖励持有代币的用户,但不会触发转账,只是单纯修改一个系数。

在这个机制中,用户有两种类型的代币数量,tAmount和rAmount。tAmount为实际代币数量,rAmount为反映后的代币数量,比率为tTotal/rTotal,一般的代码实现如下:

functionbalanceOf(addressaccount)publicviewoverridereturns(uint256){

if(_isExcluded)return_tOwned;

returntokenFromReflection(_rOwned);

}

functiontokenFromReflection(uint256rAmount)publicviewreturns(uint256){

require(rAmount<=_rTotal,"Amountmustbelessthantotalreflections");

uint256currentRate=_getRate();

returnrAmount.div(currentRate);

}

function_getRate()privateviewreturns(uint256){

(uint256rSupply,uint256tSupply)=_getCurrentSupply();

returnrSupply.div(tSupply);

}

反射机制的代币中一般有一个叫做deliver的函数,会销毁调用者的代币,降低rTotal的值,所以比率会增加,其他用户反射后的代币数量也会增加:

functiondeliver(uint256tAmount)public{

addresssender=_msgSender();

require(!_isExcluded,"Excludedaddressescannotcallthisfunction");

(uint256rAmount,,,,,)=_getValues(tAmount);

_rOwned=_rOwned.sub(rAmount);

_rTotal=_rTotal.sub(rAmount);

_tFeeTotal=_tFeeTotal.add(tAmount);

}

攻击者注意到这个函数,并用它来攻击相应的Uniswap?的流动性池。

那他该如何进行利用呢?同样从Uniswap的skim?函数开始:

functionskim(addressto)externallock{

address_token0=token0;//gassavings

address_token1=token1;//gassavings

_safeTransfer(_token0,to,IERC20(_token0).balanceOf(address(this)).sub(reserve0));

_safeTransfer(_token1,to,IERC20(_token1).balanceOf(address(this)).sub(reserve1));

}

Uniswap中reserve是储备金,与token.balanceOf(address(this))不同。

攻击者先调用deliver函数销毁自己的代币,导致rTotal的值减少,比率随之增加,所以反射后的代币的值也会增加,token.balanceOf(address(this))也会相应变大,与reserve?的值出现了差距。

因此,攻击者可以通过调用skim函数转出数量为两者之间差值的代币从而进行获利。

Attacker:token.deliver

rtotal:decrease

rate:increase

tokenFromReflection:increase

balanceOf:increase->token.balanceOf(address(this))>reserve

Attacker:pair.skim

token.balanceOf(address(this))>reserve

token.transfer

一个真实的攻击案例,BEVONFTArtToken(BEVO):

而当代币合约中存在burn函数时,存在了另外一种相似的攻击手法:

functionburn(uint256_value)public{

_burn(msg.sender,_value);

}

function_burn(address_who,uint256_value)internal{

require(_value<=_rOwned);

_rOwned=_rOwned.sub(_value);

_tTotal=_tTotal.sub(_value);

emitTransfer(_who,address(0),_value);

}

当用户调用burn函数时,自己的代币会被销毁,同时tTotal的值会减少,所以比率会降低,对应的反射后的代币数量也会减少,所以在此时流动性池的代币的数量也会减少,从而代币的价格会上涨。

攻击者利用这个特性通过多次调用burn函数来减少tTotal的值,然后调用流动性池的sync函数同步reserve和balances。最后,流动性池中的代币大幅减少,价格飙升。然后攻击者出售代币以获取利润。

Attacker:token.burn

tTotal:decrease

rate:decrease

tokenFromReflection:decrease

balanceOf:decrease

Attacker:pair.sync

token.balanceOf(address(this))>reserve

token.transfer

一个真实的攻击案例,SheepToken(SHEEP):

防御方案

通过解读针对燃烧机制和反射机制代币的攻击手法,不难发现攻击者攻击的核心点是操纵流动性池的价格,因此将流动性池的地址加入白名单,不涉及代币的销毁,不参与代币的反射机制,可以避免此类攻击。

总结

本文分析了通缩机制代币的两种实现机制以及针对这两种机制的攻击手段,最后给出了相应的解决方案。在编写合约时,项目方必须考虑代币与去中心化交易所结合的情况,以避免此类攻击。

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

大币网

[0:15ms0-5:674ms