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;
  • You should generally do the transfer or send last, which should guarantee that a reentrant attack would not achieve its goal. – goodvibration Dec 12 '19 at 16:27
  • yeah my thoughts exactly...better safe than sorry but i am curious why would anyone elect to proceed as above, otherwise. – Robert Ggg Dec 12 '19 at 16:50

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.

  • Interesting, so since my example over-relies on transfer the only thing that can make it hackable is a potential change of gas prices in the future correct? I mean this will never happen I bet but if some day they make 2300 to be enough for money state-change this will be very bad...yet since Istanbul it seems to be even safer since the prices haven't decreased but the opposite: increased. – Robert Ggg Dec 12 '19 at 21:02
  • In the weak example, yes, the only thing saving it is the stipend and pricing. I wouldn't rule out protocol changes. Gas prices for SSTORE were close to changed significantly down in Constantinople but the fork was aborted precisely because it would break contracts that have no other defense. – Rob Hitchens Dec 12 '19 at 23:22
  • Going forward, this presents a bit of a dilemma. Keep prices artificially high, change the stipend, or break existing contracts? – Rob Hitchens Dec 12 '19 at 23:23
  • A heuristic is to never rely on gas price consistency. Over-reliance on the stipend might be thought about as an example of that. Repricing ops broke about 600 instances of a contract from a major player because they hars-coded some gas allowances instead of making it configurable or just finding another way to address their concerns. – Rob Hitchens Dec 12 '19 at 23:26
  • well with regards to the recent changes I am not really against them seeing how in Vitalik's words: the goal is about 1000 times improvement of scalability. Yes, EOS has gasless transactions but it has all the negatives too (no solidity, paid accounts, ram/cpu limitations etc etc. – Robert Ggg Dec 12 '19 at 23:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.