Source Code

;; Timelock Contract - Time-locked withdrawals for enhanced security
(define-constant err-withdrawal-locked (err u700))
(define-constant err-invalid-timelock (err u701))

(define-data-var default-timelock uint u144) ;; ~24 hours in blocks

(define-map withdrawal-requests {user: principal, request-id: uint} {amount: uint, unlock-height: uint, executed: bool})
(define-map user-request-count principal uint)

(define-public (request-withdrawal (amount uint))
  (let (
    (request-count (default-to u0 (map-get? user-request-count tx-sender)))
    (request-id (+ request-count u1))
    (unlock-height (+ block-height (var-get default-timelock)))
  )
    (map-set withdrawal-requests {user: tx-sender, request-id: request-id} 
      {amount: amount, unlock-height: unlock-height, executed: false})
    (map-set user-request-count tx-sender request-id)
    (ok request-id)
  )
)

(define-public (execute-withdrawal (request-id uint))
  (let (
    (request (unwrap! (map-get? withdrawal-requests {user: tx-sender, request-id: request-id}) err-invalid-timelock))
  )
    (asserts! (>= block-height (get unlock-height request)) err-withdrawal-locked)
    (asserts! (not (get executed request)) err-invalid-timelock)
    
    (map-set withdrawal-requests {user: tx-sender, request-id: request-id} 
      (merge request {executed: true}))
    (ok (get amount request))
  )
)

(define-public (set-timelock (new-timelock uint))
  (begin
    (var-set default-timelock new-timelock)
    (ok true)
  )
)

(define-read-only (get-withdrawal-request (user principal) (request-id uint))
  (ok (map-get? withdrawal-requests {user: user, request-id: request-id})))

(define-read-only (get-timelock)
  (ok (var-get default-timelock)))

Functions (5)

FunctionAccessArgs
request-withdrawalpublicamount: uint
execute-withdrawalpublicrequest-id: uint
set-timelockpublicnew-timelock: uint
get-withdrawal-requestread-onlyuser: principal, request-id: uint
get-timelockread-only