> For the complete documentation index, see [llms.txt](https://xiangganzi.gitbook.io/flashloan/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://xiangganzi.gitbook.io/flashloan/shan-dian-dai-gong-ji-ce-lve/eleven-finance-gong-ji-ce-lve.md).

# Eleven Finance 攻击策略

该次闪电攻击属于很明显的合约逻辑漏洞问题。攻击者使用相同方法发起了多笔攻击交易，我们只需参考其中一笔交易即可，交易链接如下：<https://bscscan.com/tx/0x6450d8f4db09972853e948bee44f2cb54b9df786dace774106cd28820e906789>

**攻击步骤**：

1. 从PancakeSwap借入基础资产（ 闪电贷）
2. 将资产转换为Nerve LP 资产
3. 通过中间金库将Nerve LP 资产存入`MasterMind`合约
4. 在中间金库上调用`emergencyBurn`函数，将等于之前存入的金额（等于攻击前的金库余额）转移给攻击者
5. 继续常规提款，将先前存入的资产余额转回给攻击者
6. 还掉闪电贷的费用

出问题的合约来自`MasterMind`，合约地址为 [0x2EBe8CDbCB5fB8564bC45999DAb8DA264E31f24E](https://bscscan.com/address/0x2EBe8CDbCB5fB8564bC45999DAb8DA264E31f24E#code)

下面截取了问题代码

```
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`函数有做燃烧动作，减去用户在合约的代币余额。导致结果是，攻击者不仅能够取出他自己的存款，而且还能够取出与之前金库中相同金额的全部余额。
