mirror of https://github.com/crytic/slither
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.8 KiB
54 lines
1.8 KiB
// pragma solidity ^0.5.0;
|
|
|
|
contract Reentrancy {
|
|
mapping (address => uint) userBalance;
|
|
|
|
function getBalance(address u) view public returns(uint){
|
|
return userBalance[u];
|
|
}
|
|
|
|
function addToBalance() payable public{
|
|
userBalance[msg.sender] += msg.value;
|
|
}
|
|
|
|
function withdrawBalance() public{
|
|
// send userBalance[msg.sender] ethers to msg.sender
|
|
// if mgs.sender is a contract, it will call its fallback function
|
|
(bool ret, bytes memory mem) = msg.sender.call{value:userBalance[msg.sender]}("");
|
|
if( ! ret ){
|
|
revert();
|
|
}
|
|
userBalance[msg.sender] = 0;
|
|
}
|
|
|
|
function withdrawBalance_fixed() public{
|
|
// To protect against re-entrancy, the state variable
|
|
// has to be change before the call
|
|
uint amount = userBalance[msg.sender];
|
|
userBalance[msg.sender] = 0;
|
|
(bool ret, bytes memory mem) = msg.sender.call{value:amount}("");
|
|
if( ! ret ){
|
|
revert();
|
|
}
|
|
}
|
|
|
|
function withdrawBalance_fixed_2() public{
|
|
// send() and transfer() are safe against reentrancy
|
|
// they do not transfer the remaining gas
|
|
// and they give just enough gas to execute few instructions
|
|
// in the fallback function (no further call possible)
|
|
msg.sender.transfer(userBalance[msg.sender]);
|
|
userBalance[msg.sender] = 0;
|
|
}
|
|
|
|
function withdrawBalance_fixed_3() public{
|
|
// The state can be changed
|
|
// But it is fine, as it can only occur if the transaction fails
|
|
uint amount = userBalance[msg.sender];
|
|
userBalance[msg.sender] = 0;
|
|
(bool ret, bytes memory mem) = msg.sender.call{value:amount}("");
|
|
if( ! ret ){
|
|
userBalance[msg.sender] = amount;
|
|
}
|
|
}
|
|
}
|
|
|