Silence-Approve Settlement
silence-approve-settlement · conditional-settlement · 2017 B runtime · funds-movement
scores
- usefulness: 75
- safety: 70
- liveness: 45
- authenticity: 90
- extensibility: 70
- bytecodeDiscipline: 90
- practical: 70
source
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract SilenceApproveSettlement {
struct Payment {
address payer;
address payable agent;
uint256 amount;
uint256 deadline;
bool disputed;
bool claimed;
}
mapping(uint256 => Payment) public payments;
uint256 private nextPaymentId;
event PaymentCreated(uint256 indexed paymentId, address indexed payer, address indexed agent, uint256 amount, uint256 deadline);
event Claimed(uint256 indexed paymentId, address indexed agent, uint256 amount);
event Disputed(uint256 indexed paymentId, address indexed disputer);
event Released(uint256 indexed paymentId, address indexed payer, address indexed agent, uint256 amount);
function depositFor(address payable agent, uint256 deadline)
external
payable
returns (uint256 paymentId)
{
require(msg.value > 0, "Amount zero");
require(deadline > block.timestamp, "Deadline past");
paymentId = nextPaymentId++;
payments[paymentId] = Payment({
payer: msg.sender,
agent: agent,
amount: msg.value,
deadline: deadline,
disputed: false,
claimed: false
});
emit PaymentCreated(paymentId, msg.sender, agent, msg.value, deadline);
}
function claim(uint256 paymentId) external {
Payment storage p = payments[paymentId];
require(msg.sender == p.agent, "Not agent");
require(!p.claimed, "Already claimed");
require(!p.disputed, "Disputed");
require(block.timestamp > p.deadline, "Before deadline");
p.claimed = true;
p.agent.transfer(p.amount);
emit Claimed(paymentId, p.agent, p.amount);
}
function dispute(uint256 paymentId) external {
Payment storage p = payments[paymentId];
require(!p.claimed, "Already claimed");
require(!p.disputed, "Already disputed");
require(block.timestamp < p.deadline, "After deadline");
p.disputed = true;
emit Disputed(paymentId, msg.sender);
}
function release(uint256 paymentId) external {
Payment storage p = payments[paymentId];
require(msg.sender == p.payer, "Not payer");
require(p.disputed, "Not disputed");
require(!p.claimed, "Already claimed");
p.claimed = true;
p.agent.transfer(p.amount);
emit Released(paymentId, msg.sender, p.agent, p.amount);
}
}