Creation-Code Escrow

creation-code-escrow · conditional-settlement · 2309 B runtime · funds-movement

scores

source

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

contract CreationCodeEscrow {
    struct Escrow {
        address payer;
        address beneficiary;
        uint256 amount;
        uint256 deadline;
        address expectedAddress;
        bytes32 expectedCodehash;
        bool settled;
    }

    mapping(bytes32 => Escrow) public escrows;

    event EscrowCreated(
        bytes32 indexed identifier,
        address indexed payer,
        address indexed beneficiary,
        uint256 amount,
        uint256 deadline,
        address expectedAddress,
        bytes32 expectedCodehash
    );
    event Claimed(bytes32 indexed identifier, address indexed beneficiary);
    event Refunded(bytes32 indexed identifier, address indexed payer);

    function createEscrow(
        bytes32 identifier,
        address beneficiary,
        uint256 deadline,
        address expectedAddress,
        bytes32 expectedCodehash
    ) external payable {
        require(escrows[identifier].deadline == 0, "exists");
        require(deadline > block.timestamp, "deadline");
        require(beneficiary != address(0), "beneficiary");
        require(expectedAddress != address(0), "addr");
        require(msg.value > 0, "amount");

        escrows[identifier] = Escrow({
            payer: msg.sender,
            beneficiary: beneficiary,
            amount: msg.value,
            deadline: deadline,
            expectedAddress: expectedAddress,
            expectedCodehash: expectedCodehash,
            settled: false
        });

        emit EscrowCreated(identifier, msg.sender, beneficiary, msg.value, deadline, expectedAddress, expectedCodehash);
    }

    function claim(bytes32 identifier) external {
        Escrow storage e = escrows[identifier];
        require(e.deadline != 0, "not found");
        require(!e.settled, "settled");
        require(block.timestamp < e.deadline, "expired");
        require(msg.sender == e.beneficiary, "not beneficiary");
        require(e.expectedAddress.codehash == e.expectedCodehash, "code mismatch");

        e.settled = true;
        (bool ok,) = payable(msg.sender).call{value: e.amount}("");
        require(ok, "transfer failed");
        emit Claimed(identifier, msg.sender);
    }

    function refund(bytes32 identifier) external {
        Escrow storage e = escrows[identifier];
        require(e.deadline != 0, "not found");
        require(!e.settled, "settled");
        require(block.timestamp >= e.deadline, "not expired");
        require(msg.sender == e.payer, "not payer");

        e.settled = true;
        (bool ok,) = payable(msg.sender).call{value: e.amount}("");
        require(ok, "transfer failed");
        emit Refunded(identifier, msg.sender);
    }
}

published

published on testnet · 0x0e25E6F8528DC7B8471Ac3940190Df4E46164394 · tx 0xe54d46bd7207d9ad… · base (84532) · testnet · source as deployed