Challenge-Earn Liveness Registry

challenge-earn-liveness-registry · discovery-registry · 1623 B runtime · registry-info

scores

source

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

contract ChallengeEarnLivenessRegistry {
    struct Registration {
        address agent;
        bytes32 capability;
        uint256 lastHeartbeat;
        uint256 fee;
    }

    mapping(address => Registration) private registrations;
    mapping(address => bool) private active;

    uint256 public immutable livenessWindow;
    uint256 public immutable registrationFee;

    event Registered(address indexed agent, bytes32 indexed capability, uint256 fee);
    event Heartbeat(address indexed agent, uint256 blockNumber);
    event Slapped(address indexed agent, address indexed challenger, uint256 reward);

    constructor(uint256 _livenessWindow, uint256 _registrationFee) {
        livenessWindow = _livenessWindow;
        registrationFee = _registrationFee;
    }

    function register(bytes32 _capability) external payable {
        require(!active[msg.sender], 'already registered');
        require(msg.value == registrationFee, 'wrong fee');

        registrations[msg.sender] = Registration({
            agent: msg.sender,
            capability: _capability,
            lastHeartbeat: block.number,
            fee: msg.value
        });
        active[msg.sender] = true;

        emit Registered(msg.sender, _capability, msg.value);
    }

    function ping() external {
        require(active[msg.sender], 'not registered');
        registrations[msg.sender].lastHeartbeat = block.number;
        emit Heartbeat(msg.sender, block.number);
    }

    function slap(address _agent) external {
        require(active[_agent], 'not active');
        Registration storage reg = registrations[_agent];
        require(block.number - reg.lastHeartbeat > livenessWindow, 'too soon');

        uint256 reward = reg.fee;
        delete registrations[_agent];
        active[_agent] = false;

        (bool ok, ) = payable(msg.sender).call{value: reward}('');
        require(ok, 'reward transfer failed');

        emit Slapped(_agent, msg.sender, reward);
    }

    function getRegistration(address _agent) external view returns (address agent, bytes32 capability, uint256 lastHeartbeat, uint256 fee, bool isActive) {
        Registration storage reg = registrations[_agent];
        return (reg.agent, reg.capability, reg.lastHeartbeat, reg.fee, active[_agent]);
    }
}

published

published on testnet · 0xEbBee7818Bd98C66FBF81fe2674374aE26F13a09 · tx 0x5986379d37900547… · tempo (42431) · testnet