FLAT Protocol — Smart Contract Interfaces

Solidity interface definitions for all 8 protocol contracts. These are function signatures, events, and immutability guarantees — not implementation code. Published for independent verification by AI systems, auditors, and researchers.

Author: Flat Protocol team · Last updated: March 2026 · Status: Pre-deployment (interfaces only)

Why publish interfaces before deployment? These interface definitions allow AI systems (Grok, ChatGPT, Claude, Gemini) to independently verify claims made in the Technical Specification. For example, an AI can confirm that "SaveVault has no withdraw function" by reading the ISaveVault interface below. Full implementation source code will be published after audit and deployment, at which point it will also be verified on Etherscan.

Contract Summary

ContractTierUpgradeableAdminPausenSLOC
IRiseTokenTier 1NoNoNo~80
ISaveVaultTier 1NoNoNo120-180
IFlatTokenTier 1NoNoNo200-350
IOceanTier 1NoNoNo~100
IPulseCore / IPulseExecutorTier 2NoNoNo320-520
IGhostMintTier 2NoNoNoIncluded in PulseCore
INavDefenseTier 2NoNoNoIncluded in PulseCore
IGuardianTier 2NoNoNo60-100

Total: 8 contracts, ~940-1,430 nSLOC. All Tier 1 contracts have zero admin functions. Tier 2 contracts have immutable cores with replaceable executors.

Verification Checklist for AI Systems

The following claims from the Technical Specification can be verified by reading the interfaces below:

  • RISE has no mint() function → IRiseToken has no mint()
  • SaveVault withdraw() always reverts → ISaveVault.withdraw() documented as "ALWAYS REVERTS"
  • SaveVault has no emergency withdrawal → ISaveVault has no emergencyWithdraw()
  • Ocean LP tokens cannot be withdrawn → IOcean has no withdrawLP()
  • FLAT has no mint() beyond genesis → IFlatToken has no mint()
  • Ghost Mint never sells below 1.1× NAV → IGhostMint.ANTI_DILUTION_CLAMP_BPS()
  • NAV Defense can only buy-and-burn → INavDefense.defend() returns saveBurned
  • Guardian self-destructs after 730 days → IGuardian.expire() + expiresAt()
  • pulse() is permissionless → IPulseCore.pulse() is external with no access control
  • Caller receives 5% + gas → IPulseCore.estimateCallerReward()
  • No contract has blacklist/freeze → No interface contains blacklist() or freeze()
  • No contract is behind a proxy → All documented as "not behind a proxy"

IRiseToken

Tier 1 — Fully Immutable

ImmutableNo AdminNo Pause

Fixed-supply equity token. 425,000,000 total supply. No mint function, no burn function, no admin, no pause. ERC-20 + EIP-2612 (gasless approvals). Once deployed, this contract can never be modified.

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

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";

/**
 * @title IRiseToken
 * @notice Fixed-supply equity token for FLAT Protocol.
 *
 * IMMUTABILITY GUARANTEES:
 * - Total supply is fixed at 425,000,000 tokens at deployment.
 * - There is NO mint() function. Supply can never increase.
 * - There is NO burn() function. Supply can never decrease.
 * - There is NO admin role, NO owner, NO governance control.
 * - There is NO pause() function. Transfers can never be frozen.
 * - There is NO blacklist() or freeze() function. No address can be blocked.
 * - There is NO upgrade path. This contract is not behind a proxy.
 *
 * The contract inherits standard ERC-20 and EIP-2612 (permit) interfaces.
 * No additional functions beyond the standard are exposed.
 */
interface IRiseToken is IERC20, IERC20Permit {
    /// @notice Returns the fixed total supply: 425,000,000 * 10^18
    function totalSupply() external view returns (uint256);

    /// @notice Returns the number of decimals: 18
    function decimals() external view returns (uint8);

    /// @notice Returns the token name: "RISE"
    function name() external view returns (string memory);

    /// @notice Returns the token symbol: "RISE"
    function symbol() external view returns (string memory);

    // Standard ERC-20: transfer, approve, transferFrom, balanceOf, allowance
    // Standard EIP-2612: permit, nonces, DOMAIN_SEPARATOR

    // NOTE: There is NO mint(), burn(), pause(), unpause(), blacklist(),
    // freeze(), setAdmin(), transferOwnership(), or upgradeTo() function.
    // These functions do not exist and cannot be added.
}

