Last active
April 2, 2018 06:27
-
-
Save dshulyak/cee4fd86471c7d6666112c06bfb577c4 to your computer and use it in GitHub Desktop.
protected payments for service model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity 0.4.21; | |
import './ecrecovery.sol'; | |
contract Payments { | |
event LogExit(address recepient, uint256 value, uint id); | |
struct Exit { | |
address recipient; | |
uint256 value; | |
uint256 timestamp; | |
} | |
mapping(address => uint256) public deposits; | |
mapping(address => mapping(uint => bool)) public nonces; | |
mapping(uint => Exit) public exits; | |
uint currentExit; | |
function Payments() public {} | |
function deposit() payable public { | |
// overflow check | |
require(deposits[msg.sender] + msg.value > deposits[msg.sender]); | |
deposits[msg.sender] += msg.value; | |
} | |
function withdraw(uint256 value) public{ | |
exits[currentExit] = Exit(msg.sender, value, block.timestamp); | |
emit LogExit(msg.sender, value, currentExit); | |
currentExit++; | |
} | |
// two days window required for a receiver to claim a payment | |
function finalizeWithdraw(uint id) public { | |
require(exits[id].value != 0); | |
uint256 twoDaysOld = block.timestamp - 2 days; | |
require(exits[id].timestamp < twoDaysOld); | |
require(deposits[exits[id].recipient] >= exits[id].value); | |
uint256 value = exits[id].value; | |
exits[id].value = 0; | |
exits[id].recipient.transfer(value); | |
} | |
function claimPayment(uint256 total, uint256 price, uint nonce, address receiver, bytes sig) public { | |
address payer = ECRecovery.recover( | |
keccak256( | |
"\x19Ethereum Signed Message:\n32", | |
keccak256(total, price, nonce, receiver)), | |
sig); | |
require(payer != address(0)); | |
// TODO price should be a floating number | |
uint256 value = total * price; | |
// verify that payment for a given nonce wasn't claimed before | |
require(!nonces[payer][nonce]); | |
// verify that address has a deposit higher than promised payment | |
// also protects against underflow | |
require(deposits[payer] >= value); | |
nonces[payer][nonce] = true; | |
deposits[payer] -= value; | |
receiver.transfer(value); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment