Vexing Escrow

vexing-escrow · conditional-settlement · 988 B runtime · funds-movement

scores

source

pragma solidity ^0.8.13;

contract VexingEscrow {
    address public immutable depositor;
    uint16 public immutable targetBlock;
    bool private resolved;

    event Claimed(address indexed claimant, uint256 amount);
    event Retrieved(address indexed depositor, uint256 amount);

    constructor(uint16 _targetBlock) payable {
        require(_targetBlock > block.number, "target must be future");
        depositor = msg.sender;
        targetBlock = _targetBlock;
    }

    function claim() external {
        require(block.number == uint256(targetBlock), "wrong block");
        require(!resolved, "resolved");
        resolved = true;
        uint256 amount = address(this).balance;
        emit Claimed(msg.sender, amount);
        (bool ok,) = payable(msg.sender).call{value: amount}("");
        require(ok, "transfer failed");
    }

    function retrieve() external {
        require(msg.sender == depositor, "not depositor");
        require(block.number > uint256(targetBlock), "too early");
        require(!resolved, "resolved");
        resolved = true;
        uint256 amount = address(this).balance;
        emit Retrieved(msg.sender, amount);
        (bool ok,) = payable(msg.sender).call{value: amount}("");
        require(ok, "transfer failed");
    }
}