作者: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;
}
然后我们讨论这种情况下可能存在的风险。
如果单看代币合约,我们会发现这种写法其实没有什么问题,但是区块链中有很多复杂的情况,需要我们考虑很多方面。
Osmosis已通过关于Thridening的两项提案:7月11日消息,基于Cosmos的去中心化交易所Osmosis已通过关于Thridening的两项提案,其中551提案提议燃烧6月20日Thirdening事件延迟期间产生的约54万枚多余的OSMO,将最大发行量恢复至10亿枚;552提案提议将Thirdening效果恢复为1/3缩减、将间隔时间延长至两年。[2023/7/11 10:47:26]
通常,为了让代币有价格,项目方会在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));
}
此时发送方变成了流动性池,当调用_transfer时,流动性池中的代币将被部分销毁,导致代币价格部分上涨。
攻击者利用此特性将代币直接转入流动性池中,然后调用skim函数转出,然后多次重复此操作,导致流动性池中大量代币被燃烧,价格也随之飙升,最后卖出代币获利。
一个真实的攻击案例,winnerdoge(WDOGE)?:
印度在担任G20轮值主席国期间将探索禁止无担保的加密货币:金色财经报道,印度周四表示,在其正在担任的G20轮值主席国期间,他将优先制定一个无担保加密资产、稳定币和去中心化金融的全球监管框架,并将探索“禁止它们的可能性”,这对新生行业来说可能是一个巨大的挫折。
金色财经此前报道,印度央行发布《金融稳定报告》称加密货币未能成为对冲通胀工具。[2022/12/30 22:15:43]
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;
emitTransfer(sender,recipient,amount);
}
else
{
uint256onePercent=findOnePercent(amount);
uint256tokensToBurn=onePercent*4;
尼日利亚为推动CBDC的普及将现金提取限制在每天45美元:金色财经报道,尼日利亚中央银行限制了现金提现,以推动消费者使用包括其其中央银行数字货币(CBDC)eNaira在内的替代货币。尼日利亚中央银行(CBN)在周二发布的致银行和其他金融机构的信中,对个人场外提款实行了新的限制,每周仅为10万奈拉(225美元),企业为50万奈拉(1123美元)。每天从ATM机取出现金的上限为2万奈拉(45美元),ATM机只能提供200奈拉(0.45美元)及更小面额的纸币。在某些情况下,客户仍可以提取更多金额,但必须支付5%至10%的手续费。
据悉,eNaira于去年10月推出,但只有不到0.5%的尼日利亚人在使用它。[2022/12/7 21:28:43]
uint256tokensToRedistribute=onePercent*4;
uint256toFeeWallet=onePercent*1;
uint256todev=onePercent*1;
uint256tokensToTransfer=amount-tokensToBurn-tokensToRedistribute-toFeeWallet-todev;
?
_balances.amount-=amount;
_balances.amount+=tokensToTransfer;
_balances.amount+=toFeeWallet;
_balances.amount+=todev;
if(!_balances.exists){
_balanceOwners.push(recipient);
_balances.exists=true;
}
redistribute(sender,tokensToRedistribute);
Kraken:没有Alameda敞口,但持有近9000枚FTT:金色财经报道,加密货币交易所Kraken表示,它没有接触Alameda Research,但它持有近9000个原生代币FTT。我们没有在我们的现货或期货交易所上市FTT代币,Kraken不受最近 FTX 消息的任何实质性影响。[2022/11/10 12:43:49]
_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){
美联储巴尔金:对央行数字货币概念持开放态度:6月21日消息,美联储巴尔金称,在利用资产负债表加大紧缩力度方面门槛很高。调整资产负债表缩减可能是明智的,但这是“未来的方案”。关于是否出售抵押贷款支持证券的任何决定都还有待做出。我仍然对美联储是否需要数字货币持怀疑态度,但我对央行数字货币概念持开放态度。[2022/6/22 4:43:37]
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):
防御方案
通过解读针对燃烧机制和反射机制代币的攻击手法,不难发现攻击者攻击的核心点是操纵流动性池的价格,因此将流动性池的地址加入白名单,不涉及代币的销毁,不参与代币的反射机制,可以避免此类攻击。
总结
本文分析了通缩机制代币的两种实现机制以及针对这两种机制的攻击手段,最后给出了相应的解决方案。在编写合约时,项目方必须考虑代币与去中心化交易所结合的情况,以避免此类攻击。
标签:RESKENTOKENTOKEAAG VenturesDiamond Hands TokenOraichain TokenCITEX Fund Token
YugaLabs比特币NFT系列TwelveFold拍卖模式引发加密社区的不满。根据拍卖规则,竞标者被要求将其全部BTC投标金额发送到由Yuga控制的唯一BTC地址,中标者只需支付其出价的BTC,而Yuga表示会将BTC返还给出价失败.
1900/1/1 0:00:00作者:Web3Traveler3月16日,Arbitrum正式官宣为ArbitrumOne和ArbitrumNova网络推出DAO治理和治理代币ARB,同时公布备受期待的空投细节,目前已开放空投资格查询.
1900/1/1 0:00:00两位知情人士透露,人工智能初创公司Anthropic以41亿美元的投前估值获3亿美元融资,SparkCapital领投。其中一位知情人士说,在这笔交易之前,谷歌向这家初创公司投资了4亿美元.
1900/1/1 0:00:00撰文:waynezhang.eth上周,我们发布了LSDFi生态/LSDFiWar报告以及上海升级给LSD带来的影响的报告,但无论是选择的项目还是思考的背景都是以太坊。这是因为仅以太坊流动性质押带来的资金量就超过140亿美元.
1900/1/1 0:00:00流动性质押协议Lido公布了与用户提款ETH挂钩的NFT发行计划,每个NFT作为取消质押其ETH的请求。这些提款将在下个月以太坊上海升级后启用.
1900/1/1 0:00:00作者:zf857.eth,R3POSilvergate与SVB带崩加密行业在经历了动荡的一年之后.
1900/1/1 0:00:00