# Architecture

## Smart contracts

$PACK Protocol primarily consists of three smart contracts:

### [ProtocolControl.sol](https://github.com/nftlabs/pack-protocol/blob/main/contracts/ProtocolControl.sol)

`ProtocolControl.sol` acts as a control center for the protocol.&#x20;

* It stores the addresses of all modules of the protocol e.g. the protocol's ERC 1155 contract for packs.
* It defines the `PROTOCOL_ADMIN` role, and contains functions to grant or revoke that role.
* It holds the protocol fees collected on every pack and reward sale / resale. This fees an be transferred by addresses having the `PROTOCOL_ADMIN` role.

### [Pack.sol](https://github.com/nftlabs/pack-protocol/blob/main/contracts/Pack.sol)

`Pack.sol` is the [ERC 1155](https://eips.ethereum.org/EIPS/eip-1155) smart contract for packs.

* It contains all logic for creating packs, opening a pack, and distributing rewards to pack openers.
* It inherits [VRFConsumerBase](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.6/VRFConsumerBase.sol) and interacts with [Chainlink VRF](https://docs.chain.link/docs/chainlink-vrf-api-reference/).
* It is an [IERC1155Receiver](https://docs.openzeppelin.com/contracts/4.x/api/token/erc1155#IERC1155Receiver), and holds rewards that haven't been distributed to pack openers.

### [Market.sol](https://github.com/nftlabs/pack-protocol/blob/main/contracts/Market.sol)

`Market.sol` is the protocol's dedicated market contract for packs and rewards.&#x20;

* It enables buying and selling packs and rewards, and distributes a fixed percentage fee to the relevant pack creator, and the protocol, on every pack and reward sale/ resale.

## Main Actions

The protocol has five main actions that can be performed by external actors e.g. pack creators.

* Creating a set of packs.
* Opening a pack.
* Listing packs or rewards for sale.
* Updating the parameters of a pack or reward listing.
* Buying packs or rewards listed for sale.

{% hint style="info" %}
The following gives a high level overview of how the protocol's smart contracts operate when an external actor performs one of these actions. \
\
For a detailed guide on how to perform these actions programmatically, join us at the [NFT Labs discord](https://discord.gg/hxDH4DH9) so we can help you out!\
\
These docs are under construction. We plan to add a section on how to build on $PACK Protocol, soon.
{% endhint %}

### Creating a set of packs

$PACK Protocol recognizes any [ERC 1155](https://eips.ethereum.org/EIPS/eip-1155) token as a reward. An actor creates a set of packs by batch transferring reward tokens to `Pack.sol`, and receiving the relevant packs in return.

![](https://3276703226-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdSPak5YQbbmBeLd2Zm%2F-Mhjk7w6wrZ-E1Gr1dNW%2F-MhjlcUif9YT8mwwbSbM%2Fpp-architecture%20-1.png?alt=media\&token=27bd698e-1a9b-419d-beb2-454a3b029c9e)

ERC 1155 standard's [`safeBatchTransferFrom`](https://docs.openzeppelin.com/contracts/4.x/api/token/erc1155#ERC1155-safeBatchTransferFrom-address-address-uint256---uint256---bytes-) allows passing arbitrary bytes data in the function call. `Pack.sol` expects the caller to encode relevant parameters for creating the set of packs, and pass them in the `safeBatchTransferFrom` call. These parameters are decoded `Pack.sol` to create the desired set of packs.

### Opening a pack

An actor opens a pack by calling the `openPack` function on `Pack.sol`. Opening a pack burns the pack.

![](https://3276703226-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdSPak5YQbbmBeLd2Zm%2F-MhjpAOb1mkWf9VrMnbS%2F-Mhjr5IJg0aCoClY_VqW%2Fpp-architecture%20-2%20\(2\).png?alt=media\&token=6c1feaed-8f0c-4f80-a53f-bb51d2def9aa)

Upon `openPack` being called, `Pack.sol` requests a random number from Chainlink VRF, to be used in determining which reward to distribute to the pack opener. Chainlink VRF fulfills this request with a random number, upon which the relevant reward is distributed to the pack opener.

### Listing packs or rewards for sale

An actor lists packs or rewards they own by calling the `list` function on `Market.sol` with the relevant parameters to set for the listing e.g. price per token listed.

![](https://3276703226-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdSPak5YQbbmBeLd2Zm%2F-MhjrsBGhpUFyiLjRugm%2F-Mhjt3NlKAXjZc7HytOP%2Fpp-architecture%20-3.png?alt=media\&token=6f7d6973-2fe3-4381-82c5-e70f2c582e58)

Listing tokens (packs or rewards) for sale locks the tokens being listed in the `Market.sol` contract.

### Updating the parameters of a pack or reward listing

An actor can update the parameters of their token (pack or reward) listing, e.g. price per token or the currency accepted by the listing, by calling the `updateListingParams` function on `Market.sol`.

![](https://3276703226-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdSPak5YQbbmBeLd2Zm%2F-MhjyK7FA5EZUcTnTJcc%2F-MhjzGkazhcDK1yyjojv%2Fpp-architecture%20-4.png?alt=media\&token=fd62012f-4b72-4bf0-96e6-31adde2cc926)

Updating the parameters of a token listing is a state changing transaction, which requires the caller to pay the requisite gas fees.

### Buying packs or rewards listed for sale

An actor can buy tokens (packs or rewards) listed on sale by calling the `buy` function on `Market.sol`.

![](https://3276703226-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdSPak5YQbbmBeLd2Zm%2F-MhjzS1T1dxccD6iLi0y%2F-Mhk2mDPgj7QCQYsYGad%2Fpp-architecture%20-5%20\(1\).png?alt=media\&token=95fead98-b096-43a9-a1ef-84f75880464b)

2.5% of the total price paid by the buyer is transferred to the creator of the tokens being sold (only if the seller associated with the token listing is not the creator of the tokens). An additional 2.5% of the total price is transferred to `ProtocolControl.sol` as a fee. The remainder is transferred to the seller associated with the token listing.


---

# 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://nkrishang.gitbook.io/pack-protocol/technical-reference/architecture.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.
