Secret Reveal Escrow

secret-reveal-escrow · conditional-settlement · 1999 B runtime · funds-movement

scores

source

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

contract SecretRevealEscrow {
    bytes32 public secretHash;
    bytes32 public revealedSecret;
    uint256 public deadline;
    address payable public buyer;
    uint256 public amount;
    bool public resolved;
    bool public active;

    uint256 public constant DURATION = 7 days;

    event EscrowCreated(address indexed buyer, bytes32 hash, uint256 amount, uint256 deadline);
    event SecretRevealed(address indexed revealer, bytes32 preimage);
    event Refunded(address indexed buyer, uint256 amount);

    function createEscrow(bytes32 hash) external payable {
        require(!active, "Escrow already active");
        require(msg.value > 0, "Must send ETH");
        secretHash = hash;
        deadline = block.timestamp + DURATION;
        buyer = payable(msg.sender);
        amount = msg.value;
        resolved = false;
        active = true;
        emit EscrowCreated(msg.sender, hash, msg.value, deadline);
    }

    function reveal(bytes32 preimage) external {
        require(active, "No active escrow");
        require(!resolved, "Escrow already resolved");
        require(block.timestamp <= deadline, "Deadline passed");
        require(keccak256(abi.encodePacked(preimage)) == secretHash, "Incorrect preimage");

        resolved = true;
        active = false;
        revealedSecret = preimage;
        uint256 payout = amount;
        amount = 0;
        (bool ok, ) = payable(msg.sender).call{value: payout}("");
        require(ok, "Transfer failed");
        emit SecretRevealed(msg.sender, preimage);
    }

    function refund() external {
        require(active, "No active escrow");
        require(!resolved, "Escrow already resolved");
        require(block.timestamp > deadline, "Deadline not passed");
        require(msg.sender == buyer, "Only buyer can refund");

        resolved = true;
        active = false;
        uint256 refundAmount = amount;
        amount = 0;
        (bool ok, ) = buyer.call{value: refundAmount}("");
        require(ok, "Refund transfer failed");
        emit Refunded(buyer, refundAmount);
    }
}