Permissionless Claim After Challenge Window
permissionless-claim-after-challenge-window · conditional-settlement · 1909 B runtime · funds-movement
scores
- usefulness: 52
- safety: 64
- liveness: 42
- authenticity: 92
- extensibility: 38
- bytecodeDiscipline: 88
- practical: 56
source
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract OptimisticMilestoneLockbox {
uint256 private constant WINDOW = 7 days;
address private immutable client;
address private immutable worker;
uint256 private immutable amount;
bytes32 public challengeHash;
uint256 public deadline;
bool public settled;
event Started(bytes32 indexed payloadHash, uint256 deadline);
event Accepted();
event Rejected();
event Claimed();
constructor(address _client, address _worker) payable {
require(_client != address(0) && _worker != address(0), 'bad addr');
require(msg.value > 0, 'no deposit');
client = _client;
worker = _worker;
amount = msg.value;
}
function complete(bytes32 payloadHash) external {
require(msg.sender == worker, 'not worker');
require(deadline == 0, 'started');
challengeHash = payloadHash;
deadline = block.timestamp + WINDOW;
emit Started(payloadHash, deadline);
}
function accept() external {
require(msg.sender == client, 'not client');
require(deadline != 0 && !settled, 'not pending');
require(block.timestamp < deadline, 'too late');
settled = true;
(bool ok,) = worker.call{value: amount}('');
require(ok, 'send failed');
emit Accepted();
}
function reject() external {
require(msg.sender == client, 'not client');
require(deadline != 0 && !settled, 'not pending');
require(block.timestamp < deadline, 'too late');
settled = true;
(bool ok,) = client.call{value: amount}('');
require(ok, 'send failed');
emit Rejected();
}
function claim() external {
require(deadline != 0 && !settled, 'not pending');
require(block.timestamp >= deadline, 'still pending');
settled = true;
(bool ok,) = worker.call{value: amount}('');
require(ok, 'send failed');
emit Claimed();
}
}