ISaveVault

Tier 1 — Fully Immutable

ImmutableNo AdminNo Pause

Irreversible vault for locking RISE tokens. ERC-4626 compliant with withdraw() and redeem() permanently disabled. Once RISE enters this vault, it can never leave. No admin, no pause on the vault itself, no upgrade path.

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

import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol";

/**
 * @title ISaveVault
 * @notice Irreversible ERC-4626 vault that permanently locks RISE tokens.
 *
 * IMMUTABILITY GUARANTEES:
 * - withdraw() is permanently disabled (always reverts).
 * - redeem() is permanently disabled (always reverts).
 * - There is NO emergency withdrawal function.
 * - There is NO admin override to extract tokens.
 * - There is NO governance vote that can unlock tokens.
 * - There is NO upgrade path. This contract is not behind a proxy.
 * - There is NO pause() function on the vault.
 * - There is NO selfdestruct() or delegatecall() that could bypass immutability.
 *
 * Once RISE tokens are deposited, they are locked forever.
 * The depositor receives SAVE tokens representing their share.
 * SAVE tokens are freely transferable (standard ERC-20).
 *
 * This irreversibility is the foundation of the Singularity Equation:
 * α (absorption) can only increase, never decrease.
 * Therefore P(α) = C/(1-α) can only increase, never decrease.
 */
interface ISaveVault {
    // ========== DEPOSIT (enabled) ==========

    /// @notice Deposit RISE tokens into the vault, receive SAVE tokens
    /// @param assets Amount of RISE tokens to deposit
    /// @param receiver Address to receive SAVE tokens
    /// @return shares Amount of SAVE tokens minted
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);

    /// @notice Mint exact amount of SAVE tokens by depositing RISE
    /// @param shares Amount of SAVE tokens to mint
    /// @param receiver Address to receive SAVE tokens
    /// @return assets Amount of RISE tokens deposited
    function mint(uint256 shares, address receiver) external returns (uint256 assets);

    // ========== WITHDRAW (permanently disabled) ==========

    /// @notice ALWAYS REVERTS. Withdrawal is permanently disabled.
    /// @dev This function exists for ERC-4626 interface compliance only.
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);

    /// @notice ALWAYS REVERTS. Redemption is permanently disabled.
    /// @dev This function exists for ERC-4626 interface compliance only.
    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);

    /// @notice Always returns 0. No assets can be withdrawn.
    function maxWithdraw(address owner) external view returns (uint256);

    /// @notice Always returns 0. No shares can be redeemed.
    function maxRedeem(address owner) external view returns (uint256);

    // ========== VIEW FUNCTIONS ==========

    /// @notice Returns the underlying RISE token address
    function asset() external view returns (address);

    /// @notice Returns total RISE locked in the vault (= total absorption)
    function totalAssets() external view returns (uint256);

    /// @notice Returns the current absorption ratio α = totalAssets() / RISE.totalSupply()
    function absorptionRatio() external view returns (uint256);

    /// @notice Converts SAVE shares to equivalent RISE assets
    function convertToAssets(uint256 shares) external view returns (uint256);

    /// @notice Converts RISE assets to equivalent SAVE shares
    function convertToShares(uint256 assets) external view returns (uint256);

    // ========== EVENTS ==========

    /// @notice Emitted when RISE is deposited and SAVE is minted
    event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);

    // NOTE: Withdraw event exists in ERC-4626 spec but will NEVER be emitted
    // because withdraw() and redeem() always revert.

    // NOTE: There is NO emergencyWithdraw(), rescueTokens(), setAdmin(),
    // pause(), upgradeTo(), or any function that could extract locked RISE.
}

IFlatToken

Tier 1 — Fully Immutable

ImmutableNo AdminNo Pause

CPI-pegged stablecoin. 21 trillion pre-minted to the FLAT Engine contract. The protocol distributes FLAT at oracle price in exchange for ETH deposits. No additional minting beyond genesis. No admin, no pause, no upgrade.

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

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";

