5月8日 bistroo.io 收到攻击 损失47000$
攻击交易:
https://bscscan.com/tx/0x8c96b3314e30cf62bdfd4f94df38a2f040e171e849208b328dcd4ac2cdbcb748
被攻击合约:
https://bscscan.com/address/0x2987b3983bfa7e2698b4c10a361ca5119697a080#code
合约代码:
bist:https://bscscan.com/address/0x4fb276defa6c5c7df26e4b8ae53d41223a098886#code
被攻击合约代码:暂无(未找到);
被攻击合约中合约中函数emergencyWithdraw
没有防重入同时在发送token后再更新用户质押数,
function emergencyWithdraw(var arg0, var arg1) {
arg0 = msg.data[arg0:arg0 + 0x20];
arg1 = 0x00;
var var0 = 0x06;
var var1 = arg0;
if (var1 >= storage[var0]) { assert();
memory[0x00:0x20] = var0;
var temp0 = var1 * 0x04 + keccak256(memory[0x00:0x20]);
arg1 = temp0;
memory[0x00:0x20] = arg0;
memory[0x20:0x40] = 0x07;
var temp1 = keccak256(memory[0x00:0x40]);
memory[0x00:0x20] = msg.sender;
memory[0x20:0x40] = temp1;
var0 = keccak256(memory[0x00:0x40]);
var1 = 0x13ea;
var var2 = storage[arg1] & 0xffffffffffffffffffffffffffffffffffffffff;
***********👆获得代币合约地址地址
var var3 = msg.sender;
var var4 = storage[var0];
************👆获得用户质押数
func_24EE(var2, var3, var4);
**************👆发送代币代码
var temp2 = var0;
var temp3 = memory[0x40:0x60];
memory[temp3:temp3 + 0x20] = storage[temp2];
var temp4 = memory[0x40:0x60];
log(memory[temp4:temp4 + (temp3 + 0x20) - temp4], [0xbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae0595, msg.sender, stack[-3]]);
*******************👇清空用户质押数
storage[temp2] = 0x00;
storage[temp2 + 0x01] = 0x00;
}
同时,bist token 为ERC777token,在发送代币后回回调用户合约,
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
require(recipient != address(0), "ERC777: transfer to the zero address");
address from = _msgSender();
_callTokensToSend(from, from, recipient, amount, "", "");
_move(from, from, recipient, amount, "", "");
_callTokensReceived(from, from, recipient, amount, "", "", false);
return true;
}
通过再回调函数中,继续调用emergencyWithdraw
即可多次提取质押代币.