0

I am trying to understand the role of :

 withdraw.pendingReturns[msg.sender]=0;

in detecting denial of Service (DoS) vulnerability. The following paper VeriSolid says that:

withdraw.pendingReturns[msg.sender]=0; will eventually happen after withdraw.msg.sender.transfer(amount);

how this can help us to detect DoS vulnerability because after ‘transfer’ we can’t execute anything so how this technique can help in determining DoS vulnerability. However, in the following code withdrawals[msg.sender].amount = 0; is done before transfer which is different as in the paper:

function withdraw() public {
   if(withdrawals[msg.sender].amount > 0
      uint amount = withdrawals[msg.sender].amount;
      withdrawals[msg.sender].amount = 0;
      msg.sender.transfer(amount);
   }
}

Can we use:

withdrawals[msg.sender].amount = 0; 

after 'transfer' for determining DoS vulnerability?

Zulfi.

1
  • I don't have an answer to your question but more of a note: the concept of "DoS" in Ethereum does not really exist. The network is decentralized and there is no entity to DoS. Furthermore, all transactions cost gas so you can't do change states without paying for it. Dec 29, 2020 at 19:41

1 Answer 1

0

In my opinion, the paper is poorly worded and misleading. Admittedly, I have only glanced at the following statement and nearby regions.

The above template expresses a safety property type. A typical vulnerabilityis that currency withdrawal functions, e.g.,transfer, allow an attacker to with-draw currency again before updating her balance.

First, I feel I should collapse some confusion that arises from the misuse of common terms. The attack described is not "Denial of Service." It's "Re-entrance." The former generally means denying access to other users in some way, such as sabotage. The latter is a method of making the contract behave in an unintended (by the creator) way such as sending more money than the requester is entitled to.

Can we use: withdrawals[msg.sender].amount = 0; after 'transfer'

You shouldn't. A best practice is to use the "Checks, Effects, Interactions" pattern that basically means validate, set the state optimistically, then interact with other contracts and addresses.

The reason you do it like that is to ensure that the contract is in a consistent state with everything accounted for before another contract receives flow control. In the vulnerable configuration, a hostile contract can make a call back to the naive contract where it will find that the accounting has not happened yet. In the simplest conception of the attack, they can withdraw money again.

The attack works because the receiving contract (Attacker) has a fallback function that runs when funds are received and that can be coded to attack the naive victim.

To protect itself, the victim should first get its house in order and perform the accounting as though a successful transfer in the next step is assured. That way, the attacker will see that their entitlement is already reduced and they cannot withdraw the same money again. If the accounting comes after the transfer then their balance will be unchanged every time and that can trick the victim into releasing more funds.

When a contract reverts after a failed transfer (usually the right thing to do), that reverses the optimistic accounting performed earlier, so you can safely use the counter-intuitive order of events.

There is a partial re-entrance guard known as the gas stipend but it is bad practice to rely on it exclusively when the Checks, Effects, Interactions can be followed religiously.

Hope it helps.

1
  • 1
    Yes they mixed it with DAO. The paper discussed the DoS in the context of Liveness property. When we use ‘transfer’ for sending money but the fallback function at the receiver contains ‘revoke’ then it causes a DoS because statements in the caller contract after ‘transfer’ are not executed. Kindly read the line: ” Blind Auction to check the Denial-of-Service vulnerability (Appendix C.2): “withdraw.pendingReturns[msg.sender]=0; will eventually happen after withdraw.msg.sender.transfer(amount);”
    – zak100
    Dec 29, 2020 at 23:10

Your Answer

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

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