// 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); } }