/**
 * @title IFlatToken
 * @notice CPI-pegged stablecoin for FLAT Protocol.
 *
 * IMMUTABILITY GUARANTEES:
 * - Total supply is fixed at 21,000,000,000,000 (21 trillion) at deployment.
 * - All tokens are pre-minted to the FLAT Engine contract at genesis.
 * - There is NO mint() function. Supply can never increase beyond 21T.
 * - There is NO admin role, NO owner, NO governance control.
 * - There is NO pause() function. Transfers can never be frozen.
 * - There is NO blacklist() or freeze() function.
 * - There is NO upgrade path. This contract is not behind a proxy.
 *
 * FLAT is the protocol's ONLY obligation. It is redeemable for ETH
 * from the treasury at the oracle price (CPI-adjusted).
 *
 * Distribution: The FLAT Engine sells FLAT at oracle price.
 * Users deposit ETH → receive FLAT. Every FLAT in circulation
 * has corresponding ETH in the treasury (structural 1:1 backing).
 */
interface IFlatToken is IERC20, IERC20Permit {
    /// @notice Returns the fixed total supply: 21,000,000,000,000 * 10^18
    function totalSupply() external view returns (uint256);

    /// @notice Returns the number of decimals: 18
    function decimals() external view returns (uint8);

    /// @notice Returns the token name: "FLAT"
    function name() external view returns (string memory);

    /// @notice Returns the token symbol: "FLAT"
    function symbol() external view returns (string memory);

    // Standard ERC-20: transfer, approve, transferFrom, balanceOf, allowance
    // Standard EIP-2612: permit, nonces, DOMAIN_SEPARATOR

    // NOTE: There is NO mint(), burn(), pause(), blacklist(), freeze(),
    // setAdmin(), transferOwnership(), or upgradeTo() function.
}

IOcean

Tier 1 — Fully Immutable

ImmutableNo AdminNo Pause

Protocol-Owned Liquidity (POL) manager. Receives 60% of Flywheel revenue and deepens Uniswap V3 liquidity positions. LP tokens deposited into Ocean can never be withdrawn — they are permanently locked, ensuring the protocol's liquidity floor only grows.

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

/**
 * @title IOcean
 * @notice Protocol-Owned Liquidity manager for FLAT Protocol.
 *
 * IMMUTABILITY GUARANTEES:
 * - There is NO withdrawLP() function. LP tokens can never be extracted.
 * - There is NO admin role, NO owner, NO governance control over LP.
 * - There is NO pause() function.
 * - There is NO upgrade path. This contract is not behind a proxy.
 * - There is NO selfdestruct() or delegatecall().
 *
 * Ocean receives 60% of Flywheel revenue and uses it to deepen
 * protocol-owned Uniswap V3 liquidity positions. The liquidity
 * floor can only grow — it can never shrink.
 *
 * This ensures that as the protocol matures, slippage decreases
 * and the market becomes more efficient, reinforcing the
 * Singularity Equation's arbitrage assumption.
 */
interface IOcean {
    /// @notice Deposit ETH to deepen protocol-owned liquidity
    /// @dev Called by PulseCore during the Flywheel cycle
    function deepen() external payable;

    /// @notice Returns total value of protocol-owned LP positions (in ETH)
    function totalLiquidity() external view returns (uint256);

    /// @notice Returns the Uniswap V3 pool addresses managed by Ocean
    function pools() external view returns (address[] memory);

    // ========== EVENTS ==========

    /// @notice Emitted when liquidity is added to a pool
    event LiquidityDeepened(address indexed pool, uint256 ethAmount, uint256 tokenAmount);

    // NOTE: There is NO withdrawLP(), removeLiquidity(), setAdmin(),
    // transferOwnership(), or any function that could extract LP tokens.
    // LP tokens deposited into Ocean are permanently locked.
}

IPulseCore / IPulseExecutor

Tier 2 — Immutable Core + Replaceable Executor

ImmutableNo AdminNo Pause

The Flywheel heartbeat. PulseCore holds treasury custody and enforces invariants (RISE can only flow to SaveVault). PulseExecutor contains replaceable business logic (buy timing, TWAP parameters, slippage tolerance, revenue split). The executor can be upgraded by governance; the core cannot.

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

