Skip to content

Commit

Permalink
Tests for boxes, tighten asset quantity checks
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Feb 3, 2024
1 parent 78b1fdd commit 95c8ac5
Show file tree
Hide file tree
Showing 13 changed files with 246 additions and 178 deletions.
28 changes: 7 additions & 21 deletions convex-core/src/main/cvx/asset/box.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

;;;;;;;;;; Setup


(import asset.box.actor :as box.actor)
(import convex.asset :as asset-lib)

(import convex.asset :as asset-lib)


;;;;;;;;;; Public API
Expand All @@ -40,29 +40,15 @@
(call actor
(create))))



(defn insert
^{:doc {:description "Inserts an asset into a box."
:signature [{:params [box-id asset]}
{:params [actor box-id asset]}]}}
([box-id asset]
(insert box.actor
box-id
asset))
([actor box-id asset]
(asset-lib/transfer actor
asset
box-id)))
:signature [{:params [box asset]}]}}
([box asset]
(asset-lib/transfer box asset)))

(defn remove
^{:doc {:description "Removes an asset from the given box."
:signature [{:params [box-id]}
{:params [actor box-id asset]}]}}
([box-id asset]
(remove box.actor
box-id
asset))
([actor box-id asset]
(call actor
(remove box-id asset))))
([box asset]
(call box (remove asset))))
113 changes: 49 additions & 64 deletions convex-core/src/main/cvx/asset/box/actor.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
^{:doc {:description "Map of `box id` -> `asset quantity`."}}
{})


(def counter
^{:doc {:description "Used for creating box ids."}}
^{:doc {:description "Count of boxes created, used for creating box ids."}}
0)

(def offers
Expand All @@ -30,103 +29,102 @@

;;;;;;;;;; Private helpers

(defn -qc
^{:doc {:description "Checks a box quantity."}
:private? true}
[q]
(cond (set? q) q ;; base case, quantity of boxes should always be a Set
(int? q) #{q}
(nil? q) #{}
(fail :ARGUMENT "Invalid box quantity")))

(defn -direct-transfer
^{:private? true}
;; Internal implementation for executing a direct transfer.
;; Internal implementation for executing a direct transfer of box(es).
[sender receiver quantity]
(let [receiver (address receiver)
(let [q (-qc quantity)
receiver (address receiver)
sender-balance (get ownership
sender
#{})
_ (assert (subset? quantity
sender-balance)) ;; TODO. Replace with `fail` for better error messages?
_ (or (subset? q sender-balance)
(fail :FUNDS "Cannot transfer box(es) not owned by sender."))
receiver-balance (get ownership
receiver
#{})
new-sender-balance (difference sender-balance
quantity)
q)
new-receiver-balance (union receiver-balance
quantity)]
q)]
(set! ownership
(assoc ownership
sender new-sender-balance
receiver new-receiver-balance))
quantity))
q))

;;;;;;;;;; Implementation of `convex.asset` interface

