Permissionless Claim After Challenge Window

permissionless-claim-after-challenge-window · conditional-settlement · 1909 B runtime · funds-movement

scores

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();
    }
}