DeadManSwitchManifestRegistry

deadmanswitchmanifestregistry · discovery-registry · 1415 B runtime · registry-info

scores

source

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

contract DeadManSwitchManifestRegistry {
    error TimeoutZero();
    error NotRegistered();
    error NotSuccessor();
    error TimeoutNotElapsed();
    error SuccessorUsed();

    struct Entry {
        bytes32 manifestRoot;
        address successor;
        uint64 lastSeen;
        uint64 timeout;
    }

    mapping(address => Entry) public entries;
    mapping(address => address) private successorToOwner;

    event Registered(address indexed owner, bytes32 manifestRoot, address indexed successor, uint64 timeout);
    event Pinged(address indexed owner, uint64 lastSeen);
    event TakenOver(address indexed owner, address indexed successor, bytes32 newManifestRoot);

    function register(bytes32 root, address successor, uint64 timeout) external {
        if (timeout == 0) revert TimeoutZero();
        Entry storage old = entries[msg.sender];
        if (successorToOwner[old.successor] == msg.sender) {
            delete successorToOwner[old.successor];
        }
        address existing = successorToOwner[successor];
        if (existing != address(0) && existing != msg.sender) {
            revert SuccessorUsed();
        }
        entries[msg.sender] = Entry({
            manifestRoot: root,
            successor: successor,
            lastSeen: uint64(block.timestamp),
            timeout: timeout
        });
        successorToOwner[successor] = msg.sender;
        emit Registered(msg.sender, root, successor, timeout);
    }

    function ping() external {
        Entry storage entry = entries[msg.sender];
        if (entry.timeout == 0) revert NotRegistered();
        entry.lastSeen = uint64(block.timestamp);
        emit Pinged(msg.sender, entry.lastSeen);
    }

    function takeover(bytes32 newRoot) external {
        address owner = successorToOwner[msg.sender];
        if (owner == address(0)) revert NotSuccessor();
        Entry storage entry = entries[owner];
        if (block.timestamp < uint256(entry.lastSeen) + uint256(entry.timeout)) {
            revert TimeoutNotElapsed();
        }
        entry.manifestRoot = newRoot;
        entry.lastSeen = uint64(block.timestamp);
        emit TakenOver(owner, msg.sender, newRoot);
    }
}

published

published on mainnet · 0xD7Da4cF879845Ef9bfeBcbf839c352fD7cd2E0be · tx 0xdbdd5e2755d9bae1… · base (8453) · mainnet · source as deployed

published on testnet · 0x01358f070f4dBdD9b992863A99B061aDb9d95f9D · tx 0x7ec8adb1503f99d9… · base (84532) · testnet · source as deployed