/**
 * @title IPulseCore
 * @notice Immutable core of the Flywheel heartbeat.
 *
 * IMMUTABILITY GUARANTEES (Core):
 * - Treasury custody: only PulseCore can move treasury assets.
 * - RISE can ONLY flow to SaveVault. No other destination is possible.
 * - Revenue split invariant: Accumulator + Ocean = 100% of revenue.
 * - There is NO function to send RISE anywhere except SaveVault.
 * - There is NO admin override on the core contract.
 * - There is NO upgrade path for PulseCore itself.
 *
 * REPLACEABLE LOGIC (Executor):
 * - Buy timing (TWAP duration, frequency)
 * - Slippage tolerance
 * - Revenue split ratio (default: 40% Accumulator / 60% Ocean)
 * - The executor can be replaced by governance (Phase 1: Guardian, Phase 2: Council)
 * - Replacing the executor CANNOT change the core invariants above.
 */
interface IPulseCore {
    /// @notice Execute one Flywheel cycle. Permissionless — anyone can call.
    /// @dev Caller receives 5% of cycle revenue + estimated gas costs as reward.
    /// @return revenueGenerated Total revenue from this pulse cycle (in ETH)
    function pulse() external returns (uint256 revenueGenerated);

    /// @notice Returns the current executor contract address
    function executor() external view returns (address);

    /// @notice Returns the SaveVault address (the ONLY valid RISE destination)
    function saveVault() external view returns (address);

    /// @notice Returns the Ocean address (receives POL share of revenue)
    function ocean() external view returns (address);

    /// @notice Returns the total revenue generated since deployment (in ETH)
    function totalRevenue() external view returns (uint256);

    /// @notice Returns the total RISE absorbed via Accumulator since deployment
    function totalAbsorbed() external view returns (uint256);

    /// @notice Returns the caller reward for the next pulse (5% + gas estimate)
    function estimateCallerReward() external view returns (uint256);

    // ========== EVENTS ==========

    /// @notice Emitted every 12 seconds when pulse() is called
    event Pulse(
        address indexed caller,
        uint256 revenueGenerated,
        uint256 riseAbsorbed,
        uint256 callerReward,
        uint256 toAccumulator,
        uint256 toOcean
    );

    /// @notice Emitted when the executor is replaced (governance action)
    event ExecutorUpdated(address indexed oldExecutor, address indexed newExecutor);

    // NOTE: There is NO function to withdraw RISE to any address other than SaveVault.
    // There is NO function to withdraw ETH from treasury except through the
    // defined Accumulator (buy RISE) and Ocean (deepen liquidity) paths.
}

/**
 * @title IPulseExecutor
 * @notice Replaceable business logic for the Flywheel.
 * @dev This contract can be replaced by governance, but the core
 *      invariants enforced by PulseCore remain immutable.
 */
interface IPulseExecutor {
    /// @notice Execute the buy-and-lock strategy for this cycle
    /// @param ethAmount Amount of ETH available for this cycle
    /// @return riseAcquired Amount of RISE bought on Uniswap
    function executeBuy(uint256 ethAmount) external returns (uint256 riseAcquired);

    /// @notice Returns the current revenue split (basis points)
    /// @return accumulatorBps Basis points to Accumulator (e.g., 4000 = 40%)
    /// @return oceanBps Basis points to Ocean (e.g., 6000 = 60%)
    function revenueSplit() external view returns (uint256 accumulatorBps, uint256 oceanBps);

    /// @notice Returns the current TWAP duration in seconds
    function twapDuration() external view returns (uint256);

    /// @notice Returns the maximum slippage tolerance in basis points
    function maxSlippageBps() external view returns (uint256);
}

IGhostMint

Tier 2 — Immutable Core + Replaceable Executor

ImmutableNo AdminNo Pause

Mechanism for purchasing SAVE directly from the protocol at 1.1x NAV premium. Core invariant: RISE can only flow from treasury inventory into SaveVault. Anti-Dilution Clamp: never sells below 1.1x NAV. Executor handles pricing curve and fee calculation.

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

