A contract may be exposed to gas-dependent reentrancy if: (1) the amount of transferred ether depends on some state that gets updated only after the transfer is made and (2) the amount of gas handed to the caller depends on the amount of available gas. The call instruction for ether transfer grants control over the transaction execution to the ether receiver while handing all available gas. This allows the receiver to call the contract again (before its state is updated) to receive the same amount of ether again. An attacker can repeat this process until the contract's balance is drained.

contract Wallet { uint balance; function send(){ if (balance > 0){ msg.sender.call.value(balance)(); balance = 0; } } }

The balance of the wallet is set to zero out only after it is transferred to the transaction sender. This contract is vulnerable to a gas-dependent reentrancy because it uses the call.value() statement, which transfers all available gas to msg.sender and also it updates the state of the contract (setting the balance to zero) after the call statement is executed.