Eleven Finance 攻击策略
该次闪电攻击属于很明显的合约逻辑漏洞问题。攻击者使用相同方法发起了多笔攻击交易,我们只需参考其中一笔交易即可,交易链接如下:https://bscscan.com/tx/0x6450d8f4db09972853e948bee44f2cb54b9df786dace774106cd28820e906789
攻击步骤:
从PancakeSwap借入基础资产( 闪电贷)
将资产转换为Nerve LP 资产
通过中间金库将Nerve LP 资产存入
MasterMind
合约在中间金库上调用
emergencyBurn
函数,将等于之前存入的金额(等于攻击前的金库余额)转移给攻击者继续常规提款,将先前存入的资产余额转回给攻击者
还掉闪电贷的费用
出问题的合约来自MasterMind
,合约地址为 0x2EBe8CDbCB5fB8564bC45999DAb8DA264E31f24E
下面截取了问题代码
function withdraw(uint256 _pid, uint256 _amount) public {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount >= _amount, "withdraw: not good");
updatePool(_pid);
uint256 pending =
user.amount.mul(pool.accNervePerShare).div(1e12).sub(
user.rewardDebt
);
safeNerveTransfer(msg.sender, pending);
user.amount = user.amount.sub(_amount);
user.rewardDebt = user.amount.mul(pool.accNervePerShare).div(1e12);
pool.lpToken.safeTransfer(address(msg.sender), _amount);
emit Withdraw(msg.sender, _pid, _amount);
}
// Withdraw without caring about rewards. EMERGENCY ONLY.
function emergencyWithdraw(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
pool.lpToken.safeTransfer(address(msg.sender), user.amount);
emit EmergencyWithdraw(msg.sender, _pid, user.amount);
user.amount = 0;
user.rewardDebt = 0;
}
函数emergencyBurn
内部允许攻击者提取存款余额,却没有像上面withdraw
函数有做燃烧动作,减去用户在合约的代币余额。导致结果是,攻击者不仅能够取出他自己的存款,而且还能够取出与之前金库中相同金额的全部余额。
Last updated
Was this helpful?