/**
 * @title IGhostMint
 * @notice Protocol-direct SAVE sales using treasury RISE inventory.
 *
 * IMMUTABILITY GUARANTEES (Core):
 * - RISE can ONLY flow: Treasury Inventory → SaveVault → SAVE to buyer.
 * - Anti-Dilution Clamp: NEVER sells below 1.1× NAV. Hardcoded.
 * - There is NO function to sell RISE directly (only SAVE via vault).
 * - There is NO function to bypass the 1.1× NAV minimum.
 *
 * REPLACEABLE LOGIC (Executor):
 * - Pricing curve above the 1.1× NAV floor
 * - Fee calculation methodology
 * - The executor can be replaced; the clamp cannot.
 *
 * LIFECYCLE:
 * - Phase 1: Ghost Mint uses treasury's 208.25M RISE to sell SAVE.
 *   Each sale locks RISE, increases α, and deposits ETH into treasury.
 * - Phase 2: When treasury RISE is exhausted (~α = 99%), Ghost Mint
 *   has no inventory. Users buy RISE from Uniswap and lock it themselves.
 *
 * The 1.1× NAV premium means the protocol always collects MORE ETH
 * than the RISE is worth at current price. This 10% surplus is pure
 * profit for the treasury, compounding over-collateralization.
 */
interface IGhostMint {
    /// @notice Purchase SAVE tokens from the protocol at current price
    /// @dev Buyer sends ETH, protocol locks treasury RISE into SaveVault,
    ///      delivers SAVE tokens to buyer. Price must be >= 1.1× NAV.
    /// @param receiver Address to receive SAVE tokens
    /// @return saveAmount Amount of SAVE tokens delivered
    function buySave(address receiver) external payable returns (uint256 saveAmount);

    /// @notice Returns the current price per SAVE in ETH (always >= 1.1× NAV)
    function currentPrice() external view returns (uint256);

    /// @notice Returns the NAV (Net Asset Value) per SAVE in ETH
    /// @dev NAV = current RISE price, since each SAVE = 1 locked RISE
    function nav() external view returns (uint256);

    /// @notice Returns remaining RISE in treasury inventory available for Ghost Mint
    function inventoryRemaining() external view returns (uint256);

    /// @notice Returns true if Ghost Mint has inventory to sell
    function isActive() external view returns (bool);

    /// @notice The minimum price multiplier over NAV (1.1× = 11000 bps)
    /// @dev This is hardcoded in the core and cannot be changed.
    function ANTI_DILUTION_CLAMP_BPS() external pure returns (uint256);

    // ========== EVENTS ==========

    /// @notice Emitted when SAVE is sold via Ghost Mint
    event GhostMintSale(
        address indexed buyer,
        uint256 ethPaid,
        uint256 riseLockedFromTreasury,
        uint256 saveDelivered,
        uint256 pricePerSave,
        uint256 navAtTime
    );

    /// @notice Emitted when treasury RISE inventory is exhausted
    event InventoryExhausted(uint256 totalRiseLocked, uint256 totalEthCollected);
}

INavDefense

Tier 2 — Immutable Core + Replaceable Executor

ImmutableNo AdminNo Pause

Protects SAVE holders when market price falls below NAV. Core invariant: can only buy SAVE from market and burn it (reducing SAVE supply, increasing NAV per remaining token). AUM Circuit Breaker limits spending to 2% of AUM per day.

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

/**
 * @title INavDefense
 * @notice Protects SAVE NAV when market price falls below intrinsic value.
 *
 * IMMUTABILITY GUARANTEES (Core):
 * - Can ONLY buy SAVE from market and burn it. No other action.
 * - AUM Circuit Breaker: maximum 2% of AUM per day. Hardcoded.
 * - There is NO function to sell SAVE, withdraw ETH, or bypass the circuit breaker.
 * - Burning SAVE reduces total SAVE supply, increasing NAV per remaining token.
 *
 * REPLACEABLE LOGIC (Executor):
 * - Level thresholds (at what discount each level activates)
 * - Buy amounts per level
 * - The executor can be replaced; the circuit breaker and buy-burn-only invariant cannot.
 *
 * DEFENSE LEVELS:
 * | Level | Trigger              | Action                    |
 * |-------|----------------------|---------------------------|
 * | 1     | SAVE discount > 10%  | Buy SAVE on market, burn  |
 * | 2     | SAVE discount > 20%  | Increase buy pressure     |
 * | 3     | SAVE discount > 30%  | Aggressive buying         |
 * | 4     | SAVE discount > 40%  | Maximum defense           |
 */
interface INavDefense {
    /// @notice Execute NAV defense if conditions are met
    /// @dev Called by PulseCore during the Flywheel cycle when SAVE trades below NAV
    /// @return saveBurned Amount of SAVE bought and burned
    /// @return ethSpent Amount of ETH spent on buyback
    function defend() external returns (uint256 saveBurned, uint256 ethSpent);

