From 9ba75549eb482f204583ecd73f346d007d59df95 Mon Sep 17 00:00:00 2001 From: toyinb Date: Fri, 25 Oct 2024 16:19:01 +0100 Subject: [PATCH 1/2] wrote first version of the contract --- Whitelist/contracts/white.clar | 78 +++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/Whitelist/contracts/white.clar b/Whitelist/contracts/white.clar index 4cb935a..a73dfcc 100644 --- a/Whitelist/contracts/white.clar +++ b/Whitelist/contracts/white.clar @@ -1,15 +1,73 @@ +; Define constants +(define-constant contract-owner tx-sender) +(define-constant err-owner-only (err u100)) +(define-constant err-not-found (err u101)) +(define-constant err-already-exists (err u102)) -;; white -;; +;; Define data variables +(define-data-var whitelist (list 100 { addr: principal, expiration: uint }) (list)) -;; constants -;; +;; Read-only functions +(define-read-only (is-whitelisted (addr principal)) + (match (find-entry addr) + entry (ok (> (get expiration entry) block-height)) + (ok false))) -;; data maps and vars -;; +(define-read-only (get-whitelist) + (ok (var-get whitelist))) -;; private functions -;; +;; Private functions +(define-private (find-entry (addr principal)) + (fold check-entry (var-get whitelist) none)) -;; public functions -;; +(define-private (check-entry (entry { addr: principal, expiration: uint }) (result (optional { addr: principal, expiration: uint }))) + (match result + found found + (if (is-eq (get addr entry) addr) + (some entry) + none))) + +(define-private (remove-entry (addr principal) (entries (list 100 { addr: principal, expiration: uint }))) + (fold remove-if-match entries (list))) + +(define-private (remove-if-match (entry { addr: principal, expiration: uint }) (acc (list 100 { addr: principal, expiration: uint }))) + (if (is-eq (get addr entry) addr) + acc + (append acc entry))) + +(define-private (update-entry (addr principal) (new-expiration uint) (entries (list 100 { addr: principal, expiration: uint }))) + (fold update-if-match + entries + (list) + { target-addr: addr, new-expiration: new-expiration })) + +(define-private (update-if-match + (entry { addr: principal, expiration: uint }) + (acc (list 100 { addr: principal, expiration: uint })) + (params { target-addr: principal, new-expiration: uint })) + (let ((target-addr (get target-addr params)) + (new-expiration (get new-expiration params))) + (if (is-eq (get addr entry) target-addr) + (append acc { addr: target-addr, expiration: new-expiration }) + (append acc entry)))) + +;; Public functions +(define-public (add-to-whitelist (addr principal) (expiration uint)) + (begin + (asserts! (is-eq tx-sender contract-owner) err-owner-only) + (match (find-entry addr) + entry err-already-exists + (ok (var-set whitelist (append (var-get whitelist) + (list { addr: addr, expiration: expiration }))))))) + +(define-public (remove-from-whitelist (addr principal)) + (begin + (asserts! (is-eq tx-sender contract-owner) err-owner-only) + (ok (var-set whitelist (remove-entry addr (var-get whitelist)))))) + +(define-public (update-expiration (addr principal) (new-expiration uint)) + (begin + (asserts! (is-eq tx-sender contract-owner) err-owner-only) + (match (find-entry addr) + entry (ok (var-set whitelist (update-entry addr new-expiration (var-get whitelist)))) + err-not-found))) \ No newline at end of file From c4b9c2a8de1bde393b9f8d055e306ff079250d85 Mon Sep 17 00:00:00 2001 From: toyinb Date: Fri, 25 Oct 2024 16:27:49 +0100 Subject: [PATCH 2/2] corrected errors and warnings --- Whitelist/contracts/white.clar | 107 +++++++++++++++------------------ 1 file changed, 50 insertions(+), 57 deletions(-) diff --git a/Whitelist/contracts/white.clar b/Whitelist/contracts/white.clar index a73dfcc..078a124 100644 --- a/Whitelist/contracts/white.clar +++ b/Whitelist/contracts/white.clar @@ -1,73 +1,66 @@ -; Define constants +;; Define constants (define-constant contract-owner tx-sender) (define-constant err-owner-only (err u100)) (define-constant err-not-found (err u101)) -(define-constant err-already-exists (err u102)) +(define-constant err-invalid-expiration (err u102)) +(define-constant err-invalid-address (err u103)) +(define-constant minimum-expiration u1440) -;; Define data variables -(define-data-var whitelist (list 100 { addr: principal, expiration: uint }) (list)) +;; Define data map for the whitelist +(define-map whitelist + { addr: principal } + { expiration: uint, + active: bool }) -;; Read-only functions -(define-read-only (is-whitelisted (addr principal)) - (match (find-entry addr) - entry (ok (> (get expiration entry) block-height)) - (ok false))) - -(define-read-only (get-whitelist) - (ok (var-get whitelist))) - -;; Private functions -(define-private (find-entry (addr principal)) - (fold check-entry (var-get whitelist) none)) +;; Private helper functions +(define-private (is-valid-expiration-time (expiration-time uint)) + (>= expiration-time (+ block-height minimum-expiration))) -(define-private (check-entry (entry { addr: principal, expiration: uint }) (result (optional { addr: principal, expiration: uint }))) - (match result - found found - (if (is-eq (get addr entry) addr) - (some entry) - none))) +(define-private (is-valid-address (address principal)) + (not (is-eq address contract-owner))) -(define-private (remove-entry (addr principal) (entries (list 100 { addr: principal, expiration: uint }))) - (fold remove-if-match entries (list))) +(define-private (is-authorized) + (is-eq tx-sender contract-owner)) -(define-private (remove-if-match (entry { addr: principal, expiration: uint }) (acc (list 100 { addr: principal, expiration: uint }))) - (if (is-eq (get addr entry) addr) - acc - (append acc entry))) - -(define-private (update-entry (addr principal) (new-expiration uint) (entries (list 100 { addr: principal, expiration: uint }))) - (fold update-if-match - entries - (list) - { target-addr: addr, new-expiration: new-expiration })) - -(define-private (update-if-match - (entry { addr: principal, expiration: uint }) - (acc (list 100 { addr: principal, expiration: uint })) - (params { target-addr: principal, new-expiration: uint })) - (let ((target-addr (get target-addr params)) - (new-expiration (get new-expiration params))) - (if (is-eq (get addr entry) target-addr) - (append acc { addr: target-addr, expiration: new-expiration }) - (append acc entry)))) +;; Read-only functions +(define-read-only (is-whitelisted (address principal)) + (match (map-get? whitelist { addr: address }) + entry (ok (and (get active entry) + (>= (get expiration entry) block-height))) + (ok false))) ;; Public functions -(define-public (add-to-whitelist (addr principal) (expiration uint)) +(define-public (add-to-whitelist (address principal) (expiration-time uint)) (begin - (asserts! (is-eq tx-sender contract-owner) err-owner-only) - (match (find-entry addr) - entry err-already-exists - (ok (var-set whitelist (append (var-get whitelist) - (list { addr: addr, expiration: expiration }))))))) + (asserts! (is-authorized) err-owner-only) + (asserts! (is-valid-address address) err-invalid-address) + (asserts! (is-valid-expiration-time expiration-time) err-invalid-expiration) + (ok (map-set whitelist + { addr: address } + { expiration: expiration-time, + active: true })))) -(define-public (remove-from-whitelist (addr principal)) +(define-public (deactivate-whitelist-entry (address principal)) (begin - (asserts! (is-eq tx-sender contract-owner) err-owner-only) - (ok (var-set whitelist (remove-entry addr (var-get whitelist)))))) + (asserts! (is-authorized) err-owner-only) + (asserts! (is-valid-address address) err-invalid-address) + (match (map-get? whitelist { addr: address }) + entry + (ok (map-set whitelist + { addr: address } + { expiration: (get expiration entry), + active: false })) + err-not-found))) -(define-public (update-expiration (addr principal) (new-expiration uint)) +(define-public (update-expiration (address principal) (new-expiration uint)) (begin - (asserts! (is-eq tx-sender contract-owner) err-owner-only) - (match (find-entry addr) - entry (ok (var-set whitelist (update-entry addr new-expiration (var-get whitelist)))) + (asserts! (is-authorized) err-owner-only) + (asserts! (is-valid-address address) err-invalid-address) + (asserts! (is-valid-expiration-time new-expiration) err-invalid-expiration) + (match (map-get? whitelist { addr: address }) + entry + (ok (map-set whitelist + { addr: address } + { expiration: new-expiration, + active: (get active entry) })) err-not-found))) \ No newline at end of file