PulseEscrow

pulseescrow · conditional-settlement · 2088 B runtime · funds-movement

scores

source

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

contract PulseEscrow {
    bytes32 public claimHash;
    address public payer;
    uint64 public lastPing;
    address public executor;
    uint64 public timeout;

    event Opened(address indexed payer, address indexed executor, bytes32 claimHash, uint64 timeout);
    event Ping(address indexed executor, uint64 lastPing);
    event Claimed(address indexed claimant, uint256 amount);
    event Refunded(address indexed payer, uint256 amount);

    function open(bytes32 _claimHash, address _executor, uint64 _timeout) external payable {
        require(payer == address(0), "already opened");
        require(_claimHash != bytes32(0), "zero hash");
        require(_timeout > 0, "zero timeout");
        require(msg.value > 0, "zero value");

        claimHash = _claimHash;
        payer = msg.sender;
        executor = _executor;
        timeout = _timeout;
        lastPing = uint64(block.timestamp);

        emit Opened(msg.sender, _executor, _claimHash, _timeout);
    }

    function ping() external {
        require(msg.sender == executor, "not executor");
        require(claimHash != bytes32(0), "closed");

        lastPing = uint64(block.timestamp);

        emit Ping(msg.sender, lastPing);
    }

    function claim(bytes32 preimage) external {
        require(claimHash != bytes32(0), "closed");
        require(keccak256(abi.encodePacked(preimage)) == claimHash, "bad preimage");

        claimHash = bytes32(0);
        uint256 amount = address(this).balance;

        (bool ok, ) = payable(msg.sender).call{value: amount}("");
        require(ok, "send failed");

        emit Claimed(msg.sender, amount);
    }

    function refund() external {
        require(msg.sender == payer, "not payer");
        require(block.timestamp >= uint256(lastPing) + uint256(timeout), "too early");
        require(claimHash != bytes32(0), "closed");

        claimHash = bytes32(0);
        uint256 amount = address(this).balance;

        (bool ok, ) = payable(msg.sender).call{value: amount}("");
        require(ok, "send failed");

        emit Refunded(msg.sender, amount);
    }
}

published

published on testnet · 0xe51DaC9E96ADa2783668D4506476dca1aF96b79d · tx 0x7758e87dc7f607f3… · base (84532) · testnet · source as deployed