StarGuard

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "src/StarGuard.sol": {
      "content": "// SPDX-FileCopyrightText: © 2025 Dai Foundation <www.daifoundation.org>
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

pragma solidity ^0.8.24;

interface SubProxyLike {
    /**
     * @notice Executes a calldata-encoded call `args` in the context of `target`
     * @param target The target contract
     * @param args The calldata-encoded call
     * @return out The result of the execution
     */
    function exec(address target, bytes calldata args) external payable returns (bytes memory out);
    /**
     * @notice Check owner access
     * @param usr The address to check
     * @return allowed The result of the check
     */
    function wards(address usr) external view returns (uint256 allowed);
}

interface StarSpellLike {
    /**
     * @notice Executes actions performed on behalf of the `SubProxy` – i.e. the actual payload
     * @dev Required, will be called by the StarGuard during permissionless execution
     */
    function execute() external;
    /**
     * @notice Checks if the star payload is executable in the current block
     * @dev Required, useful for implementing "earliest launch date" or "office hours" strategy
     * @return result The result of the check (true = executable, false = not)
     */
    function isExecutable() external view returns (bool result);
}

contract StarGuard {
    // --- structs ---

    /**
     * @notice Star payload data
     * @param addr The payload address
     * @param tag The keccak hash of the bytecode
     * @param deadline The timestamp after which the spell is no longer executable
     */
    struct SpellData {
        address addr;
        bytes32 tag;
        uint256 deadline;
    }

    // --- storage variables ---

    /// @notice Addresses with owner access on this contract
    mapping(address usr => uint256 allowed) public wards;

    /// @notice Maximum delay in seconds between whitelisting and execution
    uint256 public maxDelay;

    /// @notice "Whitelisted" star payload data
    SpellData public spellData;

    // --- immutables ---

    /// @notice Star admin contract (instance of `SubProxy`)
    SubProxyLike public immutable subProxy;

    // --- events ---

    /**
     * @notice `usr` was granted owner access
     * @param usr The user address
     */
    event Rely(address indexed usr);

    /**
     * @notice `usr` owner access was revoked
     * @param usr The user address
     */
    event Deny(address indexed usr);

    /**
     * @notice A contract parameter was updated
     * @param what The changed parameter name
     * @param data The new value of the parameter
     */
    event File(bytes32 indexed what, uint256 data);

    /**
     * @notice A payload has been whitelisted
     * @param addr The payload address
     * @param tag The payload codehash
     * @param deadline The timestamp after which the spell is no longer executable
     */
    event Plot(address indexed addr, bytes32 tag, uint256 deadline);

    /**
     * @notice A previously "whitelisted" payload has been dropped
     * @param addr The payload address
     */
    event Drop(address indexed addr);

    /**
     * @notice A previously whitelisted payload has been executed
     * @param addr The payload address
     */
    event Exec(address indexed addr);

    // --- modifiers ---

    /**
     * @notice Check if sender is authorized
     */
    modifier auth() {
        require(wards[msg.sender] == 1, "StarGuard/not-authorized");
        _;
    }

    // --- constructor ---

    constructor(address subProxy_) {
        subProxy = SubProxyLike(subProxy_);

        wards[msg.sender] = 1;
        emit Rely(msg.sender);
    }

    // --- administration ---

    /**
     * @notice Grants `usr` admin access to this contract
     * @param usr The user address
     */
    function rely(address usr) external auth {
        wards[usr] = 1;
        emit Rely(usr);
    }

    /**
     * @notice Revokes `usr` admin access from this contract
     * @param usr The user address
     */
    function deny(address usr) external auth {
        wards[usr] = 0;
        emit Deny(usr);
    }

    /**
     * @notice Updates mutable variables
     * @param what Name of the mutable variable
     * @param data New value of the variable
     */
    function file(bytes32 what, uint256 data) external auth {
        if (what == "maxDelay") {
            maxDelay = data;
        } else {
            revert("StarGuard/file-unrecognized-param");
        }
        emit File(what, data);
    }

    // --- operations ---

    /**
     * @notice "Whitelists" the payload for the future execution
     * @param addr_ The Star payload to be whitelisted
     * @param tag_ The keccak hash of the bytecode
     */
    function plot(address addr_, bytes32 tag_) external auth {
        require(addr_ != address(0), "StarGuard/zero-spell-address");
        if (spellData.addr != address(0)) emit Drop(spellData.addr);
        spellData.addr = addr_;
        spellData.tag = tag_;
        spellData.deadline = block.timestamp + maxDelay;
        emit Plot(addr_, tag_, spellData.deadline);
    }

    /**
     * @notice Removes the payload from the "whitelist"
     */
    function drop() external auth {
        if (spellData.addr == address(0)) return;
        emit Drop(spellData.addr);
        delete spellData;
    }

    /**
     * @notice Checks if the plotted payload is executable in the current block
     * @return result The result of the check (true = executable, false = reverts)
     */
    function prob() external view returns (bool) {
        return (
            spellData.addr != address(0) && spellData.tag == spellData.addr.codehash
                && block.timestamp <= spellData.deadline && StarSpellLike(spellData.addr).isExecutable()
        );
    }

    /**
     * @notice Executes previously scheduled payload
     * @return addr Executed payload address
     */
    function exec() external returns (address addr) {
        SpellData memory spellDataCopy = spellData;
        require(spellDataCopy.addr != address(0), "StarGuard/unplotted-spell");
        require(spellDataCopy.tag == spellDataCopy.addr.codehash, "StarGuard/wrong-codehash");
        require(block.timestamp <= spellDataCopy.deadline, "StarGuard/expired-spell");
        require(StarSpellLike(spellDataCopy.addr).isExecutable(), "StarGuard/not-yet-executable");

        delete spellData;
        subProxy.exec(spellDataCopy.addr, abi.encodePacked(StarSpellLike.execute.selector));

        require(subProxy.wards(address(this)) == 1, "StarGuard/subProxy-owner-change");
        emit Exec(spellDataCopy.addr);
        return spellDataCopy.addr;
    }
}
"
    }
  },
  "settings": {
    "remappings": [
      "ds-test/=lib/endgame-toolkit/lib/forge-std/lib/ds-test/src/",
      "dss-interfaces/=lib/dss-test/lib/dss-interfaces/src/",
      "dss-test/=lib/dss-test/src/",
      "dss-vest/=lib/endgame-toolkit/lib-0_6_x/dss-vest/src/",
      "endgame-toolkit/=lib/endgame-toolkit/",
      "forge-std/=lib/forge-std/src/",
      "openzeppelin-contracts/=lib/endgame-toolkit/lib/openzeppelin-contracts/",
      "token-tests/=lib/endgame-toolkit/lib/token-tests/src/"
    ],
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "metadata": {
      "useLiteralContent": false,
      "bytecodeHash": "ipfs",
      "appendCBOR": true
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "evmVersion": "cancun",
    "viaIR": false
  }
}}

Tags:
Factory|addr:0x6605aa120fe8b656482903e7757babf56947e45e|verified:true|block:23645986|tx:0x99bd68c4586b6e761e5b9fe171f16a8dfdcbcb0b9a98617d3d09dd6ba0905c5b|first_check:1761324345

Submitted on: 2025-10-24 18:45:45

Comments

Log in to comment.

No comments yet.