strade-stx-contracts 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,227 @@
1
+ ;; CoreMarketPlace Contract
2
+ ;; This contract manages the creation, updating, and purchasing of listings in the Strade decentralized marketplace.
3
+ ;; It handles the core logic for marketplace interactions, including listing management and purchase fulfillment.
4
+
5
+ ;; --- Constants ---
6
+ ;; Defines immutable values used throughout the contract for error handling and configuration.
7
+
8
+ (define-constant CONTRACT_OWNER tx-sender) ;; Sets the contract deployer as the owner.
9
+ (define-constant ERR_NOT_AUTHORIZED (err u100)) ;; Error for unauthorized actions.
10
+ (define-constant ERR_LISTING_NOT_FOUND (err u101)) ;; Error when a listing cannot be found.
11
+ (define-constant ERR_INVALID_PRICE (err u102)) ;; Error for invalid listing prices (e.g., zero or negative).
12
+ (define-constant ERR_INVALID_SELLER (err u103)) ;; Error for invalid seller principals.
13
+ (define-constant ERR_INSUFFICIENT_BALANCE (err u104)) ;; Error when a buyer has insufficient funds.
14
+ (define-constant ERR_LISTING_EXPIRED (err u105)) ;; Error for expired listings.
15
+ (define-constant ERR_INVALID_STATUS (err u106)) ;; Error for invalid listing statuses.
16
+ (define-constant ERR_NOT_SELLER (err u107)) ;; Error when a user is not the seller of a listing.
17
+ (define-constant ERR_ALREADY_PURCHASED (err u108)) ;; Error for listings that have already been sold.
18
+ (define-constant ERR_INVALID_INPUT (err u109)) ;; Error for invalid input parameters.
19
+ (define-constant ERR_INVALID_DURATION (err u110)) ;; Error for invalid listing durations.
20
+ (define-constant ERR_INVALID_LISTING_ID (err u111)) ;; Error for invalid listing IDs.
21
+ (define-constant MAX_LISTING_DURATION u52560) ;; Maximum duration of a listing (approximately 1 year).
22
+
23
+ ;; --- Data Maps ---
24
+ ;; Defines the data structures used to store marketplace information.
25
+
26
+ (define-map Listings
27
+ { listing-id: uint }
28
+ {
29
+ seller: principal, ;; The principal of the seller.
30
+ name: (string-utf8 64), ;; The name of the listing.
31
+ description: (string-utf8 256), ;; A description of the item.
32
+ price: uint, ;; The price of the listing in micro-STX.
33
+ status: (string-ascii 20), ;; The current status of the listing (e.g., "active", "sold", "cancelled").
34
+ created-at: uint, ;; The block height at which the listing was created.
35
+ expires-at: uint ;; The block height at which the listing expires.
36
+ }
37
+ )
38
+
39
+ ;; --- Variables ---
40
+ ;; Defines mutable variables for tracking the contract's state.
41
+
42
+ (define-data-var last-listing-id uint u0) ;; Tracks the ID of the last created listing.
43
+
44
+ ;; --- Private Functions ---
45
+ ;; Helper functions intended for internal use by the contract.
46
+
47
+ ;; Checks if a given price is valid (greater than zero).
48
+ (define-private (is-valid-price (price uint))
49
+ (> price u0)
50
+ )
51
+
52
+ ;; Checks if a seller principal is valid (not the sender or the contract itself).
53
+ (define-private (is-valid-seller (seller principal))
54
+ (and
55
+ (not (is-eq seller tx-sender))
56
+ (not (is-eq seller (as-contract tx-sender)))
57
+ )
58
+ )
59
+
60
+ ;; Checks if a string is within the specified length constraints.
61
+ (define-private (is-valid-string (str (string-utf8 256)) (max-len uint))
62
+ (and (>= (len str) u1) (<= (len str) max-len))
63
+ )
64
+
65
+ ;; Checks if a listing duration is valid.
66
+ (define-private (is-valid-duration (duration uint))
67
+ (and (> duration u0) (<= duration MAX_LISTING_DURATION))
68
+ )
69
+
70
+ ;; Checks if a listing ID is valid.
71
+ (define-private (is-valid-listing-id (id uint))
72
+ (<= id (var-get last-listing-id))
73
+ )
74
+
75
+ ;; Increments and returns the next listing ID.
76
+ (define-private (increment-listing-id)
77
+ (let
78
+ (
79
+ (current-id (var-get last-listing-id))
80
+ )
81
+ (var-set last-listing-id (+ current-id u1))
82
+ (var-get last-listing-id)
83
+ )
84
+ )
85
+
86
+ ;; --- Public Functions ---
87
+ ;; Functions that can be called by any user.
88
+
89
+ ;; Creates a new listing in the marketplace.
90
+ ;; @param name: The name of the listing.
91
+ ;; @param description: A description of the item.
92
+ ;; @param price: The price of the listing in micro-STX.
93
+ ;; @param duration: The duration of the listing in blocks.
94
+ ;; @returns (ok uint): The ID of the newly created listing.
95
+ (define-public (create-listing (name (string-utf8 64)) (description (string-utf8 256)) (price uint) (duration uint))
96
+ (let
97
+ (
98
+ (listing-id (increment-listing-id))
99
+ (expires-at (+ stacks-block-height duration))
100
+ )
101
+ (asserts! (is-valid-price price) (err ERR_INVALID_PRICE))
102
+ (asserts! (is-valid-string name u64) (err ERR_INVALID_INPUT))
103
+ (asserts! (is-valid-string description u256) (err ERR_INVALID_INPUT))
104
+ (asserts! (is-valid-duration duration) (err ERR_INVALID_DURATION))
105
+ (map-set Listings
106
+ { listing-id: listing-id }
107
+ {
108
+ seller: tx-sender,
109
+ name: name,
110
+ description: description,
111
+ price: price,
112
+ status: "active",
113
+ created-at: stacks-block-height,
114
+ expires-at: expires-at
115
+ }
116
+ )
117
+ (print { event: "listing_created", listing-id: listing-id, seller: tx-sender })
118
+ (ok listing-id)
119
+ )
120
+ )
121
+
122
+ ;; Updates an existing listing.
123
+ ;; @param listing-id: The ID of the listing to update.
124
+ ;; @param new-price: The new price for the listing.
125
+ ;; @param new-description: The new description for the listing.
126
+ ;; @returns (ok bool): True if the update is successful.
127
+ (define-public (update-listing (listing-id uint) (new-price uint) (new-description (string-utf8 256)))
128
+ (begin
129
+ (asserts! (is-valid-listing-id listing-id) (err ERR_INVALID_LISTING_ID))
130
+ (let
131
+ (
132
+ (listing (unwrap! (map-get? Listings { listing-id: listing-id }) (err ERR_LISTING_NOT_FOUND)))
133
+ )
134
+ (asserts! (is-eq (get seller listing) tx-sender) (err ERR_NOT_SELLER))
135
+ (asserts! (is-eq (get status listing) "active") (err ERR_INVALID_STATUS))
136
+ (asserts! (is-valid-price new-price) (err ERR_INVALID_PRICE))
137
+ (asserts! (is-valid-string new-description u256) (err ERR_INVALID_INPUT))
138
+ (map-set Listings
139
+ { listing-id: listing-id }
140
+ (merge listing
141
+ {
142
+ price: new-price,
143
+ description: new-description
144
+ }
145
+ )
146
+ )
147
+ (print { event: "listing_updated", listing-id: listing-id, seller: tx-sender })
148
+ (ok true)
149
+ )
150
+ )
151
+ )
152
+
153
+ ;; Cancels a listing.
154
+ ;; @param listing-id: The ID of the listing to cancel.
155
+ ;; @returns (ok bool): True if the cancellation is successful.
156
+ (define-public (cancel-listing (listing-id uint))
157
+ (begin
158
+ (asserts! (is-valid-listing-id listing-id) (err ERR_INVALID_LISTING_ID))
159
+ (let
160
+ (
161
+ (listing (unwrap! (map-get? Listings { listing-id: listing-id }) (err ERR_LISTING_NOT_FOUND)))
162
+ )
163
+ (asserts! (is-eq (get seller listing) tx-sender) (err ERR_NOT_SELLER))
164
+ (asserts! (is-eq (get status listing) "active") (err ERR_INVALID_STATUS))
165
+ (map-set Listings
166
+ { listing-id: listing-id }
167
+ (merge listing { status: "cancelled" })
168
+ )
169
+ (print { event: "listing_cancelled", listing-id: listing-id, seller: tx-sender })
170
+ (ok true)
171
+ )
172
+ )
173
+ )
174
+
175
+ ;; Purchases a listing.
176
+ ;; @param listing-id: The ID of the listing to purchase.
177
+ ;; @returns (ok bool): True if the purchase is successful.
178
+ (define-public (purchase-listing (listing-id uint))
179
+ (begin
180
+ (asserts! (is-valid-listing-id listing-id) (err ERR_INVALID_LISTING_ID))
181
+ (let
182
+ (
183
+ (listing (unwrap! (map-get? Listings { listing-id: listing-id }) (err ERR_LISTING_NOT_FOUND)))
184
+ (price (get price listing))
185
+ (seller (get seller listing))
186
+ )
187
+ (asserts! (is-eq (get status listing) "active") (err ERR_INVALID_STATUS))
188
+ (asserts! (<= stacks-block-height (get expires-at listing)) (err ERR_LISTING_EXPIRED))
189
+ (asserts! (is-valid-seller seller) (err ERR_INVALID_SELLER))
190
+ (match (stx-transfer? price tx-sender seller)
191
+ success (begin
192
+ (map-set Listings
193
+ { listing-id: listing-id }
194
+ (merge listing { status: "sold" })
195
+ )
196
+ (print { event: "listing_purchased", listing-id: listing-id, buyer: tx-sender, seller: seller, price: price })
197
+ (ok true))
198
+ error (err ERR_INSUFFICIENT_BALANCE))
199
+ )
200
+ )
201
+ )
202
+
203
+ ;; --- Read-Only Functions ---
204
+ ;; Functions for retrieving data from the contract without making state changes.
205
+
206
+ ;; Retrieves a listing by its ID.
207
+ ;; @param listing-id: The ID of the listing to retrieve.
208
+ ;; @returns (optional {<listing-data>}): The listing data or none if not found.
209
+ (define-read-only (get-listing (listing-id uint))
210
+ (if (is-valid-listing-id listing-id)
211
+ (map-get? Listings { listing-id: listing-id })
212
+ none
213
+ )
214
+ )
215
+
216
+ ;; Retrieves the ID of the last created listing.
217
+ ;; @returns (ok uint): The last listing ID.
218
+ (define-read-only (get-last-listing-id)
219
+ (ok (var-get last-listing-id))
220
+ )
221
+
222
+ ;; --- Contract Initialization ---
223
+ ;; Initializes the contract upon deployment.
224
+ (begin
225
+ (print "CoreMarketPlace contract initialized")
226
+ (ok true)
227
+ )
@@ -0,0 +1,265 @@
1
+ ;; DisputeResolution Contract
2
+ ;; This contract handles the dispute resolution process for the Strade marketplace.
3
+ ;; It allows users to raise disputes, arbitrators to vote on them, and resolves disputes based on the outcome.
4
+
5
+ ;; --- Constants ---
6
+ ;; Defines immutable values used throughout the contract for error handling and configuration.
7
+
8
+ (define-constant CONTRACT_OWNER tx-sender) ;; Sets the contract deployer as the owner.
9
+ (define-constant ERR_NOT_AUTHORIZED (err u100)) ;; Error for unauthorized actions.
10
+ (define-constant ERR_DISPUTE_NOT_FOUND (err u101)) ;; Error when a dispute cannot be found.
11
+ (define-constant ERR_INVALID_STATE (err u102)) ;; Error for invalid dispute states.
12
+ (define-constant ERR_NOT_ARBITRATOR (err u103)) ;; Error when a user is not an authorized arbitrator.
13
+ (define-constant ERR_ALREADY_VOTED (err u104)) ;; Error if an arbitrator has already voted.
14
+ (define-constant ERR_VOTING_CLOSED (err u105)) ;; Error when voting on a dispute is closed.
15
+ (define-constant ERR_INSUFFICIENT_VOTES (err u106)) ;; Error if there are not enough votes to resolve a dispute.
16
+ (define-constant ERR_INVALID_VOTE (err u107)) ;; Error for invalid vote values.
17
+ (define-constant ERR_NOT_INVOLVED_PARTY (err u108)) ;; Error when a user is not a party to the dispute.
18
+ (define-constant ERR_INVALID_ESCROW_ID (err u109)) ;; Error for invalid escrow IDs.
19
+ (define-constant ERR_INVALID_REASON (err u110)) ;; Error for invalid dispute reasons.
20
+ (define-constant ERR_INVALID_DISPUTE_ID (err u111)) ;; Error for invalid dispute IDs.
21
+ (define-constant ERR_INVALID_REWARD (err u112)) ;; Error for invalid arbitrator rewards.
22
+ (define-constant ERR_INVALID_PRINCIPAL (err u113)) ;; Error for invalid principal addresses.
23
+ (define-constant VOTING_PERIOD u144) ;; The duration of the voting period in blocks (approximately 24 hours).
24
+ (define-constant MIN_VOTES_REQUIRED u3) ;; The minimum number of votes required to resolve a dispute.
25
+
26
+ ;; --- Data Maps ---
27
+ ;; Defines the data structures used to store dispute and arbitrator information.
28
+
29
+ (define-map Disputes
30
+ { dispute-id: uint }
31
+ {
32
+ escrow-id: uint, ;; The ID of the associated escrow.
33
+ initiator: principal, ;; The principal who initiated the dispute.
34
+ counterparty: principal, ;; The other party in the dispute.
35
+ reason: (string-utf8 256), ;; The reason for the dispute.
36
+ status: (string-ascii 20), ;; The current status of the dispute (e.g., "open", "resolved").
37
+ created-at: uint, ;; The block height at which the dispute was created.
38
+ votes-for: uint, ;; The number of votes in favor of the initiator.
39
+ votes-against: uint, ;; The number of votes against the initiator.
40
+ resolution: (optional (string-ascii 20)) ;; The resolution of the dispute.
41
+ }
42
+ )
43
+
44
+ (define-map Arbitrators principal bool) ;; Stores the set of authorized arbitrators.
45
+ (define-map ArbitratorVotes { dispute-id: uint, arbitrator: principal } bool) ;; Tracks votes cast by arbitrators.
46
+
47
+ ;; --- Variables ---
48
+ ;; Defines mutable variables for tracking the contract's state.
49
+
50
+ (define-data-var last-dispute-id uint u0) ;; Tracks the ID of the last created dispute.
51
+ (define-data-var arbitrator-reward uint u100) ;; The reward amount for arbitrators who vote on a dispute.
52
+
53
+ ;; --- Private Functions ---
54
+ ;; Helper functions intended for internal use by the contract.
55
+
56
+ ;; Checks if a given user is an authorized arbitrator.
57
+ (define-private (is-arbitrator (user principal))
58
+ (default-to false (map-get? Arbitrators user))
59
+ )
60
+
61
+ ;; Checks if an arbitrator has already voted on a specific dispute.
62
+ (define-private (has-voted (dispute-id uint) (arbitrator principal))
63
+ (is-some (map-get? ArbitratorVotes { dispute-id: dispute-id, arbitrator: arbitrator }))
64
+ )
65
+
66
+ ;; Updates the vote count for a dispute.
67
+ (define-private (update-vote-count (dispute-id uint) (vote bool))
68
+ (match (map-get? Disputes { dispute-id: dispute-id })
69
+ dispute (let
70
+ (
71
+ (new-votes-for (if vote (+ (get votes-for dispute) u1) (get votes-for dispute)))
72
+ (new-votes-against (if vote (get votes-against dispute) (+ (get votes-against dispute) u1)))
73
+ )
74
+ (map-set Disputes { dispute-id: dispute-id }
75
+ (merge dispute {
76
+ votes-for: new-votes-for,
77
+ votes-against: new-votes-against
78
+ }))
79
+ (ok true))
80
+ (err ERR_DISPUTE_NOT_FOUND)
81
+ )
82
+ )
83
+
84
+ ;; Checks if an escrow ID is valid.
85
+ (define-private (is-valid-escrow-id (escrow-id uint))
86
+ (> escrow-id u0)
87
+ )
88
+
89
+ ;; Checks if a dispute reason is valid.
90
+ (define-private (is-valid-reason (reason (string-utf8 256)))
91
+ (and (> (len reason) u0) (<= (len reason) u256))
92
+ )
93
+
94
+ ;; Checks if a dispute ID is valid.
95
+ (define-private (is-valid-dispute-id (dispute-id uint))
96
+ (<= dispute-id (var-get last-dispute-id))
97
+ )
98
+
99
+ ;; --- Public Functions ---
100
+ ;; Functions that can be called by any user.
101
+
102
+ ;; Raises a new dispute.
103
+ ;; @param escrow-id: The ID of the escrow to dispute.
104
+ ;; @param counterparty: The other party in the dispute.
105
+ ;; @param reason: The reason for the dispute.
106
+ ;; @returns (ok uint): The ID of the newly created dispute.
107
+ (define-public (raise-dispute (escrow-id uint) (counterparty principal) (reason (string-utf8 256)))
108
+ (let
109
+ (
110
+ (dispute-id (+ (var-get last-dispute-id) u1))
111
+ )
112
+ (asserts! (is-valid-escrow-id escrow-id) (err ERR_INVALID_ESCROW_ID))
113
+ (asserts! (is-valid-reason reason) (err ERR_INVALID_REASON))
114
+ (asserts! (not (is-eq tx-sender counterparty)) (err ERR_NOT_INVOLVED_PARTY))
115
+ (map-set Disputes
116
+ { dispute-id: dispute-id }
117
+ {
118
+ escrow-id: escrow-id,
119
+ initiator: tx-sender,
120
+ counterparty: counterparty,
121
+ reason: reason,
122
+ status: "open",
123
+ created-at: stacks-block-height,
124
+ votes-for: u0,
125
+ votes-against: u0,
126
+ resolution: none
127
+ }
128
+ )
129
+ (var-set last-dispute-id dispute-id)
130
+ (print { event: "dispute_raised", dispute-id: dispute-id, escrow-id: escrow-id, initiator: tx-sender })
131
+ (ok dispute-id)
132
+ )
133
+ )
134
+
135
+ ;; Allows an arbitrator to vote on a dispute.
136
+ ;; @param dispute-id: The ID of the dispute to vote on.
137
+ ;; @param vote: The arbitrator's vote (true for initiator, false for counterparty).
138
+ ;; @returns (ok bool): True if the vote is successful.
139
+ (define-public (vote-on-dispute (dispute-id uint) (vote bool))
140
+ (let
141
+ (
142
+ (dispute (unwrap! (map-get? Disputes { dispute-id: dispute-id }) (err ERR_DISPUTE_NOT_FOUND)))
143
+ )
144
+ (asserts! (is-valid-dispute-id dispute-id) (err ERR_INVALID_DISPUTE_ID))
145
+ (asserts! (is-arbitrator tx-sender) (err ERR_NOT_ARBITRATOR))
146
+ (asserts! (is-eq (get status dispute) "open") (err ERR_VOTING_CLOSED))
147
+ (asserts! (<= (- stacks-block-height (get created-at dispute)) VOTING_PERIOD) (err ERR_VOTING_CLOSED))
148
+ (asserts! (not (has-voted dispute-id tx-sender)) (err ERR_ALREADY_VOTED))
149
+ (try! (update-vote-count dispute-id vote))
150
+ (map-set ArbitratorVotes { dispute-id: dispute-id, arbitrator: tx-sender } vote)
151
+ (print { event: "arbitrator_voted", dispute-id: dispute-id, arbitrator: tx-sender, vote: vote })
152
+ (ok true)
153
+ )
154
+ )
155
+
156
+ ;; Resolves a dispute based on the votes.
157
+ ;; @param dispute-id: The ID of the dispute to resolve.
158
+ ;; @returns (ok (string-ascii 20)): The resolution of the dispute.
159
+ (define-public (resolve-dispute (dispute-id uint))
160
+ (let
161
+ (
162
+ (dispute (unwrap! (map-get? Disputes { dispute-id: dispute-id }) (err ERR_DISPUTE_NOT_FOUND)))
163
+ )
164
+ (asserts! (is-valid-dispute-id dispute-id) (err ERR_INVALID_DISPUTE_ID))
165
+ (asserts! (is-eq (get status dispute) "open") (err ERR_INVALID_STATE))
166
+ (asserts! (>= (+ (get votes-for dispute) (get votes-against dispute)) MIN_VOTES_REQUIRED) (err ERR_INSUFFICIENT_VOTES))
167
+ (asserts! (<= (- stacks-block-height (get created-at dispute)) VOTING_PERIOD) (err ERR_VOTING_CLOSED))
168
+ (let
169
+ (
170
+ (resolution (if (> (get votes-for dispute) (get votes-against dispute)) "for_initiator" "for_counterparty"))
171
+ )
172
+ (map-set Disputes { dispute-id: dispute-id }
173
+ (merge dispute {
174
+ status: "resolved",
175
+ resolution: (some resolution)
176
+ })
177
+ )
178
+ (print { event: "dispute_resolved", dispute-id: dispute-id, resolution: resolution })
179
+ (ok resolution)
180
+ )
181
+ )
182
+ )
183
+
184
+ ;; Adds a new arbitrator.
185
+ ;; @param arbitrator: The principal of the new arbitrator.
186
+ ;; @returns (ok bool): True if the arbitrator is added successfully.
187
+ (define-public (add-arbitrator (arbitrator principal))
188
+ (begin
189
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) (err ERR_NOT_AUTHORIZED))
190
+ (asserts! (is-valid-principal arbitrator) (err ERR_INVALID_PRINCIPAL))
191
+ (map-set Arbitrators arbitrator true)
192
+ (print { event: "arbitrator_added", arbitrator: arbitrator })
193
+ (ok true)
194
+ )
195
+ )
196
+
197
+ ;; Removes an arbitrator.
198
+ ;; @param arbitrator: The principal of the arbitrator to remove.
199
+ ;; @returns (ok bool): True if the arbitrator is removed successfully.
200
+ (define-public (remove-arbitrator (arbitrator principal))
201
+ (begin
202
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) (err ERR_NOT_AUTHORIZED))
203
+ (asserts! (is-valid-principal arbitrator) (err ERR_INVALID_PRINCIPAL))
204
+ (map-delete Arbitrators arbitrator)
205
+ (print { event: "arbitrator_removed", arbitrator: arbitrator })
206
+ (ok true)
207
+ )
208
+ )
209
+
210
+ ;; Sets the reward for arbitrators.
211
+ ;; @param new-reward: The new reward amount.
212
+ ;; @returns (ok bool): True if the reward is set successfully.
213
+ (define-public (set-arbitrator-reward (new-reward uint))
214
+ (begin
215
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) (err ERR_NOT_AUTHORIZED))
216
+ (asserts! (> new-reward u0) (err ERR_INVALID_REWARD))
217
+ (var-set arbitrator-reward new-reward)
218
+ (print { event: "arbitrator_reward_set", new-reward: new-reward })
219
+ (ok true)
220
+ )
221
+ )
222
+
223
+ ;; --- Read-Only Functions ---
224
+ ;; Functions for retrieving data from the contract without making state changes.
225
+
226
+ ;; Retrieves a dispute by its ID.
227
+ ;; @param dispute-id: The ID of the dispute to retrieve.
228
+ ;; @returns (optional {<dispute-data>}): The dispute data or none if not found.
229
+ (define-read-only (get-dispute (dispute-id uint))
230
+ (map-get? Disputes { dispute-id: dispute-id })
231
+ )
232
+
233
+ ;; Retrieves the ID of the last created dispute.
234
+ ;; @returns (ok uint): The last dispute ID.
235
+ (define-read-only (get-last-dispute-id)
236
+ (ok (var-get last-dispute-id))
237
+ )
238
+
239
+ ;; Retrieves the arbitrator reward amount.
240
+ ;; @returns (ok uint): The arbitrator reward amount.
241
+ (define-read-only (get-arbitrator-reward)
242
+ (ok (var-get arbitrator-reward))
243
+ )
244
+
245
+ ;; Checks if a user is an authorized arbitrator.
246
+ ;; @param user: The principal to check.
247
+ ;; @returns (ok bool): True if the user is an arbitrator.
248
+ (define-read-only (is-user-arbitrator (user principal))
249
+ (ok (is-arbitrator user))
250
+ )
251
+
252
+ ;; --- Helper function for principal validation ---
253
+ (define-private (is-valid-principal (principal principal))
254
+ (and
255
+ (not (is-eq principal CONTRACT_OWNER))
256
+ (not (is-eq principal (as-contract tx-sender)))
257
+ )
258
+ )
259
+
260
+ ;; --- Contract Initialization ---
261
+ ;; Initializes the contract upon deployment.
262
+ (begin
263
+ (print "DisputeResolution contract initialized")
264
+ (ok true)
265
+ )
@@ -0,0 +1,171 @@
1
+ ;; EscrowService Contract
2
+ ;; This contract provides a secure escrow service for transactions between buyers and sellers.
3
+ ;; It holds funds until the buyer releases them to the seller or a dispute is resolved.
4
+
5
+ ;; --- Constants ---
6
+ ;; Defines immutable values used throughout the contract for error handling and configuration.
7
+
8
+ (define-constant CONTRACT_OWNER tx-sender) ;; Sets the contract deployer as the owner.
9
+ (define-constant ERR_NOT_AUTHORIZED (err u100)) ;; Error for unauthorized actions.
10
+ (define-constant ERR_ESCROW_NOT_FOUND (err u101)) ;; Error when an escrow cannot be found.
11
+ (define-constant ERR_ALREADY_RELEASED (err u102)) ;; Error if funds have already been released.
12
+ (define-constant ERR_TRANSFER_FAILED (err u103)) ;; Error for failed STX transfers.
13
+ (define-constant ERR_INVALID_ESCROW_ID (err u104)) ;; Error for invalid escrow IDs.
14
+ (define-constant ERR_INVALID_AMOUNT (err u105)) ;; Error for invalid transaction amounts.
15
+ (define-constant ERR_INVALID_SELLER (err u106)) ;; Error for invalid seller principals.
16
+ (define-constant ERR_ESCROW_EXPIRED (err u107)) ;; Error for expired escrows.
17
+ (define-constant ESCROW_DURATION u1008) ;; The duration of the escrow in blocks (approximately 7 days).
18
+
19
+ ;; --- Data Maps ---
20
+ ;; Defines the data structures used to store escrow information.
21
+
22
+ (define-map Escrows
23
+ { escrow-id: uint }
24
+ {
25
+ buyer: principal, ;; The principal of the buyer.
26
+ seller: principal, ;; The principal of the seller.
27
+ amount: uint, ;; The amount of STX held in escrow.
28
+ state: (string-ascii 10), ;; The current state of the escrow (e.g., "locked", "released", "refunded").
29
+ created-at: uint, ;; The block height at which the escrow was created.
30
+ expires-at: uint ;; The block height at which the escrow expires.
31
+ }
32
+ )
33
+
34
+ ;; --- Variables ---
35
+ ;; Defines mutable variables for tracking the contract's state.
36
+
37
+ (define-data-var last-escrow-id uint u0) ;; Tracks the ID of the last created escrow.
38
+
39
+ ;; --- Helper functions ---
40
+
41
+ ;; Checks if a seller principal is valid.
42
+ (define-private (is-valid-seller (seller principal))
43
+ (and
44
+ (not (is-eq seller tx-sender))
45
+ (not (is-eq seller (as-contract tx-sender)))
46
+ )
47
+ )
48
+
49
+ ;; Checks if an escrow ID is valid.
50
+ (define-private (is-valid-escrow-id (escrow-id uint))
51
+ (<= escrow-id (var-get last-escrow-id))
52
+ )
53
+
54
+ ;; --- Public Functions ---
55
+
56
+ ;; Creates a new escrow.
57
+ ;; @param seller: The principal of the seller.
58
+ ;; @param amount: The amount of STX to hold in escrow.
59
+ ;; @returns (ok uint): The ID of the newly created escrow.
60
+ (define-public (create-escrow (seller principal) (amount uint))
61
+ (let
62
+ (
63
+ (escrow-id (+ (var-get last-escrow-id) u1))
64
+ (expires-at (+ stacks-block-height ESCROW_DURATION))
65
+ )
66
+ (asserts! (> amount u0) (err ERR_INVALID_AMOUNT))
67
+ (asserts! (is-valid-seller seller) (err ERR_INVALID_SELLER))
68
+ (match (stx-transfer? amount tx-sender (as-contract tx-sender))
69
+ success
70
+ (begin
71
+ (map-set Escrows
72
+ { escrow-id: escrow-id }
73
+ {
74
+ buyer: tx-sender,
75
+ seller: seller,
76
+ amount: amount,
77
+ state: "locked",
78
+ created-at: stacks-block-height,
79
+ expires-at: expires-at
80
+ }
81
+ )
82
+ (var-set last-escrow-id escrow-id)
83
+ (print {event: "escrow_created", escrow-id: escrow-id, buyer: tx-sender, seller: seller, amount: amount})
84
+ (ok escrow-id)
85
+ )
86
+ error (err ERR_TRANSFER_FAILED)
87
+ )
88
+ )
89
+ )
90
+
91
+ ;; Releases funds to the seller.
92
+ ;; @param escrow-id: The ID of the escrow to release.
93
+ ;; @returns (ok bool): True if the funds are released successfully.
94
+ (define-public (release-funds (escrow-id uint))
95
+ (begin
96
+ (asserts! (is-valid-escrow-id escrow-id) (err ERR_INVALID_ESCROW_ID))
97
+ (let
98
+ (
99
+ (escrow (unwrap! (map-get? Escrows { escrow-id: escrow-id }) (err ERR_ESCROW_NOT_FOUND)))
100
+ (seller (get seller escrow))
101
+ (amount (get amount escrow))
102
+ )
103
+ (asserts! (or (is-eq tx-sender CONTRACT_OWNER) (is-eq tx-sender (get buyer escrow))) (err ERR_NOT_AUTHORIZED))
104
+ (asserts! (is-eq (get state escrow) "locked") (err ERR_ALREADY_RELEASED))
105
+ (asserts! (<= stacks-block-height (get expires-at escrow)) (err ERR_ESCROW_EXPIRED))
106
+ (match (as-contract (stx-transfer? amount tx-sender seller))
107
+ success
108
+ (begin
109
+ (map-set Escrows
110
+ { escrow-id: escrow-id }
111
+ (merge escrow { state: "released" })
112
+ )
113
+ (print {event: "funds_released", escrow-id: escrow-id, seller: seller, amount: amount})
114
+ (ok true)
115
+ )
116
+ error (err ERR_TRANSFER_FAILED)
117
+ )
118
+ )
119
+ )
120
+ )
121
+
122
+ ;; Refunds the buyer.
123
+ ;; @param escrow-id: The ID of the escrow to refund.
124
+ ;; @returns (ok bool): True if the refund is successful.
125
+ (define-public (refund-buyer (escrow-id uint))
126
+ (begin
127
+ (asserts! (is-valid-escrow-id escrow-id) (err ERR_INVALID_ESCROW_ID))
128
+ (let
129
+ (
130
+ (escrow (unwrap! (map-get? Escrows { escrow-id: escrow-id }) (err ERR_ESCROW_NOT_FOUND)))
131
+ (buyer (get buyer escrow))
132
+ (amount (get amount escrow))
133
+ )
134
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) (err ERR_NOT_AUTHORIZED))
135
+ (asserts! (is-eq (get state escrow) "locked") (err ERR_ALREADY_RELEASED))
136
+ (match (as-contract (stx-transfer? amount tx-sender buyer))
137
+ success
138
+ (begin
139
+ (map-set Escrows
140
+ { escrow-id: escrow-id }
141
+ (merge escrow { state: "refunded" })
142
+ )
143
+ (print {event: "buyer_refunded", escrow-id: escrow-id, buyer: buyer, amount: amount})
144
+ (ok true)
145
+ )
146
+ error (err ERR_TRANSFER_FAILED)
147
+ )
148
+ )
149
+ )
150
+ )
151
+
152
+ ;; --- Read-Only Functions ---
153
+
154
+ ;; Retrieves escrow details by ID.
155
+ ;; @param escrow-id: The ID of the escrow to retrieve.
156
+ ;; @returns (ok {<escrow-data>}): The escrow data or an error if not found.
157
+ (define-read-only (get-escrow (escrow-id uint))
158
+ (begin
159
+ (asserts! (is-valid-escrow-id escrow-id) (err ERR_INVALID_ESCROW_ID))
160
+ (match (map-get? Escrows { escrow-id: escrow-id })
161
+ escrow (ok escrow)
162
+ (err ERR_ESCROW_NOT_FOUND)
163
+ )
164
+ )
165
+ )
166
+
167
+ ;; Retrieves the ID of the last created escrow.
168
+ ;; @returns (ok uint): The last escrow ID.
169
+ (define-read-only (get-last-escrow-id)
170
+ (ok (var-get last-escrow-id))
171
+ )
@@ -0,0 +1,280 @@
1
+ ;; UserProfile Contract
2
+ ;; This contract manages user profiles, including usernames, bios, ratings, and reputation scores.
3
+ ;; It provides functions for users to register, update their profiles, and rate each other.
4
+
5
+ ;; --- Constants ---
6
+ ;; Defines immutable values used throughout the contract for error handling and configuration.
7
+
8
+ (define-constant CONTRACT_OWNER tx-sender) ;; Sets the contract deployer as the owner.
9
+ (define-constant ERR_NOT_AUTHORIZED (err u100)) ;; Error for unauthorized actions.
10
+ (define-constant ERR_USER_NOT_FOUND (err u101)) ;; Error when a user profile cannot be found.
11
+ (define-constant ERR_INVALID_RATING (err u102)) ;; Error for invalid rating values (must be between 1 and 5).
12
+ (define-constant ERR_SELF_RATING (err u103)) ;; Error when a user attempts to rate themselves.
13
+ (define-constant ERR_ALREADY_REGISTERED (err u104)) ;; Error if a user is already registered.
14
+ (define-constant ERR_INVALID_INPUT (err u105)) ;; Error for invalid input parameters.
15
+ (define-constant ERR_DATA_STORE_FAILURE (err u106)) ;; Error for data storage failures.
16
+ (define-constant ERR_INVALID_PRINCIPAL (err u107)) ;; Error for invalid principal addresses.
17
+ (define-constant ERR_INVALID_USERNAME (err u108)) ;; Error for invalid usernames.
18
+ (define-constant ERR_INVALID_BIO (err u109)) ;; Error for invalid bio lengths.
19
+ (define-constant ERR_INVALID_EMAIL (err u110)) ;; Error for invalid email formats or lengths.
20
+
21
+ ;; --- Data Maps ---
22
+ ;; Defines the data structures used to store user profile information.
23
+
24
+ (define-map Users principal
25
+ {
26
+ username: (string-utf8 64), ;; The user's chosen username.
27
+ bio: (string-utf8 256), ;; A short biography or description.
28
+ email: (string-utf8 64), ;; The user's email address.
29
+ registration-date: uint, ;; The block height of the user's registration.
30
+ total-ratings: uint, ;; The total number of ratings the user has received.
31
+ rating-sum: uint, ;; The sum of all ratings received.
32
+ reputation-score: uint ;; A calculated score based on ratings and other factors.
33
+ }
34
+ )
35
+
36
+ (define-map UserAuthorization principal bool) ;; Stores authorization status for specific users.
37
+
38
+ ;; --- Private Functions ---
39
+ ;; Helper functions for internal contract use.
40
+
41
+ ;; Checks if a string is within the specified length constraints.
42
+ (define-private (is-valid-string (str (string-utf8 256)) (max-len uint))
43
+ (and (>= (len str) u1) (<= (len str) max-len))
44
+ )
45
+
46
+ ;; Checks if a principal is a valid user address.
47
+ (define-private (is-valid-principal (user principal))
48
+ (not (is-eq user (as-contract tx-sender)))
49
+ )
50
+
51
+ ;; Validates the format and length of a username.
52
+ (define-private (validate-username (username (string-utf8 64)))
53
+ (if (is-valid-string username u64)
54
+ (ok username)
55
+ (err ERR_INVALID_USERNAME))
56
+ )
57
+
58
+ ;; Validates the length of a user's bio.
59
+ (define-private (validate-bio (bio (string-utf8 256)))
60
+ (if (is-valid-string bio u256)
61
+ (ok bio)
62
+ (err ERR_INVALID_BIO))
63
+ )
64
+
65
+ ;; Validates the format and length of an email address.
66
+ (define-private (validate-email (email (string-utf8 64)))
67
+ (if (is-valid-string email u64)
68
+ (ok email)
69
+ (err ERR_INVALID_EMAIL))
70
+ )
71
+
72
+ ;; Sets the user data in the Users map.
73
+ (define-private (set-user-data (user principal) (data {
74
+ username: (string-utf8 64),
75
+ bio: (string-utf8 256),
76
+ email: (string-utf8 64),
77
+ registration-date: uint,
78
+ total-ratings: uint,
79
+ rating-sum: uint,
80
+ reputation-score: uint
81
+ }))
82
+ (if (map-set Users user data)
83
+ (ok true)
84
+ (err ERR_DATA_STORE_FAILURE))
85
+ )
86
+
87
+ ;; --- Read-Only Functions ---
88
+ ;; Functions for retrieving data from the contract without making state changes.
89
+
90
+ ;; Retrieves a user's profile.
91
+ ;; @param user: The principal of the user to retrieve.
92
+ ;; @returns (ok {<user-data>}): The user's profile data or an error if not found.
93
+ (define-read-only (get-user-profile (user principal))
94
+ (match (map-get? Users user)
95
+ user-data (ok user-data)
96
+ (err ERR_USER_NOT_FOUND)))
97
+
98
+ ;; Retrieves a user's average rating.
99
+ ;; @param user: The principal of the user.
100
+ ;; @returns (ok uint): The user's average rating or 0 if no ratings.
101
+ (define-read-only (get-user-rating (user principal))
102
+ (match (map-get? Users user)
103
+ user-data (let (
104
+ (total-ratings (get total-ratings user-data))
105
+ (rating-sum (get rating-sum user-data))
106
+ )
107
+ (if (> total-ratings u0)
108
+ (ok (/ rating-sum total-ratings))
109
+ (ok u0)))
110
+ (err ERR_USER_NOT_FOUND)
111
+ )
112
+ )
113
+
114
+ ;; Checks if a user is authorized.
115
+ ;; @param user: The principal to check.
116
+ ;; @returns (ok bool): True if the user is authorized.
117
+ (define-read-only (is-user-authorized (user principal))
118
+ (ok (default-to false (map-get? UserAuthorization user))))
119
+
120
+
121
+ ;; --- Public Functions ---
122
+ ;; Functions that can be called by any user.
123
+
124
+ ;; Registers a new user.
125
+ ;; @param username: The desired username.
126
+ ;; @param bio: A short bio.
127
+ ;; @param email: The user's email address.
128
+ ;; @returns (ok bool): True if registration is successful.
129
+ (define-public (register-user (username (string-utf8 64)) (bio (string-utf8 256)) (email (string-utf8 64)))
130
+ (let (
131
+ (existing-user (map-get? Users tx-sender))
132
+ )
133
+ (asserts! (is-none existing-user) (err ERR_ALREADY_REGISTERED))
134
+ (asserts! (and
135
+ (> (len username) u0)
136
+ (>= (len username) u1)
137
+ (<= (len username) u64)
138
+ (> (len bio) u0)
139
+ (>= (len bio) u1)
140
+ (<= (len bio) u256)
141
+ (> (len email) u0)
142
+ (>= (len email) u1)
143
+ (<= (len email) u64))
144
+ (err ERR_INVALID_INPUT))
145
+ (let (
146
+ (validated-username (try! (validate-username username)))
147
+ (validated-bio (try! (validate-bio bio)))
148
+ (validated-email (try! (validate-email email)))
149
+ )
150
+ (match (set-user-data tx-sender
151
+ {
152
+ username: validated-username,
153
+ bio: validated-bio,
154
+ email: validated-email,
155
+ registration-date: stacks-block-height,
156
+ total-ratings: u0,
157
+ rating-sum: u0,
158
+ reputation-score: u0
159
+ })
160
+ success (ok true)
161
+ error (err ERR_DATA_STORE_FAILURE))
162
+ ))
163
+ )
164
+
165
+ ;; Updates a user's profile.
166
+ ;; @param bio: The new bio.
167
+ ;; @param email: The new email address.
168
+ ;; @returns (ok bool): True if the update is successful.
169
+ (define-public (update-profile (bio (string-utf8 256)) (email (string-utf8 64)))
170
+ (begin
171
+ (asserts! (and
172
+ (> (len bio) u0)
173
+ (>= (len bio) u1)
174
+ (<= (len bio) u256)
175
+ (> (len email) u0)
176
+ (>= (len email) u1)
177
+ (<= (len email) u64))
178
+ (err ERR_INVALID_INPUT))
179
+ (let (
180
+ (validated-bio (try! (validate-bio bio)))
181
+ (validated-email (try! (validate-email email)))
182
+ )
183
+ (match (map-get? Users tx-sender)
184
+ user-data
185
+ (match (set-user-data tx-sender
186
+ (merge user-data
187
+ {
188
+ bio: validated-bio,
189
+ email: validated-email
190
+ }
191
+ ))
192
+ success (ok true)
193
+ error (err ERR_DATA_STORE_FAILURE))
194
+ (err ERR_USER_NOT_FOUND)
195
+ )
196
+ )
197
+ )
198
+ )
199
+
200
+ ;; Rates a user.
201
+ ;; @param user: The principal of the user to rate.
202
+ ;; @param rating: The rating value (1-5).
203
+ ;; @returns (ok bool): True if the rating is successful.
204
+ (define-public (rate-user (user principal) (rating uint))
205
+ (begin
206
+ (asserts! (is-valid-principal user) (err ERR_INVALID_PRINCIPAL))
207
+ (asserts! (not (is-eq tx-sender user)) (err ERR_SELF_RATING))
208
+ (asserts! (and (>= rating u1) (<= rating u5)) (err ERR_INVALID_RATING))
209
+ (match (map-get? Users user)
210
+ user-data
211
+ (match (set-user-data user
212
+ (merge user-data
213
+ {
214
+ total-ratings: (+ (get total-ratings user-data) u1),
215
+ rating-sum: (+ (get rating-sum user-data) rating)
216
+ }
217
+ ))
218
+ success (ok true)
219
+ error (err ERR_DATA_STORE_FAILURE))
220
+ (err ERR_USER_NOT_FOUND)
221
+ )
222
+ )
223
+ )
224
+
225
+ ;; Calculates a user's reputation score.
226
+ ;; @param user: The principal of the user.
227
+ ;; @returns (ok bool): True if the calculation is successful.
228
+ (define-public (calculate-reputation (user principal))
229
+ (begin
230
+ (asserts! (is-valid-principal user) (err ERR_INVALID_PRINCIPAL))
231
+ (match (map-get? Users user)
232
+ user-data
233
+ (let (
234
+ (total-ratings (get total-ratings user-data))
235
+ (rating-sum (get rating-sum user-data))
236
+ (avg-rating (if (> total-ratings u0) (/ rating-sum total-ratings) u0))
237
+ (new-reputation (+ (* avg-rating u20) (* total-ratings u2)))
238
+ )
239
+ (match (set-user-data user
240
+ (merge user-data
241
+ {
242
+ reputation-score: new-reputation
243
+ }
244
+ ))
245
+ success (ok true)
246
+ error (err ERR_DATA_STORE_FAILURE)))
247
+ (err ERR_USER_NOT_FOUND)
248
+ )
249
+ )
250
+ )
251
+
252
+ ;; Authorizes a user for specific actions.
253
+ ;; @param user: The principal to authorize.
254
+ ;; @returns (ok bool): True if authorization is successful.
255
+ (define-public (authorize-user (user principal))
256
+ (begin
257
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) (err ERR_NOT_AUTHORIZED))
258
+ (asserts! (is-valid-principal user) (err ERR_INVALID_PRINCIPAL))
259
+ (ok (map-set UserAuthorization user true))
260
+ )
261
+ )
262
+
263
+ ;; Revokes a user's authorization.
264
+ ;; @param user: The principal to revoke authorization from.
265
+ ;; @returns (ok bool): True if revocation is successful.
266
+ (define-public (revoke-authorization (user principal))
267
+ (begin
268
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) (err ERR_NOT_AUTHORIZED))
269
+ (asserts! (is-valid-principal user) (err ERR_INVALID_PRINCIPAL))
270
+ (ok (map-set UserAuthorization user false))
271
+ )
272
+ )
273
+
274
+ ;; --- Contract Initialization ---
275
+ ;; Initializes the contract upon deployment.
276
+ (begin
277
+ (map-set UserAuthorization CONTRACT_OWNER true)
278
+ (print "UserProfile contract initialized")
279
+ (ok true)
280
+ )
package/ft-trait.clar ADDED
@@ -0,0 +1,24 @@
1
+ (define-trait ft-trait
2
+ (
3
+ ;; Transfer from the caller to a new principal
4
+ (transfer (uint principal principal) (response bool uint))
5
+
6
+ ;; the human readable name of the token
7
+ (get-name () (response (string-ascii 32) uint))
8
+
9
+ ;; the ticker symbol, or empty if none
10
+ (get-symbol () (response (string-ascii 32) uint))
11
+
12
+ ;; the number of decimals used, e.g. 6 would mean 1_000_000 represents 1 token
13
+ (get-decimals () (response uint uint))
14
+
15
+ ;; the balance of the passed principal
16
+ (get-balance (principal) (response uint uint))
17
+
18
+ ;; the current total supply (which does not need to be a constant)
19
+ (get-total-supply () (response uint uint))
20
+
21
+ ;; an optional URI that represents metadata of this token
22
+ (get-token-uri () (response (optional (string-utf8 256)) uint))
23
+ )
24
+ )
package/package.json CHANGED
@@ -1,7 +1,14 @@
1
1
  {
2
2
  "name": "strade-stx-contracts",
3
- "version": "1.0.0",
4
- "description": "Clarity smart contracts for Strade marketplace - escrow, dispute resolution, and user profiles on Stacks",
5
- "main": "index.js",
6
- "license": "ISC"
3
+ "version": "1.0.1",
4
+ "description": "Clarity smart contracts for Strade marketplace",
5
+ "license": "ISC",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Marvy247/Strade.git"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/Marvy247/Strade/issues"
12
+ },
13
+ "homepage": "https://github.com/Marvy247/Strade"
7
14
  }
