# Prize Splits

## Introduction

The prize split features (introduced in v3.4.0) allows contract owners to designate a percentage of the awarded prize to a fixed wallet address in every draw period. In other words, prize pools can now directly award a wallet, whether that's a charity organization, prize pool manager, decentralized autonomous organization or any unique combination of prize splits every time a draw occurs.

### Example

#### Setup

**Prize Award:** $10,000 USDC\
**Loot Box:** $2,500 COMP \
**Number of Winners:** 3\
**Prize Splits:** \
&#x20;  \- 5% Sponsorship to Gitcoin Developer\
&#x20;  \- 5% Ticket to PrizePool manager

#### Outcome

**Main Winner:** $3,000 and Loot Box ($2,500)\
**Secondary Winners:** $3,000\
**Prize Splits:** \
&#x20;   \- $500 to Gitcoin Developer Address\
&#x20;   \- $500 to PrizePool manager

#### Code

```
PrizeSplitConfig {
  target: 0x0000000000000000000000000000000000000000 // Gitcoin Wallet
  percentage: 50 // 5%
  token: 1 // Sponsorship Token
}

PrizeSplitConfig {
  target: 0x0000000000000000000000000000000000000001 // Owner Wallet 
  percentage: 50 // 5%
  token: 0 // Ticket Token
}
```

## How It Works

The prize split configuration is an **abstract contract** inherited by any PrizePool smart contract. The PrizeSplit.sol smart contract is a minimal smart contract with limited external functions and a single primary `internal` function named `_distributePrizeSplits` which should be called at the top of the inheriting smart contracts `_distribute` function.

**Public Functions**

* `setPrizeSplits`
* `setPrizeSplit`

**Primary Internal Functions**

* `_distributePrizeSplits`

**Helper Internal Functions**

* `_getPrizeSplitAmount`
* `_totalPrizeSplitPercentageAmount`

### Prize Split Config (PrizeSplitConfig)

Prize split configurations are saved in a PrizeSplitConfig struct and stored in the internal \_prizeSplits array. During the award distribution (before awarding the winners) prize split recipients are awarded the designated token type (Ticket or Sponsorship). After the recipients have been awarded, the remaining updated prize award amount is distributed to the winners.

### Prize Splits Configuration

Each prize splits is stored in a `PrizeSplitConfig` struct with 3 configurable variables: target, percentage and token. The `target` variable designates the receiver of the prize split. The `percentage` variable stores single point decimal precision percentage using a number with a range between 0-to-1000. And finally the `token` parameter references the index position of the `ControlledToken` in the `PrizePool.tokens` array.

```
PrizeSplits.sol
---------------

struct PrizeSplitConfig {
  address target;
  uint16 percentage;
  uint8 token;
}
```

Target is self-explanatory, but percentage and token require a deeper understanding of percentages are calculated and how an external contract stores token references.

#### Percentage &#x20;

The `percentage` uses a range of 0-to-1000 so single decimal precision can easily be calculated without requiring a fixed point math library.

```
PrizeSplits.sol
---------------

function _getPrizeSplitAmount(uint256 amount, uint16 percentage) internal pure returns (uint256) {
  return (amount * percentage).div(1000);
}
```

When calculating a prize split distribution amount, the result of totalPrizeAmount \* prizeSplitPercentage  is divided by 1,000. Thus if the prize split percentage is set to `1000` than the distribution amount would result in 100% of the prize being awarded to the prize split. If the the prize split percentage is set to `505` distribution amount would equate to `50.5%` of the original award amount.&#x20;

#### Token

If using the `PoolWithMultipleWinnersBuilder.sol` instance to deploy a new PrizePool, the first token stored in the `tokens` array is the `Ticket` and the second is the `Sponsorship` token. Thus, when deciding which token is minted during the prize split distribution, the `token` variable must be set to either `0` or `1` depending on the desired  ticket to be awarded.

```
PoolWithMultipleWinnersBuilder.sol
----------------------------------

function _tokens(MultipleWinners _multipleWinners) internal view returns (ControlledTokenInterface[] memory) {
  ControlledTokenInterface[] memory tokens = new ControlledTokenInterface[](2);
  tokens[0] = ControlledTokenInterface(address(_multipleWinners.ticket()));
  tokens[1] = ControlledTokenInterface(address(_multipleWinners.sponsorship()));
  return tokens;
}

```

## Awarding the Prize Splits

Before the draw winners are award `Tickets` the prize splits must first be distributed, so the remaining prize award amount can be used to calculate the winners distribution amount.

Thus when the `_distribute` function is called within `MultipleWinners.sol` (*responsible for capturing the interest earned during that award period*) the captured award balance is immediately passed into the internal`_distributePrizeSplits` function. Distributing the prize splits to target recipients and returning the updated `prize` amount for winner award distribution.

```
MultipleWinners.sol
-------------------

function _distribute(uint256 randomNumber) internal override {
  uint256 prize = prizePool.captureAwardBalance();
  
  // distributes prize to prize splits and returns remaining award.
  prize = _distributePrizeSplits(prize);

  if (IERC20Upgradeable(address(ticket)).totalSupply() == 0) {
    emit NoWinners();
    return;
  }

  ...
}
```


---

# 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://v3.docs.pooltogether.com/protocol/prize-splits.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.
