> For the complete documentation index, see [llms.txt](https://gamefi-stacks.gitbook.io/stacks-degens-gaming-universe/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gamefi-stacks.gitbook.io/stacks-degens-gaming-universe/trustless-rewards/smart-contract.md).

# 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 %}
