Source Code

;; Emergency Controls Contract (Clarity 4)
;; Circuit breaker and pause mechanisms
;; Uses stacks-block-time for timelocks

;; constants
(define-constant CONTRACT_OWNER tx-sender)
(define-constant ERR_UNAUTHORIZED (err u9001))
(define-constant ERR_NOT_FOUND (err u9002))
(define-constant ERR_ALREADY_PAUSED (err u9003))
(define-constant ERR_NOT_PAUSED (err u9004))

(define-constant TIMELOCK_DURATION u86400)

;; data vars
(define-data-var global-pause bool false)
(define-data-var emergency-mode bool false)

;; data maps
(define-map admins principal bool)

(define-map contract-pauses
    principal
    {
        is-paused: bool,
        paused-at: (optional uint),
        paused-by: (optional principal)
    })

(define-map timelocked-operations
    uint
    {
        operation-type: (string-ascii 50),
        proposer: principal,
        execute-after: uint,
        executed: bool
    })

(define-data-var operation-counter uint u0)

;; public functions
(define-public (add-admin (new-admin principal))
    (begin
        (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_UNAUTHORIZED)
        (map-set admins new-admin true)
        (ok true)))

(define-public (toggle-global-pause)
    (begin
        (asserts! (or (is-eq tx-sender CONTRACT_OWNER) (default-to false (map-get? admins tx-sender))) ERR_UNAUTHORIZED)
        (var-set global-pause (not (var-get global-pause)))
        (ok (var-get global-pause))))

(define-public (pause-contract (contract principal))
    (begin
        (asserts! (default-to false (map-get? admins tx-sender)) ERR_UNAUTHORIZED)
        (map-set contract-pauses contract {
            is-paused: true,
            paused-at: (some stacks-block-time),
            paused-by: (some tx-sender)
        })
        (ok true)))

(define-public (unpause-contract (contract principal))
    (begin
        (asserts! (default-to false (map-get? admins tx-sender)) ERR_UNAUTHORIZED)
        (let ((pause-data (unwrap! (map-get? contract-pauses contract) ERR_NOT_FOUND)))
            (map-set contract-pauses contract (merge pause-data { is-paused: false })))
        (ok true)))

(define-public (propose-operation (operation-type (string-ascii 50)))
    (let ((operation-id (+ (var-get operation-counter) u1)))
        (asserts! (default-to false (map-get? admins tx-sender)) ERR_UNAUTHORIZED)
        (map-set timelocked-operations operation-id {
            operation-type: operation-type,
            proposer: tx-sender,
            execute-after: (+ stacks-block-time TIMELOCK_DURATION),
            executed: false
        })
        (var-set operation-counter operation-id)
        (ok operation-id)))

;; read only functions
(define-read-only (is-globally-paused)
    (ok (var-get global-pause)))

(define-read-only (is-contract-paused (contract principal))
    (match (map-get? contract-pauses contract)
        data (ok (get is-paused data))
        (ok false)))

(define-read-only (is-admin (user principal))
    (ok (or (is-eq user CONTRACT_OWNER) (default-to false (map-get? admins user)))))

Functions (8)

FunctionAccessArgs
add-adminpublicnew-admin: principal
toggle-global-pausepublic
pause-contractpubliccontract: principal
unpause-contractpubliccontract: principal
propose-operationpublicoperation-type: (string-ascii 50
is-globally-pausedread-only
is-contract-pausedread-onlycontract: principal
is-adminread-onlyuser: principal