合约地址:
BunnyMinterV2:https://bscscan.com/address/0x819eea71d3f93bb604816f1797d4828c90219b5d#code
VaultFlipToFlip:https://bscscan.com/address/0xd415e6caa8af7cc17b7abd872a42d5f2c90838ea#code
MasterChefh:https://bscscan.com/address/0x73feaa1ee314f8c655e354234017be2193c9e24e#code
pancakePair:https://bscscan.com/address/0x16b9a82891338f9ba80e2d6970fdda79d1eb0dae#code
PancakeRouter:https://bscscan.com/address/0x10ED43C718714eb63d5aA57B78B54704E256024E#code
攻击交易:
一:https://bscscan.com/tx/0x88fcffc3256faac76cde4bbd0df6ea3603b1438a5a0409b2e2b91e7c2ba3371a
二:https://bscscan.com/tx/0x897c2de73dd55d7701e1b69ffb3a17b0f4801ced88b0c75fe1551c5fcce6a979
参考文章:
PancakeBunny攻击事件复盘分析 | 零时科技:http://www.xilian.link/depth/75435.html
慢雾:PancakeBunny 黑客分析:
https://slowmist.medium.com/slowmist-pancakebunny-hack-analysis-4a708e284693
合约BunnyMinterv2中函数mintForV2通过performanceFee与valueInBNB 计算mint生成的数量。
uint performanceFee = canMint() ? _minter.performanceFee(amount) : 0;
if (performanceFee > DUST) {
_minter.mintForV2(address(_stakingToken), 0, performanceFee, msg.sender, depositTimestamp);
amount = amount.sub(performanceFee);
}
function mintForV2(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint) external payable override onlyMinter {
uint feeSum = _performanceFee.add(_withdrawalFee);
_transferAsset(asset, feeSum);
if (asset == BUNNY) {
IBEP20(BUNNY).safeTransfer(DEAD, feeSum);
return;
}
uint bunnyBNBAmount = _zapAssetsToBunnyBNB(asset, feeSum, true);
if (bunnyBNBAmount == 0) return;
IBEP20(BUNNY_BNB).safeTransfer(BUNNY_POOL, bunnyBNBAmount);
IStakingRewards(BUNNY_POOL).notifyRewardAmount(bunnyBNBAmount);
(uint valueInBNB,) = priceCalculator.valueOfAsset(BUNNY_BNB, bunnyBNBAmount);
uint contribution = valueInBNB.mul(_performanceFee).div(feeSum);
uint mintBunny = amountBunnyToMint(contribution);
if (mintBunny == 0) return;
_mint(mintBunny, to);
}
但在函数_zapAssetsToBunnyBNB
返回的bunnyBNBAmount数量是由IBEP20(BUNNY_BNB).balanceOf(address(this)).sub(_initBunnyBNBAmount)
操作后减操作前的balance计算出来的。
同时中间有removeLiquidity
操作。
再看removeLiquidity代码:文章来源:https://www.toymoban.com/news/detail-416184.html
function removeLiquidity()
......
address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB);
IPancakePair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair
(uint amount0, uint amount1) = IPancakePair(pair).burn(to);
.............
------------
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;
amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution
amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution
_burn(address(this), liquidity);
_safeTransfer(_token0, to, amount0);
_safeTransfer(_token1, to, amount1);
再调用burn时会将当前pair中的lptoken全部燃烧并发送相应的token到目标地址。
如果将lptoken提前存入pair中,那么在调用函数_zapAssetsToBunnyBNB
时因为removeLiquidity的操作,会将提前存入的lptoken也一并转换为token并发送回合约,大量bnb与usdt 来到合约后。
zapInToken又将这些token转换为bnb后再(转换一半数量为bunny。一半bnb)1:1存入bunny:bnb池子,增加池子中bnb数量(影响bunny价格),_zapAssetsToBunnyBNB
返回时因为提前存入lp导致返回的 bunnyBNBAmount 数量也异常的大。
在(uint valueInBNB,) = priceCalculator.valueOfAsset(BUNNY_BNB, bunnyBNBAmount);
时因为zapInToken的操作,导致计算的valueInBNB结果也变得非常高。
最终生成了大量bunnytoken。文章来源地址https://www.toymoban.com/news/detail-416184.html
到了这里,关于pancake闪电贷攻击学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!