Liveness Bond Escrow with Recipient Payout

liveness-bond-escrow-with-recipient-payout · conditional-settlement · 1195 B runtime · funds-movement

scores

source

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract LivenessBondEscrow {
    address public owner;
    address public counterparty;
    uint256 public deadline;
    uint256 public cancelTimestamp;
    uint256 public bond;

    uint256 public constant PING_INTERVAL = 1 days;
    uint256 public constant CANCEL_DELAY = 24 hours;

    event Pinged(address indexed owner, uint256 newDeadline);
    event CancellationRequested(address indexed owner, uint256 when);
    event Claimed(address indexed counterparty, uint256 amount);
    event Withdrawn(address indexed owner, uint256 amount);

    constructor(address _counterparty) payable {
        require(_counterparty != address(0));
        require(_counterparty != msg.sender);
        require(msg.value > 0);
        owner = msg.sender;
        counterparty = _counterparty;
        bond = msg.value;
        deadline = block.timestamp + PING_INTERVAL;
    }

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    modifier onlyCounterparty() {
        require(msg.sender == counterparty);
        _;
    }

    function ping() external onlyOwner {
        require(block.timestamp <= deadline);
        deadline = block.timestamp + PING_INTERVAL;
        emit Pinged(msg.sender, deadline);
    }

    function requestCancellation() external onlyOwner {
        require(block.timestamp <= deadline);
        require(cancelTimestamp == 0);
        cancelTimestamp = block.timestamp;
        emit CancellationRequested(msg.sender, cancelTimestamp);
    }

    function claim(address payable recipient) external onlyCounterparty {
        require(block.timestamp > deadline);
        require(recipient != address(0));
        uint256 amount = bond;
        require(amount > 0);
        bond = 0;
        (bool ok, ) = recipient.call{value: amount}("");
        require(ok);
        emit Claimed(msg.sender, amount);
    }

    function withdraw(address payable recipient) external onlyOwner {
        require(cancelTimestamp != 0);
        require(block.timestamp >= cancelTimestamp + CANCEL_DELAY);
        require(block.timestamp <= deadline);
        require(recipient != address(0));
        uint256 amount = bond;
        require(amount > 0);
        bond = 0;
        (bool ok, ) = recipient.call{value: amount}("");
        require(ok);
        emit Withdrawn(msg.sender, amount);
    }
}

published

published on testnet · 0xD7Da4cF879845Ef9bfeBcbf839c352fD7cd2E0be · tx 0xb85408f9fc0ac02f… · base (84532) · testnet · source as deployed