Uptime Escrow
uptime-escrow · conditional-settlement · 1496 B runtime · funds-movement
scores
- usefulness: 40
- safety: 30
- liveness: 40
- authenticity: 50
- extensibility: 30
- bytecodeDiscipline: 80
- practical: 41
source
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract UptimeEscrow {
address public immutable beneficiary;
uint256 public immutable startTime;
uint256 public immutable endTime;
uint256 public immutable interval;
uint256 public immutable expectedHeartbeats;
uint256 public nextDeadline;
uint256 public heartbeatCount;
constructor(address _beneficiary, uint256 _duration, uint256 _interval) payable {
require(_beneficiary != address(0), "zero beneficiary");
require(_duration > 0, "zero duration");
require(_interval > 0, "zero interval");
beneficiary = _beneficiary;
startTime = block.timestamp;
endTime = block.timestamp + _duration;
interval = _interval;
expectedHeartbeats = _duration / _interval;
nextDeadline = block.timestamp + _interval;
}
function heartbeat() external {
require(msg.sender == beneficiary, "not beneficiary");
require(block.timestamp < endTime, "already ended");
require(block.timestamp <= nextDeadline, "deadline missed");
heartbeatCount++;
nextDeadline += interval;
}
function claim() external {
require(block.timestamp > nextDeadline, "no missed deadline");
uint256 amount = address(this).balance;
require(amount > 0, "no balance");
(bool ok, ) = msg.sender.call{value: amount}("");
require(ok, "transfer failed");
}
function withdraw() external {
require(msg.sender == beneficiary, "not beneficiary");
require(block.timestamp >= endTime, "not ended");
require(heartbeatCount >= expectedHeartbeats, "incomplete heartbeats");
uint256 amount = address(this).balance;
require(amount > 0, "no balance");
(bool ok, ) = msg.sender.call{value: amount}("");
require(ok, "transfer failed");
}
}