Solidity Reentrancy Protection – How Transfer and Send Guard Against Reentrancy by Gas from EOA

contract-developmentgasreentrant-attacksSecuritysolidity

I guess transfer and send simply allow 2300 gas but no gas is taken from the contract? In other words if a wallet calls this function with say one million wei gas:

function sending() public payable
{
contract.transfer(1 ether);
balance[someone] = 0;
}

This is enough to stop reentrancy? Since the 2300 gas will prevent callback even if EOA sends it with million gas?

However this will NOT stop it since the allowed will be 30,000+?

function sending() public payable
{
contract.call.value(1 ether)();
balance[someone] = 0;
}

Best Answer

How are transfer and send protecting against reentrancy

The EVM is withholding gas to starve attackers. That severely constrains what they can do before they return.

Since the 2300 gas will prevent callback even if EOA sends it with million gas?

Yes, it is bad form but the gas stimpend should protect this poorly-constructed function. The called contract will not have enough gas to change its state or very much at all.

However this will NOT stop it

That will pass all (99% ish) of the unspent gas to the called contract (attacker) and it could use the caller's inconsistent state to start bad things. The caller is vulnerable because the state is inconsistent. It has not, yet, updated data that should be updated.

send(), transfer() and call() hand over flow control to another contract, as do function calls, e.g. otherContract.doSomething(args). If the other contract is untrusted, meaning you did not write it yourself (many systems include multiple contracts for different concerns), then it is important to put the state in order first, then transfer flow control to the other contract.

The gas stipend (2300 gas) is a hack to protect some of the bad contracts some of the time. It is far better than you make good contracts all of the time.

  1. Check acceptable inputs - the transaction is allowed?
  2. Execute effects - update everything that should be updated.
  3. Safely interact with untrusted contracts - send, transfer, call, etc.

Hope it helps.

Related Topic