Skip to content

Instantly share code, notes, and snippets.

@Melvillian
Last active November 5, 2021 16:04
Show Gist options
  • Select an option

  • Save Melvillian/5c0b9eb25916f6c21ae7af30c0d0209b to your computer and use it in GitHub Desktop.

Select an option

Save Melvillian/5c0b9eb25916f6c21ae7af30c0d0209b to your computer and use it in GitHub Desktop.
A contract that seems to follow checks-effects-interaction pattern, but is still vulnerable to re-entrancy, taken from https://gist.github.com/ritzdorf/a00d68d015d2834e25df54d710ebfb3b#file-attacker-js
pragma solidity 0.8.4;
contract PaymentSharer {
mapping(uint => uint) splits;
mapping(uint => uint) deposits;
mapping(uint => address payable) first;
mapping(uint => address payable) second;
function init(uint id, address payable _first, address payable _second) public {
require(first[id] == address(0) && second[id] == address(0));
require(first[id] == address(0) && second[id] == address(0));
first[id] = _first;
second[id] = _second;
}
function deposit(uint id) public payable {
deposits[id] += msg.value;
}
function updateSplit(uint id, uint split) public {
require(split <= 100);
splits[id] = split;
}
function splitFunds(uint id) public {
// Here would be:
// Signatures that both parties agree with this split
// Split
address payable a = first[id];
address payable b = second[id];
uint depo = deposits[id];
deposits[id] = 0;
(bool aSent,) = a.call{value: depo * splits[id] / 100}("");
require(aSent, "Failed to send Ether to a");
(bool bSent,) = b.call{value: depo * (100 - splits[id]) / 100}("");
require(bSent, "Failed to send Ether to b");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment