# Smart Contract

{% embed url="<https://explorer.stacks.co/txid/SP1SCEXE6PMGPAC6B4N5P2MDKX8V4GF9QDE1FNNGJ.trustless-rewards?chain=mainnet>" %}
Trustless Rewards on Mainnet
{% endembed %}

{% embed url="<https://explorer.stackscode.co/txid/SP1SCEXE6PMGPAC6B4N5P2MDKX8V4GF9QDE1FNNGJ.trustless-rewards?chain=mainnet>" %}
The complete code with used Traits
{% endembed %}

## Data Stored On Chain

### Error Codes used

{% code lineNumbers="true" %}

```lisp
;; constants
(define-constant ERR-NOT-AUTHORIZED (err u401))
(define-constant ERR-NOT-FOUND (err u404))
(define-constant ERR-NOT-ACTIVE (err u403))
(define-constant ERR-ALREADY-JOINED (err u405))
(define-constant ERR-JOIN-FAILED (err u500))
(define-constant OK-SUCCESS u200)
(define-constant DEFAULT-PRICE u100)
```

{% endcode %}

### Variables used

> Lobbies map - keep data about each lobby using their unique id
>
> For a lobby id - have details such as&#x20;
>
> &#x20; \- owner of lobby, a short description, STX amount accumulated, entry fee
>
> &#x20; \- factor and commission which are used in the calculus formula for rewards
>
> &#x20; \- mapy, length, traffic, curves to display transparently the racing map info
>
> &#x20; \- hours and active for increased security to pay only once the rewards after the lobby is done
>
> Scoreboard to keep the highscore of each address that played in a given lobby and info for rewarding that specific player
>
> Count of lobbies for generating a new id each time one lobby is created
>
> The owner to let only him to pay rewards

{% code overflow="wrap" lineNumbers="true" %}

```lisp
;; data maps and vars
(define-map lobbies {id: uint} {owner: principal, description: (string-ascii 99), balance: uint, price: uint, factor: uint, commission: uint, mapy: (string-ascii 30), length: (string-ascii 10), traffic: (string-ascii 10), curves: (string-ascii 10), hours: uint, active: bool})
(define-map scoreboard {lobby-id: uint, address: principal} {score: uint, rank: uint, sum-rank-factor: uint, rank-factor: uint, rewards: uint, rac: uint, nft: (string-ascii 99)})
(define-data-var lobby-count uint u0)
(define-data-var contract-owner principal tx-sender)
```

{% endcode %}

## Public Functions For Any User

### Lobby Creation

```
;; public functions
;; anyone can create a lobby
(define-public (create-lobby 
  (description (string-ascii 99)) (price uint) (factor uint) (commission uint) 
  (mapy (string-ascii 30)) (length (string-ascii 10)) (traffic (string-ascii 10)) (curves (string-ascii 10)) (hours uint) 
)
    (let (
        (lobby-id (increment-lobby-count))
        )
        ;; (asserts! (is-eq tx-sender (var-get contract-owner)) ERR-NOT-AUTHORIZED)
        (map-set lobbies {id: lobby-id} 
          {
            owner: tx-sender, description: description, balance: u0, price: price, factor: factor, commission: commission, 
            mapy: mapy, length: length, traffic: traffic, curves: curves, hours: hours, active: true
          }
        )
        (try! (join lobby-id))
        (ok lobby-id)
    )
)
```

### Joining a lobby

{% code overflow="wrap" lineNumbers="true" %}

```lisp
;; anyone can join a lobby
(define-public (join (id uint))
    (let (
        (entry-price (default-to DEFAULT-PRICE (get price (map-get? lobbies {id: id}))))
        (joined (map-insert scoreboard {lobby-id: id, address: tx-sender} {score: u0, rank: u0, sum-rank-factor: u0, rank-factor: u0, rewards: u0, rac: u0, nft: ""}))
        )
        (unwrap-panic (map-get? lobbies {id: id}))
        (asserts! (default-to false (get active (map-get? lobbies {id: id}))) ERR-NOT-ACTIVE)
        (asserts! joined ERR-ALREADY-JOINED)
        (add-balance id tx-sender entry-price)
        (print {action: "join", lobby-id: id, address: tx-sender })
        (ok OK-SUCCESS)
    )
)
```

{% endcode %}

## Admin Functions

### Change of Contract Admin

{% code overflow="wrap" lineNumbers="true" %}

```lisp
(define-public (set-owner (new-owner principal))
  (begin
    (asserts! (is-eq tx-sender (var-get contract-owner)) ERR-NOT-AUTHORIZED)
    (var-set contract-owner new-owner)
    (ok true))
)
```

{% endcode %}

### Publish New Highscores On Smart Contract

the new highscores freshly stored on the db are uploaded to the smart contract for full transparency of the data - max 50 per transaction for optimised cost analysis

{% code overflow="wrap" lineNumbers="true" %}

```lisp
(define-public (publish-result-many (run-result (list 50 { lobby-id: uint, address: principal, score: uint, rank: uint, sum-rank-factor: uint, rank-factor: uint, rewards: uint, rac: uint, nft: (string-ascii 99)})))
  (fold check-err
    (map publish-result run-result)
    (ok true)
  )
)
```

{% endcode %}

### Finish a lobby

upload the last highscores to sync the smart contract with the database

{% code overflow="wrap" lineNumbers="true" %}

```lisp
(define-public (finish-result-many  (run-result (list 50 { lobby-id: uint, address: principal, score: uint, rank: uint, sum-rank-factor: uint, rank-factor: uint, rewards: uint, rac: uint, nft: (string-ascii 99)})))
  (fold check-err
    (map finish-result run-result)
    (ok true)
  )
)
```

{% endcode %}

### Disable the lobby after its time is over

{% code overflow="wrap" lineNumbers="true" %}

```lisp
(define-public (disable-lobby (id uint))
    (begin
        (asserts! (is-eq tx-sender (var-get contract-owner)) ERR-NOT-AUTHORIZED)
        (match
        (map-get? lobbies {id: id})
        lobby
        (map-set lobbies {id: id} (merge lobby {active: false}))
        false
        )
        (ok true)
    )
)
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gamefi-stacks.gitbook.io/stacks-degens-gaming-universe/trustless-rewards/smart-contract.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
