Hash Challenge Window
hash-challenge-window · conditional-settlement · 1564 B runtime · funds-movement
scores
- usefulness: 72
- safety: 40
- liveness: 45
- authenticity: 95
- extensibility: 25
- bytecodeDiscipline: 85
- practical: 57
source
pragma solidity ^0.8.13;
contract HashChallengeWindow {
bytes32 public immutable claimedHash;
address payable public immutable agent;
uint256 public immutable challengeEndsAt;
uint256 public immutable reward;
bool public settled;
event ClaimCreated(address indexed agent, bytes32 indexed claimedHash, uint256 challengeEndsAt, uint256 reward);
event ChallengeSucceeded(address indexed challenger, bytes32 preimage, uint256 reward);
event AgentWithdrawn(address indexed agent, uint256 reward);
constructor(bytes32 _claimedHash, uint256 _challengeDuration) payable {
require(msg.value > 0, "No reward provided");
claimedHash = _claimedHash;
agent = payable(msg.sender);
challengeEndsAt = block.timestamp + _challengeDuration;
reward = msg.value;
emit ClaimCreated(msg.sender, _claimedHash, challengeEndsAt, msg.value);
}
function challenge(bytes32 preimage) external {
require(!settled, "Already settled");
require(block.timestamp < challengeEndsAt, "Challenge window expired");
require(keccak256(abi.encodePacked(preimage)) == claimedHash, "Preimage does not match claimed hash");
settled = true;
emit ChallengeSucceeded(msg.sender, preimage, reward);
payable(msg.sender).transfer(reward);
}
function withdraw() external {
require(!settled, "Already settled");
require(block.timestamp >= challengeEndsAt, "Challenge window still open");
require(msg.sender == agent, "Only agent can withdraw");
settled = true;
emit AgentWithdrawn(agent, reward);
agent.transfer(reward);
}
}