# Simple Dead Man Switch Recovery Signer

**URL:** <https://forum.safefoundation.org/t/simple-dead-man-switch-recovery-signer/7094>\
**Category:** Modules\
**Created:** [September 2, 2026, 1:09pm UTC](https://forum.safefoundation.org/t/simple-dead-man-switch-recovery-signer/7094 "2026-09-02T13:09:58Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Philogy](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.safefoundation.org/philogy/32/1394_2.png) [@Philogy](https://forum.safefoundation.org/u/Philogy)\
**Post date:** [September 2, 2026, 1:09pm UTC](https://forum.safefoundation.org/t/simple-dead-man-switch-recovery-signer/7094/1 "2026-09-02T13:09:58Z")

</div>

Made a “dead simple” (pun intended) dead man switch signer that let’s you easily configure your safe to fallback from being N-of-M to {N-1}-of-M with a delay.

To use it you just deploy the contract giving it the address of your safe + the intended delay and then add the contract as a signer to your multisig. Practically it works by letting any member on the multisig double-sign with a delay. If your member signing threshold is more than 2 I could imagine deploying several of these for the same multisig so that the threshold can “decay” if needed e.g. a 4-of-7 that becomes a 3/7 after 15 days, 2/7 after 30 days and 1/7 after 60 days.

To prevent misuse you’ll need to actively monitor it so that you can remove the `DeadManSigner` as a signer from your multisig in time if it was triggered maliciously.

Using this for my personal setup and thought I’d share!

```solidity
// SPDX-License-Identifier: MIT
pragma solidity =0.8.36;

interface ISafe {
    function isOwner(address owner) external view returns (bool);

    function approveHash(bytes32 hashToApprove) external;
}

contract DeadManSigner {
    ISafe internal immutable safe;
    uint256 internal immutable delay;

    bytes32 public safeTxHash;
    uint256 public validAfter;

    error InvalidConfig();
    error AlreadyTriggered();
    error NotSafeOwner();
    error ManNotDead();

    constructor(ISafe safe_, uint256 delay_) {
        require(address(safe_) != address(0) && delay_ != 0, InvalidConfig());

        safe = safe_;
        delay = delay_;
    }

    function params() public view returns (ISafe, uint256) {
        return (safe, delay);
    }

    function queue(bytes32 hash) external {
        require(validAfter == 0 && safeTxHash == bytes32(0), AlreadyTriggered());
        require(safe.isOwner(msg.sender), NotSafeOwner());

        safeTxHash = hash;
        validAfter = block.timestamp + delay;
    }

    function pushSignature() external {
        require(validAfter != 0 && block.timestamp >= validAfter, ManNotDead());

        safe.approveHash(safeTxHash);
        safeTxHash = bytes32(0);
        validAfter = 0;
    }
}

```
