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.

3
  • I want to know method of ethereum. Don't say secure coding please.
    – cidiot
    Sep 6, 2017 at 15:47
  • The DAO hack was not an Ethereum bug. It's like blaming computer crashes on a C compiler.
    – lungj
    Sep 6, 2017 at 16:42
  • @lungj computer crashes??? I don't understand.. If you have ref site for me?
    – cidiot
    Sep 7, 2017 at 3:32

3 Answers 3

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).

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.

2
  • Thanks, I overlook gas system. It helped me, but I can't vote because this site system.
    – cidiot
    Sep 7, 2017 at 3:27
  • Ensure you check the return value if using send.
    – Tom Hale
    Oct 1, 2017 at 8:18
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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