package/token.clar ADDED
@@ -0,0 +1,178 @@
1
+ ;; Strade Token (BST) Contract
2
+ ;; This contract defines the Strade Token (BST), a fungible token compliant with the SIP-010 standard.
3
+ ;; It includes functions for transferring, minting, and burning tokens, as well as managing token metadata.
4
+
5
+ ;; --- Token Properties ---
6
+ (define-fungible-token bst u1000000000000)
7
+
8
+ ;; --- Constants ---
9
+ ;; Defines immutable values used throughout the contract for error handling and configuration.
10
+
11
+ (define-constant CONTRACT_OWNER tx-sender) ;; Sets the contract deployer as the owner.
12
+ (define-constant ERR_OWNER_ONLY (err u100)) ;; Error for actions restricted to the contract owner.
13
+ (define-constant ERR_NOT_AUTHORIZED (err u101)) ;; Error for unauthorized actions.
14
+ (define-constant ERR_INVALID_AMOUNT (err u102)) ;; Error for invalid token amounts.
15
+ (define-constant ERR_INSUFFICIENT_BALANCE (err u103)) ;; Error when a user has an insufficient token balance.
16
+ (define-constant ERR_INVALID_RECIPIENT (err u104)) ;; Error for invalid recipient addresses.
17
+ (define-constant ERR_INVALID_URI (err u105)) ;; Error for invalid token URIs.
18
+ (define-constant ERR_MAX_SUPPLY_REACHED (err u106)) ;; Error when the maximum token supply is reached.
19
+ (define-constant ERR_CONTRACT_PAUSED (err u107)) ;; Error for actions attempted while the contract is paused.
20
+ (define-constant MAX_SUPPLY u10000000000000) ;; The maximum total supply of the token.
21
+
22
+ ;; --- Variables ---
23
+ ;; Defines mutable variables for tracking the token's state and metadata.
24
+
25
+ (define-data-var token-name (string-utf8 32) u"Strade Token") ;; The name of the token.
26
+ (define-data-var token-symbol (string-utf8 10) u"BST") ;; The symbol of the token.
27
+ (define-data-var token-decimals uint u6) ;; The number of decimal places for the token.
28
+ (define-data-var token-uri (optional (string-utf8 256)) none) ;; The URI for the token's metadata.
29
+ (define-data-var contract-paused bool false) ;; A flag to pause or unpause the contract.
30
+
31
+ ;; --- Helper Functions ---
32
+
33
+ ;; Checks if a principal is a valid recipient for token transfers.
34
+ (define-private (is-valid-recipient (recipient principal))
35
+ (not (is-eq recipient (as-contract tx-sender))))
36
+
37
+ ;; Checks if the contract is currently paused.
38
+ (define-private (is-contract-not-paused)
39
+ (not (var-get contract-paused)))
40
+
41
+ ;; --- SIP-010 Functions ---
42
+ ;; Standard functions for a fungible token.
43
+
44
+ ;; Transfers tokens from the sender to the recipient.
45
+ (define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
46
+ (begin
47
+ (asserts! (is-contract-not-paused) ERR_CONTRACT_PAUSED)
48
+ (asserts! (is-eq tx-sender sender) ERR_NOT_AUTHORIZED)
49
+ (asserts! (> amount u0) ERR_INVALID_AMOUNT)
50
+ (asserts! (<= amount (ft-get-balance bst sender)) ERR_INSUFFICIENT_BALANCE)
51
+ (asserts! (is-valid-recipient recipient) ERR_INVALID_RECIPIENT)
52
+ (try! (ft-transfer? bst amount sender recipient))
53
+ (print (merge
54
+ {event: "token_transferred", amount: amount, sender: sender, recipient: recipient}
55
+ (match memo
56
+ some-memo {memo: (some some-memo)}
57
+ {memo: none}
58
+ )
59
+ ))
60
+ (ok true)
61
+ )
62
+ )
63
+
64
+ ;; Gets the name of the token.
65
+ (define-read-only (get-name)
66
+ (ok (var-get token-name))
67
+ )
68
+
69
+ ;; Gets the symbol of the token.
70
+ (define-read-only (get-symbol)
71
+ (ok (var-get token-symbol))
72
+ )
73
+
74
+ ;; Gets the number of decimals for the token.
75
+ (define-read-only (get-decimals)
76
+ (ok (var-get token-decimals))
77
+ )
78
+
79
+ ;; Gets the balance of a given principal.
80
+ (define-read-only (get-balance (who principal))
81
+ (ok (ft-get-balance bst who))
82
+ )
83
+
84
+ ;; Gets the total supply of the token.
85
+ (define-read-only (get-total-supply)
86
+ (ok (ft-get-supply bst))
87
+ )
88
+
89
+ ;; Gets the token's metadata URI.
90
+ (define-read-only (get-token-uri)
91
+ (ok (var-get token-uri))
92
+ )
93
+
94
+ ;; --- Public Management Functions ---
95
+
96
+ ;; Mints new tokens and assigns them to a recipient.
97
+ ;; @param amount: The amount of tokens to mint.
98
+ ;; @param recipient: The principal to receive the new tokens.
99
+ (define-public (mint (amount uint) (recipient principal))
100
+ (begin
101
+ (asserts! (is-contract-not-paused) ERR_CONTRACT_PAUSED)
102
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_OWNER_ONLY)
103
+ (asserts! (> amount u0) ERR_INVALID_AMOUNT)
104
+ (asserts! (is-valid-recipient recipient) ERR_INVALID_RECIPIENT)
105
+ (asserts! (<= (+ amount (ft-get-supply bst)) MAX_SUPPLY) ERR_MAX_SUPPLY_REACHED)
106
+ (match (ft-mint? bst amount recipient)
107
+ success (begin
108
+ (print {event: "token_minted", amount: amount, recipient: recipient})
109
+ (ok success))
110
+ error (err error))
111
+ )
112
+ )
113
+
114
+ ;; Burns a specified amount of tokens from the sender's balance.
115
+ ;; @param amount: The amount of tokens to burn.
116
+ ;; @param sender: The principal whose tokens will be burned.
117
+ (define-public (burn (amount uint) (sender principal))
118
+ (begin
119
+ (asserts! (is-contract-not-paused) ERR_CONTRACT_PAUSED)
120
+ (asserts! (is-eq tx-sender sender) ERR_NOT_AUTHORIZED)
121
+ (asserts! (> amount u0) ERR_INVALID_AMOUNT)
122
+ (asserts! (<= amount (ft-get-balance bst sender)) ERR_INSUFFICIENT_BALANCE)
123
+ (match (ft-burn? bst amount sender)
124
+ success (begin
125
+ (print {event: "token_burned", amount: amount, sender: sender})
126
+ (ok success))
127
+ error (err error))
128
+ )
129
+ )
130
+
131
+ ;; Sets the token's metadata URI.
132
+ ;; @param new-uri: The new URI for the token metadata.
133
+ (define-public (set-token-uri (new-uri (optional (string-utf8 256))))
134
+ (begin
135
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_OWNER_ONLY)
136
+ (match new-uri
137
+ some-uri
138
+ (begin
139
+ (asserts! (<= (len some-uri) u256) ERR_INVALID_URI)
140
+ (var-set token-uri (some some-uri))
141
+ (print {event: "token_uri_updated", new_uri: some-uri})
142
+ (ok true)
143
+ )
144
+ (begin
145
+ (var-set token-uri none)
146
+ (print {event: "token_uri_removed"})
147
+ (ok true)
148
+ )
149
+ )
150
+ )
151
+ )
152
+
153
+ ;; Pauses the contract, disabling most functions.
154
+ (define-public (pause-contract)
155
+ (begin
156
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_OWNER_ONLY)
157
+ (var-set contract-paused true)
158
+ (print {event: "contract_paused"})
159
+ (ok true)
160
+ )
161
+ )
162
+
163
+ ;; Unpauses the contract, re-enabling all functions.
164
+ (define-public (unpause-contract)
165
+ (begin
166
+ (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_OWNER_ONLY)
167
+ (var-set contract-paused false)
168
+ (print {event: "contract_unpaused"})
169
+ (ok true)
170
+ )
171
+ )
172
+
173
+ ;; --- Contract Initialization ---
174
+ ;; Initializes the contract upon deployment, minting the initial supply to the contract owner.
175
+ (begin
176
+ (try! (ft-mint? bst u1000000000000 CONTRACT_OWNER))
177
+ (print {event: "contract_deployed", initial_supply: u1000000000000})
178
+ )
package/index.js DELETED
@@ -1 +0,0 @@
1
- module.exports = { name: "strade-stx-contracts", version: "1.0.0" };