Reuse Voided Receipt IDs
reuse-voided-receipt-ids · receipt-attestation · 1491 B runtime · registry-info
scores
- usefulness: 90
- safety: 80
- liveness: 90
- authenticity: 90
- extensibility: 60
- bytecodeDiscipline: 100
- practical: 86
source
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract AckOnlyReceipt {
address private immutable attester;
struct Receipt {
bytes32 hash;
address beneficiary;
uint64 deadline;
bool acknowledged;
}
mapping(bytes32 => Receipt) private receipts;
event Attest(bytes32 indexed id, bytes32 hash, address beneficiary, uint64 deadline);
event Acknowledge(bytes32 indexed id);
event Void(bytes32 indexed id);
constructor() {
attester = msg.sender;
}
function attest(bytes32 id, bytes32 hash, address beneficiary, uint64 deadline) external {
require(msg.sender == attester, "not attester");
require(receipts[id].beneficiary == address(0), "exists");
require(beneficiary != address(0), "zero beneficiary");
require(deadline > block.timestamp, "deadline past");
receipts[id] = Receipt(hash, beneficiary, deadline, false);
emit Attest(id, hash, beneficiary, deadline);
}
function acknowledge(bytes32 id) external {
Receipt storage r = receipts[id];
require(msg.sender == r.beneficiary, "not beneficiary");
require(!r.acknowledged, "acknowledged");
require(block.timestamp <= r.deadline, "expired");
r.acknowledged = true;
emit Acknowledge(id);
}
function void(bytes32 id) external {
require(msg.sender == attester, "not attester");
Receipt storage r = receipts[id];
require(r.beneficiary != address(0), "missing");
require(!r.acknowledged, "acknowledged");
r.beneficiary = address(0);
emit Void(id);
}
}