(defn accept
^{:callable? true
:private? true}
[sender quantity]
(let [sender (address sender)
sender-offers (get offers
sender
{})
offer (or (get-in offers
[sender *caller*])
#{})
_ (assert (subset? quantity
offer))
(let [q (-qc quantity)
sender (address sender)
sender-offers (get offers sender {})
offer (get-in offers [sender *caller*] #{})
_ (or (subset? q offer) (fail :STATE "Insufficent offer of box(es)"))
receiver-balance (get ownership
*caller*
#{})
new-offer (difference offer
quantity)]
new-offer (difference offer q)]
(set! offers
(assoc offers sender
(assoc sender-offers
*caller*
new-offer)))
(-direct-transfer sender
*caller*
quantity)))
(-direct-transfer sender *caller* q)))


(defn balance
^{:callable? true
:private? true}
[owner]
(or (get ownership
owner)
(or (get ownership owner)
#{}))

(defn direct-transfer
^{:callable? true
:private? true}
[receiver quantity]
(-direct-transfer *caller*
receiver
quantity))
(-direct-transfer *caller* receiver quantity))

(defn offer
^{:callable? true
:private? true}
[receiver quantity]
(let [caller-offers (get offers
(let [q (-qc quantity)
caller-offers (get offers
*caller*
{})]
(set! offers
(assoc offers
*caller*
(assoc caller-offers
receiver
quantity)))))
q)))))

(defn receive-asset
^{:callable? true
:private? true}
[asset box-id]
(let [box-id (long box-id)]
;; Accepting first solves the problem of putting a box into itself.
;;
(asset-lib/accept *caller*
asset)
[path quantity _]
(let [box-id (int *scope*)]
;; NOTE: Accepting first solves the problem of putting a box into itself.
(asset-lib/accept *caller* path quantity)

(cond
(not (contains-key? boxes
box-id))
(fail :STATE
"Target box does not exist")
(fail :STATE "Target box does not exist")

(not (contains-key? (get ownership
*caller*)
Expand All @@ -136,9 +134,8 @@
(set! boxes
(assoc boxes
box-id
(asset-lib/quantity-add (get boxes
box-id)
asset)))))
(asset-lib/quantity-add (get boxes box-id)
[path quantity])))))

(def quantity-add
^{:callable? true
Expand Down Expand Up @@ -186,17 +183,12 @@


(defn create

^{:callable? true
:private? true}

[]

(let [id counter
owner *caller*
owned-boxes (or (get ownership
owner)
#{})]
owned-boxes (or (get ownership owner) #{})]
(set! ownership
(assoc ownership
owner
Expand All @@ -206,34 +198,27 @@
(assoc boxes
id
{})) ;; New box contains no assets
(set! counter
(inc counter))
id))

(set! counter (inc counter))
[~*address* id]))


(defn remove

^{:callable? true
:private? true}

[box-id asset]

(let [current-asset (get boxes
box-id)]
(when-not (asset-lib/quantity-contains? current-asset
asset)
[asset]
(let [id *scope*
current-asset (get boxes id)]
(when-not (asset-lib/quantity-contains? current-asset asset)
(fail "Box does not contain quantity of asset specified for removal"))
(when-not (contains-key? (ownership *caller*)
box-id)
id)
(fail :TRUST
(str "Box not owned: " box-id)))
(str "Box not owned: " id)))
(set! boxes
(assoc boxes
box-id
id
(asset-lib/quantity-sub current-asset
asset)))
;; Delivers the asset to the caller.
;;
(asset-lib/transfer *caller*
asset)))
(asset-lib/transfer *caller* asset)))
14 changes: 11 additions & 3 deletions convex-core/src/main/cvx/asset/multi-token.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@

;;;;;;;;; Private functions

(defn -qc
^{:doc {:description "Checks a token quantity."}
:private? true}
[q]
(cond (int? q) q ;; base case, quantity should always be an integer
(nil? q) 0
(fail :ARGUMENT "Invalid token quantity")))

(defn -set-balance
[addr id bal]
(let [h (get-holding addr)
Expand Down Expand Up @@ -98,7 +106,7 @@
^{:callable? true}
[sender quantity]
(let [id *scope*
quantity (int quantity)
quantity (-qc quantity)
_ (cond
(zero? quantity) (return 0)
(< quantity 0) (fail :ARGUMENT "Negative accept amount"))
Expand Down Expand Up @@ -134,7 +142,7 @@
^{:callable? true}
[receiver quantity]
(let [id *scope*
quantity (cond (nil? quantity) 0 (int quantity))
quantity (-qc quantity)
receiver (address receiver)
hs (get-holding *caller*)
rec (get hs id)]
Expand All @@ -159,7 +167,7 @@
(when-not (trust/trusted? controller *caller* :mint)
(fail :TRUST "No rights to mint"))

(let [amount (int amount) ;; Mint amount.
(let [amount (-qc amount) ;; Mint amount.
new-supply (+ supply amount)
bal (-get-balance *caller* id)
new-bal (+ bal amount)]
Expand Down
Loading

0 comments on commit 95c8ac5

Please sign in to comment.