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.
90 lines
2.5 KiB
90 lines
2.5 KiB
pragma solidity ^0.4.24;
|
|
|
|
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
|
|
if( ! (msg.sender.call.value(userBalance[msg.sender])() ) ){
|
|
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;
|
|
if( ! (msg.sender.call.value(amount)() ) ){
|
|
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;
|
|
if( ! (msg.sender.call.value(amount)() ) ){
|
|
userBalance[msg.sender] = amount;
|
|
}
|
|
}
|
|
function withdrawBalance_fixed_4() 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;
|
|
if( (msg.sender.call.value(amount)() ) ){
|
|
return;
|
|
}
|
|
else{
|
|
userBalance[msg.sender] = amount;
|
|
}
|
|
}
|
|
|
|
function withdrawBalance_nested() public{
|
|
uint amount = userBalance[msg.sender];
|
|
if( ! (msg.sender.call.value(amount/2)() ) ){
|
|
msg.sender.call.value(amount/2)();
|
|
userBalance[msg.sender] = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
contract Called{
|
|
function f() public;
|
|
}
|
|
|
|
contract ReentrancyEvent {
|
|
|
|
event E();
|
|
|
|
function test(Called c) public{
|
|
|
|
c.f();
|
|
emit E();
|
|
|
|
}
|
|
}
|
|
|
|
|