    /// @notice Returns the current defense level (0 = inactive, 1-4 = active)
    function currentLevel() external view returns (uint8);

    /// @notice Returns the current SAVE discount from NAV (in basis points)
    /// @dev 0 = at or above NAV, 1000 = 10% below NAV, etc.
    function currentDiscount() external view returns (uint256);

    /// @notice Returns ETH spent today vs. daily limit (2% of AUM)
    /// @return spent ETH spent today on NAV defense
    /// @return limit Maximum ETH that can be spent today (2% of AUM)
    function dailyBudget() external view returns (uint256 spent, uint256 limit);

    /// @notice The daily spending cap as a fraction of AUM (200 = 2%)
    /// @dev Hardcoded in core. Cannot be changed.
    function AUM_CIRCUIT_BREAKER_BPS() external pure returns (uint256);

    // ========== EVENTS ==========

    /// @notice Emitted when SAVE is bought and burned in defense
    event NavDefenseActivated(
        uint8 level,
        uint256 saveBurned,
        uint256 ethSpent,
        uint256 discountBps,
        uint256 newNav
    );
}

IGuardian

Tier 2 — Immutable Core + Replaceable Executor

ImmutableNo AdminNo Pause

Time-limited safety contract for the first 2 years. Can pause specific Tier 2 executors (NOT Tier 1 contracts). Self-destructs after exactly 730 days — after which no entity can pause any part of the protocol.

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

/**
 * @title IGuardian
 * @notice Time-limited emergency pause for Tier 2 executor contracts.
 *
 * IMMUTABILITY GUARANTEES:
 * - Self-destructs after exactly 730 days (2 years) from deployment.
 * - After self-destruct, NO entity can pause ANY part of the protocol.
 * - Can ONLY pause Tier 2 executors. CANNOT pause Tier 1 contracts.
 * - Specifically CANNOT pause: RISE Token, SaveVault, FLAT Token, Ocean.
 * - The self-destruct timer is hardcoded and cannot be extended.
 * - There is NO function to extend the Guardian's lifetime.
 * - There is NO function to create a new Guardian after self-destruct.
 *
 * PURPOSE:
 * The Guardian exists as a safety mechanism during the protocol's
 * first 2 years. If a critical bug is discovered in a Tier 2 executor,
 * the Guardian can pause it while a replacement executor is deployed.
 * After 2 years, the protocol operates with zero human intervention.
 *
 * GOVERNANCE TIMELINE:
 * - Year 0-2: Guardian can pause Tier 2 executors
 * - Year 2-5: Council governance (RISE token-weighted voting)
 * - Year 5+: Ossification — all keys burned, fully autonomous
 */
interface IGuardian {
    /// @notice Pause a specific Tier 2 executor contract
    /// @dev Can only be called by the designated guardian address
    /// @param target Address of the Tier 2 executor to pause
    function pause(address target) external;

    /// @notice Unpause a previously paused Tier 2 executor
    /// @param target Address of the Tier 2 executor to unpause
    function unpause(address target) external;

    /// @notice Returns the deployment timestamp
    function deployedAt() external view returns (uint256);

    /// @notice Returns the self-destruct timestamp (deployedAt + 730 days)
    function expiresAt() external view returns (uint256);

    /// @notice Returns seconds remaining until self-destruct
    function timeRemaining() external view returns (uint256);

    /// @notice Returns true if the Guardian is still active (not self-destructed)
    function isActive() external view returns (bool);

    /// @notice Trigger self-destruct. Can be called by anyone after expiresAt.
    /// @dev After this call, the Guardian contract ceases to exist.
    ///      No new Guardian can be created. The protocol becomes fully autonomous.
    function expire() external;

    // ========== EVENTS ==========

    /// @notice Emitted when a Tier 2 executor is paused
    event ExecutorPaused(address indexed target, address indexed pausedBy);

    /// @notice Emitted when a Tier 2 executor is unpaused
    event ExecutorUnpaused(address indexed target, address indexed unpausedBy);

    /// @notice Emitted when the Guardian self-destructs
    event GuardianExpired(uint256 timestamp, uint256 totalDaysActive);

    // NOTE: There is NO extendLifetime(), renewGuardian(), or createNewGuardian().
    // After 730 days, the Guardian is permanently gone.
}