1

I studied The DAO attack. Ethereum's reentrancy attack is still working. but the Ethereum network also still works ( Sure, the compiler says "warning" )

How do you believe your contract will be safe? How Ethereum patch this bug?

and How can send ether to anyone without calling the fallback function? this is the cause of dao attack

Has Ethereum got a good idea?

I want you to let me know, please.

Ismael
  • 30,570
  • 21
  • 53
  • 96
cidiot
  • 13
  • 2

3 Answers3

2

When sending ether

Using address.transfer or address.send is the simple and reentrant-safe way to send ether.

TheDAO used call.value which is more powerful but also has risks for reentrancy: What does `call.value` mean and how did it allow the attack to The DAO?

Generally

Reentrancy is an issue when code can call back into your contract and change state, such as withdrawing ether.

Keep an eye on Solidity leveraging the new opcode STATIC_CALL (EIP 214) for a general solution:

To increase smart contract security, this proposal adds a new opcode that can be used to call another contract (or itself) while disallowing any modifications to the state during the call (and its subcalls, if present).

eth
  • 85,679
  • 53
  • 285
  • 406
1

If you use the "send" or "transfer" functions, then you are safe against the DAO attack, as those functions do not delegate enough gas for the fallback function to make a function call itself.

There is no protection in Ethereum against all reentrancy, as it may be a feature and not a bug ; but if you use send your are probably safe.

Distic
  • 870
  • 7
  • 22
0
  • First, we do not want reentrancy. Reentrancy attack is actually withdrawing money recursively. We do not want a chain of functions. To prevent this, you can add this:

    require(tx.origin == msg.sender)
    

funcA => funcB => funcC

msg.sender is the caller of funcC whereas tx.origin is the caller of funcA. If tx.origin == msg.sender is satisfied, we guarantee that there is no recursive function calls.

  • Write a modifier to prevent reentrancy into the function:

    bool private locked=false;
    modifier guardReentrant(){
      require(!locked,"You are not allow to reenter");
      locked=true;
      // _ this where modified function code gets executed
      _;
      locked=false;
    } 
    

Then modify the withdraw

function withdraw() public guardReentrant payable {
  • Lastly change the logic of withdraw. Before trasnferring the funds, update the balance of msg.sender

          uint bal = balances[msg.sender];
          require(bal > 0, 'No balance amount');
          // check-effect-interact pattern
          balances[msg.sender] = 0;
          (bool sent, ) = msg.sender.call{value: bal}("");
    

this is the principle of ATM. In atm, when you withdraw money, your balance gets updated first and you get your money

Yilmaz
  • 1,580
  • 10
  • 24