# Introduction

[![PoolTogether Brand](https://github.com/pooltogether/pooltogether--brand-assets/blob/977e03604c49c63314450b5d432fe57d34747c66/logo/pooltogether-logo--purple-gradient.png?raw=true)](https://github.com/pooltogether/pooltogether--brand-assets)

## ✨ Introduction

PoolTogether is a protocol for no-loss prize games on the Ethereum blockchain. The protocol:

**1) Enables developers to build their own no-loss prize games**\
**2)** **Offers governance-managed no-loss prize games**

Prize games are pools of funds whose accrued interest is distributed as prizes. The concept is well-established and otherwise known as "[no loss lotteries](http://beniverson.org/papers/MaMa.pdf)" or "[prize savings accounts](https://en.wikipedia.org/wiki/Prize-linked_savings_account)". All prize games created by the protocol share the same key characteristics:

* No loss of deposited funds
* Ability to withdraw at any time
* Fair prize distribution according to a prize strategy

Prize games can be differentiated in the following ways:

* The yield source the prize pool uses to generate no loss return
* The prize strategy used to determine frequency and distribution of prizes&#x20;
* The additional rewards offered by the prize pool
* The asset type the prize pool accepts for deposits&#x20;
* The fairness parameters&#x20;

### Governance

The PoolTogether Protocol governance serves two primary functions.

* Governing the prize pool creation tools
* Governing a sub-set of prize pools

The protocol governed prize pools appear on the official [PoolTogether App](https://app-v3.pooltogether.com). Governance is currently the core PoolTogether team, but very soon governance control will be distributed amongst protocol stakeholders.


# Contracts

Official deployed PoolTogether contracts

PoolTogether is currently deployed to:

* [Ethereum](/resources/networks/ethereum)
* [Celo](/resources/networks/celo#celo)
* [Matic](/resources/networks/matic)


# Ethereum

## Mainnet

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.7.1** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract                         | Address                                                                                                               |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Dai Prize Pool                   | [0xEBfb47A7ad0FD6e57323C8A42B2E5A6a4F68fc1a](https://etherscan.io/address/0xEBfb47A7ad0FD6e57323C8A42B2E5A6a4F68fc1a) |
| Dai Prize Strategy               | [0x178969A87a78597d303C47198c66F68E8be67Dc2](https://etherscan.io/address/0x178969A87a78597d303C47198c66F68E8be67Dc2) |
| Dai Pod                          | [0x2f994e2E4F3395649eeE8A89092e63Ca526dA829](https://etherscan.io/address/0x2f994e2E4F3395649eeE8A89092e63Ca526dA829) |
| USDC Prize Pool                  | [0xde9ec95d7708b8319ccca4b8bc92c0a3b70bf416](https://etherscan.io/address/0xde9ec95d7708b8319ccca4b8bc92c0a3b70bf416) |
| USDC Prize Strategy              | [0x3d9946190907ada8b70381b25c71eb9adf5f9b7b](https://etherscan.io/address/0x3d9946190907ada8b70381b25c71eb9adf5f9b7b) |
| USDC Pod                         | [0x386EB78f2eE79AddE8Bdb0a0e27292755ebFea58](https://etherscan.io/address/0x386EB78f2eE79AddE8Bdb0a0e27292755ebFea58) |
| UNI Prize Pool                   | [0x0650d780292142835F6ac58dd8E2a336e87b4393](https://etherscan.io/address/0x0650d780292142835F6ac58dd8E2a336e87b4393) |
| UNI Prize Strategy               | [0xe8726B85236a489a8E84C56c95790d07a368f913](https://etherscan.io/address/0xe8726B85236a489a8E84C56c95790d07a368f913) |
| COMP Prize Pool                  | [0xBC82221e131c082336cf698F0cA3EBd18aFd4ce7](https://etherscan.io/address/0xBC82221e131c082336cf698F0cA3EBd18aFd4ce7) |
| COMP Prize Strategy              | [0x3ec4694b65e41f12d6b5d5ba7c2341f4d6859773](https://etherscan.io/address/0x3ec4694b65e41f12d6b5d5ba7c2341f4d6859773) |
| GUSD Prize Pool                  | [0x65C8827229FbD63f9de9FDfd400C9D264066A336](https://etherscan.io/address/0x65C8827229FbD63f9de9FDfd400C9D264066A336) |
| GUSD Prize Strategy              | [0x821cF440654addD81493e1949F9ee078D65bb57f](https://etherscan.io/address/0x821cF440654addD81493e1949F9ee078D65bb57f) |
| POOL Prize Pool                  | [0x396b4489da692788e327e2e4b2b0459a5ef26791](https://etherscan.io/address/0x396b4489da692788e327e2e4b2b0459a5ef26791) |
| POOL Prize Strategy              | [0x21e5e62e0b6b59155110cd36f3f6655fbbcf6424](https://etherscan.io/address/0x21e5e62e0b6b59155110cd36f3f6655fbbcf6424) |
| Loot Box ERC721                  | [0x4d695c615a7AACf2d7b9C481B66045BB2457Dfde](https://etherscan.io/address/0x4d695c615a7AACf2d7b9C481B66045BB2457Dfde) |
| Loot Box Prize Strategy Listener | [0xfe7205DF55BA42c8801e44B55BF05F06cCe8565E](https://etherscan.io/address/0xfe7205DF55BA42c8801e44B55BF05F06cCe8565E) |
| Aave USDT Prize Pool             | [0xc7d56c06F136EFff93e349C7BF8cc46bBF5D902c](https://etherscan.io/address/0xc7d56c06F136EFff93e349C7BF8cc46bBF5D902c) |
| Aave USDT Prize Strategy         | [0x2223d2e68e0990567f5e0451f4c027870ea07227](https://etherscan.io/address/0x2223d2e68e0990567f5e0451f4c027870ea07227) |
| Sushi Prize Pool                 | [0xc32a0f9dfe2d93e8a60ba0200e033a59aec91559](https://etherscan.io/address/0xc32a0f9dfe2d93e8a60ba0200e033a59aec91559) |
| Sushi Prize Strategy             | [0x94ac4f591908ad5a1ccc9e05d2d75b0dd62d97fa](https://etherscan.io/address/0x94ac4f591908ad5a1ccc9e05d2d75b0dd62d97fa) |
| USDT Prize Pool                  | [0x481f1BA81f7C01400831DfF18215961C3530D118](https://etherscan.io/address/0x481f1BA81f7C01400831DfF18215961C3530D118) |
| USDT Prize Strategy              | [0xc0fcdb4d882c28238cbcfbb023f87a7a7a1bdaa1](https://etherscan.io/address/0xc0fcdb4d882c28238cbcfbb023f87a7a7a1bdaa1) |
| Uniswap POOL LP Prize Pool       | [0x3AF7072D29Adde20FC7e173a7CB9e45307d2FB0A](https://etherscan.io/address/0x3AF7072D29Adde20FC7e173a7CB9e45307d2FB0A) |
| Reserve Registry                 | [0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295](https://etherscan.io/address/0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295) |
| Pod Factory                      | [0x4e3a9F9fBAFB2EC49727cFfa2a411F7a0C1C4cE1](https://etherscan.io/address/0x4e3a9F9fBAFB2EC49727cFfa2a411F7a0C1C4cE1) |

### Configurable Reserve

**@pooltogether/configurable-reserve-contracts ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/configurable-reserve-contracts)

| Contract                                                                                                                            | Address                                                                                                               | Artifact                                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| [ConfigurableReserve](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/contracts/ConfigurableReserve.sol) | [0xd1797D46C3E825fce5215a0259D3426a5c49455C](https://etherscan.io/address/0xd1797D46C3E825fce5215a0259D3426a5c49455C) | [Artifact](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/deployments/mainnet/ConfigurableReserve.json) |

### Governance

**@pooltogether/governance ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/governance)

| Contract                                                                                          | Address                                                                                                               | Artifact                                                                                                            |
| ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [GovernorAlpha](https://github.com/pooltogether/governance/tree/main/contracts/GovernorAlpha.sol) | [0xB3a87172F555ae2a2AB79Be60B336D2F7D0187f0](https://etherscan.io/address/0xB3a87172F555ae2a2AB79Be60B336D2F7D0187f0) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/GovernorAlpha.json)             |
| [Pool](https://github.com/pooltogether/governance/tree/main/contracts/Pool.sol)                   | [0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e](https://etherscan.io/address/0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/Pool.json)                      |
| [Timelock](https://github.com/pooltogether/governance/tree/main/contracts/Timelock.sol)           | [0x42cd8312D2BCe04277dD5161832460e95b24262E](https://etherscan.io/address/0x42cd8312D2BCe04277dD5161832460e95b24262E) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/Timelock.json)                  |
| TreasuryVesterForTreasury                                                                         | [0x21950E281bDE1714ffd1062ed17c56D4D8de2359](https://etherscan.io/address/0x21950E281bDE1714ffd1062ed17c56D4D8de2359) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/TreasuryVesterForTreasury.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.3.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                               | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xb1D89477d1b505C261bab6e73f08fA834544CD21](https://etherscan.io/address/0xb1D89477d1b505C261bab6e73f08fA834544CD21) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mainnet/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F](https://etherscan.io/address/0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mainnet/RNGChainlink.json) |

### Loot Box Contracts

**@pooltogether/loot-box ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/loot-box)

| Contract                                                                                                                                    | Address                                                                                                               | Artifact                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [ERC721ControlledFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/ERC721ControlledFactory.sol)                         | [0x4E869b3A0978fA61DAbd7Da8F9B272AADc745Fb3](https://etherscan.io/address/0x4E869b3A0978fA61DAbd7Da8F9B272AADc745Fb3) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/ERC721ControlledFactory.json)             |
| [LootBoxController](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxController.sol)                                     | [0x2c2a966b7F5448A36EC9f896088DfB99B21d8A24](https://etherscan.io/address/0x2c2a966b7F5448A36EC9f896088DfB99B21d8A24) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/LootBoxController.json)                   |
| [LootBoxPrizeStrategyListenerFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxPrizeStrategyListenerFactory.sol) | [0x25e6a78D93D2935A638fDbd684e7b39565d0B7eA](https://etherscan.io/address/0x25e6a78D93D2935A638fDbd684e7b39565d0B7eA) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/LootBoxPrizeStrategyListenerFactory.json) |

### Retroactive Token Distribution

**@pooltogether/merkle-distributor ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/merkle-distributor)

| Contract                                                                                                          | Address                                                                                                               | Artifact                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [MerkleDistributor](https://github.com/pooltogether/merkle-distributor/tree/main/contracts/MerkleDistributor.sol) | [0xBE1a33519F586A4c8AA37525163Df8d67997016f](https://etherscan.io/address/0xBE1a33519F586A4c8AA37525163Df8d67997016f) | [Artifact](https://github.com/pooltogether/merkle-distributor/tree/main/deployments/mainnet/MerkleDistributor.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                               | Artifact                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0x14e09c3319244a84e7c1E7B52634f5220FA96623](https://etherscan.io/address/0x14e09c3319244a84e7c1E7B52634f5220FA96623) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/mainnet/GenericProxyFactory.json) |

### Prize Pool Registry

**@pooltogether/pooltogether-prizepool-registry ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizepool-registry)

| Contract        | Address                                                                                                               | Artifact                                                                                                                       |
| --------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| AddressRegistry | [0x34733851E2047F8d0e1aa91124A6f9EaDc54D253](https://etherscan.io/address/0x34733851E2047F8d0e1aa91124A6f9EaDc54D253) | [Artifact](https://github.com/pooltogether/pooltogether-prizepool-registry/tree/main/deployments/mainnet/AddressRegistry.json) |

### Pods Registry

**@pooltogether/pooltogether-pods-registry ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-registry)

| Contract     | Address                                                                                                               | Artifact                                                                                                                    |
| ------------ | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| PodsRegistry | [0x4658f736b93dCDdCbCe46cDe955970E697fd351f](https://etherscan.io/address/0x4658f736b93dCDdCbCe46cDe955970E697fd351f) | [Artifact](https://github.com/pooltogether/pooltogether-prizepool-registry/tree/main/deployments/mainnet/PodsRegistry.json) |

### Prize Strategy Upkeep

**@pooltogether/pooltogether-prizestrategy-upkeep ^1.0.6** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizestrategy-upkeep)

| Contract                                                                                                                             | Address                                                                                                               | Artifact                                                                                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| [PrizeStrategyUpkeep](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/contracts/PrizeStrategyUpkeep.sol) | [0xb9D70C3d7E4453Cc679D8A91145a28782268f229](https://etherscan.io/address/0xb9D70C3d7E4453Cc679D8A91145a28782268f229) | [Artifact](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/deployments/mainnet/PrizeStrategyUpkeep.json) |

### Pods Upkeep

**@pooltogether/pooltogether-pods-upkeep ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-upkeep)

| Contract                                                                                                    | Address                                                                                                               | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [PodsUpkeep](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/contracts/PodsUpkeep.sol) | [0x6c87C9960fac84F31AEc88964cA1270C70Ca6853](https://etherscan.io/address/0x6c87C9960fac84F31AEc88964cA1270C70Ca6853) | [Artifact](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/deployments/mainnet/PodsUpkeep.json) |

### Aave Yield Source

**@pooltogether/aave-yield-source ^1.0.3** [**npm**](https://www.npmjs.com/package/@pooltogether/aave-yield-source)

| Contract                                                                                                                      | Address                                                                                                               | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| AaveBUSDYieldSource                                                                                                           | [0x858415FdB262F17F7a63f6B1F6fEd7AF8308A1A7](https://etherscan.io/address/0x858415FdB262F17F7a63f6B1F6fEd7AF8308A1A7) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/AaveBUSDYieldSource.json) |
| AaveGUSDYieldSource                                                                                                           | [0x2bA1e000a381aD42af10C6e33aFe5994eE878D72](https://etherscan.io/address/0x2bA1e000a381aD42af10C6e33aFe5994eE878D72) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/AaveGUSDYieldSource.json) |
| AaveSUSDYieldSource                                                                                                           | [0x4C8D99B0c7022923ef1A81ADb4E4e326f8E91ac9](https://etherscan.io/address/0x4C8D99B0c7022923ef1A81ADb4E4e326f8E91ac9) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/AaveSUSDYieldSource.json) |
| AaveUSDTYieldSource                                                                                                           | [0x6E159B199423383572B7CB05FBbD54103A827F2b](https://etherscan.io/address/0x6E159B199423383572B7CB05FBbD54103A827F2b) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/AaveUSDTYieldSource.json) |
| [ATokenYieldSource](https://github.com/pooltogether/aave-yield-source/tree/main/contracts/yield-source/ATokenYieldSource.sol) | [0xBa71a9907e88925F59a3658C3a7618440Df6406E](https://etherscan.io/address/0xBa71a9907e88925F59a3658C3a7618440Df6406E) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/ATokenYieldSource.json)   |

### Sushi Yield Source

**@pooltogether/pooltogether-sushi-yield-source ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-sushi-yield-source)

| Contract                                                                                                          | Address                                                                                                               | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [SushiYieldSource](https://github.com/pooltogether/sushi-pooltogether/tree/master/contracts/SushiYieldSource.sol) | [0x9858aC37e385E52dA6385d828Cfe55a182D8ffA6](https://etherscan.io/address/0x9858aC37e385E52dA6385d828Cfe55a182D8ffA6) | [Artifact](https://github.com/pooltogether/sushi-pooltogether/tree/master/deployments/mainnet/SushiYieldSource.json) |

### EVM Bridge

**@pooltogether/pooltogether-evm-bridge ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-evm-bridge)

| Contract                                                                                                                                 | Address                                                                                                               | Artifact                                                                                                                           |
| ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| [PoolTogetherEVMBridgeRoot](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/contracts/PoolTogetherEVMBridgeRoot.sol) | [0xfe6c5Ae087366A7119f12946d07E04C94BB7A048](https://etherscan.io/address/0xfe6c5Ae087366A7119f12946d07E04C94BB7A048) | [Artifact](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/deployments/mainnet/PoolTogetherEVMBridgeRoot.json) |

### Multi Token Listener

**@pooltogether/multi-token-listener ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/multi-token-listener)

| Contract                                                                                                                | Address                                                                                                               | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [MultiTokenListener](https://github.com/pooltogether/multi-token-listener/tree/master/contracts/MultiTokenListener.sol) | [0x04458bA489cFa284ED8A693e3bea3e1DF600d022](https://etherscan.io/address/0x04458bA489cFa284ED8A693e3bea3e1DF600d022) | [Artifact](https://github.com/pooltogether/multi-token-listener/tree/master/deployments/mainnet/MultiTokenListener.json) |

## Rinkeby

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.7.1** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract            | Address                                                                                                                       |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Dai Prize Pool      | [0x4706856FA8Bb747D50b4EF8547FE51Ab5Edc4Ac2](https://rinkeby.etherscan.io/address/0x4706856FA8Bb747D50b4EF8547FE51Ab5Edc4Ac2) |
| Dai Prize Strategy  | [0x5E0A6d336667EACE5D1b33279B50055604c3E329](https://rinkeby.etherscan.io/address/0x5E0A6d336667EACE5D1b33279B50055604c3E329) |
| Dai Pod             | [0x4A26b34A902045CFb573aCb681550ba30AA79783](https://rinkeby.etherscan.io/address/0x4A26b34A902045CFb573aCb681550ba30AA79783) |
| USDC Prize Pool     | [0xde5275536231eCa2Dd506B9ccD73C028e16a9a32](https://rinkeby.etherscan.io/address/0xde5275536231eCa2Dd506B9ccD73C028e16a9a32) |
| USDC Prize Strategy | [0x1b92BC2F339ef25161711e4EafC31999C005aF21](https://rinkeby.etherscan.io/address/0x1b92BC2F339ef25161711e4EafC31999C005aF21) |
| USDC Pod            | [0x68c96179Cf9a90C589571Dc7AA94AD15d94e917d](https://rinkeby.etherscan.io/address/0x68c96179Cf9a90C589571Dc7AA94AD15d94e917d) |
| BAT Prize Pool      | [0xab068F220E10eEd899b54F1113dE7E354c9A8eB7](https://rinkeby.etherscan.io/address/0xab068F220E10eEd899b54F1113dE7E354c9A8eB7) |
| BAT Prize Strategy  | [0x41CF0758b7Cc2394b1C2dfF6133FEbb0Ef317C3b](https://rinkeby.etherscan.io/address/0x41CF0758b7Cc2394b1C2dfF6133FEbb0Ef317C3b) |
| Loot Box ERC721     | [0xfbC6677806253dB9739d0F6CBD89b9e7Ed4A5c66](https://rinkeby.etherscan.io/address/0xfbC6677806253dB9739d0F6CBD89b9e7Ed4A5c66) |
| USDT Prize Pool     | [0xDCB24C5C96D3D0677add5B688DCD144601410244](https://rinkeby.etherscan.io/address/0xDCB24C5C96D3D0677add5B688DCD144601410244) |
| USDT Prize Strategy | [0x1607ce8aDe05C324043D7f5362A6d856cd4Ae589](https://rinkeby.etherscan.io/address/0x1607ce8aDe05C324043D7f5362A6d856cd4Ae589) |
| Pod Factory         | [0x5C126F8F6107b2da41dAA8b7E4c3f4a01098A6db](https://rinkeby.etherscan.io/address/0x5C126F8F6107b2da41dAA8b7E4c3f4a01098A6db) |

### Builders

**@pooltogether/pooltogether-contracts ^3.4.5** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                                           | Address                                                                                                                       | Artifact                                                                                                                                      |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| cDaiYieldSource                                                                                                                                                                    | [0x14B9165F881D0a13a8001181440b35aB615fC7b2](https://rinkeby.etherscan.io/address/0x14B9165F881D0a13a8001181440b35aB615fC7b2) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/cDaiYieldSource.json)                  |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/ControlledTokenBuilder.sol)                                    | [0xbe7F1F1E4BF65C465153AbbB4629D4FB0758c292](https://rinkeby.etherscan.io/address/0xbe7F1F1E4BF65C465153AbbB4629D4FB0758c292) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/ControlledTokenBuilder.json)           |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/MultipleWinnersBuilder.sol)                                    | [0x1020C38d8fa2ce7aF3235e7Dfbf974aC046bCb24](https://rinkeby.etherscan.io/address/0x1020C38d8fa2ce7aF3235e7Dfbf974aC046bCb24) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/MultipleWinnersBuilder.json)           |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/PoolWithMultipleWinnersBuilder.sol)                    | [0xB852Bb662B692146BEC334A9E91C8e2e6e64FCdc](https://rinkeby.etherscan.io/address/0xB852Bb662B692146BEC334A9E91C8e2e6e64FCdc) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/PoolWithMultipleWinnersBuilder.json)   |
| [TokenFaucetProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/token-faucet/TokenFaucetProxyFactory.sol)                              | [0x08dBBD18DBfAb1396B5Dc542E975E0219DA498c9](https://rinkeby.etherscan.io/address/0x08dBBD18DBfAb1396B5Dc542E975E0219DA498c9) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/TokenFaucetProxyFactory.json)          |
| [YieldSourcePrizePoolProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/prize-pool/yield-source/YieldSourcePrizePoolProxyFactory.sol) | [0xD6073119B123859A0e390865A5630E0bB4E2670C](https://rinkeby.etherscan.io/address/0xD6073119B123859A0e390865A5630E0bB4E2670C) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/YieldSourcePrizePoolProxyFactory.json) |

### Governance

**@pooltogether/governance ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/governance)

| Contract                                                                                          | Address                                                                                                                       | Artifact                                                                                                            |
| ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [GovernorAlpha](https://github.com/pooltogether/governance/tree/main/contracts/GovernorAlpha.sol) | [0x9B63243CD27102fbEc9FAf67CA1a858dcC16Ee01](https://rinkeby.etherscan.io/address/0x9B63243CD27102fbEc9FAf67CA1a858dcC16Ee01) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/GovernorAlpha.json)             |
| [Pool](https://github.com/pooltogether/governance/tree/main/contracts/Pool.sol)                   | [0xc4E90a8Dc6CaAb329f08ED3C8abc6b197Cf0F40A](https://rinkeby.etherscan.io/address/0xc4E90a8Dc6CaAb329f08ED3C8abc6b197Cf0F40A) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/Pool.json)                      |
| [Timelock](https://github.com/pooltogether/governance/tree/main/contracts/Timelock.sol)           | [0x8Df0AfB54836dc8D0AE795503F837Cff197d3df1](https://rinkeby.etherscan.io/address/0x8Df0AfB54836dc8D0AE795503F837Cff197d3df1) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/Timelock.json)                  |
| TreasuryVesterForTreasury                                                                         | [0x529a916B8B7EC8E01805D45AEd1109C764ea88B9](https://rinkeby.etherscan.io/address/0x529a916B8B7EC8E01805D45AEd1109C764ea88B9) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/TreasuryVesterForTreasury.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.3.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                       | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xA932e74d5263A754Ea04432E5c53658434b0484B](https://rinkeby.etherscan.io/address/0xA932e74d5263A754Ea04432E5c53658434b0484B) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/rinkeby/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0x11D94431718934868C4339aFc5ea27585F46C99A](https://rinkeby.etherscan.io/address/0x11D94431718934868C4339aFc5ea27585F46C99A) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/rinkeby/RNGChainlink.json) |

### Loot Box Contracts

**@pooltogether/loot-box ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/loot-box)

| Contract                                                                                                                                    | Address                                                                                                                       | Artifact                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [ERC1155Mintable](https://github.com/pooltogether/loot-box/tree/main/contracts/test/ERC1155Mintable.sol)                                    | [0x72De7A75Fb7c094e410205aFAF9615E7dAA120b3](https://rinkeby.etherscan.io/address/0x72De7A75Fb7c094e410205aFAF9615E7dAA120b3) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC1155Mintable.json)                     |
| [ERC20Mintable](https://github.com/pooltogether/loot-box/tree/main/contracts/test/ERC20Mintable.sol)                                        | [0xdD1cba915Be9c7a1e60c4B99DADE1FC49F67f80D](https://rinkeby.etherscan.io/address/0xdD1cba915Be9c7a1e60c4B99DADE1FC49F67f80D) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC20Mintable.json)                       |
| [ERC721ControlledFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/ERC721ControlledFactory.sol)                         | [0x1D90F79a8515F63881075Ec2C212e18272aD9E38](https://rinkeby.etherscan.io/address/0x1D90F79a8515F63881075Ec2C212e18272aD9E38) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC721ControlledFactory.json)             |
| [ERC721Mintable](https://github.com/pooltogether/loot-box/tree/main/contracts/test/ERC721Mintable.sol)                                      | [0x0F5963607bE6f255549cA684F01ff1D7FC6d3B0B](https://rinkeby.etherscan.io/address/0x0F5963607bE6f255549cA684F01ff1D7FC6d3B0B) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC721Mintable.json)                      |
| [ERC777Mintable](https://github.com/pooltogether/loot-box/tree/main/contracts/test/ERC777Mintable.sol)                                      | [0x8c26F9526a0b9639Edb7080dFba596e8FeFafAcC](https://rinkeby.etherscan.io/address/0x8c26F9526a0b9639Edb7080dFba596e8FeFafAcC) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC777Mintable.json)                      |
| [LootBoxController](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxController.sol)                                     | [0xb1EAc75da9bc31B078742C5AF9EDe62EFE31299D](https://rinkeby.etherscan.io/address/0xb1EAc75da9bc31B078742C5AF9EDe62EFE31299D) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/LootBoxController.json)                   |
| [LootBoxPrizeStrategyListenerFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxPrizeStrategyListenerFactory.sol) | [0xadB4D93D84b18b5D82063aCf58b21587c92fdfb5](https://rinkeby.etherscan.io/address/0xadB4D93D84b18b5D82063aCf58b21587c92fdfb5) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/LootBoxPrizeStrategyListenerFactory.json) |

### Retroactive Token Distribution

**@pooltogether/merkle-distributor ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/merkle-distributor)

| Contract                                                                                                          | Address                                                                                                                       | Artifact                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [MerkleDistributor](https://github.com/pooltogether/merkle-distributor/tree/main/contracts/MerkleDistributor.sol) | [0x93a6540DcE05a4A5E5B906eB97bBCBb723768F2D](https://rinkeby.etherscan.io/address/0x93a6540DcE05a4A5E5B906eB97bBCBb723768F2D) | [Artifact](https://github.com/pooltogether/merkle-distributor/tree/main/deployments/rinkeby/MerkleDistributor.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                                       | Artifact                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0x594069c560D260F90C21Be25fD2C8684efbb5628](https://rinkeby.etherscan.io/address/0x594069c560D260F90C21Be25fD2C8684efbb5628) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/rinkeby/GenericProxyFactory.json) |

### Prize Pool Registry

**@pooltogether/pooltogether-prizepool-registry ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizepool-registry)

| Contract        | Address                                                                                                                       | Artifact                                                                                                                       |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| AddressRegistry | [0xF76f17682888a738a6DF40aa63ac2b4B1a380831](https://rinkeby.etherscan.io/address/0xF76f17682888a738a6DF40aa63ac2b4B1a380831) | [Artifact](https://github.com/pooltogether/pooltogether-prizepool-registry/tree/main/deployments/rinkeby/AddressRegistry.json) |

### Pods Registry

**@pooltogether/pooltogether-pods-registry ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-registry)

| Contract     | Address                                                                                                                       | Artifact                                                                                                                    |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| PodsRegistry | [0xB917f266424B803F389c79B86609710247a0370f](https://rinkeby.etherscan.io/address/0xB917f266424B803F389c79B86609710247a0370f) | [Artifact](https://github.com/pooltogether/pooltogether-prizepool-registry/tree/main/deployments/rinkeby/PodsRegistry.json) |

### Prize Strategy Upkeep

**@pooltogether/pooltogether-prizestrategy-upkeep ^1.0.6** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizestrategy-upkeep)

| Contract                                                                                                                             | Address                                                                                                                       | Artifact                                                                                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| [PrizeStrategyUpkeep](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/contracts/PrizeStrategyUpkeep.sol) | [0x3fBCb09Ee774F7e32Ba4D60d1E2D4CB9CE703984](https://rinkeby.etherscan.io/address/0x3fBCb09Ee774F7e32Ba4D60d1E2D4CB9CE703984) | [Artifact](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/deployments/rinkeby/PrizeStrategyUpkeep.json) |

### Pods Upkeep

**@pooltogether/pooltogether-pods-upkeep ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-upkeep)

| Contract                                                                                                    | Address                                                                                                                       | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [PodsUpkeep](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/contracts/PodsUpkeep.sol) | [0x3F861649a7517af171ff845a5cb7aE6ACeEbd6aA](https://rinkeby.etherscan.io/address/0x3F861649a7517af171ff845a5cb7aE6ACeEbd6aA) | [Artifact](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/deployments/rinkeby/PodsUpkeep.json) |

### Sushi Yield Source

**@pooltogether/pooltogether-sushi-yield-source ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-sushi-yield-source)

| Contract                                                                                                          | Address                                                                                                                       | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [SushiYieldSource](https://github.com/pooltogether/sushi-pooltogether/tree/master/contracts/SushiYieldSource.sol) | [0x248FCb04de8901c32e0815349f071542556cCF91](https://rinkeby.etherscan.io/address/0x248FCb04de8901c32e0815349f071542556cCF91) | [Artifact](https://github.com/pooltogether/sushi-pooltogether/tree/master/deployments/rinkeby/SushiYieldSource.json) |

### Multi Token Listener

**@pooltogether/multi-token-listener ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/multi-token-listener)

| Contract                                                                                                                | Address                                                                                                                       | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [MultiTokenListener](https://github.com/pooltogether/multi-token-listener/tree/master/contracts/MultiTokenListener.sol) | [0xDC78901e0FC2097B07008f98Fb28F57fBA0a2CB7](https://rinkeby.etherscan.io/address/0xDC78901e0FC2097B07008f98Fb28F57fBA0a2CB7) | [Artifact](https://github.com/pooltogether/multi-token-listener/tree/master/deployments/rinkeby/MultiTokenListener.json) |

## Kovan

### Builders

**@pooltogether/pooltogether-contracts ^3.4.5** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                                           | Address                                                                                                                     | Artifact                                                                                                                                    |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| cDaiYieldSource                                                                                                                                                                    | [0x6aeBE10a4607B1002ea56D825Ee18Ce751fD9592](https://kovan.etherscan.io/address/0x6aeBE10a4607B1002ea56D825Ee18Ce751fD9592) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/cDaiYieldSource.json)                  |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/ControlledTokenBuilder.sol)                                    | [0x17445F57ea2779dDa88Fce2bc4f58a245F9013DC](https://kovan.etherscan.io/address/0x17445F57ea2779dDa88Fce2bc4f58a245F9013DC) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/ControlledTokenBuilder.json)           |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/MultipleWinnersBuilder.sol)                                    | [0xF516710Cc8C23b1477C2716A996DF99b2858FDC8](https://kovan.etherscan.io/address/0xF516710Cc8C23b1477C2716A996DF99b2858FDC8) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/MultipleWinnersBuilder.json)           |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/PoolWithMultipleWinnersBuilder.sol)                    | [0xEccfB4F7aB44effE457e399cebAa04A95a9061d8](https://kovan.etherscan.io/address/0xEccfB4F7aB44effE457e399cebAa04A95a9061d8) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/PoolWithMultipleWinnersBuilder.json)   |
| [TokenFaucetProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/token-faucet/TokenFaucetProxyFactory.sol)                              | [0xdE55668e38FEcD037BFA40AcFD7d30e58F9143D4](https://kovan.etherscan.io/address/0xdE55668e38FEcD037BFA40AcFD7d30e58F9143D4) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/TokenFaucetProxyFactory.json)          |
| [YieldSourcePrizePoolProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/prize-pool/yield-source/YieldSourcePrizePoolProxyFactory.sol) | [0x941011a95ad6a69d3b06218A3b74a3f6296481A8](https://kovan.etherscan.io/address/0x941011a95ad6a69d3b06218A3b74a3f6296481A8) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/YieldSourcePrizePoolProxyFactory.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.3.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                     | Artifact                                                                                                               |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xe20ba80D263246537592B14211746E438be6b756](https://kovan.etherscan.io/address/0xe20ba80D263246537592B14211746E438be6b756) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/kovan/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0x0FcEDB079E56F336840Aa0c0f20816CcE7de63B6](https://kovan.etherscan.io/address/0x0FcEDB079E56F336840Aa0c0f20816CcE7de63B6) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/kovan/RNGChainlink.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                                     | Artifact                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0x713edC7728C4F0BCc135D48fF96282444d77E604](https://kovan.etherscan.io/address/0x713edC7728C4F0BCc135D48fF96282444d77E604) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/kovan/GenericProxyFactory.json) |

### Prize Strategy Upkeep

**@pooltogether/pooltogether-prizestrategy-upkeep ^1.0.6** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizestrategy-upkeep)

| Contract                                                                                                                             | Address                                                                                                                     | Artifact                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| PrizePoolRegistry                                                                                                                    | [0x8817bB292941e1A69F12879B274c8A15D315ABb1](https://kovan.etherscan.io/address/0x8817bB292941e1A69F12879B274c8A15D315ABb1) | [Artifact](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/deployments/kovan/PrizePoolRegistry.json)   |
| [PrizeStrategyUpkeep](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/contracts/PrizeStrategyUpkeep.sol) | [0xb853503F62779ac16068A8fc40B84Ee174b50337](https://kovan.etherscan.io/address/0xb853503F62779ac16068A8fc40B84Ee174b50337) | [Artifact](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/deployments/kovan/PrizeStrategyUpkeep.json) |

### Pods Upkeep

**@pooltogether/pooltogether-pods-upkeep ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-upkeep)

| Contract     | Address                                                                                                                     | Artifact                                                                                                             |
| ------------ | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| PodsRegistry | [0x9DA83B2EAc639EBcA7c070532453822cBc3266c0](https://kovan.etherscan.io/address/0x9DA83B2EAc639EBcA7c070532453822cBc3266c0) | [Artifact](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/deployments/kovan/PodsRegistry.json) |

### Aave Yield Source

**@pooltogether/aave-yield-source ^1.0.3** [**npm**](https://www.npmjs.com/package/@pooltogether/aave-yield-source)

| Contract                                                                                                                      | Address                                                                                                                     | Artifact                                                                                                           |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| AaveAAVEYieldSource                                                                                                           | [0x495F5751780FE4F0dfCd7E43215F250ecE671Fe2](https://kovan.etherscan.io/address/0x495F5751780FE4F0dfCd7E43215F250ecE671Fe2) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveAAVEYieldSource.json) |
| AaveBATYieldSource                                                                                                            | [0xB1f5Bd3486dAEff298f3DB631F0ae9db9aCF7F22](https://kovan.etherscan.io/address/0xB1f5Bd3486dAEff298f3DB631F0ae9db9aCF7F22) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveBATYieldSource.json)  |
| AaveBUSDYieldSource                                                                                                           | [0x80e9186658Bcb2cd70cdd07B2552a6aFDD0fd04c](https://kovan.etherscan.io/address/0x80e9186658Bcb2cd70cdd07B2552a6aFDD0fd04c) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveBUSDYieldSource.json) |
| AaveDAIYieldSource                                                                                                            | [0xA36600E9A97fbfb0123312A9510a5b1A87e9DA5D](https://kovan.etherscan.io/address/0xA36600E9A97fbfb0123312A9510a5b1A87e9DA5D) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveDAIYieldSource.json)  |
| AaveENJYieldSource                                                                                                            | [0xEc1882A1B4177dE860A08A94a9a879Af79AE56DD](https://kovan.etherscan.io/address/0xEc1882A1B4177dE860A08A94a9a879Af79AE56DD) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveENJYieldSource.json)  |
| AaveKNCYieldSource                                                                                                            | [0x7D6435431bd94e11f0841633B4438F43689c4509](https://kovan.etherscan.io/address/0x7D6435431bd94e11f0841633B4438F43689c4509) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveKNCYieldSource.json)  |
| AaveLINKYieldSource                                                                                                           | [0x0142f2B70096EB85e445E4AaC6E6EA6080b2b24b](https://kovan.etherscan.io/address/0x0142f2B70096EB85e445E4AaC6E6EA6080b2b24b) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveLINKYieldSource.json) |
| AaveMANAYieldSource                                                                                                           | [0xCD54847e1Cf0842af9DD161D34bF885AB4860a39](https://kovan.etherscan.io/address/0xCD54847e1Cf0842af9DD161D34bF885AB4860a39) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveMANAYieldSource.json) |
| AaveMKRYieldSource                                                                                                            | [0xC4ab4345cb443770F4d14a3dA48A4cB5A40cf25b](https://kovan.etherscan.io/address/0xC4ab4345cb443770F4d14a3dA48A4cB5A40cf25b) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveMKRYieldSource.json)  |
| [ATokenYieldSource](https://github.com/pooltogether/aave-yield-source/tree/main/contracts/yield-source/ATokenYieldSource.sol) | [0x96161e596b14aae63Edcf7Ca3fE3470F6A7f3F1B](https://kovan.etherscan.io/address/0x96161e596b14aae63Edcf7Ca3fE3470F6A7f3F1B) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/ATokenYieldSource.json)   |

### Sushi Yield Source

**@pooltogether/pooltogether-sushi-yield-source ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-sushi-yield-source)

| Contract                                                                                                          | Address                                                                                                                     | Artifact                                                                                                           |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| [SushiYieldSource](https://github.com/pooltogether/sushi-pooltogether/tree/master/contracts/SushiYieldSource.sol) | [0x559Aa5568543678793fA3d4A839815e68E183D5c](https://kovan.etherscan.io/address/0x559Aa5568543678793fA3d4A839815e68E183D5c) | [Artifact](https://github.com/pooltogether/sushi-pooltogether/tree/master/deployments/kovan/SushiYieldSource.json) |


# Celo

## Celo

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.7.1** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract            | Address                                                                                                                    |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| cUSD Prize Pool     | [0x6F634F531ED0043B94527F68EC7861B4B1Ab110d](https://explorer.celo.org/address/0x6F634F531ED0043B94527F68EC7861B4B1Ab110d) |
| cUSD Prize Strategy | [0x56837090bb659ee4e468ae22eb97e17cdf829f9f](https://explorer.celo.org/address/0x56837090bb659ee4e468ae22eb97e17cdf829f9f) |
| cEUR Prize Pool     | [0xbe55435BdA8f0A2A20D2Ce98cC21B0AF5bfB7c83](https://explorer.celo.org/address/0xbe55435BdA8f0A2A20D2Ce98cC21B0AF5bfB7c83) |
| cEUR Prize Strategy | [0xc935142eef56f2467e2baa8d1821f6d9178320c7](https://explorer.celo.org/address/0xc935142eef56f2467e2baa8d1821f6d9178320c7) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.3.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                    | Artifact                                                                                                              |
| ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xa6d1C81A07c080d11A39F151E0ae69543a20e6e5](https://explorer.celo.org/address/0xa6d1C81A07c080d11A39F151E0ae69543a20e6e5) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/celo/RNGBlockhash.json) |

## Alfajores

### Builders

**@pooltogether/pooltogether-contracts ^3.4.5** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                                           | Address                                                                                                                                        | Artifact                                                                                                                                          |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/ControlledTokenBuilder.sol)                                    | [0x03e75AeEB92adD6f3b168412671360eB94f0dBf7](https://alfajores-blockscout.celo-testnet.org/address/0x03e75AeEB92adD6f3b168412671360eB94f0dBf7) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/celoTestnet/ControlledTokenBuilder.json)           |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/MultipleWinnersBuilder.sol)                                    | [0xc79B5D46f010c88f738A00B3bed7757d04dd2a37](https://alfajores-blockscout.celo-testnet.org/address/0xc79B5D46f010c88f738A00B3bed7757d04dd2a37) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/celoTestnet/MultipleWinnersBuilder.json)           |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/PoolWithMultipleWinnersBuilder.sol)                    | [0xa6358441F68eD4707E1c4366a0D2E2233bB4841D](https://alfajores-blockscout.celo-testnet.org/address/0xa6358441F68eD4707E1c4366a0D2E2233bB4841D) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/celoTestnet/PoolWithMultipleWinnersBuilder.json)   |
| [Reserve](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/reserve/Reserve.sol)                                                                   | [0xdb8E47BEFe4646fCc62BE61EEE5DF350404c124F](https://alfajores-blockscout.celo-testnet.org/address/0xdb8E47BEFe4646fCc62BE61EEE5DF350404c124F) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/celoTestnet/Reserve.json)                          |
| ReserveRegistry                                                                                                                                                                    | [0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295](https://alfajores-blockscout.celo-testnet.org/address/0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/celoTestnet/ReserveRegistry.json)                  |
| [TokenFaucetProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/token-faucet/TokenFaucetProxyFactory.sol)                              | [0x4027dE966127af5F015Ea1cfd6293a3583892668](https://alfajores-blockscout.celo-testnet.org/address/0x4027dE966127af5F015Ea1cfd6293a3583892668) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/celoTestnet/TokenFaucetProxyFactory.json)          |
| [YieldSourcePrizePoolProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/prize-pool/yield-source/YieldSourcePrizePoolProxyFactory.sol) | [0x17CfE08818E8260FAe3a19761668EBc27B24d72A](https://alfajores-blockscout.celo-testnet.org/address/0x17CfE08818E8260FAe3a19761668EBc27B24d72A) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/celoTestnet/YieldSourcePrizePoolProxyFactory.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.3.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                                        | Artifact                                                                                                                     |
| ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xCB876f60399897db24058b2d58D0B9f713175eeF](https://alfajores-blockscout.celo-testnet.org/address/0xCB876f60399897db24058b2d58D0B9f713175eeF) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/celoTestnet/RNGBlockhash.json) |


# Matic

## Matic

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.7.1** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract            | Address                                                                                                                  |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| USDC Prize Pool     | [0xEE06AbE9e2Af61cabcb13170e01266Af2DEFa946](https://polygonscan.com/address/0xEE06AbE9e2Af61cabcb13170e01266Af2DEFa946) |
| USDC Prize Strategy | [0x640bc9e20fb1e1d6af59d6b9e684d57947966678](https://polygonscan.com/address/0x640bc9e20fb1e1d6af59d6b9e684d57947966678) |
| USDT Prize Pool     | [0x887E17D791Dcb44BfdDa3023D26F7a04Ca9C7EF4](https://polygonscan.com/address/0x887E17D791Dcb44BfdDa3023D26F7a04Ca9C7EF4) |
| USDT Prize Strategy | [0x5A65f0CE666B8334b6481A8d8C8323BB782386e6](https://polygonscan.com/address/0x5A65f0CE666B8334b6481A8d8C8323BB782386e6) |

### Configurable Reserve

**@pooltogether/configurable-reserve-contracts ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/configurable-reserve-contracts)

| Contract                                                                                                                            | Address                                                                                                                  | Artifact                                                                                                                          |
| ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| [ConfigurableReserve](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/contracts/ConfigurableReserve.sol) | [0xdEcD3c72187325C26f85099A89EED6D5bB4604D3](https://polygonscan.com/address/0xdEcD3c72187325C26f85099A89EED6D5bB4604D3) | [Artifact](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/deployments/matic/ConfigurableReserve.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.3.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                  | Artifact                                                                                                               |
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F](https://polygonscan.com/address/0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/matic/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0xEccfB4F7aB44effE457e399cebAa04A95a9061d8](https://polygonscan.com/address/0xEccfB4F7aB44effE457e399cebAa04A95a9061d8) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/matic/RNGChainlink.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                                  | Artifact                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0xd1797D46C3E825fce5215a0259D3426a5c49455C](https://polygonscan.com/address/0xd1797D46C3E825fce5215a0259D3426a5c49455C) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/matic/GenericProxyFactory.json) |

### Aave Yield Source

**@pooltogether/aave-yield-source ^1.0.3** [**npm**](https://www.npmjs.com/package/@pooltogether/aave-yield-source)

| Contract                                                                                                                      | Address                                                                                                                  | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| AaveAAVEYieldSource                                                                                                           | [0xEbED994f97396106f7B3d55C287A6A51128cDBB1](https://polygonscan.com/address/0xEbED994f97396106f7B3d55C287A6A51128cDBB1) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveAAVEYieldSource.json)   |
| AaveDAIYieldSource                                                                                                            | [0x2FA36043BC27C8Da595F32099f4e8E5Ae48cf46e](https://polygonscan.com/address/0x2FA36043BC27C8Da595F32099f4e8E5Ae48cf46e) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveDAIYieldSource.json)    |
| AaveUSDCYieldSource                                                                                                           | [0xABCea7B7f5ea7929b1Df9e3e7241547Fe7b7af14](https://polygonscan.com/address/0xABCea7B7f5ea7929b1Df9e3e7241547Fe7b7af14) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveUSDCYieldSource.json)   |
| AaveUSDTYieldSource                                                                                                           | [0x3C7CdFb942eb98cCe7e4d004e2927788CD9E54fe](https://polygonscan.com/address/0x3C7CdFb942eb98cCe7e4d004e2927788CD9E54fe) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveUSDTYieldSource.json)   |
| AaveWBTCYieldSource                                                                                                           | [0x46CEB180cd117C333Faebd98DbC31BeE32e7c116](https://polygonscan.com/address/0x46CEB180cd117C333Faebd98DbC31BeE32e7c116) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveWBTCYieldSource.json)   |
| AaveWETHYieldSource                                                                                                           | [0x37c7Fc5fF5e265AE0fA12D2367fbDdA7D22c862C](https://polygonscan.com/address/0x37c7Fc5fF5e265AE0fA12D2367fbDdA7D22c862C) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveWETHYieldSource.json)   |
| AaveWMATICYieldSource                                                                                                         | [0x4570Ab872EbF376caBbbB0CBecb985dFe2757900](https://polygonscan.com/address/0x4570Ab872EbF376caBbbB0CBecb985dFe2757900) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveWMATICYieldSource.json) |
| [ATokenYieldSource](https://github.com/pooltogether/aave-yield-source/tree/main/contracts/yield-source/ATokenYieldSource.sol) | [0xd06814AC6CD4A5192E3767a7329a731A3d2E3F1C](https://polygonscan.com/address/0xd06814AC6CD4A5192E3767a7329a731A3d2E3F1C) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/ATokenYieldSource.json)     |

### EVM Bridge

**@pooltogether/pooltogether-evm-bridge ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-evm-bridge)

| Contract                                                                                                                                   | Address                                                                                                                  | Artifact                                                                                                                          |
| ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| [PoolTogetherEVMBridgeChild](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/contracts/PoolTogetherEVMBridgeChild.sol) | [0xfaB3b5c4F7959579e350532600707e0269e01F38](https://polygonscan.com/address/0xfaB3b5c4F7959579e350532600707e0269e01F38) | [Artifact](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/deployments/matic/PoolTogetherEVMBridgeChild.json) |
| [TestContract](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/contracts/test/TestContract.sol)                        | [0xc404c2e69cc82dF8e2F22221f1D1d8e6663bc5F5](https://polygonscan.com/address/0xc404c2e69cc82dF8e2F22221f1D1d8e6663bc5F5) | [Artifact](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/deployments/matic/TestContract.json)               |

### Multi Token Listener

**@pooltogether/multi-token-listener ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/multi-token-listener)

| Contract                                                                                                                | Address                                                                                                                  | Artifact                                                                                                               |
| ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| [MultiTokenListener](https://github.com/pooltogether/multi-token-listener/tree/master/contracts/MultiTokenListener.sol) | [0x8a4416453340ECF6c489eFf3030EDb632b0087B2](https://polygonscan.com/address/0x8a4416453340ECF6c489eFf3030EDb632b0087B2) | [Artifact](https://github.com/pooltogether/multi-token-listener/tree/master/deployments/matic/MultiTokenListener.json) |

## Mumbai

### Configurable Reserve

**@pooltogether/configurable-reserve-contracts ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/configurable-reserve-contracts)

| Contract                                                                                                                            | Address                                                                                                                                 | Artifact                                                                                                                           |
| ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| [ConfigurableReserve](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/contracts/ConfigurableReserve.sol) | [0x941011a95ad6a69d3b06218A3b74a3f6296481A8](https://explorer-mumbai.maticvigil.com/address/0x941011a95ad6a69d3b06218A3b74a3f6296481A8) | [Artifact](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/deployments/mumbai/ConfigurableReserve.json) |

### Builders

**@pooltogether/pooltogether-contracts ^3.4.5** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                                           | Address                                                                                                                                 | Artifact                                                                                                                                     |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/ControlledTokenBuilder.sol)                                    | [0xc0dA19bB3BC4644399ec85808d1ea52cD9f01bB3](https://explorer-mumbai.maticvigil.com/address/0xc0dA19bB3BC4644399ec85808d1ea52cD9f01bB3) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/ControlledTokenBuilder.json)           |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/MultipleWinnersBuilder.sol)                                    | [0x335d7C74b174Edb2a2aB9717A2f2b42D0EC1b0c3](https://explorer-mumbai.maticvigil.com/address/0x335d7C74b174Edb2a2aB9717A2f2b42D0EC1b0c3) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/MultipleWinnersBuilder.json)           |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/PoolWithMultipleWinnersBuilder.sol)                    | [0xfAe3C60e0e14b90de41FbD05d9D82Cd5e8D90068](https://explorer-mumbai.maticvigil.com/address/0xfAe3C60e0e14b90de41FbD05d9D82Cd5e8D90068) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/PoolWithMultipleWinnersBuilder.json)   |
| [TokenFaucetProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/token-faucet/TokenFaucetProxyFactory.sol)                              | [0x1a8A2F20E37dCc27d5d18af65eC58Be02CEd979D](https://explorer-mumbai.maticvigil.com/address/0x1a8A2F20E37dCc27d5d18af65eC58Be02CEd979D) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/TokenFaucetProxyFactory.json)          |
| [YieldSourcePrizePoolProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/prize-pool/yield-source/YieldSourcePrizePoolProxyFactory.sol) | [0x17445F57ea2779dDa88Fce2bc4f58a245F9013DC](https://explorer-mumbai.maticvigil.com/address/0x17445F57ea2779dDa88Fce2bc4f58a245F9013DC) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/YieldSourcePrizePoolProxyFactory.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.3.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                                 | Artifact                                                                                                                |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xE1d06d492107F14AE024c357005c5c692158B13D](https://explorer-mumbai.maticvigil.com/address/0xE1d06d492107F14AE024c357005c5c692158B13D) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mumbai/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0x9eA5656117f4d42CF82AfE2d9686004BDaAea2B3](https://explorer-mumbai.maticvigil.com/address/0x9eA5656117f4d42CF82AfE2d9686004BDaAea2B3) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mumbai/RNGChainlink.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                                                 | Artifact                                                                                                                     |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0xd1797D46C3E825fce5215a0259D3426a5c49455C](https://explorer-mumbai.maticvigil.com/address/0xd1797D46C3E825fce5215a0259D3426a5c49455C) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/mumbai/GenericProxyFactory.json) |

### Aave Yield Source

**@pooltogether/aave-yield-source ^1.0.3** [**npm**](https://www.npmjs.com/package/@pooltogether/aave-yield-source)

| Contract                                                                                                                      | Address                                                                                                                                 | Artifact                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| AaveAAVEYieldSource                                                                                                           | [0x31c457b2AdD91196B3B0Ed9D0bFAFF22052fA38a](https://explorer-mumbai.maticvigil.com/address/0x31c457b2AdD91196B3B0Ed9D0bFAFF22052fA38a) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mumbai/AaveAAVEYieldSource.json) |
| [ATokenYieldSource](https://github.com/pooltogether/aave-yield-source/tree/main/contracts/yield-source/ATokenYieldSource.sol) | [0x6cFbf44ac86eFB9110c3b7D393E783bAEEf243D2](https://explorer-mumbai.maticvigil.com/address/0x6cFbf44ac86eFB9110c3b7D393E783bAEEf243D2) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mumbai/ATokenYieldSource.json)   |

### EVM Bridge

**@pooltogether/pooltogether-evm-bridge ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-evm-bridge)

| Contract                                                                                                                                   | Address                                                                                                                                 | Artifact                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| [PoolTogetherEVMBridgeChild](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/contracts/PoolTogetherEVMBridgeChild.sol) | [0x3F861649a7517af171ff845a5cb7aE6ACeEbd6aA](https://explorer-mumbai.maticvigil.com/address/0x3F861649a7517af171ff845a5cb7aE6ACeEbd6aA) | [Artifact](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/deployments/mumbai/PoolTogetherEVMBridgeChild.json) |

### Multi Token Listener

**@pooltogether/multi-token-listener ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/multi-token-listener)

| Contract                                                                                                                | Address                                                                                                                                 | Artifact                                                                                                                |
| ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| [MultiTokenListener](https://github.com/pooltogether/multi-token-listener/tree/master/contracts/MultiTokenListener.sol) | [0xB29A3c1a9d4eFa7391e685bFD2654ea31E2f3125](https://explorer-mumbai.maticvigil.com/address/0xB29A3c1a9d4eFa7391e685bFD2654ea31E2f3125) | [Artifact](https://github.com/pooltogether/multi-token-listener/tree/master/deployments/mumbai/MultiTokenListener.json) |


# Tokens

A list of tokens and the networks they bridge across

## Token List

PoolTogether has a [Token List](https://github.com/pooltogether/pooltogether-token-list) that you can plug into Uniswap-compatible AMMS.

## Bridged Tokens

| Token    | Ethereum Address                                                                                                      | Polygon Address                                                                                                                                         |
| -------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| POOL     | [0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e](https://etherscan.io/address/0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e) | [0x25788a1a171ec66da6502f9975a15b609ff54cf6](https://explorer-mainnet.maticvigil.com/tokens/0x25788a1a171ec66Da6502f9975a15B609fF54CF6/token-transfers) |
| Pod USDC | [0x386EB78f2eE79AddE8Bdb0a0e27292755ebFea58](https://etherscan.io/address/0x386EB78f2eE79AddE8Bdb0a0e27292755ebFea58) | [0x96d161cbf38FACCeD333851A9cEf20936DDA88F4](https://explorer-mainnet.maticvigil.com/address/0x96d161cbf38FACCeD333851A9cEf20936DDA88F4/transactions)   |
| Pod DAI  | [0x2f994e2E4F3395649eeE8A89092e63Ca526dA829](https://etherscan.io/address/0x2f994e2E4F3395649eeE8A89092e63Ca526dA829) | [0x18C4315847Cf73D5028c8A98EAd16e862450E618](https://explorer-mainnet.maticvigil.com/address/0x18C4315847Cf73D5028c8A98EAd16e862450E618/transactions)   |


# 🕹️ Apps

## Flagship App

{% embed url="<https://app.pooltogether.com>" %}

Play with official and featured prize pools

## Prize Pool Builder

{% embed url="<https://builder.pooltogether.com>" %}

Create new prize pools using the [Prize Pool Builder](https://builder.pooltogether.com)

Fork the [source code on Github](https://github.com/pooltogether/pooltogether-pool-builder-ui)

## Prize Pool Reference App

{% embed url="<https://reference-app.pooltogether.com>" %}

Interact with prize pools you create using the [Reference App](https://reference-app.pooltogether.com/).

Fork the [source code on Github](https://github.com/pooltogether/pooltogether-reference-pool-ui)


# Subgraphs

Information on PoolTogether's subgraph integration.

Both the PoolTogether [app](https://app.pooltogether.com) and [reference](https://reference-app.pooltogether.com/) app use [subgraphs](https://thegraph.com) to index the protocols smart contract events. A cryptocurrency powered economy of participants work together to index various blockchains and make this data available in configurable and consumable form to front-end users. PoolTogether was the first set of subgraphs to be indexed in the The Graph's decentralized indexer network.

There are PoolTogether v3 subgraphs available for most networks that PoolTogether has been deployed on. There are separate subgraphs available for PoolTogether's [LootBox](/protocol/lootbox) on Ethereum Mainnet and Rinkeby (fun fact: the LootBox indexes every single ERC20, ERC721 and ERC1155 transfer since the LootBox launched!).

There are currently 3 separate subgraphs for different versions of deployed prize pool contracts. Some networks only have 1 or 2 subgraphs as they were introduced after the v3.3.8 changes.

## PrizePool Subgraphs

### [Subgraph Code on GitHub](https://github.com/pooltogether/pooltogether-subgraph-v3)

| Subgraph                                                                                   | Version(s)     |
| ------------------------------------------------------------------------------------------ | -------------- |
| **Ethereum Mainnet**                                                                       |                |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-v3_1_0)        | 3.0.0 - 3.3.1  |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-v3_3_2)        | 3.3.2 - 3.3.7  |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-v3_3_8)        | 3.3.8 - 3.3.11 |
| [Explorer](https://thegraph.com/legacy-explorer/subgraph/pooltogether/pooltogether-v3_4_3) | 3.4.3          |
| **Rinkeby Testnet**                                                                        |                |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/rinkeby-staging-v3_1_0)     | 3.0.0 - 3.3.1  |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/rinkeby-v3_3_2)             | 3.3.2 - 3.3.7  |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/rinkeby-v3_3_8)             | 3.3.8 - 3.3.11 |
| [Explorer](https://thegraph.com/legacy-explorer/subgraph/pooltogether/rinkeby-v3_4_3)      | 3.4.3          |
| **Polygon**                                                                                |                |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-polygon-v3_3)  | 3.3.2 - 3.3.7  |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/polygon-v3_3_8)             | 3.3.8 - 3.3.11 |
| [Explorer](https://thegraph.com/legacy-explorer/subgraph/pooltogether/polygon-v3_4_3)      | 3.4.3          |
| **Xdai**                                                                                   |                |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-xdai-v3_3)     | 3.3.8 and up   |
| **BSC**                                                                                    |                |
| [Explorer](https://thegraph.com/legacy-explorer/subgraph/pooltogether/bsc-v3_4_3)          | 3.4.3          |
| **POA Sokol**                                                                              |                |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether-sokol-v3_3)                 | 3.3.8 and up   |
| **Celo**                                                                                   |                |
| [Explorer](https://thegraph.com/legacy-explorer/subgraph/pooltogether/celo-v3_4_5)         | 3.4.5          |

## LootBox Subgraphs

### [Subgraph Code on GitHub](https://github.com/pooltogether/loot-box-subgraph)

|                                                                                              |              |
| -------------------------------------------------------------------------------------------- | ------------ |
| **Ethereum Mainnet**                                                                         |              |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/lootbox-v1_0_0)               | 3.0.0 and up |
|                                                                                              |              |
| **Rinkeby Testnet**                                                                          |              |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/ptv3-lootbox-rinkeby-staging) | 3.0.0 and up |


# Overview

What are No-Loss Prize Games?

No-loss prize games are pools of funds whose accrued interest is distributed as prizes.

The high level protocol architecture is outlined below. The code is available on [Github](https://github.com/pooltogether/pooltogether-pool-contracts).

## How it works

1. Users deposit funds into a Prize Pool.  They receive pool tokens in exchange.
2. The funds earn interest.
3. The interest is distributed by the Prize Strategy as pool tokens.
4. Users withdraw their funds at any time by telling the Prize Pool to burn their pool tokens.

## Architecture

{% hint style="success" %}
**None of the contracts are upgradeable!  The code is stable.**
{% endhint %}

### [Prize Pools](/protocol/prize-pool)

Prize Pools are the central building block of prize games. They pool user funds in a **yield source** and expose the yield to their **Prize Strategy**, which then disburses as desired.

Prize Pools can be differentiated in four primary ways:

* The yield source the prize pool uses to generate no loss return
* The prize strategy used to determine frequency and distribution&#x20;
* The rewards offered by the prize pool
* The asset type the prize pool accepts for deposits&#x20;
* The fairness parameters&#x20;

### [Prize Strategies](/protocol/prize-strategy)

Prize Strategies determine the prize distribution for the Prize Pool. They can define any logic to allocate tokens that the prize pool accrues. Specifically they can:

* Award yield in the Prize Pool as pool tokens
* Award ERC20 tokens held by the Prize Pool
* Award ERC721 tokens held by the Prize Pool

### [Builders](https://github.com/pooltogether/documentation/tree/6c30eec9a3787b298b041b5d864e955c716185ba/protocol/builders/README.md)

Builders make it easy to create pre-configured prize games. There are currently three Prize Pool types paired with the MultipleWinners, documentation available [here](https://github.com/pooltogether/documentation/tree/6c30eec9a3787b298b041b5d864e955c716185ba/protocol/builders/README.md).

### [Random Number Generator](/protocol/random-number-generator)

There are many different ways to generate a random number, so we've abstracted them as request-based Random Number Generator services. Each RNG service has a different security profile, so be sure to use the appropriate one for your game.

## Conventions

Fixed point math is used extensively in PoolTogether. We used fixed point math with 18 decimal places for all fractional numbers. You can think of this as being just like Ether and wei: a value of "1" Ether is represented as "1000000000000000000" wei.

When a number is a fixed point 18 number we always suffix the number with *mantissa.* For example the credit rate is written as *creditRateMantissa*, because it is a fixed point number.


# Prize Pools

Pool deposits and award accrued interest periodically as a prize

## Introduction

Prize Pools allow funds to be pooled together into a no-loss yield source, such as Compound, and have the yield safely exposed to a separate Prize Strategy. They are the primary way through which users interact with PoolTogether prize games.

Prize Pools provide controls to the owner so that participation can be made fair. See [Fairness](/protocol/prize-pool/fairness) for more information.

There is a different type of prize pool for each yield source. For example, if you wish to use Compound you will use the Compound Prize Pool.

All Prize Pools share the functionality below.

## Owner

When a Prize Pool is created, the creator is set as the pool's "owner". The owner is able to:

* Add additional pool tokens
* Change the Prize Strategy
* Set the [credit rate and credit limit](/protocol/prize-pool/fairness#credit)
* Shutdown the prize pool
* Transfer ownership
* Renounce ownership

**The prize pool is not upgradeable and therefore the owner can never seize the funds deposited into the prize pool**

## Limits

When a Prize Pool is created it is initialized with some hard-coded limits to protect users. See [Fairness](/protocol/prize-pool/fairness) for more details.

### **Maximum Timelock Duration**

The maximum timelock duration ensures that a user has to wait at most X amount of time to withdraw their funds loss-lessly. If the owner of a pool sets the credit rate to be way too low, this limit ensures users will still be able to withdraw.

If using the Single Random Winner Prize Strategy, it would make sense to set the maximum timelock duration to 2x the prize period. That way the owner has some flexibility when adjusting the credit limit and credit rate.

### **Maximum Credit Limit**

The maximum credit limit ensures that the credit limit cannot be set higher than this number. This prevents the owner of the Prize Pool from capturing \*all\* of a user's deposit at withdrawal time.

### **Maximum Liquidity Limit**

The maximum liquidity limit allows the PrizePool owner to set a cap on the amount of liquidity the pool can hold. This can be set by calling:

```javascript
function setLiquidityCap(uint256 _liquidityCap) external override onlyOwner
```

## Token Model

A Prize Pool accepts a single type of ERC20 token for deposits. This token depends on the implementation: for a Compound Prize Pool bound to cDai it will be Dai, for a yEarn yUSDC vault it will be USDC. This is the underlying **asset** of the Prize Pool.

Prize Pools use **Controlled Tokens** for their internal accounting. These tokens are minted when depositing or awarding prizes. Controlled Tokens are burned when users withdraw. They are exchanged at a ratio of 1:1 to the asset.

The tokens associated with a PrizePool can be seen by calling:

```javascript
function tokens() external override view returns (address[] memory)
```

### Controlled Tokens

A Controlled Token is a standard ERC20 that is bound to a **Token Controller**.

The Token Controller has the privileged ability to mint and burn tokens on user's behalf, and has a callback that listens for token transfers. Controlled Tokens are expected to trigger this callback on any mint, burns or transfers.

The Prize Pool must be the Token Controller for the controlled tokens that it is initialized with at construction.

The default [Compound Prize Pool Builder](https://github.com/pooltogether/documentation/tree/6c30eec9a3787b298b041b5d864e955c716185ba/protocol/builders/README.md) creates a Ticket controlled token and a [Sponsorship](/protocol/tokens/sponsorship) controlled token.

A Controlled Token can be added by the PrizePool owner by calling:

```javascript
function addControlledToken(ControlledTokenInterface _controlledToken) 
external override onlyOwner
```

### Minting

When a user deposits into a Prize Pool they must request what type of controlled token they receive in exchange. This token will be minted to them at an exchange rate of 1:1 for the asset.

### Burning

When a user wishes to withdraw from a Prize Pool they must burn controlled tokens.

## Depositing

Users can deposit into the Prize Pool using the **depositTo** function. A user is instantly minted tokens upon deposit.

```javascript
function depositTo(
    address to,
    uint256 amount,
    address controlledToken,
    address referrer
) external;
```

| Parameter       | Description                                                                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| to              | The address to whom the controlled tokens should be minted                                                                                                                                                   |
| amount          | The amount of the underlying asset the user wishes to deposit.  The Prize Pool contract should have been pre-approved by the caller to transfer the underlying ERC20 tokens.                                 |
| controlledToken | The address of the token that they wish to mint.  For our default Prize Strategy this will either be the Ticket address or the Sponsorship address.  Those addresses can be looked up on the Prize Strategy. |
| referrer        | The address that should receive [referral awards](https://github.com/pooltogether/documentation/tree/6c30eec9a3787b298b041b5d864e955c716185ba/governance/untitled.md#referral-volume-drips), if any.         |

Depositing fires the event:

```javascript
event Deposited(
    address indexed operator,
    address indexed to,
    address indexed token,
    uint256 amount
);
```

| Event Data | Description                                                                                   |
| ---------- | --------------------------------------------------------------------------------------------- |
| operator   | The caller that made the deposit                                                              |
| to         | The address that received the minted tokens                                                   |
| token      | The address of the controlled token that was minted                                           |
| amount     | The amount of both the underlying asset that was transferred and the tokens that were minted. |

### Depositing Using Timelocked Funds

If a user wishes to re-deposit their timelocked funds, they can do so using this function:

```javascript
function timelockDepositTo(
    address to,
    uint256 amount,
    address controlledToken
) external;
```

| Parameter       | Description                                                                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| to              | The address to whom the controlled tokens should be minted                                                                                                                                                   |
| amount          | The amount of the underlying asset the user wishes to deposit.  The Prize Pool contract should have been pre-approved by the caller to transfer the underlying ERC20 tokens.                                 |
| controlledToken | The address of the token that they wish to mint.  For our default Prize Strategy this will either be the Ticket address or the Sponsorship address.  Those addresses can be looked up on the Prize Strategy. |

## Withdrawing

When a user withdraws they may need to contribute to the prize according to the [fairness rules](/protocol/prize-pool/fairness). They may either cover the contribution by time-locking their funds, or cover the contribution explicitly using funds.

### **Withdraw with Timelock**

Funds can be withdrawn losslessly by time-locking the funds. The withdrawal amount will be unlocked at a later date at which point the funds can be swept back to the user. The timelock duration is calculated based on the users accrued credit, the credit rate, and the fairness fee.

If the user has sufficient credit, the unlockTimestamp may be "now" and the funds are instantly swept to the `from` address.

Tip: You can call this function in a constant way to see when the users funds will be unlocked.

To start a lossless withdrawal a user may call:

```javascript
function withdrawWithTimelockFrom(
    address from,
    uint256 amount,
    address controlledToken
) external returns (uint256 unlockTimestamp);
```

| Parameter Name  | Parameter Description                                                                                                            |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| from            | The user from whom to withdraw.  This means you may withdraw on another user's behalf if they have given you an ERC20 allowance. |
| amount          | The amount of collateral to withdraw.                                                                                            |
| controlledToken | The type of controlled token to withdraw.                                                                                        |

### Checking Timelock Balances

To see how many funds have been timelocked for a `user` call:

```javascript
function timelockBalanceOf(address user) external view returns (uint256)
```

After funds have been time-locked, you can see at what timestamp they'll be available:

```javascript
function timelockBalanceAvailableAt(address user) external view returns (uint256)
```

### Checking Timelock Duration

To calculate a timelocked withdrawal duration and credit consumption call:

```javascript
function calculateTimelockDuration(address from, address controlledToken, uint256 amount) 
external override returns (uint256 durationSeconds,uint256 burnedCredit)
```

| Parameter Name  | Description                               |
| --------------- | ----------------------------------------- |
| from            | The user who is withdrawing.              |
| amount          | The amount the user is withdrawing.       |
| controlledToken | The type of controlled token to withdraw. |

**returns**:

| Returned Parameter Name | Description                               |
| ----------------------- | ----------------------------------------- |
| `durationSeconds`       | The duration of the timelock in seconds   |
| `burned`                | The amount of credit that would be burned |

### Estimating Credit Accrual Time

Similarly it is also possible to calculate how long a user must keep their funds in the pool:

```javascript
function estimateCreditAccrualTime(address _controlledToken,
 uint256 _principal,
 uint256 _interest) 
 external override view returns (uint256 durationSeconds)
```

| Parameter Name    | Parameter Description                               |
| ----------------- | --------------------------------------------------- |
| \_controlledToken | The type of controlled token.                       |
| \_principal       | The principal amount on which interest is accruing. |
| \_interest        | The amount of interest that must accrue.            |

### Sweeping Timelocked Funds

When a user's withdrawal timelocks have ended, the funds may be swept to their wallets:

```javascript
function sweepTimelockBalances(
    address[] memory users
) external returns (uint256 totalWithdrawal);
```

The function accepts an array of addresses and will attempt to sweep the time-locked funds for each one. The funds will be transferred back to the users wallets.

### Withdraw Instantly

If a user would like their tickets right away, they may pay an early exit fee to the prize. The early exit fee is determined by the [Prize Strategy](/protocol/prize-strategy).

The instant withdrawal function returns the amount of the withdrawal that was retained as payment. This means you can call this function in a constant way to check to see what the exit fee will be. When it comes time to run the tx, that exit fee can be passed as the `maximumExitFee` to ensure it doesn't exceed the expected limit.

```javascript
function withdrawInstantlyFrom(
    address from,
    uint256 amount,
    address controlledToken,
    uint256 maximumExitFee
  )
    external
    returns (uint256 exitFee);
```

| Parameter Name  | Parameter Description                                                                                                                  |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| from            | The address to withdraw from.  This means you can withdraw on another user's behalf if you have an allowance for the controlled token. |
| amount          | The amount to withdraw                                                                                                                 |
| controlledToken | The controlled token to withdraw from                                                                                                  |
| maximumExitFee  | The maximum early exit fee the caller is willing to pay.  This prevents the Prize Strategy from changing the fee on-the-fly.           |

This early exit fee can also be calculated by calling:

```javascript
function calculateEarlyExitFee(address from, address controlledToken, uint256 amount)
 external override returns (uint256 exitFee, uint256 burnedCredit)
```

| Parameter Name  | Parameter Description                 |
| --------------- | ------------------------------------- |
| from            | The address to withdraw from          |
| controlledToken | The controlled token to withdraw from |
| amount          | The amount to withdraw                |

returns the `exitFee` that would be paid along with the credit that would be burned (`burnedCredit`).

## Awarding

Only the Prize Strategy can call the award functions. These functions allow prizes to be disbursed to users.

### Awarding Yield

Yield that accrues in the Prize Pool can be awarded by the Prize Strategy. The yield must first be **captured** and then it can be **awarded.**

To capture the yield the prize strategy can call the `captureAwardBalance` function:

```javascript
function captureAwardBalance() external onlyPrizeStrategy returns (uint256);
```

This function will:

* add the current yield balance to the available award balance
* capture a portion for the reserve
* return the total available award balance.

To award the captured yield to an address, the Prize strategy uses the `award` function. The yield must be awarded as one of the controlled tokens configured in the Prize Pool.

```javascript
function award(
    address to,
    uint256 amount,
    address controlledToken
) external onlyPrizeStrategy;
```

| Parameter Name  | Parameter Description                          |
| --------------- | ---------------------------------------------- |
| to              | The address to receive the newly minted tokens |
| amount          | The amount of tokens to mint                   |
| controlledToken | The type of token to mint                      |

### Awarding ERC20s

The Prize Strategy can award ERC20 tokens that are held by the Prize Pool.

```javascript
function awardExternalERC20(
    address to,
    address externalToken,
    uint256 amount
) external onlyPrizeStrategy;
```

However, some tokens are be blacklisted if they need to be held to generate yield (i.e. Compound cTokens).

| Parameter Name | Parameter Description               |
| -------------- | ----------------------------------- |
| to             | The address to receive the transfer |
| externalToken  | The ERC20 to transfer               |
| amount         | The amount of tokens to transfer    |

### Awarding ERC721s (NFTs)

The Prize Strategy can award ERC721 tokens that are held by the Prize Pool.

```javascript
function awardExternalERC721(
    address to,
    address externalToken,
    uint256[] calldata tokenIds
  )
    external
    onlyPrizeStrategy;
```

| Parameter Name | Parameter Description           |
| -------------- | ------------------------------- |
| to             | The address to receive the NFTs |
| externalToken  | The ERC721 contract address     |
| tokenIds       | The NFT token ids to transfer.  |

## Credit

Credit accrues differently for each of the Prize Pool's controlled tokens, so each token will have its own credit rate and credit limit.

### Credit Balance

To get a users credit balance for a controlled token:

```javascript
function balanceOfCredit(
    address user,
    address controlledToken
) external returns (uint256);
```

| Parameter Name  | Parameter Description                                   |
| --------------- | ------------------------------------------------------- |
| user            | The user whose credit balance should be returned        |
| controlledToken | The token for which the credit balance should be pulled |

### Credit Plan

The credit rate and credit limit for a controlled token can be checked like so:

```javascript
function creditPlanOf(
    address controlledToken
) external override view returns (
    uint128 creditLimitMantissa,
    uint128 creditRateMantissa
);
```

| Parameter Name  | Parameter Description                                                |
| --------------- | -------------------------------------------------------------------- |
| controlledToken | The controlled token whose credit limit and rate should be returned. |

Note that the returned values are "mantissas": i.e. fixed point numbers with 18 decimal places.

## Prizes

### Current Award Balance

The following function returns the amount calculated by `captureAwardBalance()`:

```javascript
function awardBalance() external override view returns (uint256)
```

### Total Balances

The total of all controlled tokens (including timelocked) can be obtained by calling:

```javascript
function accountedBalance() external override view returns (uint256)
```

The total underlying balance of all assets (including both principal and interest) can be obtained by calling:

```javascript
function balance() external returns (uint256)
```

## External Prizes

### Adding Tokens

The owner can add "external" ERC20 tokens as prizes. The strategy will award the entire balance held by the Prize Pool to the winner.

```javascript
function addExternalErc20Award(address _externalErc20) external onlyOwner;
```

The owner can add "external" ERC721 tokens as prizes. These tokens will be transferred to the winner.

```javascript
function addExternalErc721Award(
    address _externalErc721,
    uint256[] calldata _tokenIds
) external onlyOwner
```

### Checking Tokens

Checks with the Prize Pool if a specific token type (`_externalToken`) may be awarded as an external prize:

```javascript
function canAwardExternal(address _externalToken) external view returns (bool)
```

## Prize Time Periods

To retrieve when the current prize started:

```javascript
function prizePeriodStartedAt() external view returns (uint256)
```

To retrieve when the prize will end:

```javascript
function prizePeriodEndAt() external view returns (uint256)
```

## Reserve

### Calculate Reserve Fee

Calculates the reserve portion of the given `amount` of funds. If there is no reserve address, the Reserve fee portion will be zero.

```javascript
function calculateReserveFee(uint256 amount) public view returns (uint256)
```

## Prize Strategy

### Set the Prize Strategy

The associated Prize Strategy can be set by calling:

```javascript
function setPrizeStrategy(TokenListenerInterface _prizeStrategy) external override onlyOwner
```

Only the Prize Pool owner can call this function.


# ⚖️ Fairness

How Prize Pools Ensure Fair Play

When users play a game they want it to be fair. In PoolTogether, this means that everyone has contributed the same amount of interest to prizes they are eligible to win. Interest accrues over time, so the Prize Pool needs to measure and enforce the time that funds are held. Without this mechanism, it would be very easy to game the system by depositing right before a prize, having a chance to win, and withdrawing right after.

Prize Pools measure the duration of time funds are held by accruing **credit** for each user at the **credit rate**. The longer a user holds tokens, the more credit they accrue.

Prize Pools enforce the duration of time funds are held by setting a **credit limit**. Once a credit limit is reached a user can withdraw instantly with no loss. If the credit limit has not been reached the user can either use a withdrawal **timelock** or pay an early exit contribution to the prize.

## Credit

After a user deposits funds they begin to accrue credit according to the credit rate. The credit rate is expressed in tokens per second.

For example: if the user deposits 100 DAI and the credit rate is 0.1, then they will have accrued 1 DAI in credit after 10 seconds. Note that they cannot withdraw the 1 DAI credit; it's simply a measure of their contribution.

Users will accrue credit up until the **credit limit**. The credit limit is a fraction, so a users credit limit is that fraction of their entire balance. For example, if the user holds 100 DAI and the credit limit is 0.1, then they will accrue a maximum of 10 DAI in credit.

Once a deposit has accrued maximum credit, it is considered **matured**.

## Timelock

A deposit can be withdrawn instantly from the Prize Pool if it has matured. Otherwise, upon withdrawal the deposit will be timelocked until it has matured, at which point the funds can be swept back to the user by anyone.

The timelock duration is calculated based on the spare credit the user has. The spare credit for a withdrawal is their credit balance *less the credit limit for their remaining balance of tokens*. For example: let's say a user has 100 DAI and is attempting to withdraw 10 DAI. They currently have 9 DAI in credit and the credit limit is 0.1. The user's spare credit is 9 - (100 - 10) \* 0.1 = 0 DAI. If the user was instead withdrawing 50 DAI, then they would have 9 - (100 - 50) \* 0.1 = 4 DAI in spare credit.

The duration of the timelock is the time it takes for the withdrawal to mature less the spare credit. For example: if the withdrawal amount is 100 DAI, and the user has 5 DAI in spare credit, and the credit rate is 0.1, then the timelock will be ((100 \* 0.1) - 5) / 0.1 = 50 seconds. The spare credit is burned and the funds are placed in a timelock that can be swept after the duration has elapsed.

### Paying Off the Timelock

It's possible for a user to withdraw their funds instantly. Instead of a timelock, the Prize Pool will capture the remaining contribution directly from the withdrawal amount. The user will receive the withdrawal amount less the remaining contribution. Their spare credit will be burned. We call this an **instant withdrawal.**

## What should the credit rate and credit limit for a pool be?

In principal, we want the timelock to be as short as possible and most users should never encounter it. We are trying to prevent abuse of the system by a small subset of users while keeping the smoothest experience for the majority of users.

At first glance the credit limit should simply be equal to the amount of interest a deposit would contribute over a prize period. But there are several factors that can change the cost / benefit balance for depositors, specifically:

* Any subsidies to the prize (whether through sponsored deposits or direct additions)
* Any rewards given to deposits through the token drips
* Fluctuations in the yield rate
* Total amount of outstanding tickets for a given prize
* Gas fees of entering and exiting the pool

To find the ideal credit limit it is best to estimate the **effective APR** a pool is offering.

**Example**

Assume a pool has a yield source that returns 5% APR. The pool awards prizes weekly, which means that each week approximately 5% / 52 = 0.096% accrues. A fair credit limit could be 0.1%: if the user decides to game the prize, they will need to contribute 0.1% of their deposit.

However, we want users who have been in the pool since the beginning to not have to pay anything. Let's say we wish for users to accrue 0.1% credit per week, so that they can withdraw losslessly. The credit rate is applied per second and does not compound, so we can calculate the credit rate as the credit limit / seconds in a week, or 0.1% / 86400 = 0.0000011574074074074074.

This means that users will need to stay in the pool for a week, otherwise they'll need to pay an early exit fee of 0.1%. Note, however, that this fee diminishes over time.


# Stake Prize Pool

The Stake Prize Pool is a prize pool that uses an ERC-20 compatible token as the underlying asset.

Users's can stake their tokens to become eligible for whatever prize is defined as the prize strategy for that pool.

This is particularly useful for protocols that are sitting inactively in users's wallets - why not stake them in a pool and become eligible for rewards?

The returned [ticket](/protocol/tokens/ticket) can be thought of as a "proof-of-liquidity".

## Retrieving the Underlying ERC-20

The underlying staked asset can be retrieved by calling:

```javascript
function token() returns (address);
```


# Yield Source Prize Pool

A prize pool that uses a yield source to generate prizes.

The Yield Source Prize Pool uses a yield source contract to generate prizes.  Funds that are deposited into the prize pool are then deposited into a yield source.

## Retrieving the Yield Source

You can access the yield source contract by using this function:

```javascript
function yieldSource() public view returns (IYieldSource);
```

See the [IYieldSource](/protocol/yield-sources#yield-source-interface) interface for more information on the yield source.


# Prize Strategies

Customize how a Prize Pool distributes prizes

A Prize Strategy handles prize distribution for a [Prize Pool](/protocol/prize-pool). When a Prize Pool is constructed it is configured with a Prize Strategy. The Prize Strategy has the privileged ability to award tokens from the Prize Pool.

The most popular Prize Strategy offering is the [Multiple Winner](https://github.com/pooltogether/documentation/tree/6c30eec9a3787b298b041b5d864e955c716185ba/protocol/prize-strategy/multiple-winners/README.md) strategy. Earlier versions (< v3.1.0) of the protocol used the Single Random Winner strategy, which is now a trivial subset of Multiple Winners (with `numberofWinners = 1`).

Prize Strategies must implement the [Token Listener](https://github.com/pooltogether/documentation/tree/6c30eec9a3787b298b041b5d864e955c716185ba/protocol/tokens/token-listener.md) interface so that they can be aware of the full token lifecycle.

## Privileged Actions

A [Prize Pool's](/protocol/prize-pool) Prize Strategy is able to award tokens held by the Prize Pool contract. The Prize Strategy is able to:

* [award yield](/protocol/prize-pool#awarding-yield) that has accrued in the Prize Pool
* [award any ERC20 balance](/protocol/prize-pool#awarding-erc-20-s) held by the Prize Pool
* [award any ERC721](/protocol/prize-pool#awarding-erc-721-s-nfts) owned by the Prize Pool

## Required Behaviour

A Prize Strategy must implement the [Token Listener](https://github.com/pooltogether/documentation/tree/6c30eec9a3787b298b041b5d864e955c716185ba/protocol/tokens/token-listener.md) interface so that it can listen to pool token mint, transfer and burn actions by the Prize Pool.


# Multiple Winners

The Multiple Winners prize strategy periodically selects a predefined number of winners and awards to them an equal share of the prizes available in the Prize Pool.

## Initialization

A Multiple Winners prize strategy is initialized with:

**Prize Period Start:** the timestamp at which the prize period should start

**Prize Period Seconds**: the duration of time between prizes

**PrizePool Address**: the address of the [prize pool](/protocol/prize-pool) that implements the pool functionality such as deposit and withdraw

[**Ticket**](/protocol/tokens/ticket)**:** The interface to use to select winners

[**Sponsorship**](/protocol/tokens/sponsorship)**:** The token that represents sponsorship

[**Random Number Generator**](/protocol/random-number-generator): used to generate random numbers for winner selection

**Number of Winners**: the number of winners in a prize period. This can be later changed by the owner calling set number of winners.

## Strategy Settings

### Set Number of Winners

The number of winners in a prize period can be set by calling:

```javascript
function setNumberOfWinners(uint256 count) 
external onlyOwner requireAwardNotInProgress
```

* Requires that the Award process is not in progress
* `count` must be greater than 0

### View Number of Winners

The number of winners setting can be viewed by calling:

```javascript
function numberOfWinners() external view returns (uint256
```

### Set Split External ERC-20 Awards

The `SplitExternalErc20Awards` flag can be set by calling:

```javascript
function setSplitExternalErc20Awards(bool _splitExternalErc20Awards) 
external onlyOwner requireAwardNotInProgress
```

This controls how externally added ERC-20's are distributed. Setting to `true` results in the ERC-20's paid out uniformly (similar to the main prize), while `false` does not pay out external ERC-20's for that award.

### Set Random Number Generation Service

The [Random Number Generation](/protocol/random-number-generator) Service can be set when the award process has not started by the Prize Pool owner by calling:

```javascript
  function setRngService(RNGInterface rngService) 
  external onlyOwner requireAwardNotInProgress 
```

### Set Random Number Generator Request Timeout

The RNG request timeout parameter can be set (in seconds) when the award process has not started by the Prize Pool owner by calling:

```javascript
function setRngRequestTimeout(uint32 _rngRequestTimeout)
external onlyOwner requireAwardNotInProgress {
```

## Prize Period Information

#### View if the Prize Period is Over

To check if the prize period is finished call:

```javascript
function isPrizePeriodOver() external view returns (bool) 
```

Returns `true` if the prize period is over, `false` otherwise.

#### View when the Prize Period Finishes

To check the unix time when the prize period ends call:

```javascript
function prizePeriodEndAt() external view returns (uint256)
```

#### View Estimate of Number of Blocks to Prize Block

To estimate the remaining blocks until the prize given a number of seconds per block call `estimateRemainingBlocksToPrize` with `secondPerBlockMantissa` set to 15 seconds for Ethereum mainnet:

```javascript
function estimateRemainingBlocksToPrize(uint256 secondsPerBlockMantissa) public
view returns (uint256) 
```

#### View Prize Period Remaining Time (in seconds)

To get the number of seconds remaining until the prize can be awarded call:

```javascript
 function prizePeriodRemainingSeconds() external view returns (uint256) 
```

#### View Next Prize Period Start Time

To get the Unix timestamp of when the next prize period will start call `calculateNextPrizePeriodStartTime` with `currentTime` set to the current Unix time:&#x20;

```javascript
function calculateNextPrizePeriodStartTime(uint256 currentTime) 
external view returns (uint256)
```

## Award Process

At the end of the prize period, anyone can begin the award process. This happens in two main stages - `startAward` and `completeAward`. `startAward` triggers the configured Random Number Generator request, which will take some blocks. `completeAward` can then be called, which selects the winners using the RNG result and pushes the tokens out to the winners.&#x20;

### Start Award

The award process can be started by calling `startAward`.  This function starts the award process by starting the configured random number request. The prize period must have ended. The RNG-Request-Fee is expected to be held within this contract before calling this function.&#x20;

```
function startAward() external requireCanStartAward
```

Upon completion this function fires the following event:

```csharp
event PrizePoolAwardStarted(
    address indexed operator,
    address indexed prizePool,
    uint32 indexed rngRequestId,
    uint32 rngLockBlock
);
```

### Complete Award

The award process can be finished by calling `completeAward`. The random number must have been requested and now available (is can be checked by calling `isRngCompleted()`).

```javascript
function completeAward() external requireCanCompleteAward
```

This function fires two events upon completion:

```csharp
event PrizePoolAwarded(
    address indexed operator,
    uint256 randomNumber
);
```

Since Prize Pools are continuously rolling the next prize period is now open:

```csharp
event PrizePoolOpened(
    address indexed operator,
    uint256 indexed prizePeriodStartedAt
);
```

### Cancel Award

This function can be called by anyone to unlock the tickets if the RNG has timed out:

```javascript
function cancelAward() public
```

This function will fire the event:

```csharp
event PrizePoolAwardCancelled(
    address indexed operator,
    address indexed prizePool,
    uint32 indexed rngRequestId,
    uint32 rngLockBlock
);
```

### Listeners

A prize strategy can have both a [token listener](https://github.com/pooltogether/pooltogether-pool-contracts/blob/master/contracts/token/TokenListener.sol) and a periodic prize strategy listener in order execute code for certain callbacks (event hooks).

#### Set Token Listener

The token listener can be set by the prize pool owner when the award process is not in progress by calling `setTokenListener` with the address of the new `tokenList` :

```javascript
function setTokenListener(TokenListenerInterface _tokenListener)
  external onlyOwner requireAwardNotInProgress
```

#### Set Periodic Prize Strategy Listener

The periodic prize strategy listener can be set by the prize pool owner when the award process is not in progress by calling `setPeriodicPrizeStrategyListener` with the address of the new `PeriodicPrizeStrategyListener`:

```javascript
function setPeriodicPrizeStrategyListener(PeriodicPrizeStrategyListenerInterface _periodicPrizeStrategyListener) 
 external onlyOwner requireAwardNotInProgress
```

This function will ensure the Listener Interface is implementing using ERC-165 introspection, and upon completion fire the following event:

```csharp
event PeriodicPrizeStrategyListenerSet(
    PeriodicPrizeStrategyListenerInterface indexed periodicPrizeStrategyListener
);
```

### External ERC20 and ERC721 Awards

External awards can be added to the pool. This is particularly useful in the case of the stake pool. Although still possible for either the token listener or the owner to manually add or remove ERC-20's and ERC-721's, it is recommended to add a single [LootBox](/protocol/lootbox) per prize period and direct the external awards to this LootBox address.&#x20;

The pool owner or the token listener can add/remove ERC721's by calling:&#x20;

```javascript
function addExternalErc721Award(IERC721Upgradeable _externalErc721,
  uint256[] calldata _tokenIds) 
  external onlyOwnerOrListener requireAwardNotInProgress 
```

```javascript
function removeExternalErc721Award(
  IERC721Upgradeable _externalErc721,
  IERC721Upgradeable _prevExternalErc721)
  external onlyOwner requireAwardNotInProgress
```

The pool owner or the token listener can add/remove ERC20's by calling:&#x20;

```javascript
function addExternalErc20Awards(IERC20Upgradeable[] calldata _externalErc20s) 
    external onlyOwnerOrListener requireAwardNotInProgress
```

```javascript
function removeExternalErc20Award(
  IERC20Upgradeable _externalErc20,
  IERC20Upgradeable _prevExternalErc20) 
  external onlyOwner requireAwardNotInProgress 
```

Corresponding events are fired for each ERC type added or removed:

```csharp
  event ExternalErc721AwardAdded(
    IERC721Upgradeable indexed externalErc721,
    uint256[] tokenIds
  );

  event ExternalErc20AwardAdded(
    IERC20Upgradeable indexed externalErc20
  );

  event ExternalErc721AwardRemoved(
    IERC721Upgradeable indexed externalErc721Award
  );

  event ExternalErc20AwardRemoved(
    IERC20Upgradeable indexed externalErc20Award
  );
```


# 👨‍🌾 Yield Sources

Yield sources generate yield for prize pools.

A **Yield Source** contract is used by a Yield Source Prize Pool to generate yield for prizes.

[See the Specification on Github ](https://github.com/pooltogether/yield-source-interface)

The yield source just needs these properties:

* &#x20;The deposit asset is the same as the asset that accrues.  I.e. if users deposit Dai into the yield source, then it should yield Dai as well
* Yield must always be increasing.  The mechanics of the Prize Pool require yield to always go up, as it's a no-loss system.  The yield source must protect depositor's collateral.

There are implementations for all of the major yield sources:

* Compound
* Aave
* Yearn
* More!

See the full list [here](https://github.com/pooltogether/yield-source-interface)

## Yield Source Interface

The yield source interface is very simple; it just needs to support four functions:

```javascript
/// @title Defines the functions used to interact with a yield source.  The Prize Pool inherits this contract.
/// @notice Prize Pools subclasses need to implement this interface so that yield can be generated.
interface IYieldSource {

  /// @notice Returns the ERC20 asset token used for deposits.
  /// @return The ERC20 asset token
  function depositToken() external view returns (address);

  /// @notice Returns the total balance (in asset tokens).  This includes the deposits and interest.
  /// @return The underlying balance of asset tokens
  function balanceOfToken(address addr) external returns (uint256);

  /// @notice Supplies tokens to the yield source.  Allows assets to be supplied on other user's behalf using the `to` param.
  /// @param amount The amount of `token()` to be supplied
  /// @param to The user whose balance will receive the tokens
  function supplyTokenTo(uint256 amount, address to) external;

  /// @notice Redeems tokens from the yield source.
  /// @param amount The amount of `token()` to withdraw.  Denominated in `token()` as above.
  /// @return The actual amount of tokens that were redeemed.
  function redeemToken(uint256 amount) external returns (uint256);

}
```


# 🎟️ Tokens

When users deposit into a Prize Pool they receive an ERC20 compatible [ticket](/protocol/tokens/ticket).

External ERC721 and ERC20's can also be [added, controlled and removed](/protocol/prize-strategy/multiple-winners#external-erc20-and-erc721-awards) by Prize Pools.

[Sponsorship](/protocol/tokens/sponsorship) tokens are created when funds are added to the pool that are not eligible to win any prizes.


# 🎟️ Ticket

The Ticket contract is an [ERC20](https://eips.ethereum.org/EIPS/eip-20)-compatible token that allows users to be selected by a token index.

The contract organizes the balances into a sum tree data structure, so that each address holds a "range" of tokens.  A number can be used as an index within that range, and the holder of the tokens in that range is selected:

```javascript
function draw(uint256 randomNumber) public view returns (address)
```

The **randomNumber** will be used as a token index into a specialized data structure that stores the user balances.  The randomNumber is constrained to the token supply and modulo bias is corrected.

The returned address is the user who holds the token index corresponding to the random number.


# Sponsorship

Users may "sponsor" the prize pool by depositing funds that don't make them eligible to win.

This can be useful for the creators of the pool to bootstrap its liquidity.


# Random Number Generator

PoolTogether has abstracted the generation of random numbers by creating a request-based Random Number Generator interface.

It functions like so:

1. The user will first get the request fee.  The fee will be expressed using an (address, amount) pair representing the required ERC20 and amount.
2. The user will then approve the RNG to spend that ERC20 of the amount
3. The user will then request the random number.  The RNG will transfer the cost into itself and begin the request.  The request returns a request identifier.
4. The user may check to see if the random number is available using the identifier.
5. When the random number is available the user may retrieve it with the identifier.

Let's look at these functions in detail.

## Get the Request Fee

Many RNG services require tokens in order to operate.  To get the cost of the rng you may do so using:

```javascript
function getRequestFee() external view returns (address feeToken, uint256 requestFee);
```

This function returns two values:

* **feeToken:** the ERC20 that needs to be paid
* **requestFee:** is the amount of the token that needs to be paid

## Request a Random Number

Once the user has approved the RNG service spend, they may request a random number like so:

```javascript
function requestRandomNumber() external returns (uint32 requestId, uint32 lockBlock);
```

This function returns two values:

* **requestId:** the unique id for this RNG request
* **lockBlock:** the commitment block for this RNG request.  Users of the RNG request shouldn't make any changes after the lockBlock, otherwise the RNG may be less secure.  For example, the Prize Strategy will lock all ticket sales and movements after the lockBlock, as they affect the winner selection.  Once the request is complete the Prize Strategy unlocks tickets.

## Check if Request is Complete

The user may check if a request is complete:

```javascript
function isRequestComplete(uint32 requestId) external view returns (bool isCompleted)
```

## Retrieve Random Number

```javascript
function randomNumber(uint32 requestId) external returns (uint256 randomNum);
```

##


# Blockhash

The Blockhash RNG uses a future blockhash as the random number. This is the least secure method of random number generation, but also the simplest and cheapest.

When a user request a random number their lock block will be the current block. Their request is considered 'complete' when at least one block has been mined since the lock block. Upon retrieval the last blockhash will be stored as the random number and returned.

## Usage

A prize strategy can use a [RNGBlockhash](https://github.com/pooltogether/documentation/tree/6c30eec9a3787b298b041b5d864e955c716185ba/networks.md) RNG service. No additional work is needed: the blockhash service is free.


# Chainlink VRF

**A verifiable random function is a pseudo-random function whose output is unique and can be publicly verified.**

ChainLink has implemented their VRF using public key cryptography. It works like so:

1. The user creates a “seed” value
2. A ChainLink operator, who has publicly committed to a keypair, uses their secret to sign the seed value.
3. The user is able to verify that the operator has signed the seed value, and consume the signature as the “random number”. &#x20;

**ChainLink VRF Documentation:** [**https://docs.chain.link/docs/chainlink-vrf**](https://docs.chain.link/docs/chainlink-vrf)

This approach has some benefits in that the operator cannot “lie”: they must sign the seed using the secret they have committed to. The algorithm is also instantaneous: there is no delay or waiting period to get the answer. *\*\**

## Usage

To use the [RNGChainlink](https://github.com/pooltogether/documentation/tree/6c30eec9a3787b298b041b5d864e955c716185ba/networks.md) RNG service, create a new prize pool using the service or set it on an existing pool.

🚨🚨🚨 **Chainlink RNG requires 2 LINK tokens per RNG request** 🚨🚨🚨

🚨🚨🚨 **You must deposit LINK into the PRIZE STRATEGY** 🚨🚨🚨


# 🏴‍☠️ Loot Box

What is a PoolTogether Loot Box?

## Overview

The PoolTogether Loot Box is a permission-less token container. A Loot Box allows wallets to be transferred like an ERC721.

Many different tokens can be controlled simply by one counterfactual address. The holding contract is created and destroyed within the same transaction. This cheap deployment and immediate destruction of the contract minimizes the gas overhead involved with containerization.

The code can be found here: <https://github.com/pooltogether/loot-box>

## How it works

A LootBox contract ephemerally exists within a transaction. The owner of an `ERC721` owns the LootBox.

1. A `ERC721` is created by calling `createERC721Controlled()` on the `ERC721ProxyFactory` by anyone:

```javascript
  function createERC721Controlled(
    string memory name,
    string memory symbol,
    string memory baseURI
  ) external returns (ERC721Controlled)
```

1. `mint()` can then be called on the `ControlledERC721` which effectively creates a LootBox with an Owner defined by the `to` field:

```javascript
function mint(address to) external onlyAdmin returns (uint256)
```

1. The LootBox address is calculated by calling:&#x20;

```javascript
computeAddress(address erc721, uint256 tokenId)
```

1. Tokens are transferred/minted to this address. In the case of PoolTogether, these are usually external ERC20, ERC721 and ERC1155 rewards for a Prize Period.
2. Anyone can call `plunder()` on the LootBox controller which will transfer all the passed tokens to the LootBox owner.

```javascript
function plunder(
  address erc721,
  uint256 tokenId,
  address[] calldata erc20s,
  WithdrawERC721[] calldata erc721s,
  WithdrawERC1155[] calldata erc1155s
)
```

where `erc20s` is defined as an array of ERC-20 addresses,

`erc721s` is defined as:

```c
struct WithdrawERC721 {
  address token;
  uint256[] tokenIds;
}
```

and `erc1155s` as:

```c
struct WithdrawERC1155 {
  address token;
  uint256[] ids;
  uint256[] amounts;
  bytes data;
}
```


# Pods

Combine tickets and split the prize

A "Pod" is a smart contract that allows users to combine their deposits together for a higher chance to win.  If the Pod wins, users get to split the prize according to how much they contributed.

Pods introduce two major enhancements:

* Reduced gas costs when entering PrizePools via batching.
* Increased winning odds through collective deposits.

Relative to the traditional PoolTogether deposits, Pods offer a unique value proposition that may appeal to a range of users. Whether it's a small "fish" just trying to spend less on gas or a "whale" interested in increasing their chances of winning (*while also sharing their winnings with others*) Pods introduce a novel set of features for participating in a no-loss lottery.

**Primary Smart Contracts**

* [Pod.sol](https://github.com/pooltogether/pods-v3-contracts/blob/master/contracts/Pod.sol)
* [TokenDrop.sol](https://github.com/pooltogether/pods-v3-contracts/blob/master/contracts/TokenDrop.sol)
* [PodFactory.sol](https://github.com/pooltogether/pods-v3-contracts/blob/master/contracts/PodFactory.sol)
* [TokenDropFactory.sol](https://github.com/pooltogether/pods-v3-contracts/blob/master/contracts/TokenDropFactory.sol)

#### OpenZeppelin Inheritance

Pods inherit functionality from OpenZeppelin smart contracts: *ERC20Upgradeable, OwnableUpgradeable, ReentrancyGuardUpgradeable.*

**Module:** @openzeppelin/contracts-upgradeable": "^3.4.0"

## Overview

### Sharing Tickets & External ERC20/ERC721 Winnings

**The Pod is designed to distribute PrizePool winnings i.e. tokens/tickets.**

*Secondary awards (LOOT Box) are liquidated and converted to the underlying balance.*&#x20;

In other words, if a Pod contains 1,000,000 tokens (for example $1,000,000 worth of USDC) split evenly between 10 depositors (100,000 each) and the Pod is awarded 50,000 pcUSDC, each depositor will have their underlying balance increase by 5,000 USDC (10% of the total winnings).

Distribution of non-ticket winnings, such as external ERC20 and ERC721 tokens is handled via liquidation and conversion to the underlying balance token. Simply put, as of now Pods (v1) instead of splitting secondary awards (*which is not possible for non-fungible tokens*) the Pod manager liquidates the LOOT Box and converts the assets into the underlying token or reward ticket.

The liquidated/converted assets can be withdrawn by Pod share holders.

In short, **all winnings** are ultimately available as the **deposit token**.

*Example:*

* Pod awarded 50,000 ticket prize
* Pod awarded LOOT Box (external ERC20/ERC721 tokens)
* Pod liquidates LOOT Box assets into underlying asset (token)
* Underlying asset distributed across Pod holders &#x20;

### Owner & Manager

Pods include two roles: *owner and manager*. The owner is responsible for updating (if necessary) external contract references and the manager is responsible for liquidating and distributing LOOT Box winnings.

#### Owner

The owner is responsible for updating external contract references.

**Manager**

The manager is responsible for liquidating secondary prizes.

## How It Works&#x20;

From a technical perspective a Pod is a **single user** in relation to the PrizePool protocol - even though 10's, 100's or even 1000's of users may have deposited funds.

**The Pod smart contract adheres to the ERC20 specification**. While Pods include functionality to interact with a strict set of external smart contracts: *PrizePool, TokenListeners and TokenDrops,* at the core Pods can be thought of as a token.

When tokens are deposited into a Pod, via `depositTo` new shares are minted.

Minted shares, represented as an ERC20 balance, represent a user's claim on the underlying balance managed via the Pod smart contract.

In other words, user's deposits tokens directly into a Pod, and in-turn the Pod will batch those deposits into a single transaction and deposit into the PoolTogether V3 PrizePool smart contracts, but the shares minted by the Pod can be traded just like any other ERC20 token.

## Smart Contract Functions

#### `depositTo` - Deposit Tokens & Mint Shares&#x20;

```javascript
function depositTo(
 address to, 
 uint256 tokenAmount
) external override nonReentrant returns (uint256)
```

The `depositTo` function interface is similar to the PrizePool `depositTo` function interface, minus the `controlledToken` and `referrer` inputs, which are automatically added by the Pod during the batch process.

As with all ERC20 smart contracts transfers/deposits, **users must first set a positive allowance for the target contract**. Afterwards users deposit funds into the Pod by calling the `depositTo` function with the desired `to` and `tokenAmount` inputs.

Normally users will enter their personal wallet address, unless a deposit is made on behalf of user, which might be the case for a periphery smart contract. For example, a third-party contract might convert ETH into the underlying Pod token before calling depositTo - sometimes referred to as a zap.

When a user deposits tokens, the Pod mints shares - representing a claim on the deposit.

#### `withdraw` - Burn Shares & Withdraw Tokens

```javascript
function withdraw(
 uint256 shareAmount,
 uint256 maxFee
) external override nonReentrant returns (uint256)
```

The `withdraw` function, as expected, handles withdraws from the Pod. To withdraw from a Pod, the user must have a positive share balance. Whether that's via depositing tokens or being transferred Pod shares.

When a users withdraw the shares are burned and the underlying balance is transferred.&#x20;

In addition to entering a valid `shareAmount` users must also specify the `maxFee` amount. When exiting a PrizePool a fee may be applied, depending on the last deposit timestamp. Due to the nature of a Pod's regular deposits/withdrawals the early exit is constantly updating.

The early exit fee can be calculated by calling the `getEarlyExitFee` view function and entering the total underlying balance to be withdrawn.

First, a user may want to calculate the total underlying balance relative to their shares by calling `balanceOfUnderlying(address user) returns (uint256 amount)`which will calculate the underlying balance via the user's share balance.

After a user has determined their total underlying balance, they can proceed to calculate the early exit by inputting the desire withdraw amount, relative to their share balance.

#### `drop` - Claim Reward Tokens, Batch User Deposits and TokenDrop

```javascript
function drop() external override nonReentrant returns (uint256)
```

The `drop` function is responsible for claiming and distributing rewards tokens (i.e. POOL) to the TokenDrop smart contract and executing `batch` which transfers recent token deposits into the PrizePool.

The average user will not need to interact with the `drop` function. Instead it's up to the Pod owner/manager to regularly call `drop` function and batch deposits.

Pods deployed by the PoolTogether Inc team are automatically managed using the OpenZeppelin Defender system. Eliminating the need for administrator to manually manage a Pod's deposits.

[PoolTogether Pods Upkeep](https://github.com/pooltogether/pooltogether-pods-upkeep)

#### `batch` - Batch User Deposits

```javascript
function batch() external override nonReentrant returns (uint256)
```

The `batch` function is responsible for moving deposited tokens from the Pod smart contract into the PrizePool smart contract.

Overall, the batching functionality is a simple process:

* Read the current underlying token balance.
* Deposit the underlying token balance into the PrizePool.

After the Pod batches token deposits, converting the tokens into tickets, the Pod is instantly eligible for winning the PrizePool award.

Generally, the `batch` function will be called indirectly via the `drop` function. The `batch` function is called indirectly because, in addition to converting tokens to tickets, it's important to claim and distribute the reward token, which is handled via the `drop` function.

The batching functionality is the reason for an average 3x in gas savings.


# Prize Splits

Distribute a percentage of the prize (before awarding winners) on every draw to fixed address.

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

  ...
}
```


# Blocklist

Block addresses from being selected for award distribution

## Introduction

The blocklist feature (introduced in 3.4.0) allows the MultipleWinners prize strategy smart contract to prevent addresses from being eligible for winning a prize.&#x20;

⚠️ **WARNING:** The blocklist feature **SHOULD NOT** be used to prevent normal users from being eligible to win a prize. The intended use case is to prevent smart contracts, which are unable to withdraw prizes.

### Why

The blocklist feature was built specifically to overcome the problem of adding tickets to decentralized exchange, so users can easily exchange assets for a `ticket` in their desired `PrizePool` without awarding the liquidity pool address with a prize.

Depositing directly into existing `PrizePools` like USDC and DAI on average costs between 450,000 to 550,000 gas. During times of gas costs (e.x. between 90 - 200+) these can be cost prohibitive for users depositing smaller amounts.

### Side Effects of Blocked Addresses When Selecting Winners

In certain circumstances it's possible to select few winners, then the amount designated by the internal `__numberOfWinners` variable due to the number of attempts (limited by `blocklistRetryCount`) available in the `_distribute` function.

For example, if a Uniswap liquidity pool holds 50% of the available tickets, but is blocked from winning, and the number of winners is set to 3 and the try attempt is limited to 5, it's possible the liquidity pool address would be selected 5 times, before 3 winners are randomly drawn.

Resulting in only 2 of 3 winners being selected before the `blocklistRetryCount`ceiling was reached. Depending on the state of `carryOverBlocklist` the 2 of 3 selected winners would either...

A) split the total awarded prize evenly in this draw period.\
B) split the total awarded prize based off `__numberOfWinners`

If **Scenario B** occurs the remaining awarded interest would roll over to next draw period. In the next draw period the increased prize amount (*due to the carried over prize*) would be given to the selected prize.

In every scenario the selected winner(s) will **always** receive the expected prize amount.

## **How It Works**

The MultipleWinners smart contract now includes the ability to block individual address from being selected as a winner for prize distribution. &#x20;

**Public Functions**

* `setBlocklisted`
* `setCarryBlocklist`
* `setBlocklistRetryCount`

### Blocking Address from Winning

A simple mapping called `isBlocklisted` correlates a user address `isBlocked` boolean status.

`mapping(address => bool) public isBlocklisted;`

During the contract initialization all address default `isBlocked` false. After the contract has been initialized the contract owner can toggle a user's `isBlocklisted` status by calling `setBlocklisted` with the `_user` **address** and `_isBlocked` set **true**.

```
function setBlocklisted(address _user, bool _isBlocked) external onlyOwner requireAwardNotInProgress returns (bool) {
    isBlocklisted[_user] = _isBlocked;

    emit BlocklistSet(_user, _isBlocked);

    return true;
  }
```

To reverse the `isBlocked` status a contract owner calls the same function. Passing the same `_user` **address** with the `_isBlocked`set **false**.&#x20;

When winners are being selected during

### Blocklist Retry Attempt Count

When attempting to select a winner during the draw process it's still possible to select a blocked address. However, instead of adding the blocked address to the array of winners, the contract will attempt to select a new winner with a false `isBlocked` status.

By default the `blocklistRetryCount` will be set to 0.

To update the retry count a contract owner can call `setBlocklistRetryCount` with the number of retries. &#x20;

```
function setBlocklistRetryCount(uint256 _count) external onlyOwner requireAwardNotInProgress returns (bool) {
  blocklistRetryCount = _count;

  emit BlocklistRetryCountSet(_count);

  return true;
}
```

As you already know, each Ethereum transaction consumes gas. The more complex a transaction the higher the gas costs. To avoid running out of gas in a if a blocked address is selected multiple times, a retry limit is set and the transaction will continue with awarding the selected winners.

In short, the prize strategy will do its best to select winners without running out of gas.

It's important to mention, even though a a retry attempt count must be set, it's very unlikely the retry attempt limit be reached, unless a blocked address holds an unusually high amount of tickets.&#x20;

### Prize Award Carry Over

In the very unlikely circumstance the retry count is reached due to a high number of `tickets` held by a blocked address and the maximum number of winners has not been selected, the prize strategy must decide how to handle the remaining awarded interest: **evenly** **split the interest between selected winners or carry over the interest for the next draw.**

By default the award interest is carried over to the next round if the maximum of winners **IS NOT** selected.

To evenly split the interest between winners the contract owner calls `setCarryBlocklist` with true.

```
function setCarryBlocklist(bool _carry) external onlyOwner requireAwardNotInProgress returns (bool) {
  carryOverBlocklist = _carry;

  emit BlocklistCarrySet(_carry);

  return true;
}
```

#### External ERC20 Carry Over

If a PrizeStrategy also awards external ERC20 tokens during award distribution the same carry over rules to the external tokens. In other words, if the main prize is split evenly between the selected winners or carried over to the next draw period, the same logic will be applied to the tokens.

## **Smart Contract Functions** &#x20;


# 🏛️ Overview

The Role of Governance

*The PoolTogether protocol will be transitioning to decentralized governance. In the meantime, the core team serves as the interim governance body.*

PoolTogether Governance broadly serves two mandates:

* Protocol improvement
* Prize Pool management

## Protocol Improvement

Governance will guide the evolution of the protocol towards the goal of building products that create financial health. The primary functions of governance are to:

* Set [rewards](/governance/overview) for prize pool users
* Approve & implement new yield sources for prize pools&#x20;
* Implement new prize strategies

In addition to these core functions governance may:

* propose integrations with L2 systems
* Add additional prizes or rewards&#x20;
* subsidized transactions
* insurance coverage
* Anything else!&#x20;

## Prize Pool Management

Governance also manages its own set of Prize Pools. These Prize Pools are displayed on the official [PoolTogether App](https://app-v3.pooltogether.com).

## Comptroller

All Prize Pools link to a global protocol [Comptroller](/governance/overview). The Comptroller is owned by governance, and determines the reserve rate and rewards Prize Pools.


# 🕹️ Controls

A summary of governance-managed controls

PoolTogether governance primarily controls:

* Protocol prize pools
* Token Faucets (liquidity mining)
* Protocol treasury
* Reserve

## Protocol Prize Pools

The protocol owns a subset of the prize pools.  Ownership means that governance can execute privileged actions only available to the owner.

Each prize pool consists of the prize pool contract and the prize strategy contract.  These two contracts can have different owners, but typically the owner is the same.

Prize Pool actions include:

* Setting a prize pool's early exit fees
* Setting a prize pool's liquidity cap
* Setting the prize strategy for a prize pool

Prize Strategy actions include:

* Setting the number of winners
* Setting whether to split external awards among the winners
* Configuring the Random Number Generator
* Managing external awards
* Configuring token and prize listener contracts

## Token Faucets

The protocol owns a set of token faucets, and can create more.  Each faucet is bound to a prize pool as a token listener and drips POOL tokens to the users.  The original program is time-limited, but governance can:

* Deposit more tokens into each faucet
* Change the drip rate of each faucet
* Create new token faucets for new prize pools

## Protocol Treasury

The initial token distribution allocated 60% of the POOL token supply to the protocol treasury.  These tokens will be unlocked over two years by the TreasuryVesterForTreasury contract.  Anyone can execute the vesting contract to disburse more tokens to the protocol treasury.

The protocol treasury is held by the Timelock contract, which is the contract that execute proposals submitted by governance.  Proposals could do things like:

* Transfers POOL tokens to a recipient
* Approve POOL token spend by another contract, and then call the contract

## Reserve

The reserve contract is owned by governance, and determines the portion of interest earned by each prize pool that is captured as reserve funds.  Every prize pool created by the builders is linked to the reserve.  Governance can:

* Change the reserve rate.  This rate is the portion of interest that is captured for the reserve.
* Withdraw the reserve from a prize pool.


# 🗳️ Example Proposals

Illustrating governance process with examples

The governance system is very new, so it might be difficult for some people to imagine how it works.  Here we're going to give some example proposals to illustrate how governance could work.  The examples will be both PoolTogether-specific and refer to proposals created in other governance systems.  We'll cover:

* How to create a new protocol-owned prize pool
* How to create a Uniswap-style grants program
* Rewarding contributors with Sablier streams

It's important to mention that a proposal is much more likely to be successful if it is first discussed in the [governance forum](https://gov.pooltogether.com/).  Ideally the outcome of a proposal will be known before it is created.

## Proposal: Create a Protocol Prize Pool

As new assets become available and new types of prize pools are added to the [Builder](broken://pages/-M62EjiYFQOIIF0UDsxg), users may wish to create new governance owned & operated prize pools.  By having ownership only governance will be able to change parameters such as the exit fee and number of winners.  See [Controls](/governance/controls) for more info.

If POOL holders decide to create a new prize pool after thorough discussion on the governance forums, then they would need to follow these steps:

1. A user creates the appropriate prize pool using the [Prize Pool Builder app](https://builder.pooltogether.com/).
2. Once created, the user transfers the ownership of the resulting prize pool and prize strategy contracts to the Timelock contract (see the Governance section in [Networks](/resources/networks)).  The only interface for this right now is Etherscan.
3. Finally, the user creates a new governance proposal.  The proposal will include:
   1. Adding the prize pool address to the official Protocol Prize Pool Registry (coming soon!)
   2. Possible compensation for the gas spent by the user that created the pool
   3. Possible compensation for the gas costs of creating the proposal

POOL holders will need to verify that the ownership of the proposed prize pool has, in fact, been transferred to the Timelock contract.  They should also verify that the prize pool is safe and has been created by the builder app.

## Proposal: Create a Grants Program

Many protocols have created a grants program to make it easy to fund the protocol ecosystem.  Typically, grant programs have a trustworthy steward to manage the program.  The [Uniswap Grant Proposal](https://app.uniswap.org/#/vote/3) is a great example.

For Uniswap, a professional grants manager was selected to lead the program.  Him and five other people were added to a Gnosis Safe multisig.  The other people were well-known leaders in the crypto space and proved that they held the wallet addresses.  The multisig was configured to require 4-of-6 confirmations, making it quite secure.

The proposal included:

* Quarterly budget for grants, with two quarters of budget requested at the time of proposal.
* Compensation for the grants manager
* A complete description of the proposed grants program, including timeline, budget and scope.

The actual proposal was a simple token transfer from the treasury to the Gnosis Safe multisig.

## Proposal: Reward Contributors with a Sablier Stream

SushiSwap has formalized their hiring guidelines, and as part of those guidelines new hires will be paid a signing bonus and their "salary" will be sent to them as a Sablier stream.  You can read their [complete hiring process here](https://forum.sushiswapclassic.org/t/sushi-hiring-guidelines-v2/1866).

If a community member wished to apply to work for the protocol and have a salary of X tokens, they could set up a proposal like so:

1. Approve Sablier spending X tokens
2. Create a new stream in Sablier for X tokens for the given timeframe.
3. Include token transfer as a signing bonus (if applicable)


# Smart Contract Guidelines

When creating a new smart contract project, use the guidelines below to ensure your project meets our basic standards of quality.

## Security

### Re-entrancy

Any external or public functions need to be analyzed to determine whether the contract can be attacked if a user re-enters that function or another.

### Safe ERC20 Usage

ERC20 token interactions should always use SafeERC20 safeApprove and safeTransferFrom in the OpenZeppelin library.

### Math Overflow and Underflow

Any math operations need to be checked for overflow and underflow conditions, using SafeMath or similar.

### Trusted External Calls

The contract should minimize trust in external calls.

## Optimizations

* All external / public functions should return a value when possible (to save gas)
* Structs must be tightly packed
* Hardcoded integers and strings should be constants
* Contract members that don't change should be immutable

## Conventions

### Typed Arguments

All arguments, whether to an event or function, must be typed when possible. `address` types should be avoided in favour of contract or interface types

### Logs Emitted

Events must be emitted for any significant state change or event.

### Grammar

Names and documentation must be spelled correctly with no grammatical errors.

## Documentation

### Readme

A complete readme must be included with the project. It needs:

* a complete description
* usage
* setup instructions
* all test commands
* deployment instructions and information
* information on any additional scripts

### Natspec

Contracts must have (at minimum):

* `@title`: short title.  shouldn't repeat the description
* `@notice`: descriptive enough so that the reader understands the intent of the contract.

Functions must have (at minimum):

* `@notice`: explain what the function does
* `@param`: explain each parameter
* `@return`: explain the return param(s)

Events must have (at minimum):

* `@notice`: describe when the event is emitted
* `@param`: describe each of the args

## Testing

### Unit Tests

* There must be a test suite for each contract
* Each unit test should mock out contract dependencies using Waffle or Smock
* Contract functions should be tested in isolation
* Unit tests must run **locally; i.e. they do not connect to a remote node.**

### Code Coverage

* Coverage must exceed 95%

### Fork Test

* A fork test script tests the contracts in the real world
* At a minimum the test must execute the "happy path" for the code.

### Repository Badges

* Coverage badge must be included (we use Coveralls)
* Github Workflow badge for the fork test&#x20;
* Github Workflow badge for the unit tests


# Risks

Using the protocol includes substantial risks of losing some or all of your funds. The PoolTogether core team and community have made every effort to ensure the security of funds.

This section will help you understand the the types of risk you are taking what has been done to mitigate them and how to mitigate them further.&#x20;

### Protocol Dependency Risk  <a href="#a908" id="a908"></a>

The PoolTogether Protocol uses several other protocols. Therefore the first type of risk is the risk that these other integrated protocols can fail.

Specifically by using PoolTogether you are also taking on the risks of using the Ethereum network, the collateral you are depositing, and the yield service (currently Compound.Finance).

To mitigate this risk the protocol is only integrated with highly reputable and well secured protocols. &#x20;

### Smart Contract Exploit Risk <a href="#a908" id="a908"></a>

The second type of risk is specific to PoolTogether. The risk is that there could be some sort of bug or exploit in the smart contracts that run the PoolTogether Protocol. This is a risk with any product on Ethereum. Depending on what the bug or exploit is, a nefarious person may be able to take some or all of the funds stored in the PoolTogether Protocol. Here’s what we’ve done to mitigate this risk.

1. Professional, third party smart contract auditing. PoolTogether has hired companies to professionally review and audit the smart contract code for any bugs or exploits. These auditors have produced reports with their findings. As PoolTogether continues to grow we’re committed to continuing to pay for audits however, it should be understood that at any given time, 100% of the code base has not been professionally audited.&#x20;
2. Bug Bounty program. PoolTogether offers payment of up to $25,000 for reports of any bugs in the smart contracts. If someone was to discover a bug, this is a way for them to responsibly disclose it to us and be paid rather than exploit it.
3. All the smart contract code is open source, meaning it is publicly readable by anyone. At first this may sound strange but it actually makes the protocol more secure as anyone can review it for bugs and submit a bug bounty.
4. Before we even give our code to auditors we also do extensive internal testing.

### Wallet Loss Risk <a href="#e5cb" id="e5cb"></a>

This risk doesn’t have anything to do with PoolTogether but we wanted to mention it. Using PoolTogether requires you to use an Ethereum wallet that supports Ethereum apps. If you permanently lose access to this wallet, you will not be able to recover your funds. Different wallets have different recovery mechanisms. It’s important for you to know what those are and be able to recover your wallet. [Argent Wallet](https://www.argent.xyz/) is one example of a wallet with good recovery methods.


# Audits & Testing

The PoolTogether Protocol has undergone three formal professional third party audits. Two have been [conducted by Open Zeppelin](https://blog.openzeppelin.com/pooltogether-v3-audit/), and one by ditCraft.

Additionally the PoolTogether core team has a long term security relationship with [ConsenSys Diligence](https://diligence.consensys.net/audits/) including monthly code reviews.

Notwithstanding, portions of the PoolTogether Protocol codebase will continue to evolve and **it should never be expected that 100% of the deployed code has been formally audited.**

We encourage responsible disclosure of any vulnerabilities in the smart contracts and will pay up to $25,000 for those. See the [Bounties](/security/bounties) for more details.


# Bounties

We value contributions from the community to strengthen the security of the core contracts. We want to reward any hackers in good faith who report vulnerabilities.

The scope of this bounty includes the PoolTogether smart contracts. The determination of the bug severity will be made by the PoolTogether team.  We determine the severity of an issue according to the [Smart Contract Security Alliance Severity Levels](https://www.smartcontractsecurityalliance.com/)

Payouts will be as follows:

High: $25,000 DAI\
Medium: $10,000 DAI\
Low: $1,000 DAI

The issue must:

* be a previously unreported, non-public vulnerability.
* include enough detail for us to identify and reproduce the problem

All reports should start with an email to <hello@pooltogether.us> and they will receive a response within 24 hours. Non-security issues are not eligible for this bounty.

Determinations of eligibility and all terms related to this award are at the sole and final discretion of the PoolTogether team.

## Past Bounties

### PermitAndDepositDai Contract: Unrestricted Sender

Severity: Medium / High\
Date: Thursday, October 22nd, 2020\
Reporter: Kevin Foesenek\
Payout: $20,000 USD of WETH ([transaction](https://etherscan.io/tx/0xdd9fcf07a29a376b811c775d34cef4ceddf6e720981da34ac7142a8c38e7e7a6))

**Vulnerability**\
Just prior to launch a security researcher discovered a flaw in the PermitAndDepositDai contract.  This flaw would have allowed an attacker to front-run the "deposit" transaction and take the deposited amount.  This would have affected any new deposits to the system.

**Mitigation**\
References to the contract were removed from the user interface, and a fix was immediately deployed to mainnet and published via NPM.


# Introduction

[![PoolTogether Brand](https://github.com/pooltogether/pooltogether--brand-assets/blob/977e03604c49c63314450b5d432fe57d34747c66/logo/pooltogether-logo--purple-gradient.png?raw=true)](https://github.com/pooltogether/pooltogether--brand-assets)

## ✨ Introduction

PoolTogether is a decentralized protocol for no-loss prize games on the Ethereum blockchain. The protocol:

**1) Enables developers to build their own no-loss prize games**\
**2)** **Offers governance-managed no-loss prize games**

Prize games are pools of funds whose accrued interest is distributed as prizes. The concept is well-established and otherwise known as "[no loss lotteries](http://beniverson.org/papers/MaMa.pdf)" or "[prize savings accounts](https://en.wikipedia.org/wiki/Prize-linked_savings_account)".  All prize games created by the protocol share the same key characteristics:

* No loss of deposited funds
* Ability to withdraw at any time
* Fair prize distribution according to a prize strategy

Prize games can be differentiated in the following ways:

* The yield source the prize pool uses to generate no loss return
* The prize strategy used to determine frequency and distribution of prizes&#x20;
* The additional rewards offered by the prize pool
* The asset type the prize pool accepts for deposits&#x20;
* The fairness parameters&#x20;

### Governance

The PoolTogether Protocol is governed by the POOL token. [Read more here](/v3.3.0/governance/overview)

####

####


# Contracts

Official deployed PoolTogether contracts

PoolTogether is currently deployed to:

* [Ethereum](/v3.3.0/resources/networks/ethereum)
* [xDai](broken://pages/-MUyJ1zxFQ4jzIWrvUR1)
* [Matic](/v3.3.0/resources/networks/matic)
* [Binance](broken://pages/-MX--4FmqvF_hbvEiVCJ)


# Ethereum

## Mainnet

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.4.20** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract                         | Address                                                                                                               |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Dai Prize Pool                   | [0xEBfb47A7ad0FD6e57323C8A42B2E5A6a4F68fc1a](https://etherscan.io/address/0xEBfb47A7ad0FD6e57323C8A42B2E5A6a4F68fc1a) |
| Dai Prize Strategy               | [0x178969A87a78597d303C47198c66F68E8be67Dc2](https://etherscan.io/address/0x178969A87a78597d303C47198c66F68E8be67Dc2) |
| Dai POOL Faucet                  | [0xF362ce295F2A4eaE4348fFC8cDBCe8d729ccb8Eb](https://etherscan.io/address/0xF362ce295F2A4eaE4348fFC8cDBCe8d729ccb8Eb) |
| Dai Pod                          | [0x2f994e2E4F3395649eeE8A89092e63Ca526dA829](https://etherscan.io/address/0x2f994e2E4F3395649eeE8A89092e63Ca526dA829) |
| USDC Prize Pool                  | [0xde9ec95d7708b8319ccca4b8bc92c0a3b70bf416](https://etherscan.io/address/0xde9ec95d7708b8319ccca4b8bc92c0a3b70bf416) |
| USDC Prize Strategy              | [0x3d9946190907ada8b70381b25c71eb9adf5f9b7b](https://etherscan.io/address/0x3d9946190907ada8b70381b25c71eb9adf5f9b7b) |
| USDC POOL Faucet                 | [0xbd537257fad96e977b9e545be583bbf7028f30b9](https://etherscan.io/address/0xbd537257fad96e977b9e545be583bbf7028f30b9) |
| USDC Pod                         | [0x386EB78f2eE79AddE8Bdb0a0e27292755ebFea58](https://etherscan.io/address/0x386EB78f2eE79AddE8Bdb0a0e27292755ebFea58) |
| UNI Prize Pool                   | [0x0650d780292142835F6ac58dd8E2a336e87b4393](https://etherscan.io/address/0x0650d780292142835F6ac58dd8E2a336e87b4393) |
| UNI Prize Strategy               | [0xe8726B85236a489a8E84C56c95790d07a368f913](https://etherscan.io/address/0xe8726B85236a489a8E84C56c95790d07a368f913) |
| UNI POOL Faucet                  | [0xa5dddefD30e234Be2Ac6FC1a0364cFD337aa0f61](https://etherscan.io/address/0xa5dddefD30e234Be2Ac6FC1a0364cFD337aa0f61) |
| COMP Prize Pool                  | [0xBC82221e131c082336cf698F0cA3EBd18aFd4ce7](https://etherscan.io/address/0xBC82221e131c082336cf698F0cA3EBd18aFd4ce7) |
| COMP Prize Strategy              | [0x3ec4694b65e41f12d6b5d5ba7c2341f4d6859773](https://etherscan.io/address/0x3ec4694b65e41f12d6b5d5ba7c2341f4d6859773) |
| COMP POOL Faucet                 | [0x72F06a78bbAac0489067A1973B0Cef61841D58BC](https://etherscan.io/address/0x72F06a78bbAac0489067A1973B0Cef61841D58BC) |
| GUSD Prize Pool                  | [0x65C8827229FbD63f9de9FDfd400C9D264066A336](https://etherscan.io/address/0x65C8827229FbD63f9de9FDfd400C9D264066A336) |
| GUSD Prize Strategy              | [0x821cF440654addD81493e1949F9ee078D65bb57f](https://etherscan.io/address/0x821cF440654addD81493e1949F9ee078D65bb57f) |
| POOL Prize Pool                  | [0x396b4489da692788e327e2e4b2b0459a5ef26791](https://etherscan.io/address/0x396b4489da692788e327e2e4b2b0459a5ef26791) |
| POOL Prize Strategy              | [0x21e5e62e0b6b59155110cd36f3f6655fbbcf6424](https://etherscan.io/address/0x21e5e62e0b6b59155110cd36f3f6655fbbcf6424) |
| POOL POOL Faucet                 | [0x30430419b86e9512E6D93Fc2b0791d98DBeb637b](https://etherscan.io/address/0x30430419b86e9512E6D93Fc2b0791d98DBeb637b) |
| Loot Box ERC721                  | [0x4d695c615a7AACf2d7b9C481B66045BB2457Dfde](https://etherscan.io/address/0x4d695c615a7AACf2d7b9C481B66045BB2457Dfde) |
| Loot Box Prize Strategy Listener | [0xfe7205DF55BA42c8801e44B55BF05F06cCe8565E](https://etherscan.io/address/0xfe7205DF55BA42c8801e44B55BF05F06cCe8565E) |
| Aave USDT Prize Pool             | [0xc7d56c06F136EFff93e349C7BF8cc46bBF5D902c](https://etherscan.io/address/0xc7d56c06F136EFff93e349C7BF8cc46bBF5D902c) |
| Aave USDT Prize Strategy         | [0x2223d2e68e0990567f5e0451f4c027870ea07227](https://etherscan.io/address/0x2223d2e68e0990567f5e0451f4c027870ea07227) |
| Sushi Prize Pool                 | [0xc32a0f9dfe2d93e8a60ba0200e033a59aec91559](https://etherscan.io/address/0xc32a0f9dfe2d93e8a60ba0200e033a59aec91559) |
| Sushi Prize Strategy             | [0x94ac4f591908ad5a1ccc9e05d2d75b0dd62d97fa](https://etherscan.io/address/0x94ac4f591908ad5a1ccc9e05d2d75b0dd62d97fa) |
| Sushi Faucet                     | [0xddcf915656471b7c44217fb8c51f9888701e759a](https://etherscan.io/address/0xddcf915656471b7c44217fb8c51f9888701e759a) |
| USDT Prize Pool                  | [0x481f1BA81f7C01400831DfF18215961C3530D118](https://etherscan.io/address/0x481f1BA81f7C01400831DfF18215961C3530D118) |
| USDT Prize Strategy              | [0xc0fcdb4d882c28238cbcfbb023f87a7a7a1bdaa1](https://etherscan.io/address/0xc0fcdb4d882c28238cbcfbb023f87a7a7a1bdaa1) |
| Uniswap POOL LP Prize Pool       | [0x3AF7072D29Adde20FC7e173a7CB9e45307d2FB0A](https://etherscan.io/address/0x3AF7072D29Adde20FC7e173a7CB9e45307d2FB0A) |
| Uniswap POOL LP Faucet           | [0x9A29401EF1856b669f55Ae5b24505b3B6fAEb370](https://etherscan.io/address/0x9A29401EF1856b669f55Ae5b24505b3B6fAEb370) |
| Reserve Registry                 | [0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295](https://etherscan.io/address/0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295) |
| Pod Factory                      | [0x4e3a9F9fBAFB2EC49727cFfa2a411F7a0C1C4cE1](https://etherscan.io/address/0x4e3a9F9fBAFB2EC49727cFfa2a411F7a0C1C4cE1) |

### Configurable Reserve

**@pooltogether/configurable-reserve-contracts ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/configurable-reserve-contracts)

| Contract                                                                                                                            | Address                                                                                                               | Artifact                                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| [ConfigurableReserve](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/contracts/ConfigurableReserve.sol) | [0xd1797D46C3E825fce5215a0259D3426a5c49455C](https://etherscan.io/address/0xd1797D46C3E825fce5215a0259D3426a5c49455C) | [Artifact](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/deployments/mainnet/ConfigurableReserve.json) |

### Governance

**@pooltogether/governance ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/governance)

| Contract                                                                                          | Address                                                                                                               | Artifact                                                                                                            |
| ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [GovernorAlpha](https://github.com/pooltogether/governance/tree/main/contracts/GovernorAlpha.sol) | [0xB3a87172F555ae2a2AB79Be60B336D2F7D0187f0](https://etherscan.io/address/0xB3a87172F555ae2a2AB79Be60B336D2F7D0187f0) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/GovernorAlpha.json)             |
| [Pool](https://github.com/pooltogether/governance/tree/main/contracts/Pool.sol)                   | [0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e](https://etherscan.io/address/0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/Pool.json)                      |
| [Timelock](https://github.com/pooltogether/governance/tree/main/contracts/Timelock.sol)           | [0x42cd8312D2BCe04277dD5161832460e95b24262E](https://etherscan.io/address/0x42cd8312D2BCe04277dD5161832460e95b24262E) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/Timelock.json)                  |
| TreasuryVesterForTreasury                                                                         | [0x21950E281bDE1714ffd1062ed17c56D4D8de2359](https://etherscan.io/address/0x21950E281bDE1714ffd1062ed17c56D4D8de2359) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/TreasuryVesterForTreasury.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.2.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                               | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xb1D89477d1b505C261bab6e73f08fA834544CD21](https://etherscan.io/address/0xb1D89477d1b505C261bab6e73f08fA834544CD21) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mainnet/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F](https://etherscan.io/address/0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mainnet/RNGChainlink.json) |

### Loot Box Contracts

**@pooltogether/loot-box ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/loot-box)

| Contract                                                                                                                                    | Address                                                                                                               | Artifact                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [ERC721ControlledFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/ERC721ControlledFactory.sol)                         | [0x4E869b3A0978fA61DAbd7Da8F9B272AADc745Fb3](https://etherscan.io/address/0x4E869b3A0978fA61DAbd7Da8F9B272AADc745Fb3) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/ERC721ControlledFactory.json)             |
| [LootBoxController](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxController.sol)                                     | [0x2c2a966b7F5448A36EC9f896088DfB99B21d8A24](https://etherscan.io/address/0x2c2a966b7F5448A36EC9f896088DfB99B21d8A24) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/LootBoxController.json)                   |
| [LootBoxPrizeStrategyListenerFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxPrizeStrategyListenerFactory.sol) | [0x25e6a78D93D2935A638fDbd684e7b39565d0B7eA](https://etherscan.io/address/0x25e6a78D93D2935A638fDbd684e7b39565d0B7eA) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/LootBoxPrizeStrategyListenerFactory.json) |

### Retroactive Token Distribution

**@pooltogether/merkle-distributor ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/merkle-distributor)

| Contract                                                                                                          | Address                                                                                                               | Artifact                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [MerkleDistributor](https://github.com/pooltogether/merkle-distributor/tree/main/contracts/MerkleDistributor.sol) | [0xBE1a33519F586A4c8AA37525163Df8d67997016f](https://etherscan.io/address/0xBE1a33519F586A4c8AA37525163Df8d67997016f) | [Artifact](https://github.com/pooltogether/merkle-distributor/tree/main/deployments/mainnet/MerkleDistributor.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                               | Artifact                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0x14e09c3319244a84e7c1E7B52634f5220FA96623](https://etherscan.io/address/0x14e09c3319244a84e7c1E7B52634f5220FA96623) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/mainnet/GenericProxyFactory.json) |

### Prize Pool Registry

**@pooltogether/pooltogether-prizepool-registry ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizepool-registry)

| Contract        | Address                                                                                                               | Artifact                                                                                                                       |
| --------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| AddressRegistry | [0x34733851E2047F8d0e1aa91124A6f9EaDc54D253](https://etherscan.io/address/0x34733851E2047F8d0e1aa91124A6f9EaDc54D253) | [Artifact](https://github.com/pooltogether/pooltogether-prizepool-registry/tree/main/deployments/mainnet/AddressRegistry.json) |

### Pods Registry

**@pooltogether/pooltogether-pods-registry ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-registry)

| Contract     | Address                                                                                                               | Artifact                                                                                                                    |
| ------------ | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| PodsRegistry | [0x4658f736b93dCDdCbCe46cDe955970E697fd351f](https://etherscan.io/address/0x4658f736b93dCDdCbCe46cDe955970E697fd351f) | [Artifact](https://github.com/pooltogether/pooltogether-prizepool-registry/tree/main/deployments/mainnet/PodsRegistry.json) |

### Prize Strategy Upkeep

**@pooltogether/pooltogether-prizestrategy-upkeep ^1.0.6** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizestrategy-upkeep)

| Contract                                                                                                                             | Address                                                                                                               | Artifact                                                                                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| [PrizeStrategyUpkeep](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/contracts/PrizeStrategyUpkeep.sol) | [0xb9D70C3d7E4453Cc679D8A91145a28782268f229](https://etherscan.io/address/0xb9D70C3d7E4453Cc679D8A91145a28782268f229) | [Artifact](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/deployments/mainnet/PrizeStrategyUpkeep.json) |

### Pods Upkeep

**@pooltogether/pooltogether-pods-upkeep ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-upkeep)

| Contract                                                                                                    | Address                                                                                                               | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [PodsUpkeep](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/contracts/PodsUpkeep.sol) | [0x6c87C9960fac84F31AEc88964cA1270C70Ca6853](https://etherscan.io/address/0x6c87C9960fac84F31AEc88964cA1270C70Ca6853) | [Artifact](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/deployments/mainnet/PodsUpkeep.json) |

### Aave Yield Source

**@pooltogether/aave-yield-source ^1.0.3** [**npm**](https://www.npmjs.com/package/@pooltogether/aave-yield-source)

| Contract                                                                                                                      | Address                                                                                                               | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| AaveBUSDYieldSource                                                                                                           | [0x858415FdB262F17F7a63f6B1F6fEd7AF8308A1A7](https://etherscan.io/address/0x858415FdB262F17F7a63f6B1F6fEd7AF8308A1A7) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/AaveBUSDYieldSource.json) |
| AaveGUSDYieldSource                                                                                                           | [0x2bA1e000a381aD42af10C6e33aFe5994eE878D72](https://etherscan.io/address/0x2bA1e000a381aD42af10C6e33aFe5994eE878D72) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/AaveGUSDYieldSource.json) |
| AaveSUSDYieldSource                                                                                                           | [0x4C8D99B0c7022923ef1A81ADb4E4e326f8E91ac9](https://etherscan.io/address/0x4C8D99B0c7022923ef1A81ADb4E4e326f8E91ac9) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/AaveSUSDYieldSource.json) |
| AaveUSDTYieldSource                                                                                                           | [0x6E159B199423383572B7CB05FBbD54103A827F2b](https://etherscan.io/address/0x6E159B199423383572B7CB05FBbD54103A827F2b) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/AaveUSDTYieldSource.json) |
| [ATokenYieldSource](https://github.com/pooltogether/aave-yield-source/tree/main/contracts/yield-source/ATokenYieldSource.sol) | [0xBa71a9907e88925F59a3658C3a7618440Df6406E](https://etherscan.io/address/0xBa71a9907e88925F59a3658C3a7618440Df6406E) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mainnet/ATokenYieldSource.json)   |

### Sushi Yield Source

**@pooltogether/pooltogether-sushi-yield-source ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-sushi-yield-source)

| Contract                                                                                                          | Address                                                                                                               | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [SushiYieldSource](https://github.com/pooltogether/sushi-pooltogether/tree/master/contracts/SushiYieldSource.sol) | [0x9858aC37e385E52dA6385d828Cfe55a182D8ffA6](https://etherscan.io/address/0x9858aC37e385E52dA6385d828Cfe55a182D8ffA6) | [Artifact](https://github.com/pooltogether/sushi-pooltogether/tree/master/deployments/mainnet/SushiYieldSource.json) |

### EVM Bridge

**@pooltogether/pooltogether-evm-bridge ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-evm-bridge)

| Contract                                                                                                                                 | Address                                                                                                               | Artifact                                                                                                                           |
| ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| [PoolTogetherEVMBridgeRoot](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/contracts/PoolTogetherEVMBridgeRoot.sol) | [0xfe6c5Ae087366A7119f12946d07E04C94BB7A048](https://etherscan.io/address/0xfe6c5Ae087366A7119f12946d07E04C94BB7A048) | [Artifact](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/deployments/mainnet/PoolTogetherEVMBridgeRoot.json) |

### Multi Token Listener

**@pooltogether/multi-token-listener ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/multi-token-listener)

| Contract                                                                                                                | Address                                                                                                               | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [MultiTokenListener](https://github.com/pooltogether/multi-token-listener/tree/master/contracts/MultiTokenListener.sol) | [0x04458bA489cFa284ED8A693e3bea3e1DF600d022](https://etherscan.io/address/0x04458bA489cFa284ED8A693e3bea3e1DF600d022) | [Artifact](https://github.com/pooltogether/multi-token-listener/tree/master/deployments/mainnet/MultiTokenListener.json) |

## Rinkeby

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.4.20** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract            | Address                                                                                                                       |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Dai Prize Pool      | [0x4706856FA8Bb747D50b4EF8547FE51Ab5Edc4Ac2](https://rinkeby.etherscan.io/address/0x4706856FA8Bb747D50b4EF8547FE51Ab5Edc4Ac2) |
| Dai Prize Strategy  | [0x5E0A6d336667EACE5D1b33279B50055604c3E329](https://rinkeby.etherscan.io/address/0x5E0A6d336667EACE5D1b33279B50055604c3E329) |
| Dai Pod             | [0x4A26b34A902045CFb573aCb681550ba30AA79783](https://rinkeby.etherscan.io/address/0x4A26b34A902045CFb573aCb681550ba30AA79783) |
| USDC Prize Pool     | [0xde5275536231eCa2Dd506B9ccD73C028e16a9a32](https://rinkeby.etherscan.io/address/0xde5275536231eCa2Dd506B9ccD73C028e16a9a32) |
| USDC Prize Strategy | [0x1b92BC2F339ef25161711e4EafC31999C005aF21](https://rinkeby.etherscan.io/address/0x1b92BC2F339ef25161711e4EafC31999C005aF21) |
| USDC Pod            | [0x68c96179Cf9a90C589571Dc7AA94AD15d94e917d](https://rinkeby.etherscan.io/address/0x68c96179Cf9a90C589571Dc7AA94AD15d94e917d) |
| BAT Prize Pool      | [0xab068F220E10eEd899b54F1113dE7E354c9A8eB7](https://rinkeby.etherscan.io/address/0xab068F220E10eEd899b54F1113dE7E354c9A8eB7) |
| BAT Prize Strategy  | [0x41CF0758b7Cc2394b1C2dfF6133FEbb0Ef317C3b](https://rinkeby.etherscan.io/address/0x41CF0758b7Cc2394b1C2dfF6133FEbb0Ef317C3b) |
| Loot Box ERC721     | [0xfbC6677806253dB9739d0F6CBD89b9e7Ed4A5c66](https://rinkeby.etherscan.io/address/0xfbC6677806253dB9739d0F6CBD89b9e7Ed4A5c66) |
| USDT Prize Pool     | [0xDCB24C5C96D3D0677add5B688DCD144601410244](https://rinkeby.etherscan.io/address/0xDCB24C5C96D3D0677add5B688DCD144601410244) |
| USDT Prize Strategy | [0x1607ce8aDe05C324043D7f5362A6d856cd4Ae589](https://rinkeby.etherscan.io/address/0x1607ce8aDe05C324043D7f5362A6d856cd4Ae589) |
| Pod Factory         | [0x5C126F8F6107b2da41dAA8b7E4c3f4a01098A6db](https://rinkeby.etherscan.io/address/0x5C126F8F6107b2da41dAA8b7E4c3f4a01098A6db) |

### Builders

**@pooltogether/pooltogether-contracts ^3.3.10** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                                           | Address                                                                                                                       | Artifact                                                                                                                                      |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| cDaiYieldSource                                                                                                                                                                    | [0x2fD6fCf7b77884e670bc71bdAF736ab499BA6303](https://rinkeby.etherscan.io/address/0x2fD6fCf7b77884e670bc71bdAF736ab499BA6303) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/cDaiYieldSource.json)                  |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/ControlledTokenBuilder.sol)                                    | [0x800b7509a509240575d584DEEf73095a11982FbF](https://rinkeby.etherscan.io/address/0x800b7509a509240575d584DEEf73095a11982FbF) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/ControlledTokenBuilder.json)           |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/MultipleWinnersBuilder.sol)                                    | [0x66490f79b4082F127B516efF0b3faAB03D4AEd73](https://rinkeby.etherscan.io/address/0x66490f79b4082F127B516efF0b3faAB03D4AEd73) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/MultipleWinnersBuilder.json)           |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/PoolWithMultipleWinnersBuilder.sol)                    | [0xDA260C42fF6755F1B106ecC877071AaF77587e63](https://rinkeby.etherscan.io/address/0xDA260C42fF6755F1B106ecC877071AaF77587e63) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/PoolWithMultipleWinnersBuilder.json)   |
| [TokenFaucetProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/token-faucet/TokenFaucetProxyFactory.sol)                              | [0x7a20A866c24CFfb0bd80754C133F4F9487dB2AA1](https://rinkeby.etherscan.io/address/0x7a20A866c24CFfb0bd80754C133F4F9487dB2AA1) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/TokenFaucetProxyFactory.json)          |
| [YieldSourcePrizePoolProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/prize-pool/yield-source/YieldSourcePrizePoolProxyFactory.sol) | [0x91493d48136b251e125a02a7e2a9AE1ab4A553C3](https://rinkeby.etherscan.io/address/0x91493d48136b251e125a02a7e2a9AE1ab4A553C3) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/rinkeby/YieldSourcePrizePoolProxyFactory.json) |

### Governance

**@pooltogether/governance ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/governance)

| Contract                                                                                          | Address                                                                                                                       | Artifact                                                                                                            |
| ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [GovernorAlpha](https://github.com/pooltogether/governance/tree/main/contracts/GovernorAlpha.sol) | [0x9B63243CD27102fbEc9FAf67CA1a858dcC16Ee01](https://rinkeby.etherscan.io/address/0x9B63243CD27102fbEc9FAf67CA1a858dcC16Ee01) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/GovernorAlpha.json)             |
| [Pool](https://github.com/pooltogether/governance/tree/main/contracts/Pool.sol)                   | [0xc4E90a8Dc6CaAb329f08ED3C8abc6b197Cf0F40A](https://rinkeby.etherscan.io/address/0xc4E90a8Dc6CaAb329f08ED3C8abc6b197Cf0F40A) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/Pool.json)                      |
| [Timelock](https://github.com/pooltogether/governance/tree/main/contracts/Timelock.sol)           | [0x8Df0AfB54836dc8D0AE795503F837Cff197d3df1](https://rinkeby.etherscan.io/address/0x8Df0AfB54836dc8D0AE795503F837Cff197d3df1) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/Timelock.json)                  |
| TreasuryVesterForTreasury                                                                         | [0x529a916B8B7EC8E01805D45AEd1109C764ea88B9](https://rinkeby.etherscan.io/address/0x529a916B8B7EC8E01805D45AEd1109C764ea88B9) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/TreasuryVesterForTreasury.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.2.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                       | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xA932e74d5263A754Ea04432E5c53658434b0484B](https://rinkeby.etherscan.io/address/0xA932e74d5263A754Ea04432E5c53658434b0484B) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/rinkeby/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0x11D94431718934868C4339aFc5ea27585F46C99A](https://rinkeby.etherscan.io/address/0x11D94431718934868C4339aFc5ea27585F46C99A) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/rinkeby/RNGChainlink.json) |

### Loot Box Contracts

**@pooltogether/loot-box ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/loot-box)

| Contract                                                                                                                                    | Address                                                                                                                       | Artifact                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [ERC1155Mintable](https://github.com/pooltogether/loot-box/tree/main/contracts/test/ERC1155Mintable.sol)                                    | [0x72De7A75Fb7c094e410205aFAF9615E7dAA120b3](https://rinkeby.etherscan.io/address/0x72De7A75Fb7c094e410205aFAF9615E7dAA120b3) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC1155Mintable.json)                     |
| [ERC20Mintable](https://github.com/pooltogether/loot-box/tree/main/contracts/test/ERC20Mintable.sol)                                        | [0xdD1cba915Be9c7a1e60c4B99DADE1FC49F67f80D](https://rinkeby.etherscan.io/address/0xdD1cba915Be9c7a1e60c4B99DADE1FC49F67f80D) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC20Mintable.json)                       |
| [ERC721ControlledFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/ERC721ControlledFactory.sol)                         | [0x1D90F79a8515F63881075Ec2C212e18272aD9E38](https://rinkeby.etherscan.io/address/0x1D90F79a8515F63881075Ec2C212e18272aD9E38) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC721ControlledFactory.json)             |
| [ERC721Mintable](https://github.com/pooltogether/loot-box/tree/main/contracts/test/ERC721Mintable.sol)                                      | [0x0F5963607bE6f255549cA684F01ff1D7FC6d3B0B](https://rinkeby.etherscan.io/address/0x0F5963607bE6f255549cA684F01ff1D7FC6d3B0B) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC721Mintable.json)                      |
| [ERC777Mintable](https://github.com/pooltogether/loot-box/tree/main/contracts/test/ERC777Mintable.sol)                                      | [0x8c26F9526a0b9639Edb7080dFba596e8FeFafAcC](https://rinkeby.etherscan.io/address/0x8c26F9526a0b9639Edb7080dFba596e8FeFafAcC) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC777Mintable.json)                      |
| [LootBoxController](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxController.sol)                                     | [0xb1EAc75da9bc31B078742C5AF9EDe62EFE31299D](https://rinkeby.etherscan.io/address/0xb1EAc75da9bc31B078742C5AF9EDe62EFE31299D) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/LootBoxController.json)                   |
| [LootBoxPrizeStrategyListenerFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxPrizeStrategyListenerFactory.sol) | [0xadB4D93D84b18b5D82063aCf58b21587c92fdfb5](https://rinkeby.etherscan.io/address/0xadB4D93D84b18b5D82063aCf58b21587c92fdfb5) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/LootBoxPrizeStrategyListenerFactory.json) |

### Retroactive Token Distribution

**@pooltogether/merkle-distributor ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/merkle-distributor)

| Contract                                                                                                          | Address                                                                                                                       | Artifact                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [MerkleDistributor](https://github.com/pooltogether/merkle-distributor/tree/main/contracts/MerkleDistributor.sol) | [0x93a6540DcE05a4A5E5B906eB97bBCBb723768F2D](https://rinkeby.etherscan.io/address/0x93a6540DcE05a4A5E5B906eB97bBCBb723768F2D) | [Artifact](https://github.com/pooltogether/merkle-distributor/tree/main/deployments/rinkeby/MerkleDistributor.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                                       | Artifact                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0x594069c560D260F90C21Be25fD2C8684efbb5628](https://rinkeby.etherscan.io/address/0x594069c560D260F90C21Be25fD2C8684efbb5628) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/rinkeby/GenericProxyFactory.json) |

### Prize Pool Registry

**@pooltogether/pooltogether-prizepool-registry ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizepool-registry)

| Contract        | Address                                                                                                                       | Artifact                                                                                                                       |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| AddressRegistry | [0xF76f17682888a738a6DF40aa63ac2b4B1a380831](https://rinkeby.etherscan.io/address/0xF76f17682888a738a6DF40aa63ac2b4B1a380831) | [Artifact](https://github.com/pooltogether/pooltogether-prizepool-registry/tree/main/deployments/rinkeby/AddressRegistry.json) |

### Pods Registry

**@pooltogether/pooltogether-pods-registry ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-registry)

| Contract     | Address                                                                                                                       | Artifact                                                                                                                    |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| PodsRegistry | [0xB917f266424B803F389c79B86609710247a0370f](https://rinkeby.etherscan.io/address/0xB917f266424B803F389c79B86609710247a0370f) | [Artifact](https://github.com/pooltogether/pooltogether-prizepool-registry/tree/main/deployments/rinkeby/PodsRegistry.json) |

### Prize Strategy Upkeep

**@pooltogether/pooltogether-prizestrategy-upkeep ^1.0.6** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizestrategy-upkeep)

| Contract                                                                                                                             | Address                                                                                                                       | Artifact                                                                                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| [PrizeStrategyUpkeep](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/contracts/PrizeStrategyUpkeep.sol) | [0x3fBCb09Ee774F7e32Ba4D60d1E2D4CB9CE703984](https://rinkeby.etherscan.io/address/0x3fBCb09Ee774F7e32Ba4D60d1E2D4CB9CE703984) | [Artifact](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/deployments/rinkeby/PrizeStrategyUpkeep.json) |

### Pods Upkeep

**@pooltogether/pooltogether-pods-upkeep ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-upkeep)

| Contract                                                                                                    | Address                                                                                                                       | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [PodsUpkeep](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/contracts/PodsUpkeep.sol) | [0x3F861649a7517af171ff845a5cb7aE6ACeEbd6aA](https://rinkeby.etherscan.io/address/0x3F861649a7517af171ff845a5cb7aE6ACeEbd6aA) | [Artifact](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/deployments/rinkeby/PodsUpkeep.json) |

### Sushi Yield Source

**@pooltogether/pooltogether-sushi-yield-source ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-sushi-yield-source)

| Contract                                                                                                          | Address                                                                                                                       | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [SushiYieldSource](https://github.com/pooltogether/sushi-pooltogether/tree/master/contracts/SushiYieldSource.sol) | [0x248FCb04de8901c32e0815349f071542556cCF91](https://rinkeby.etherscan.io/address/0x248FCb04de8901c32e0815349f071542556cCF91) | [Artifact](https://github.com/pooltogether/sushi-pooltogether/tree/master/deployments/rinkeby/SushiYieldSource.json) |

### Multi Token Listener

**@pooltogether/multi-token-listener ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/multi-token-listener)

| Contract                                                                                                                | Address                                                                                                                       | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [MultiTokenListener](https://github.com/pooltogether/multi-token-listener/tree/master/contracts/MultiTokenListener.sol) | [0xDC78901e0FC2097B07008f98Fb28F57fBA0a2CB7](https://rinkeby.etherscan.io/address/0xDC78901e0FC2097B07008f98Fb28F57fBA0a2CB7) | [Artifact](https://github.com/pooltogether/multi-token-listener/tree/master/deployments/rinkeby/MultiTokenListener.json) |

## Kovan

### Builders

**@pooltogether/pooltogether-contracts ^3.3.10** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                                           | Address                                                                                                                     | Artifact                                                                                                                                    |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| cDaiYieldSource                                                                                                                                                                    | [0xB3e8bBD6CB0443e0dc59602825Dc6854D7ec5c4b](https://kovan.etherscan.io/address/0xB3e8bBD6CB0443e0dc59602825Dc6854D7ec5c4b) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/cDaiYieldSource.json)                  |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/ControlledTokenBuilder.sol)                                    | [0x72Edd573E230C7d68274Bf718A4C6aD82b5d5f90](https://kovan.etherscan.io/address/0x72Edd573E230C7d68274Bf718A4C6aD82b5d5f90) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/ControlledTokenBuilder.json)           |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/MultipleWinnersBuilder.sol)                                    | [0x5effa0823e486A5ED1D49d88A1374Fc337e1f9F4](https://kovan.etherscan.io/address/0x5effa0823e486A5ED1D49d88A1374Fc337e1f9F4) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/MultipleWinnersBuilder.json)           |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/PoolWithMultipleWinnersBuilder.sol)                    | [0x53A2E4F8BFe581bC28e0d1d30808ffB163E53A46](https://kovan.etherscan.io/address/0x53A2E4F8BFe581bC28e0d1d30808ffB163E53A46) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/PoolWithMultipleWinnersBuilder.json)   |
| [TokenFaucetProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/token-faucet/TokenFaucetProxyFactory.sol)                              | [0x41122Ca50202d13c809dfE88F60Da212A1525Ed7](https://kovan.etherscan.io/address/0x41122Ca50202d13c809dfE88F60Da212A1525Ed7) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/TokenFaucetProxyFactory.json)          |
| [YieldSourcePrizePoolProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/prize-pool/yield-source/YieldSourcePrizePoolProxyFactory.sol) | [0x08411ADd0b5AA8ee47563b146743C13b3556c9Cc](https://kovan.etherscan.io/address/0x08411ADd0b5AA8ee47563b146743C13b3556c9Cc) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/kovan/YieldSourcePrizePoolProxyFactory.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.2.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                     | Artifact                                                                                                               |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xe20ba80D263246537592B14211746E438be6b756](https://kovan.etherscan.io/address/0xe20ba80D263246537592B14211746E438be6b756) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/kovan/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0x0FcEDB079E56F336840Aa0c0f20816CcE7de63B6](https://kovan.etherscan.io/address/0x0FcEDB079E56F336840Aa0c0f20816CcE7de63B6) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/kovan/RNGChainlink.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                                     | Artifact                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0x713edC7728C4F0BCc135D48fF96282444d77E604](https://kovan.etherscan.io/address/0x713edC7728C4F0BCc135D48fF96282444d77E604) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/kovan/GenericProxyFactory.json) |

### Prize Strategy Upkeep

**@pooltogether/pooltogether-prizestrategy-upkeep ^1.0.6** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-prizestrategy-upkeep)

| Contract                                                                                                                             | Address                                                                                                                     | Artifact                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| PrizePoolRegistry                                                                                                                    | [0x8817bB292941e1A69F12879B274c8A15D315ABb1](https://kovan.etherscan.io/address/0x8817bB292941e1A69F12879B274c8A15D315ABb1) | [Artifact](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/deployments/kovan/PrizePoolRegistry.json)   |
| [PrizeStrategyUpkeep](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/contracts/PrizeStrategyUpkeep.sol) | [0xb853503F62779ac16068A8fc40B84Ee174b50337](https://kovan.etherscan.io/address/0xb853503F62779ac16068A8fc40B84Ee174b50337) | [Artifact](https://github.com/pooltogether/pooltogether-prizestrategy-upkeep/tree/main/deployments/kovan/PrizeStrategyUpkeep.json) |

### Pods Upkeep

**@pooltogether/pooltogether-pods-upkeep ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-pods-upkeep)

| Contract     | Address                                                                                                                     | Artifact                                                                                                             |
| ------------ | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| PodsRegistry | [0x9DA83B2EAc639EBcA7c070532453822cBc3266c0](https://kovan.etherscan.io/address/0x9DA83B2EAc639EBcA7c070532453822cBc3266c0) | [Artifact](https://github.com/pooltogether/pooltogether-pods-upkeep/tree/master/deployments/kovan/PodsRegistry.json) |

### Aave Yield Source

**@pooltogether/aave-yield-source ^1.0.3** [**npm**](https://www.npmjs.com/package/@pooltogether/aave-yield-source)

| Contract                                                                                                                      | Address                                                                                                                     | Artifact                                                                                                           |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| AaveAAVEYieldSource                                                                                                           | [0x495F5751780FE4F0dfCd7E43215F250ecE671Fe2](https://kovan.etherscan.io/address/0x495F5751780FE4F0dfCd7E43215F250ecE671Fe2) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveAAVEYieldSource.json) |
| AaveBATYieldSource                                                                                                            | [0xB1f5Bd3486dAEff298f3DB631F0ae9db9aCF7F22](https://kovan.etherscan.io/address/0xB1f5Bd3486dAEff298f3DB631F0ae9db9aCF7F22) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveBATYieldSource.json)  |
| AaveBUSDYieldSource                                                                                                           | [0x80e9186658Bcb2cd70cdd07B2552a6aFDD0fd04c](https://kovan.etherscan.io/address/0x80e9186658Bcb2cd70cdd07B2552a6aFDD0fd04c) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveBUSDYieldSource.json) |
| AaveDAIYieldSource                                                                                                            | [0xA36600E9A97fbfb0123312A9510a5b1A87e9DA5D](https://kovan.etherscan.io/address/0xA36600E9A97fbfb0123312A9510a5b1A87e9DA5D) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveDAIYieldSource.json)  |
| AaveENJYieldSource                                                                                                            | [0xEc1882A1B4177dE860A08A94a9a879Af79AE56DD](https://kovan.etherscan.io/address/0xEc1882A1B4177dE860A08A94a9a879Af79AE56DD) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveENJYieldSource.json)  |
| AaveKNCYieldSource                                                                                                            | [0x7D6435431bd94e11f0841633B4438F43689c4509](https://kovan.etherscan.io/address/0x7D6435431bd94e11f0841633B4438F43689c4509) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveKNCYieldSource.json)  |
| AaveLINKYieldSource                                                                                                           | [0x0142f2B70096EB85e445E4AaC6E6EA6080b2b24b](https://kovan.etherscan.io/address/0x0142f2B70096EB85e445E4AaC6E6EA6080b2b24b) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveLINKYieldSource.json) |
| AaveMANAYieldSource                                                                                                           | [0xCD54847e1Cf0842af9DD161D34bF885AB4860a39](https://kovan.etherscan.io/address/0xCD54847e1Cf0842af9DD161D34bF885AB4860a39) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveMANAYieldSource.json) |
| AaveMKRYieldSource                                                                                                            | [0xC4ab4345cb443770F4d14a3dA48A4cB5A40cf25b](https://kovan.etherscan.io/address/0xC4ab4345cb443770F4d14a3dA48A4cB5A40cf25b) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/AaveMKRYieldSource.json)  |
| [ATokenYieldSource](https://github.com/pooltogether/aave-yield-source/tree/main/contracts/yield-source/ATokenYieldSource.sol) | [0x96161e596b14aae63Edcf7Ca3fE3470F6A7f3F1B](https://kovan.etherscan.io/address/0x96161e596b14aae63Edcf7Ca3fE3470F6A7f3F1B) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/kovan/ATokenYieldSource.json)   |

### Sushi Yield Source

**@pooltogether/pooltogether-sushi-yield-source ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-sushi-yield-source)

| Contract                                                                                                          | Address                                                                                                                     | Artifact                                                                                                           |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| [SushiYieldSource](https://github.com/pooltogether/sushi-pooltogether/tree/master/contracts/SushiYieldSource.sol) | [0x559Aa5568543678793fA3d4A839815e68E183D5c](https://kovan.etherscan.io/address/0x559Aa5568543678793fA3d4A839815e68E183D5c) | [Artifact](https://github.com/pooltogether/sushi-pooltogether/tree/master/deployments/kovan/SushiYieldSource.json) |


# Matic

## Matic

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.4.20** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract            | Address                                                                                                                                  |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Dai Prize Pool      | [0xfecfa775643eb8c0f755491ba4569e501764da51](https://explorer-mainnet.maticvigil.com/address/0xfecfa775643eb8c0f755491ba4569e501764da51) |
| Dai Prize Strategy  | [0x94a0c72b4fec5b1abac88500c56a15c656b8a027](https://explorer-mainnet.maticvigil.com/address/0x94a0c72b4fec5b1abac88500c56a15c656b8a027) |
| USDT Prize Pool     | [0x887E17D791Dcb44BfdDa3023D26F7a04Ca9C7EF4](https://explorer-mainnet.maticvigil.com/address/0x887E17D791Dcb44BfdDa3023D26F7a04Ca9C7EF4) |
| USDT Prize Strategy | [0x5A65f0CE666B8334b6481A8d8C8323BB782386e6](https://explorer-mainnet.maticvigil.com/address/0x5A65f0CE666B8334b6481A8d8C8323BB782386e6) |
| USDT Token Faucet   | [0x90a8d8Ee6fDb1875028C6537877E6704b2646c51](https://explorer-mainnet.maticvigil.com/address/0x90a8d8Ee6fDb1875028C6537877E6704b2646c51) |

### Configurable Reserve

**@pooltogether/configurable-reserve-contracts ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/configurable-reserve-contracts)

| Contract                                                                                                                            | Address                                                                                                                                  | Artifact                                                                                                                          |
| ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| [ConfigurableReserve](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/contracts/ConfigurableReserve.sol) | [0xdEcD3c72187325C26f85099A89EED6D5bB4604D3](https://explorer-mainnet.maticvigil.com/address/0xdEcD3c72187325C26f85099A89EED6D5bB4604D3) | [Artifact](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/deployments/matic/ConfigurableReserve.json) |

### Builders

**@pooltogether/pooltogether-contracts ^3.3.10** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                                           | Address                                                                                                                                  | Artifact                                                                                                                                    |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/ControlledTokenBuilder.sol)                                    | [0x317625b28Acb3C0540DB00b179D84D9b804277f7](https://explorer-mainnet.maticvigil.com/address/0x317625b28Acb3C0540DB00b179D84D9b804277f7) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/matic/ControlledTokenBuilder.json)           |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/MultipleWinnersBuilder.sol)                                    | [0x72Edd573E230C7d68274Bf718A4C6aD82b5d5f90](https://explorer-mainnet.maticvigil.com/address/0x72Edd573E230C7d68274Bf718A4C6aD82b5d5f90) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/matic/MultipleWinnersBuilder.json)           |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/PoolWithMultipleWinnersBuilder.sol)                    | [0x5effa0823e486A5ED1D49d88A1374Fc337e1f9F4](https://explorer-mainnet.maticvigil.com/address/0x5effa0823e486A5ED1D49d88A1374Fc337e1f9F4) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/matic/PoolWithMultipleWinnersBuilder.json)   |
| [Reserve](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/reserve/Reserve.sol)                                                                   | [0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295](https://explorer-mainnet.maticvigil.com/address/0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/matic/Reserve.json)                          |
| ReserveRegistry                                                                                                                                                                    | [0x20F29CCaE4c9886964033042c6b79c2C4C816308](https://explorer-mainnet.maticvigil.com/address/0x20F29CCaE4c9886964033042c6b79c2C4C816308) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/matic/ReserveRegistry.json)                  |
| [TokenFaucetProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/token-faucet/TokenFaucetProxyFactory.sol)                              | [0xB3e8bBD6CB0443e0dc59602825Dc6854D7ec5c4b](https://explorer-mainnet.maticvigil.com/address/0xB3e8bBD6CB0443e0dc59602825Dc6854D7ec5c4b) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/matic/TokenFaucetProxyFactory.json)          |
| [YieldSourcePrizePoolProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/prize-pool/yield-source/YieldSourcePrizePoolProxyFactory.sol) | [0x4d1639e4b237BCab6F908A1CEb0995716D5ebE36](https://explorer-mainnet.maticvigil.com/address/0x4d1639e4b237BCab6F908A1CEb0995716D5ebE36) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/matic/YieldSourcePrizePoolProxyFactory.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.2.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                                  | Artifact                                                                                                               |
| ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F](https://explorer-mainnet.maticvigil.com/address/0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/matic/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0xEccfB4F7aB44effE457e399cebAa04A95a9061d8](https://explorer-mainnet.maticvigil.com/address/0xEccfB4F7aB44effE457e399cebAa04A95a9061d8) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/matic/RNGChainlink.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                                                  | Artifact                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0xd1797D46C3E825fce5215a0259D3426a5c49455C](https://explorer-mainnet.maticvigil.com/address/0xd1797D46C3E825fce5215a0259D3426a5c49455C) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/matic/GenericProxyFactory.json) |

### Aave Yield Source

**@pooltogether/aave-yield-source ^1.0.3** [**npm**](https://www.npmjs.com/package/@pooltogether/aave-yield-source)

| Contract                                                                                                                      | Address                                                                                                                                  | Artifact                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| AaveAAVEYieldSource                                                                                                           | [0xEbED994f97396106f7B3d55C287A6A51128cDBB1](https://explorer-mainnet.maticvigil.com/address/0xEbED994f97396106f7B3d55C287A6A51128cDBB1) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveAAVEYieldSource.json)   |
| AaveDAIYieldSource                                                                                                            | [0x2FA36043BC27C8Da595F32099f4e8E5Ae48cf46e](https://explorer-mainnet.maticvigil.com/address/0x2FA36043BC27C8Da595F32099f4e8E5Ae48cf46e) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveDAIYieldSource.json)    |
| AaveUSDCYieldSource                                                                                                           | [0xABCea7B7f5ea7929b1Df9e3e7241547Fe7b7af14](https://explorer-mainnet.maticvigil.com/address/0xABCea7B7f5ea7929b1Df9e3e7241547Fe7b7af14) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveUSDCYieldSource.json)   |
| AaveUSDTYieldSource                                                                                                           | [0x3C7CdFb942eb98cCe7e4d004e2927788CD9E54fe](https://explorer-mainnet.maticvigil.com/address/0x3C7CdFb942eb98cCe7e4d004e2927788CD9E54fe) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveUSDTYieldSource.json)   |
| AaveWBTCYieldSource                                                                                                           | [0x46CEB180cd117C333Faebd98DbC31BeE32e7c116](https://explorer-mainnet.maticvigil.com/address/0x46CEB180cd117C333Faebd98DbC31BeE32e7c116) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveWBTCYieldSource.json)   |
| AaveWETHYieldSource                                                                                                           | [0x37c7Fc5fF5e265AE0fA12D2367fbDdA7D22c862C](https://explorer-mainnet.maticvigil.com/address/0x37c7Fc5fF5e265AE0fA12D2367fbDdA7D22c862C) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveWETHYieldSource.json)   |
| AaveWMATICYieldSource                                                                                                         | [0x4570Ab872EbF376caBbbB0CBecb985dFe2757900](https://explorer-mainnet.maticvigil.com/address/0x4570Ab872EbF376caBbbB0CBecb985dFe2757900) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/AaveWMATICYieldSource.json) |
| [ATokenYieldSource](https://github.com/pooltogether/aave-yield-source/tree/main/contracts/yield-source/ATokenYieldSource.sol) | [0xd06814AC6CD4A5192E3767a7329a731A3d2E3F1C](https://explorer-mainnet.maticvigil.com/address/0xd06814AC6CD4A5192E3767a7329a731A3d2E3F1C) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/matic/ATokenYieldSource.json)     |

### EVM Bridge

**@pooltogether/pooltogether-evm-bridge ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-evm-bridge)

| Contract                                                                                                                                   | Address                                                                                                                                  | Artifact                                                                                                                          |
| ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| [PoolTogetherEVMBridgeChild](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/contracts/PoolTogetherEVMBridgeChild.sol) | [0xfaB3b5c4F7959579e350532600707e0269e01F38](https://explorer-mainnet.maticvigil.com/address/0xfaB3b5c4F7959579e350532600707e0269e01F38) | [Artifact](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/deployments/matic/PoolTogetherEVMBridgeChild.json) |
| [TestContract](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/contracts/test/TestContract.sol)                        | [0xc404c2e69cc82dF8e2F22221f1D1d8e6663bc5F5](https://explorer-mainnet.maticvigil.com/address/0xc404c2e69cc82dF8e2F22221f1D1d8e6663bc5F5) | [Artifact](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/deployments/matic/TestContract.json)               |

### Multi Token Listener

**@pooltogether/multi-token-listener ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/multi-token-listener)

| Contract                                                                                                                | Address                                                                                                                                  | Artifact                                                                                                               |
| ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| [MultiTokenListener](https://github.com/pooltogether/multi-token-listener/tree/master/contracts/MultiTokenListener.sol) | [0x8a4416453340ECF6c489eFf3030EDb632b0087B2](https://explorer-mainnet.maticvigil.com/address/0x8a4416453340ECF6c489eFf3030EDb632b0087B2) | [Artifact](https://github.com/pooltogether/multi-token-listener/tree/master/deployments/matic/MultiTokenListener.json) |

## Mumbai

### Configurable Reserve

**@pooltogether/configurable-reserve-contracts ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/configurable-reserve-contracts)

| Contract                                                                                                                            | Address                                                                                                                                 | Artifact                                                                                                                           |
| ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| [ConfigurableReserve](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/contracts/ConfigurableReserve.sol) | [0x941011a95ad6a69d3b06218A3b74a3f6296481A8](https://explorer-mumbai.maticvigil.com/address/0x941011a95ad6a69d3b06218A3b74a3f6296481A8) | [Artifact](https://github.com/pooltogether/pooltogether-reserve-contracts/tree/master/deployments/mumbai/ConfigurableReserve.json) |

### Builders

**@pooltogether/pooltogether-contracts ^3.3.10** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                                           | Address                                                                                                                                 | Artifact                                                                                                                                     |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/ControlledTokenBuilder.sol)                                    | [0x6aeBE10a4607B1002ea56D825Ee18Ce751fD9592](https://explorer-mumbai.maticvigil.com/address/0x6aeBE10a4607B1002ea56D825Ee18Ce751fD9592) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/ControlledTokenBuilder.json)           |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/MultipleWinnersBuilder.sol)                                    | [0xdE55668e38FEcD037BFA40AcFD7d30e58F9143D4](https://explorer-mumbai.maticvigil.com/address/0xdE55668e38FEcD037BFA40AcFD7d30e58F9143D4) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/MultipleWinnersBuilder.json)           |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/builders/PoolWithMultipleWinnersBuilder.sol)                    | [0xBA79b0aC8818e1515F51fEF240F4228F29F64948](https://explorer-mumbai.maticvigil.com/address/0xBA79b0aC8818e1515F51fEF240F4228F29F64948) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/PoolWithMultipleWinnersBuilder.json)   |
| [TokenFaucetProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/token-faucet/TokenFaucetProxyFactory.sol)                              | [0x58aF4554c0DB496EFdf93bB344eC513C5627Efb9](https://explorer-mumbai.maticvigil.com/address/0x58aF4554c0DB496EFdf93bB344eC513C5627Efb9) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/TokenFaucetProxyFactory.json)          |
| [YieldSourcePrizePoolProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/contracts/prize-pool/yield-source/YieldSourcePrizePoolProxyFactory.sol) | [0xdc488E6e8c55a11d20032997cd1fF7c4951401df](https://explorer-mumbai.maticvigil.com/address/0xdc488E6e8c55a11d20032997cd1fF7c4951401df) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/master/deployments/mumbai/YieldSourcePrizePoolProxyFactory.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.2.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                                 | Artifact                                                                                                                |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xE1d06d492107F14AE024c357005c5c692158B13D](https://explorer-mumbai.maticvigil.com/address/0xE1d06d492107F14AE024c357005c5c692158B13D) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mumbai/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0x9eA5656117f4d42CF82AfE2d9686004BDaAea2B3](https://explorer-mumbai.maticvigil.com/address/0x9eA5656117f4d42CF82AfE2d9686004BDaAea2B3) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mumbai/RNGChainlink.json) |

### Generic Proxy Factory

**@pooltogether/pooltogether-proxy-factory ^1.0.0.beta.3** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-proxy-factory)

| Contract                                                                                                                      | Address                                                                                                                                 | Artifact                                                                                                                     |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [GenericProxyFactory](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/contracts/GenericProxyFactory.sol) | [0xd1797D46C3E825fce5215a0259D3426a5c49455C](https://explorer-mumbai.maticvigil.com/address/0xd1797D46C3E825fce5215a0259D3426a5c49455C) | [Artifact](https://github.com/pooltogether/pooltogether-proxy-factory/tree/main/deployments/mumbai/GenericProxyFactory.json) |

### Aave Yield Source

**@pooltogether/aave-yield-source ^1.0.3** [**npm**](https://www.npmjs.com/package/@pooltogether/aave-yield-source)

| Contract                                                                                                                      | Address                                                                                                                                 | Artifact                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| AaveAAVEYieldSource                                                                                                           | [0x31c457b2AdD91196B3B0Ed9D0bFAFF22052fA38a](https://explorer-mumbai.maticvigil.com/address/0x31c457b2AdD91196B3B0Ed9D0bFAFF22052fA38a) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mumbai/AaveAAVEYieldSource.json) |
| [ATokenYieldSource](https://github.com/pooltogether/aave-yield-source/tree/main/contracts/yield-source/ATokenYieldSource.sol) | [0x6cFbf44ac86eFB9110c3b7D393E783bAEEf243D2](https://explorer-mumbai.maticvigil.com/address/0x6cFbf44ac86eFB9110c3b7D393E783bAEEf243D2) | [Artifact](https://github.com/pooltogether/aave-yield-source/tree/main/deployments/mumbai/ATokenYieldSource.json)   |

### EVM Bridge

**@pooltogether/pooltogether-evm-bridge ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-evm-bridge)

| Contract                                                                                                                                   | Address                                                                                                                                 | Artifact                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| [PoolTogetherEVMBridgeChild](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/contracts/PoolTogetherEVMBridgeChild.sol) | [0x3F861649a7517af171ff845a5cb7aE6ACeEbd6aA](https://explorer-mumbai.maticvigil.com/address/0x3F861649a7517af171ff845a5cb7aE6ACeEbd6aA) | [Artifact](https://github.com/pooltogether/pooltogether-evm-bridge/tree/master/deployments/mumbai/PoolTogetherEVMBridgeChild.json) |

### Multi Token Listener

**@pooltogether/multi-token-listener ^1.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/multi-token-listener)

| Contract                                                                                                                | Address                                                                                                                                 | Artifact                                                                                                                |
| ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| [MultiTokenListener](https://github.com/pooltogether/multi-token-listener/tree/master/contracts/MultiTokenListener.sol) | [0xB29A3c1a9d4eFa7391e685bFD2654ea31E2f3125](https://explorer-mumbai.maticvigil.com/address/0xB29A3c1a9d4eFa7391e685bFD2654ea31E2f3125) | [Artifact](https://github.com/pooltogether/multi-token-listener/tree/master/deployments/mumbai/MultiTokenListener.json) |


# Tokens

A list of tokens and the networks they bridge across

## Token List

PoolTogether has a [Token List](https://github.com/pooltogether/pooltogether-token-list) that you can plug into Uniswap-compatible AMMS.

## Bridged Tokens

| Token    | Ethereum Address                                                                                                      | Polygon Address                                                                                                                                         |
| -------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| POOL     | [0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e](https://etherscan.io/address/0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e) | [0x25788a1a171ec66da6502f9975a15b609ff54cf6](https://explorer-mainnet.maticvigil.com/tokens/0x25788a1a171ec66Da6502f9975a15B609fF54CF6/token-transfers) |
| Pod USDC | [0x386EB78f2eE79AddE8Bdb0a0e27292755ebFea58](https://etherscan.io/address/0x386EB78f2eE79AddE8Bdb0a0e27292755ebFea58) | [0x96d161cbf38FACCeD333851A9cEf20936DDA88F4](https://explorer-mainnet.maticvigil.com/address/0x96d161cbf38FACCeD333851A9cEf20936DDA88F4/transactions)   |
| Pod DAI  | [0x2f994e2E4F3395649eeE8A89092e63Ca526dA829](https://etherscan.io/address/0x2f994e2E4F3395649eeE8A89092e63Ca526dA829) | [0x18C4315847Cf73D5028c8A98EAd16e862450E618](https://explorer-mainnet.maticvigil.com/address/0x18C4315847Cf73D5028c8A98EAd16e862450E618/transactions)   |


# 🕹️ Apps

## Flagship App

{% embed url="<https://app.pooltogether.com>" %}

Play with official and featured prize pools

## Prize Pool Builder

{% embed url="<https://builder.pooltogether.com>" %}

Create new prize pools using the [Prize Pool Builder](https://builder.pooltogether.com)

Fork the [source code on Github](https://github.com/pooltogether/pooltogether-pool-builder-ui)

## Prize Pool Reference App

{% embed url="<https://reference-app.pooltogether.com>" %}

Interact with prize pools you create using the [Reference App](https://reference-app.pooltogether.com/).

Fork the [source code on Github](https://github.com/pooltogether/pooltogether-reference-pool-ui)


# Subgraphs

Information on PoolTogether's subgraph integration.

Both the PoolTogether [app](https://app.pooltogether.com) and [reference](https://reference-app.pooltogether.com/) app use [subgraphs](https://thegraph.com) to index the protocols smart contract events. A cryptocurrency powered economy of participants work together to index various blockchains and make this data available in configurable and consumable form to front-end users. PoolTogether was the first set of subgraphs to be indexed in the The Graph's decentralized indexer network.

There are PoolTogether v3 subgraphs available for most networks that PoolTogether has been deployed on. There are separate subgraphs available for PoolTogether's [LootBox](/v3.3.0/protocol/lootbox) on Ethereum Mainnet and Rinkeby (fun fact: the LootBox indexes every single ERC20, ERC721 and ERC1155 transfer since the LootBox launched!).

There are currently 3 separate subgraphs for different versions of deployed prize pool contracts. Some networks only have 1 or 2 subgraphs as they were introduced after the v3.3.8 changes.

## PrizePool Subgraphs

### [Subgraph Code on GitHub](https://github.com/pooltogether/pooltogether-subgraph-v3)

| Subgraph                                                                                  | Version(s)    |
| ----------------------------------------------------------------------------------------- | ------------- |
| **Ethereum Mainnet**                                                                      |               |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-v3_1_0)       | 3.0.0 - 3.3.1 |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-v3_3_2)       | 3.3.2 - 3.3.7 |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-v3_3_8)       | 3.3.8 and up  |
|                                                                                           |               |
| **Rinkeby Testnet**                                                                       |               |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/rinkeby-staging-v3_1_0)    | 3.0.0 - 3.3.1 |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/rinkeby-v3_3_2)            | 3.3.2 - 3.3.7 |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/rinkeby-v3_3_8)            | 3.3.8 and up  |
|                                                                                           |               |
| **Polygon**                                                                               |               |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-polygon-v3_3) | 3.3.2 - 3.3.7 |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/polygon-v3_3_8)            | 3.3.8 and up  |
|                                                                                           |               |
| **Xdai**                                                                                  |               |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-xdai-v3_3)    | 3.3.8 and up  |
|                                                                                           |               |
| **POA Sokol**                                                                             |               |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether-sokol-v3_3)                | 3.3.8 and up  |

## LootBox Subgraphs

### [Subgraph Code on GitHub](https://github.com/pooltogether/loot-box-subgraph)

|                                                                                              |              |
| -------------------------------------------------------------------------------------------- | ------------ |
| **Ethereum Mainnet**                                                                         |              |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/lootbox-v1_0_0)               | 3.0.0 and up |
|                                                                                              |              |
| **Rinkeby Testnet**                                                                          |              |
| [Explorer](https://thegraph.com/explorer/subgraph/pooltogether/ptv3-lootbox-rinkeby-staging) | 3.0.0 and up |


# Overview

What are No-Loss Prize Games?

No-loss prize games are pools of funds whose accrued interest is distributed as prizes.

The high level protocol architecture is outlined below. The code is available on [Github](https://github.com/pooltogether/pooltogether-pool-contracts).

## How it works

1. Users deposit funds into a Prize Pool.  They receive "ticket" tokens in exchange.
2. The funds earn interest.
3. The interest is distributed by the Prize Strategy as ticket tokens.
4. Users withdraw their funds by redeeming their ticket tokens

## Architecture

![High level overview of the V3 architecture](https://1585358117-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M58QPye9-PujrSjSWqv%2F-MZyPOo-UWkJII0feojs%2F-MZyPST-JByrekqtdaLP%2FScreen%20Shot%202021-05-05%20at%202.20.38%20PM.png?alt=media\&token=e09af4c1-7e42-490c-a9dd-9a96ad8813a8)

### [Prize Pools](/v3.3.0/protocol/prize-pool)

Prize Pools are the central building block of prize games.  They pool user funds in a **yield source** and expose the yield to a **Prize Strategy**, which then disburses as it pleases.

Prize Pools can be differentiated in four primary ways:

* The yield source the prize pool uses to generate no loss return
* The prize strategy used to determine frequency and distribution&#x20;
* The rewards offered by the prize pool
* The asset type the prize pool accepts for deposits&#x20;

### [Prize Strategies](/v3.3.0/protocol/prize-strategy)

Prize Strategies determine the prize distribution for the Prize Pool.  They can define any logic to allocate tokens that the prize pool accrues.  Specifically they can:

* Award yield in the Prize Pool as pool tokens
* Award ERC20 tokens held by the Prize Pool
* Award ERC721 tokens held by the Prize Pool

### [Yield Source](/v3.3.0/protocol/yield-sources)

Yield sources take deposits and generate interest for the prize pool.  Yield sources must be designed to be no-loss, and adhere to the [Yield Source Interface](/v3.3.0/protocol/yield-sources).

## Conventions

Fixed point math is used extensively in PoolTogether.  We used fixed point math with 18 decimal places for all fractional numbers.  You can think of this as being just like Ether and wei: a value of "1" Ether is represented as "1000000000000000000" wei.

When a number is a fixed point 18 number we always suffix the number with *mantissa.*  For example the credit rate is written as *creditRateMantissa*, because it is a fixed point number.

## Gas Usage

PoolTogether is conscious that to become a truly lossless prize protocol the transaction fees involved must be minimal. The current design utilizes the Minimal Proxy Factory design where possible to reduce gas usage.&#x20;

Note that these fees are paid to the Ethereum Network and not to PoolTogether.  The amount a transaction costs in USD is calculated as: the amount of gas used \* gasPrice \* USD/ETH.

Here is a list of common actions and their costs:

| Function Call                                                                         | Estimated Gas Cost | $USD (40 GWei, $600/ETH) |
| ------------------------------------------------------------------------------------- | ------------------ | ------------------------ |
| **Creating Pools with the Builder**                                                   |                    |                          |
| createCompoundPoolMultipleWinners()                                                   | 1.3M               | 33                       |
| createStakePoolMultipleWinners()                                                      | 1.25M              | 30                       |
| createVaultPoolMultipleWinners()                                                      | 1.2M               | 30                       |
| **Entering and Leaving Pools**                                                        |                    |                          |
| depositTo()                                                                           | 0.5M               | 12                       |
| withdrawInstantlyFrom()                                                               | 0.5M               | 12                       |
| **Award Process**                                                                     |                    |                          |
| RNG request - [Chainlink VRF](/v3.3.0/protocol/random-number-generator/chainlink-vrf) | 2 LINK             | 20 (@ 10 USD/LINK)       |
| startAward()                                                                          | 200k               | 4.8                      |
| completeAward()                                                                       | 250k+ (variable)   | 6                        |
| **Transferring Tickets**                                                              | 290k               | 7                        |


# Prize Pools

Pool deposits and award accrued interest periodically as a prize

## Introduction

Prize Pools allow funds to be pooled together into a no-loss yield source, such as Compound, and have the yield safely exposed to a separate Prize Strategy. They are the primary way through which users interact with PoolTogether prize games.

Prize Pools provide controls to the owner so that participation can be made fair. See [Fairness](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-2367081437/protocol/fairness.md) for more information.

There are two types of prize pools:

* **Yield Source Prize Pools**: these prize pools utilize a yield source to generate prizes.
* **Stake Prize Pools**: these prize pools simply hold deposits; prizes must be added manually.

All Prize Pools share the functionality below.

## Owner

When a Prize Pool is created, the creator is set as the pool's "owner". The owner is able to:

* Change the Prize Strategy
* Set the [credit rate and credit limit](/v3.3.0/protocol/prize-pool/fairness)
* Transfer ownership
* Renounce ownership

**The prize pool is not upgradeable and therefore the owner can never seize the funds deposited into the prize pool**

## Limits

When a Prize Pool is created it is initialized with some hard-coded limits to protect users. See [Fairness](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-2367081437/protocol/fairness.md) for more details.

### **Maximum Credit Limit**

The maximum credit limit ensures that the credit limit cannot be set higher than this number. This prevents the owner of the Prize Pool from capturing \*all\* of a user's deposit at withdrawal time.

### **Maximum Liquidity Limit**

The maximum liquidity limit allows the PrizePool owner to set a cap on the amount of liquidity the pool can hold. This can be set by calling:

```javascript
function setLiquidityCap(uint256 _liquidityCap) external override onlyOwner
```

## Token Model

A Prize Pool accepts a single type of ERC20 token for deposits. This token depends on the implementation: for a Compound Prize Pool bound to cDai it will be Dai, for a yEarn yUSDC vault it will be USDC. This is the underlying **asset** of the Prize Pool.

### Prize Pool Asset

The asset that user deposit into the prize pool can be retrieved by calling:

```javascript
function token() external view returns (address);
```

### Controlled Tokens

Prize Pools use **Controlled Tokens** for their internal accounting. These tokens are minted when depositing or awarding prizes. Controlled Tokens are burned when users withdraw. They are exchanged at a ratio of 1:1 to the asset.

The tokens associated with a PrizePool can be seen by calling:

```javascript
function tokens() external override view returns (address[] memory)
```

A Controlled Token is a standard ERC20 that is bound to a **Token Controller**.

The Token Controller has the privileged ability to mint and burn tokens on user's behalf, and has a callback that listens for token transfers. Controlled Tokens are expected to trigger this callback on any mint, burns or transfers.

The Prize Pool must be the Token Controller for the controlled tokens that it is initialized with at construction.

The default [Compound Prize Pool Builder](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-2367081437/builders/) creates a Ticket controlled token and a [Sponsorship](/v3.3.0/protocol/tokens/sponsorship) controlled token.

A Controlled Token can added by the PrizePool owner by calling:

```javascript
function addControlledToken(ControlledTokenInterface _controlledToken) 
external override onlyOwner
```

### Minting

When a user deposits into a Prize Pool they must request what type of controlled token they receive in exchange. This token will be minted to them at an exchange rate of 1:1 for the asset.

### Burning

When a user wishes to withdraw from a Prize Pool they must burn controlled tokens.

## Depositing

Users can deposit into the Prize Pool using the **depositTo** function. A user is instantly minted tokens upon deposit.

```javascript
function depositTo(
    address to,
    uint256 amount,
    address controlledToken,
    address referrer
) external;
```

| Parameter       | Description                                                                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| to              | The address to whom the controlled tokens should be minted                                                                                                                                                   |
| amount          | The amount of the underlying asset the user wishes to deposit.  The Prize Pool contract should have been pre-approved by the caller to transfer the underlying ERC20 tokens.                                 |
| controlledToken | The address of the token that they wish to mint.  For our default Prize Strategy this will either be the Ticket address or the Sponsorship address.  Those addresses can be looked up on the Prize Strategy. |
| referrer        | The address that should receive referral awards, if any.                                                                                                                                                     |

Depositing fires the event:

```javascript
event Deposited(
    address indexed operator,
    address indexed to,
    address indexed token,
    uint256 amount
);
```

| Event Data | Description                                                                                   |
| ---------- | --------------------------------------------------------------------------------------------- |
| operator   | The caller that made the deposit                                                              |
| to         | The address that received the minted tokens                                                   |
| token      | The address of the controlled token that was minted                                           |
| amount     | The amount of both the underlying asset that was transferred and the tokens that were minted. |

## Withdrawing

When a user withdraws they may need to contribute to the prize according to the [fairness rules](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-2367081437/protocol/fairness.md).  If a user would like their tickets right away, they may pay an early exit fee to the prize. The early exit fee is determined by the [Prize Strategy](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-2367081437/prize-strategy/).

The instant withdrawal function returns the amount of the withdrawal that was retained as payment. This means you can call this function in a constant way to check to see what the exit fee will be. When it comes time to run the tx, that exit fee can be passed as the `maximumExitFee` to ensure it doesn't exceed the expected limit.

```javascript
function withdrawInstantlyFrom(
    address from,
    uint256 amount,
    address controlledToken,
    uint256 maximumExitFee
  )
    external
    returns (uint256 exitFee);
```

| Parameter Name  | Parameter Description                                                                                                                  |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| from            | The address to withdraw from.  This means you can withdraw on another user's behalf if you have an allowance for the controlled token. |
| amount          | The amount to withdraw                                                                                                                 |
| controlledToken | The controlled token to withdraw from                                                                                                  |
| maximumExitFee  | The maximum early exit fee the caller is willing to pay.  This prevents the Prize Strategy from changing the fee on-the-fly.           |

This early exit fee can also be calculated by calling:

```javascript
function calculateEarlyExitFee(address from, address controlledToken, uint256 amount)
 external override returns (uint256 exitFee, uint256 burnedCredit)
```

| Parameter Name  | Parameter Description                 |
| --------------- | ------------------------------------- |
| from            | The address to withdraw from          |
| controlledToken | The controlled token to withdraw from |
| amount          | The amount to withdraw                |

"calculateEarlyExitFee" returns the `exitFee` that would be paid along with the credit that would be burned (`burnedCredit`).

### Estimating Credit Accrual Time

Similarly it is also possible to calculate how long a user must keep their funds in the pool:

```javascript
function estimateCreditAccrualTime(address _controlledToken,
 uint256 _principal,
 uint256 _interest) 
 external override view returns (uint256 durationSeconds)
```

| Parameter Name    | Parameter Description                               |
| ----------------- | --------------------------------------------------- |
| \_controlledToken | The type of controlled token.                       |
| \_principal       | The principal amount on which interest is accruing. |
| \_interest        | The amount of interest that must accrue.            |

###

## Awarding

Only the Prize Strategy can call the award functions. These functions allow prizes to be disbursed to users.

### Awarding Yield

Yield that accrues in the Prize Pool can be awarded by the Prize Strategy. The yield must first be **captured** and then it can be **awarded.**

To capture the yield the prize strategy can call the `captureAwardBalance` function:

```javascript
function captureAwardBalance() external onlyPrizeStrategy returns (uint256);
```

This function will:

* add the current yield balance to the available award balance
* capture a portion for the reserve
* return the total available award balance.

To award the captured yield to an address, the Prize strategy uses the `award` function. The yield must be awarded as one of the controlled tokens configured in the Prize Pool.

```javascript
function award(
    address to,
    uint256 amount,
    address controlledToken
) external onlyPrizeStrategy;
```

| Parameter Name  | Parameter Description                          |
| --------------- | ---------------------------------------------- |
| to              | The address to receive the newly minted tokens |
| amount          | The amount of tokens to mint                   |
| controlledToken | The type of token to mint                      |

### Awarding ERC20s

The Prize Strategy can award ERC20 tokens that are held by the Prize Pool.

```javascript
function awardExternalERC20(
    address to,
    address externalToken,
    uint256 amount
) external onlyPrizeStrategy;
```

However, some tokens are be blacklisted if they need to be held to generate yield (i.e. Compound cTokens).

| Parameter Name | Parameter Description               |
| -------------- | ----------------------------------- |
| to             | The address to receive the transfer |
| externalToken  | The ERC20 to transfer               |
| amount         | The amount of tokens to transfer    |

### Awarding ERC721s (NFTs)

The Prize Strategy can award ERC721 tokens that are held by the Prize Pool.

```javascript
function awardExternalERC721(
    address to,
    address externalToken,
    uint256[] calldata tokenIds
  )
    external
    onlyPrizeStrategy;
```

| Parameter Name | Parameter Description           |
| -------------- | ------------------------------- |
| to             | The address to receive the NFTs |
| externalToken  | The ERC721 contract address     |
| tokenIds       | The NFT token ids to transfer.  |

## Credit

Credit accrues differently for each of the Prize Pool's controlled tokens, so each token will have its own credit rate and credit limit.

### Credit Balance

To get a users credit balance for a controlled token:

```javascript
function balanceOfCredit(
    address user,
    address controlledToken
) external returns (uint256);
```

| Parameter Name  | Parameter Description                                   |
| --------------- | ------------------------------------------------------- |
| user            | The user whose credit balance should be returned        |
| controlledToken | The token for which the credit balance should be pulled |

### Credit Rate

The credit rate for a controlled token can be checked like so:

```javascript
function creditRateOf(
    address controlledToken
) external view returns (
    uint128 creditLimitMantissa,
    uint128 creditRateMantissa
);
```

| Parameter Name  | Parameter Description                                                |
| --------------- | -------------------------------------------------------------------- |
| controlledToken | The controlled token whose credit limit and rate should be returned. |

Note that the returned values are "mantissas": i.e. fixed point numbers with 18 decimal places.

### Credit Plan

The credit plan associated with a `controlledToken` can be found by calling:

```javascript
function creditPlanOf(address controlledToken) external override view returns (uint128 creditLimitMantissa, uint128 creditRateMantissa)
```

## Prizes

### Calculate Current Prize

To calculate the total interest that can be given away you can **statically** call this function:

```javascript
function captureAwardBalance() external returns (uint256);
```

{% hint style="info" %}
Note that this amount is just the currently accrued interest.  For prize pools with yield this amount will continue to increase.  It does not include the external awards.
{% endhint %}

### Total Balances

The total of all controlled tokens (including timelocked) can be obtained by calling:

```javascript
function accountedBalance() external override view returns (uint256)
```

The total underlying balance of all assets (including both principal and interest) can be obtained by calling:

```javascript
function balance() external returns (uint256)
```

## External Prizes

### Adding Tokens

The owner can add "external" ERC20 tokens as prizes. The strategy will award the entire balance held by the Prize Pool to the winner.

```javascript
function addExternalErc20Award(address _externalErc20) external onlyOwner;
```

The owner can add "external" ERC721 tokens as prizes. These tokens will be transferred to the winner.

```javascript
function addExternalErc721Award(
    address _externalErc721,
    uint256[] calldata _tokenIds
) external onlyOwner
```

### Checking Tokens

Checks with the Prize Pool if a specific token type (`_externalToken`) may be awarded as an external prize:

```javascript
function canAwardExternal(address _externalToken) external view returns (bool)
```

## Prize Time Periods

To retrieve when the current prize started:

```javascript
function prizePeriodStartedAt() external view returns (uint256)
```

To retrieve when the prize will end:

```javascript
function prizePeriodEndAt() external view returns (uint256)
```

## Reserve

### Calculate Reserve Fee

Calculates the reserve portion of the given `amount` of funds. If there is no reserve address, the Reserve fee portion will be zero.

```javascript
function calculateReserveFee(uint256 amount) public view returns (uint256)
```

## Prize Strategy

### Set the Prize Strategy

The associated Prize Strategy can be set by calling:

```javascript
function setPrizeStrategy(TokenListenerInterface _prizeStrategy) external override onlyOwner
```

Only the Prize Pool owner can call this function.


# ⚖️ Fairness

How Prize Pools Ensure Fair Play

When users play a game they want it to be fair. In PoolTogether, this means that everyone has contributed the same amount of interest to prizes they are eligible to win. Interest accrues over time, so the Prize Pool needs to measure and enforce the time that funds are held. Without this mechanism, it would be very easy to game the system by depositing right before a prize, having a chance to win, and withdrawing right after.

Prize Pools measure the duration of time funds are held by accruing **credit** for each user at the **credit rate**. The longer a user holds tokens, the more credit they accrue.

Prize Pools enforce the duration of time funds are held by setting a **credit limit**. Once a credit limit is reached a user can withdraw instantly with no loss. If the credit limit has not been reached the user can either use a withdrawal **timelock** or pay an early exit contribution to the prize.

## Credit

After a user deposits funds they begin to accrue credit according to the credit rate. The credit rate is expressed in tokens per second.

For example: if the user deposits 100 DAI and the credit rate is 0.1, then they will have accrued 1 DAI in credit after 10 seconds. Note that they cannot withdraw the 1 DAI credit; it's simply a measure of their contribution.

Users will accrue credit up until the **credit limit**. The credit limit is a fraction, so a users credit limit is that fraction of their entire balance. For example, if the user holds 100 DAI and the credit limit is 0.1, then they will accrue a maximum of 10 DAI in credit.

Once a deposit has accrued maximum credit, it is considered **matured**.


# Stake Prize Pool

The Stake Prize Pool is a prize pool that uses an ERC-20 compatible token as the underlying asset.

**If you transfer the underlying tokens directly to the prize pool, they will be treated like interest**&#x20;

Users's can stake their tokens to become eligible for whatever prize is defined as the prize strategy for that pool.

This is particularly useful for protocols that are sitting inactively in users's wallets - why not stake them in a pool and become eligible for rewards?

The returned [ticket](/v3.3.0/protocol/tokens/ticket) can be thought of as a "proof-of-liquidity".

### Retrieving the Underlying ERC-20

The underlying staked asset can be retrieved by calling:

```javascript
function token() returns (address);
```


# Yield Source Prize Pool

A prize pool that uses a yield source to generate prizes.

The Yield Source Prize Pool uses a yield source contract to generate prizes.  Funds that are deposited into the prize pool are then deposited into a yield source.

## Retrieving the Yield Source

You can access the yield source contract by using this function:

```javascript
function yieldSource() public view returns (IYieldSource);
```

See the [IYieldSource](/v3.3.0/protocol/yield-sources#yield-source-interface) interface for more information on the yield source.


# Prize Strategies

Customize how a Prize Pool distributes prizes

A Prize Strategy handles prize distribution for a [Prize Pool](/v3.3.0/protocol/prize-pool).  When a Prize Pool is constructed it is configured with a Prize Strategy.  The Prize Strategy has the privileged ability to award tokens from the Prize Pool.

The most popular Prize Strategy offering is the [Multiple Winner](/v3.3.0/protocol/prize-strategy/multiple-winners) strategy. Earlier versions (< v3.1.0) of the protocol used the Single Random Winner strategy, which is now a trivial subset of Multiple Winners (with `numberofWinners = 1`).

Prize Strategies must implement the Token Listener interface so that they can be aware of the full token lifecycle.

See the [Token Listener Interface on Github](https://github.com/pooltogether/token-listener-interface)

## Privileged Actions

A [Prize Pool's](/v3.3.0/protocol/prize-pool) Prize Strategy is able to award tokens held by the Prize Pool contract. The Prize Strategy is able to:

* [award yield](/v3.3.0/protocol/prize-pool#awarding-yield) that has accrued in the Prize Pool
* [award any ERC20 balance](/v3.3.0/protocol/prize-pool#awarding-erc-20-s) held by the Prize Pool
* [award any ERC721](/v3.3.0/protocol/prize-pool#awarding-erc-721-s-nfts) owned by the Prize Pool

## Required Behaviour

A Prize Strategy must implement the [Token Listener interface](https://github.com/pooltogether/token-listener-interface) so that it can listen to pool token mint, transfer and burn actions by the Prize Pool.


# Multiple Winners

The Multiple Winners prize strategy periodically selects a predefined number of winners and awards to them an equal share of the prizes available in the Prize Pool.

## Initialization

A Multiple Winners prize strategy is initialized with:

**Prize Period Start:** the timestamp at which the prize period should start

**Prize Period Seconds**: the duration of time between prizes

**PrizePool Address**: the address of the [prize pool](/v3.3.0/protocol/prize-pool) that implements the pool functionality such as deposit and withdraw

[**Ticket**](/v3.3.0/protocol/tokens/ticket)**:** The interface to use to select winners

[**Sponsorship**](/v3.3.0/protocol/tokens/sponsorship)**:** The token that represents sponsorship

[**Random Number Generator**](/v3.3.0/protocol/random-number-generator): used to generate random numbers for winner selection

**Number of Winners**: the number of winners in a prize period. This can be later changed by the owner calling set number of winners.

## Strategy Settings

### Set Number of Winners

The number of winners in a prize period can be set by calling:

```javascript
function setNumberOfWinners(uint256 count) 
external onlyOwner requireAwardNotInProgress
```

* Requires that the Award process is not in progress
* `count` must be greater than 0

### View Number of Winners

The number of winners setting can be viewed by calling:

```javascript
function numberOfWinners() external view returns (uint256
```

### Set Split External ERC-20 Awards

The `SplitExternalErc20Awards` flag can be set by calling:

```javascript
function setSplitExternalErc20Awards(bool _splitExternalErc20Awards) 
external onlyOwner requireAwardNotInProgress
```

This controls how externally added ERC-20's are distributed. Setting to `true` results in the ERC-20's paid out uniformly (similar to the main prize), while `false` does not pay out external ERC-20's for that award.

### Set Random Number Generation Service

The [Random Number Generation](/v3.3.0/protocol/random-number-generator) Service can be set when the award process has not started by the Prize Pool owner by calling:

```javascript
  function setRngService(RNGInterface rngService) 
  external onlyOwner requireAwardNotInProgress 
```

### Set Random Number Generator Request Timeout

The RNG request timeout parameter can be set (in seconds) when the award process has not started by the Prize Pool owner by calling:

```javascript
function setRngRequestTimeout(uint32 _rngRequestTimeout)
external onlyOwner requireAwardNotInProgress {
```

## Prize Period Information

#### View if the Prize Period is Over

To check if the prize period is finished call:

```javascript
function isPrizePeriodOver() external view returns (bool) 
```

Returns `true` if the prize period is over, `false` otherwise.

#### View when the Prize Period Finishes

To check the unix time when the prize period ends call:

```javascript
function prizePeriodEndAt() external view returns (uint256)
```

#### View Estimate of Number of Blocks to Prize Block

To estimate the remaining blocks until the prize given a number of seconds per block call `estimateRemainingBlocksToPrize` with `secondPerBlockMantissa` set to 15 seconds for Ethereum mainnet:

```javascript
function estimateRemainingBlocksToPrize(uint256 secondsPerBlockMantissa) public
view returns (uint256) 
```

#### View Prize Period Remaining Time (in seconds)

To get the number of seconds remaining until the prize can be awarded call:

```javascript
 function prizePeriodRemainingSeconds() external view returns (uint256) 
```

#### View Next Prize Period Start Time

To get the Unix timestamp of when the next prize period will start call `calculateNextPrizePeriodStartTime` with `currentTime` set to the current Unix time:&#x20;

```javascript
function calculateNextPrizePeriodStartTime(uint256 currentTime) 
external view returns (uint256)
```

## Award Process

At the end of the prize period, anyone can begin the award process. This happens in two main stages - `startAward` and `completeAward`. `startAward` triggers the configured Random Number Generator request, which will take some blocks. `completeAward` can then be called, which selects the winners using the RNG result and pushes the tokens out to the winners.&#x20;

### Start Award

The award process can be started by calling `startAward`.  This function starts the award process by starting the configured random number request. The prize period must have ended. The RNG-Request-Fee is expected to be held within this contract before calling this function.&#x20;

```
function startAward() external requireCanStartAward
```

Upon completion this function fires the following event:

```csharp
event PrizePoolAwardStarted(
    address indexed operator,
    address indexed prizePool,
    uint32 indexed rngRequestId,
    uint32 rngLockBlock
);
```

### Complete Award

The award process can be finished by calling `completeAward`. The random number must have been requested and now available (is can be checked by calling `isRngCompleted()`).

```javascript
function completeAward() external requireCanCompleteAward
```

This function fires two events upon completion:

```csharp
event PrizePoolAwarded(
    address indexed operator,
    uint256 randomNumber
);
```

Since Prize Pools are continuously rolling the next prize period is now open:

```csharp
event PrizePoolOpened(
    address indexed operator,
    uint256 indexed prizePeriodStartedAt
);
```

### Cancel Award

This function can be called by anyone to unlock the tickets if the RNG has timed out:

```javascript
function cancelAward() public
```

This function will fire the event:

```csharp
event PrizePoolAwardCancelled(
    address indexed operator,
    address indexed prizePool,
    uint32 indexed rngRequestId,
    uint32 rngLockBlock
);
```

### Listeners

A prize strategy can have both a [token listener](https://github.com/pooltogether/pooltogether-pool-contracts/blob/master/contracts/token/TokenListener.sol) and a periodic prize strategy listener in order execute code for certain callbacks (event hooks).

#### Set Token Listener

The token listener can be set by the prize pool owner when the award process is not in progress by calling `setTokenListener` with the address of the new `tokenList` :

```javascript
function setTokenListener(TokenListenerInterface _tokenListener)
  external onlyOwner requireAwardNotInProgress
```

#### Set Periodic Prize Strategy Listener

The periodic prize strategy listener can be set by the prize pool owner when the award process is not in progress by calling `setPeriodicPrizeStrategyListener` with the address of the new `PeriodicPrizeStrategyListener`:

```javascript
function setPeriodicPrizeStrategyListener(PeriodicPrizeStrategyListenerInterface _periodicPrizeStrategyListener) 
 external onlyOwner requireAwardNotInProgress
```

This function will ensure the Listener Interface is implementing using ERC-165 introspection, and upon completion fire the following event:

```csharp
event PeriodicPrizeStrategyListenerSet(
    PeriodicPrizeStrategyListenerInterface indexed periodicPrizeStrategyListener
);
```

### External ERC20 and ERC721 Awards

External awards can be added to the pool. This is particularly useful in the case of the stake pool. Although still possible for either the token listener or the owner to manually add or remove ERC-20's and ERC-721's, it is recommended to add a single [LootBox](/v3.3.0/protocol/lootbox) per prize period and direct the external awards to this LootBox address.&#x20;

The pool owner or the token listener can add/remove ERC721's by calling:&#x20;

```javascript
function addExternalErc721Award(IERC721Upgradeable _externalErc721,
  uint256[] calldata _tokenIds) 
  external onlyOwnerOrListener requireAwardNotInProgress 
```

```javascript
function removeExternalErc721Award(
  IERC721Upgradeable _externalErc721,
  IERC721Upgradeable _prevExternalErc721)
  external onlyOwner requireAwardNotInProgress
```

The pool owner or the token listener can add/remove ERC20's by calling:&#x20;

```javascript
function addExternalErc20Awards(IERC20Upgradeable[] calldata _externalErc20s) 
    external onlyOwnerOrListener requireAwardNotInProgress
```

```javascript
function removeExternalErc20Award(
  IERC20Upgradeable _externalErc20,
  IERC20Upgradeable _prevExternalErc20) 
  external onlyOwner requireAwardNotInProgress 
```

Corresponding events are fired for each ERC type added or removed:

```csharp
  event ExternalErc721AwardAdded(
    IERC721Upgradeable indexed externalErc721,
    uint256[] tokenIds
  );

  event ExternalErc20AwardAdded(
    IERC20Upgradeable indexed externalErc20
  );

  event ExternalErc721AwardRemoved(
    IERC721Upgradeable indexed externalErc721Award
  );

  event ExternalErc20AwardRemoved(
    IERC20Upgradeable indexed externalErc20Award
  );
```


# 👨‍🌾 Yield Sources

Yield sources generate yield for prize pools.

A **Yield Source** contract is used by a Yield Source Prize Pool to generate yield for prizes.

[See the Specification on Github ](https://github.com/pooltogether/yield-source-interface)

The yield source just needs these properties:

* &#x20;The deposit asset is the same as the asset that accrues.  I.e. if users deposit Dai into the yield source, then it should yield Dai as well
* Yield must always be increasing.  The mechanics of the Prize Pool require yield to always go up, as it's a no-loss system.  The yield source must protect depositor's collateral.

There are implementations for all of the major yield sources:

* Compound
* Aave
* Yearn
* More!

See the full list [here](https://github.com/pooltogether/yield-source-interface)

## Yield Source Interface

The yield source interface is very simple; it just needs to support four functions:

```javascript
/// @title Defines the functions used to interact with a yield source.  The Prize Pool inherits this contract.
/// @notice Prize Pools subclasses need to implement this interface so that yield can be generated.
interface IYieldSource {

  /// @notice Returns the ERC20 asset token used for deposits.
  /// @return The ERC20 asset token
  function depositToken() external view returns (address);

  /// @notice Returns the total balance (in asset tokens).  This includes the deposits and interest.
  /// @return The underlying balance of asset tokens
  function balanceOfToken(address addr) external returns (uint256);

  /// @notice Supplies tokens to the yield source.  Allows assets to be supplied on other user's behalf using the `to` param.
  /// @param amount The amount of `token()` to be supplied
  /// @param to The user whose balance will receive the tokens
  function supplyTokenTo(uint256 amount, address to) external;

  /// @notice Redeems tokens from the yield source.
  /// @param amount The amount of `token()` to withdraw.  Denominated in `token()` as above.
  /// @return The actual amount of tokens that were redeemed.
  function redeemToken(uint256 amount) external returns (uint256);

}
```


# 🎟️ Tokens

When users deposit into a Prize Pool they receive an ERC20 compatible [ticket](/v3.3.0/protocol/tokens/ticket).

External ERC721 and ERC20's can also be [added, controlled and removed](/v3.3.0/protocol/prize-strategy/multiple-winners#external-erc20-and-erc721-awards) by Prize Pools.

[Sponsorship](/v3.3.0/protocol/tokens/sponsorship) tokens are created when funds are added to the pool that are not eligible to win any prizes.


# 🎟️ Ticket

The Ticket contract is an [ERC20](https://eips.ethereum.org/EIPS/eip-20)-compatible token that allows users to be selected by a token index.

The contract organizes the balances into a sum tree data structure, so that each address holds a "range" of tokens.  A number can be used as an index within that range, and the holder of the tokens in that range is selected:

```javascript
function draw(uint256 randomNumber) public view returns (address)
```

The **randomNumber** will be used as a token index into a specialized data structure that stores the user balances.  The randomNumber is constrained to the token supply and modulo bias is corrected.

The returned address is the user who holds the token index corresponding to the random number.


# Sponsorship

Users may "sponsor" the prize pool by depositing funds that don't make them eligible to win.

This can be useful for the creators of the pool to bootstrap its liquidity.


# Random Number Generator

PoolTogether has abstracted the generation of random numbers by creating a request-based Random Number Generator interface.

It functions like so:

1. The user will first get the request fee.  The fee will be expressed using an (address, amount) pair representing the required ERC20 and amount.
2. The user will then approve the RNG to spend that ERC20 of the amount
3. The user will then request the random number.  The RNG will transfer the cost into itself and begin the request.  The request returns a request identifier.
4. The user may check to see if the random number is available using the identifier.
5. When the random number is available the user may retrieve it with the identifier.

Let's look at these functions in detail.

## Get the Request Fee

Many RNG services require tokens in order to operate.  To get the cost of the rng you may do so using:

```javascript
function getRequestFee() external view returns (address feeToken, uint256 requestFee);
```

This function returns two values:

* **feeToken:** the ERC20 that needs to be paid
* **requestFee:** is the amount of the token that needs to be paid

## Request a Random Number

Once the user has approved the RNG service spend, they may request a random number like so:

```javascript
function requestRandomNumber() external returns (uint32 requestId, uint32 lockBlock);
```

This function returns two values:

* **requestId:** the unique id for this RNG request
* **lockBlock:** the commitment block for this RNG request.  Users of the RNG request shouldn't make any changes after the lockBlock, otherwise the RNG may be less secure.  For example, the Prize Strategy will lock all ticket sales and movements after the lockBlock, as they affect the winner selection.  Once the request is complete the Prize Strategy unlocks tickets.

## Check if Request is Complete

The user may check if a request is complete:

```javascript
function isRequestComplete(uint32 requestId) external view returns (bool isCompleted)
```

## Retrieve Random Number

```javascript
function randomNumber(uint32 requestId) external returns (uint256 randomNum);
```

##


# Blockhash

The Blockhash RNG uses a future blockhash as the random number.  This is the least secure method of random number generation, but also the simplest and cheapest.

When a user request a random number their lock block will be the current block.  Their request is considered 'complete' when at least one block has been mined since the lock block.  Upon retrieval the last blockhash will be stored as the random number and returned.

## Usage

A prize strategy can use a [RNGBlockhash](/v3.3.0/resources/networks) RNG service.  No additional work is needed: the blockhash service is free.


# Chainlink VRF

**A verifiable random function is a pseudo-random function whose output is unique and can be publicly verified.**

ChainLink has implemented their VRF using public key cryptography.  It works like so:

1. The user creates a “seed” value
2. A ChainLink operator, who has publicly committed to a keypair, uses their secret to sign the seed value.
3. The user is able to verify that the operator has signed the seed value, and consume the signature as the “random number”. &#x20;

**ChainLink VRF Documentation:** [**https://docs.chain.link/docs/chainlink-vrf**](https://docs.chain.link/docs/chainlink-vrf)

This approach has some benefits in that the operator cannot “lie”: they must sign the seed using the secret they have committed to.  The algorithm is also instantaneous: there is no delay or waiting period to get the answer.&#x20;

## Usage

To use the [RNGChainlink](/v3.3.0/resources/networks) RNG service, create a new prize pool using the service or set it on an existing pool.

🚨🚨🚨 **Chainlink RNG requires 2 LINK tokens per RNG request** 🚨🚨🚨

🚨🚨🚨 **You must deposit LINK into the PRIZE STRATEGY** 🚨🚨🚨


# 🏴‍☠️ Loot Box

What is a PoolTogether Loot Box?

## Overview

A Loot Box is an address that can be controlled by the owner of an ERC721. Any ERC721 can have an associated Loot Box address, to which tokens and pretty much anything can be sent to. Anyone can "plunder" the Loot Box for tokens, and those tokens will be sent to the owner of The ERC721.

In this way, Loot Boxes allow addresses to be traded like NFTs.

The code can be found here: <https://github.com/pooltogether/loot-box>

## How it works

A LootBox contract ephemerally exists within a transaction. The owner of an `ERC721` owns the LootBox.

1. A `ERC721` is created by calling `createERC721Controlled()` on the `ERC721ControlledFactory` by anyone:

```javascript
  function createERC721Controlled(
    string memory name,
    string memory symbol,
    string memory baseURI
  ) external returns (ERC721Controlled)
```

1. `mint()` can then be called on the `ControlledERC721` which effectively creates a LootBox with an Owner defined by the `to` field:

```javascript
function mint(address to) external onlyAdmin returns (uint256)
```

1. The LootBox address is calculated by calling:&#x20;

```javascript
computeAddress(address erc721, uint256 tokenId)
```

1. Tokens are transferred/minted to this address. In the case of PoolTogether, these are usually external ERC20, ERC721 and ERC1155 rewards for a Prize Period.
2. Anyone can call `plunder()` on the LootBox controller which will transfer all the passed tokens to the LootBox owner.

```javascript
function plunder(
  address erc721,
  uint256 tokenId,
  address[] calldata erc20s,
  WithdrawERC721[] calldata erc721s,
  WithdrawERC1155[] calldata erc1155s
)
```

where `erc20s` is defined as an array of ERC-20 addresses,

`erc721s` is defined as:

```c
struct WithdrawERC721 {
  address token;
  uint256[] tokenIds;
}
```

and `erc1155s` as:

```c
struct WithdrawERC1155 {
  address token;
  uint256[] ids;
  uint256[] amounts;
  bytes data;
}
```


# Pods

Combine tickets and split the prize

A "Pod" is a smart contract that allows users to combine their deposits together for a higher chance to win.  If the Pod wins, users get to split the prize according to how much they contributed.

Pods introduce two major enhancements:

* Reduced gas costs when entering PrizePools via batching.
* Increased winning odds through collective deposits.

Relative to the traditional PoolTogether deposits, Pods offer a unique value proposition that may appeal to a range of users. Whether it's a small "fish" just trying to spend less on gas or a "whale" interested in increasing their chances of winning (*while also sharing their winnings with others*) Pods introduce a novel set of features for participating in a no-loss lottery.

**Primary Smart Contracts**

* [Pod.sol](https://github.com/pooltogether/pods-v3-contracts/blob/master/contracts/Pod.sol)
* [TokenDrop.sol](https://github.com/pooltogether/pods-v3-contracts/blob/master/contracts/TokenDrop.sol)
* [PodFactory.sol](https://github.com/pooltogether/pods-v3-contracts/blob/master/contracts/PodFactory.sol)
* [TokenDropFactory.sol](https://github.com/pooltogether/pods-v3-contracts/blob/master/contracts/TokenDropFactory.sol)

#### OpenZeppelin Inheritance

Pods inherit functionality from OpenZeppelin smart contracts: *ERC20Upgradeable, OwnableUpgradeable, ReentrancyGuardUpgradeable.*

**Module:** @openzeppelin/contracts-upgradeable": "^3.4.0"

## Overview

### Sharing Tickets & External ERC20/ERC721 Winnings

**The Pod is designed to distribute PrizePool winnings i.e. tokens/tickets.**

*Secondary awards (LOOT Box) are liquidated and converted to the underlying balance.*&#x20;

In other words, if a Pod contains 1,000,000 tokens (for example $1,000,000 worth of USDC) split evenly between 10 depositors (100,000 each) and the Pod is awarded 50,000 pcUSDC, each depositor will have their underlying balance increase by 5,000 USDC (10% of the total winnings).

Distribution of non-ticket winnings, such as external ERC20 and ERC721 tokens is handled via liquidation and conversion to the underlying balance token. Simply put, as of now Pods (v1) instead of splitting secondary awards (*which is not possible for non-fungible tokens*) the Pod manager liquidates the LOOT Box and converts the assets into the underlying token or reward ticket.

The liquidated/converted assets can be withdrawn by Pod share holders.

In short, **all winnings** are ultimately available as the **deposit token**.

*Example:*

* Pod awarded 50,000 ticket prize
* Pod awarded LOOT Box (external ERC20/ERC721 tokens)
* Pod liquidates LOOT Box assets into underlying asset (token)
* Underlying asset distributed across Pod holders &#x20;

### Owner & Manager

Pods include two roles: *owner and manager*. The owner is responsible for updating (if necessary) external contract references and the manager is responsible for liquidating and distributing LOOT Box winnings.

#### Owner

The owner is responsible for updating external contract references.

**Manager**

The manager is responsible for liquidating secondary prizes.

## How It Works&#x20;

From a technical perspective a Pod is a **single user** in relation to the PrizePool protocol - even though 10's, 100's or even 1000's of users may have deposited funds.

**The Pod smart contract adheres to the ERC20 specification**. While Pods include functionality to interact with a strict set of external smart contracts: *PrizePool, TokenListeners and TokenDrops,* at the core Pods can be thought of as a token.

When tokens are deposited into a Pod, via `depositTo` new shares are minted.

Minted shares, represented as an ERC20 balance, represent a user's claim on the underlying balance managed via the Pod smart contract.

In other words, user's deposits tokens directly into a Pod, and in-turn the Pod will batch those deposits into a single transaction and deposit into the PoolTogether V3 PrizePool smart contracts, but the shares minted by the Pod can be traded just like any other ERC20 token.

## Smart Contract Functions

#### `depositTo` - Deposit Tokens & Mint Shares&#x20;

```javascript
function depositTo(
 address to, 
 uint256 tokenAmount
) external override nonReentrant returns (uint256)
```

The `depositTo` function interface is similar to the PrizePool `depositTo` function interface, minus the `controlledToken` and `referrer` inputs, which are automatically added by the Pod during the batch process.

As with all ERC20 smart contracts transfers/deposits, **users must first set a positive allowance for the target contract**. Afterwards users deposit funds into the Pod by calling the `depositTo` function with the desired `to` and `tokenAmount` inputs.

Normally users will enter their personal wallet address, unless a deposit is made on behalf of user, which might be the case for a periphery smart contract. For example, a third-party contract might convert ETH into the underlying Pod token before calling depositTo - sometimes referred to as a zap.

When a user deposits tokens, the Pod mints shares - representing a claim on the deposit.

#### `withdraw` - Burn Shares & Withdraw Tokens

```javascript
function withdraw(
 uint256 shareAmount,
 uint256 maxFee
) external override nonReentrant returns (uint256)
```

The `withdraw` function, as expected, handles withdraws from the Pod. To withdraw from a Pod, the user must have a positive share balance. Whether that's via depositing tokens or being transferred Pod shares.

When a users withdraw the shares are burned and the underlying balance is transferred.&#x20;

In addition to entering a valid `shareAmount` users must also specify the `maxFee` amount. When exiting a PrizePool a fee may be applied, depending on the last deposit timestamp. Due to the nature of a Pod's regular deposits/withdrawals the early exit is constantly updating.

The early exit fee can be calculated by calling the `getEarlyExitFee` view function and entering the total underlying balance to be withdrawn.

First, a user may want to calculate the total underlying balance relative to their shares by calling `balanceOfUnderlying(address user) returns (uint256 amount)`which will calculate the underlying balance via the user's share balance.

After a user has determined their total underlying balance, they can proceed to calculate the early exit by inputting the desire withdraw amount, relative to their share balance.

#### `drop` - Claim Reward Tokens, Batch User Deposits and TokenDrop

```javascript
function drop() external override nonReentrant returns (uint256)
```

The `drop` function is responsible for claiming and distributing rewards tokens (i.e. POOL) to the TokenDrop smart contract and executing `batch` which transfers recent token deposits into the PrizePool.

The average user will not need to interact with the `drop` function. Instead it's up to the Pod owner/manager to regularly call `drop` function and batch deposits.

Pods deployed by the PoolTogether Inc team are automatically managed using the OpenZeppelin Defender system. Eliminating the need for administrator to manually manage a Pod's deposits.

[PoolTogether Pods Upkeep](https://github.com/pooltogether/pooltogether-pods-upkeep)

#### `batch` - Batch User Deposits

```javascript
function batch() external override nonReentrant returns (uint256)
```

The `batch` function is responsible for moving deposited tokens from the Pod smart contract into the PrizePool smart contract.

Overall, the batching functionality is a simple process:

* Read the current underlying token balance.
* Deposit the underlying token balance into the PrizePool.

After the Pod batches token deposits, converting the tokens into tickets, the Pod is instantly eligible for winning the PrizePool award.

Generally, the `batch` function will be called indirectly via the `drop` function. The `batch` function is called indirectly because, in addition to converting tokens to tickets, it's important to claim and distribute the reward token, which is handled via the `drop` function.

The batching functionality is the reason for an average 3x in gas savings.


# 🏛️ Overview

The Role of Governance

The PoolTogether Protocol is governed by the POOL token. Any changes to the Protocol are proposed and voted on by POOL token holders. These proposals can include things like adjusting the number of winners, launching new prize pools, integrating new yield sources, implementing scaling solutions and controlling future distribution of POOL to protocol contributors.

## How Governance Works

Changes to the protocol are submitted as governance proposals. Anyone who either holds 10,000 POOL tokens (0.1% of total supply) OR has 10,000 POOL tokens delegated to them can submit a governance proposal. Once submitted governance proposals are voted on for five days. After five days, if the majority of votes are in favor AND at least 100,000 votes have been cast in favor, the proposal will pass. There is a two day “timelock” before the proposal is actually implemented.&#x20;

![](https://1585358117-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M58QPye9-PujrSjSWqv%2F-MTgloZLOm-OnXrBIc0A%2F-MTgoRqxkxdWRu48dBBK%2F1_cU6O0qF_pUrcupmqiuv1AA.png?alt=media\&token=68a985be-dfea-4cad-be29-ba4b3fcaeb76)

## What Proposals Do&#x20;

A proposal can be submitted to do anything but practically speaking, proposals will likely center on a few main topics.

**Controlling governance managed prize pools**

The governance managed prize pools are displayed on app.pooltogether.com. Some parameters on these prize pools are very simple to change, for example, adjusting the number of weekly winners or changing the frequency with which prizes are distributed. We expect proposals will be submitted to adjust these parameters.

**Managing the prize pool builder**&#x20;

All prize pools are generated by the prize pool builder. Currently the only yield source supported by the protocol is the Compound Protocol. Many in the community have expressed a desire to add more yield sources. We expect governance proposals to enable prize pools using new yield sources such as Aave.

**Distributing the POOL token**

The broadest category is controlling future distribution of the POOL token. As more people contribute to the protocol by depositing, referring deposits, developing the protocol and other activities governance should continue to distribute control of the protocol to these people. Practically this can look like a referral rewards program, a grants program, a deposit reward program, or direct transfers!

## **Submitting Proposals**

The best place to start is by discussing it in the [governance forum](http://gov.pooltogether.com) and [community Discord](https://discord.gg/peE3axWSEv).&#x20;

When it comes time to actually make the proposal, you can review the documentation and use the proposal creation interface available on the "vote" section of the PoolTogether app. You can create proposals without this interface but the interface helps make it more simple for non-technical people.&#x20;

[Visit the proposal creation interface!](https://vote.pooltogether.com/proposals/create)


# 🕹️ Controls

A summary of governance-managed controls

PoolTogether governance primarily controls:

* Protocol prize pools
* Token Faucets (liquidity mining)
* Protocol treasury
* Reserve

## Protocol Prize Pools

The protocol owns a subset of the prize pools.  Ownership means that governance can execute privileged actions only available to the owner.

Each prize pool consists of the prize pool contract and the prize strategy contract.  These two contracts can have different owners, but typically the owner is the same.

Prize Pool actions include:

* Setting a prize pool's early exit fees
* Setting a prize pool's liquidity cap
* Setting the prize strategy for a prize pool

Prize Strategy actions include:

* Setting the number of winners
* Setting whether to split external awards among the winners
* Configuring the Random Number Generator
* Managing external awards
* Configuring token and prize listener contracts

## Token Faucets

The protocol owns a set of token faucets, and can create more.  Each faucet is bound to a prize pool as a token listener and drips POOL tokens to the users.  The original program is time-limited, but governance can:

* Deposit more tokens into each faucet
* Change the drip rate of each faucet
* Create new token faucets for new prize pools

## Protocol Treasury

The initial token distribution allocated 60% of the POOL token supply to the protocol treasury.  These tokens will be unlocked over two years by the TreasuryVesterForTreasury contract.  Anyone can execute the vesting contract to disburse more tokens to the protocol treasury.

The protocol treasury is held by the Timelock contract, which is the contract that execute proposals submitted by governance.  Proposals could do things like:

* Transfers POOL tokens to a recipient
* Approve POOL token spend by another contract, and then call the contract

## Reserve

The reserve contract is owned by governance, and determines the portion of interest earned by each prize pool that is captured as reserve funds.  Every prize pool created by the builders is linked to the reserve.  Governance can:

* Change the reserve rate.  This rate is the portion of interest that is captured for the reserve.
* Withdraw the reserve from a prize pool.


# 🗳️ Example Proposals

Illustrating governance process with examples

The governance system is very new, so it might be difficult for some people to imagine how it works.  Here we're going to give some example proposals to illustrate how governance could work.  The examples will be both PoolTogether-specific and refer to proposals created in other governance systems.  We'll cover:

* How to create a new protocol-owned prize pool
* How to create a Uniswap-style grants program
* Rewarding contributors with Sablier streams

It's important to mention that a proposal is much more likely to be successful if it is first discussed in the [governance forum](https://gov.pooltogether.com/).  Ideally the outcome of a proposal will be known before it is created.

## Proposal: Create a Protocol Prize Pool

As new assets become available and new types of prize pools are added to the [Builder](broken://pages/-M62EjiYFQOIIF0UDsxg), users may wish to create new governance owned & operated prize pools.  By having ownership only governance will be able to change parameters such as the exit fee and number of winners.  See [Controls](/v3.3.0/governance/controls) for more info.

If POOL holders decide to create a new prize pool after thorough discussion on the governance forums, then they would need to follow these steps:

1. A user creates the appropriate prize pool using the [Prize Pool Builder app](https://builder.pooltogether.com/).
2. Once created, the user transfers the ownership of the resulting prize pool and prize strategy contracts to the Timelock contract (see the Governance section in [Networks](/v3.3.0/resources/networks)).  The only interface for this right now is Etherscan.
3. Finally, the user creates a new governance proposal.  The proposal will include:
   1. Adding the prize pool address to the official Protocol Prize Pool Registry (coming soon!)
   2. Possible compensation for the gas spent by the user that created the pool
   3. Possible compensation for the gas costs of creating the proposal

POOL holders will need to verify that the ownership of the proposed prize pool has, in fact, been transferred to the Timelock contract.  They should also verify that the prize pool is safe and has been created by the builder app.

## Proposal: Create a Grants Program

Many protocols have created a grants program to make it easy to fund the protocol ecosystem.  Typically, grant programs have a trustworthy steward to manage the program.  The [Uniswap Grant Proposal](https://app.uniswap.org/#/vote/3) is a great example.

For Uniswap, a professional grants manager was selected to lead the program.  Him and five other people were added to a Gnosis Safe multisig.  The other people were well-known leaders in the crypto space and proved that they held the wallet addresses.  The multisig was configured to require 4-of-6 confirmations, making it quite secure.

The proposal included:

* Quarterly budget for grants, with two quarters of budget requested at the time of proposal.
* Compensation for the grants manager
* A complete description of the proposed grants program, including timeline, budget and scope.

The actual proposal was a simple token transfer from the treasury to the Gnosis Safe multisig.

## Proposal: Reward Contributors with a Sablier Stream

SushiSwap has formalized their hiring guidelines, and as part of those guidelines new hires will be paid a signing bonus and their "salary" will be sent to them as a Sablier stream.  You can read their [complete hiring process here](https://forum.sushiswapclassic.org/t/sushi-hiring-guidelines-v2/1866).

If a community member wished to apply to work for the protocol and have a salary of X tokens, they could set up a proposal like so:

1. Approve Sablier spending X tokens
2. Create a new stream in Sablier for X tokens for the given timeframe.
3. Include token transfer as a signing bonus (if applicable)


# Smart Contract Guidelines

When creating a new smart contract project, use the guidelines below to ensure your project meets our basic standards of quality.

## Security

### Re-entrancy

Any external or public functions need to be analyzed to determine whether the contract can be attacked if a user re-enters that function or another.

### Safe ERC20 Usage

ERC20 token interactions should always use SafeERC20 safeApprove and safeTransferFrom in the OpenZeppelin library.

### Math Overflow and Underflow

Any math operations need to be checked for overflow and underflow conditions, using SafeMath or similar.

### Trusted External Calls

The contract should minimize trust in external calls.

## Optimizations

* All external / public functions should return a value when possible (to save gas)
* Structs must be tightly packed
* Hardcoded integers and strings should be constants
* Contract members that don't change should be immutable

## Conventions

### Typed Arguments

All arguments, whether to an event or function, must be typed when possible. `address` types should be avoided in favour of contract or interface types

### Logs Emitted

Events must be emitted for any significant state change or event.

### Grammar

Names and documentation must be spelled correctly with no grammatical errors.

## Documentation

### Readme

A complete readme must be included with the project. It needs:

* a complete description
* usage
* setup instructions
* all test commands
* deployment instructions and information
* information on any additional scripts

### Natspec

Contracts must have (at minimum):

* `@title`: short title.  shouldn't repeat the description
* `@notice`: descriptive enough so that the reader understands the intent of the contract.

Functions must have (at minimum):

* `@notice`: explain what the function does
* `@param`: explain each parameter
* `@return`: explain the return param(s)

Events must have (at minimum):

* `@notice`: describe when the event is emitted
* `@param`: describe each of the args

## Testing

### Unit Tests

* There must be a test suite for each contract
* Each unit test should mock out contract dependencies using Waffle or Smock
* Contract functions should be tested in isolation
* Unit tests must run **locally; i.e. they do not connect to a remote node.**

### Code Coverage

* Coverage must exceed 95%

### Fork Test

* A fork test script tests the contracts in the real world
* At a minimum the test must execute the "happy path" for the code.

### Repository Badges

* Coverage badge must be included (we use Coveralls)
* Github Workflow badge for the fork test&#x20;
* Github Workflow badge for the unit tests


# Risks

Using the protocol includes substantial risks of losing some or all of your funds. The PoolTogether core team and community have made every effort to ensure the security of funds.

This section will help you understand the the types of risk you are taking what has been done to mitigate them and how to mitigate them further.&#x20;

### Protocol Dependency Risk  <a href="#a908" id="a908"></a>

The PoolTogether Protocol uses several other protocols. Therefore the first type of risk is the risk that these other integrated protocols can fail.

Specifically by using PoolTogether you are also taking on the risks of using the Ethereum network, the collateral you are depositing, and the yield service (currently Compound.Finance).

To mitigate this risk the protocol is only integrated with highly reputable and well secured protocols. &#x20;

### Smart Contract Exploit Risk <a href="#a908" id="a908"></a>

The second type of risk is specific to PoolTogether. The risk is that there could be some sort of bug or exploit in the smart contracts that run the PoolTogether Protocol. This is a risk with any product on Ethereum. Depending on what the bug or exploit is, a nefarious person may be able to take some or all of the funds stored in the PoolTogether Protocol. Here’s what we’ve done to mitigate this risk.

1. Professional, third party smart contract auditing. PoolTogether has hired companies to professionally review and audit the smart contract code for any bugs or exploits. These auditors have produced reports with their findings. As PoolTogether continues to grow we’re committed to continuing to pay for audits however, it should be understood that at any given time, 100% of the code base has not been professionally audited.&#x20;
2. Bug Bounty program. PoolTogether offers payment of up to $25,000 for reports of any bugs in the smart contracts. If someone was to discover a bug, this is a way for them to responsibly disclose it to us and be paid rather than exploit it.
3. All the smart contract code is open source, meaning it is publicly readable by anyone. At first this may sound strange but it actually makes the protocol more secure as anyone can review it for bugs and submit a bug bounty.
4. Before we even give our code to auditors we also do extensive internal testing.

### Wallet Loss Risk <a href="#e5cb" id="e5cb"></a>

This risk doesn’t have anything to do with PoolTogether but we wanted to mention it. Using PoolTogether requires you to use an Ethereum wallet that supports Ethereum apps. If you permanently lose access to this wallet, you will not be able to recover your funds. Different wallets have different recovery mechanisms. It’s important for you to know what those are and be able to recover your wallet. [Argent Wallet](https://www.argent.xyz/) is one example of a wallet with good recovery methods.


# Audits & Testing

The PoolTogether Protocol has undergone three formal professional third party audits. Two have been [conducted by Open Zeppelin](https://blog.openzeppelin.com/pooltogether-v3-audit/), and one [conducted by Ditcraft](https://www.ditcraft.io).

Additionally the PoolTogether core team has a long term security relationship with [ConsenSys Diligence](https://diligence.consensys.net/audits/) including monthly code reviews.

Notwithstanding, portions of the PoolTogether Protocol codebase will continue to evolve and **it should never be expected that 100% of the deployed code has been formally audited.**

We encourage responsible disclosure of any vulnerabilities in the smart contracts and will pay up to $25,000 for those. See the [Bounties](/v3.3.0/security/bounties) for more details.


# Bounties

We value contributions from the community to strengthen the security of the core contracts. We want to reward any hackers in good faith who report vulnerabilities.

The scope of this bounty includes the PoolTogether smart contracts. The determination of the bug severity will be made by the PoolTogether team.  We determine the severity of an issue according to the [Smart Contract Security Alliance Severity Levels](https://www.smartcontractsecurityalliance.com/)

Payouts will be as follows:

High: $25,000 DAI\
Medium: $10,000 DAI\
Low: $1,000 DAI

The issue must:

* be a previously unreported, non-public vulnerability.
* include enough detail for us to identify and reproduce the problem

All reports should start with an email to <hello@pooltogether.us> and they will receive a response within 24 hours. Non-security issues are not eligible for this bounty.

Determinations of eligibility and all terms related to this award are at the sole and final discretion of the PoolTogether team.

## Past Bounties

### PermitAndDepositDai Contract: Unrestricted Sender

Severity: Medium / High\
Date: Thursday, October 22nd, 2020\
Reporter: Kevin Foesenek\
Payout: $20,000 USD of WETH ([transaction](https://etherscan.io/tx/0xdd9fcf07a29a376b811c775d34cef4ceddf6e720981da34ac7142a8c38e7e7a6))

**Vulnerability**\
Just prior to launch a security researcher discovered a flaw in the PermitAndDepositDai contract.  This flaw would have allowed an attacker to front-run the "deposit" transaction and take the deposited amount.  This would have affected any new deposits to the system.

**Mitigation**\
References to the contract were removed from the user interface, and a fix was immediately deployed to mainnet and published via NPM.


# Introduction

[![PoolTogether Brand](https://github.com/pooltogether/pooltogether--brand-assets/blob/977e03604c49c63314450b5d432fe57d34747c66/logo/pooltogether-logo--purple-gradient.png?raw=true)](https://github.com/pooltogether/pooltogether--brand-assets)

## ✨ Introduction

PoolTogether is a decentralized protocol for no-loss prize games on the Ethereum blockchain. The protocol:

**1) Enables developers to build their own no-loss prize games**\
**2)** **Offers governance-managed no-loss prize games**

Prize games are pools of funds whose accrued interest is distributed as prizes. The concept is well-established and otherwise known as "[no loss lotteries](http://beniverson.org/papers/MaMa.pdf)" or "[prize savings accounts](https://en.wikipedia.org/wiki/Prize-linked_savings_account)".  All prize games created by the protocol share the same key characteristics:

* No loss of deposited funds
* Ability to withdraw at any time
* Fair prize distribution according to a prize strategy

Prize games can be differentiated in the following ways:

* The yield source the prize pool uses to generate no loss return
* The prize strategy used to determine frequency and distribution of prizes&#x20;
* The additional rewards offered by the prize pool
* The asset type the prize pool accepts for deposits&#x20;
* The fairness parameters&#x20;

### Governance

The PoolTogether Protocol is governed by the POOL token. [Read more here](/v3.2.0/governance/overview)

####

####


# Networks

## Mainnet

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.2.1** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract                         | Address                                                                                                               |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Dai Prize Pool                   | [0xEBfb47A7ad0FD6e57323C8A42B2E5A6a4F68fc1a](https://etherscan.io/address/0xEBfb47A7ad0FD6e57323C8A42B2E5A6a4F68fc1a) |
| Dai Prize Strategy               | [0x178969A87a78597d303C47198c66F68E8be67Dc2](https://etherscan.io/address/0x178969A87a78597d303C47198c66F68E8be67Dc2) |
| Dai POOL Faucet                  | [0xF362ce295F2A4eaE4348fFC8cDBCe8d729ccb8Eb](https://etherscan.io/address/0xF362ce295F2A4eaE4348fFC8cDBCe8d729ccb8Eb) |
| UNI Prize Pool                   | [0x0650d780292142835F6ac58dd8E2a336e87b4393](https://etherscan.io/address/0x0650d780292142835F6ac58dd8E2a336e87b4393) |
| UNI Prize Strategy               | [0xe8726B85236a489a8E84C56c95790d07a368f913](https://etherscan.io/address/0xe8726B85236a489a8E84C56c95790d07a368f913) |
| UNI POOL Faucet                  | [0xa5dddefD30e234Be2Ac6FC1a0364cFD337aa0f61](https://etherscan.io/address/0xa5dddefD30e234Be2Ac6FC1a0364cFD337aa0f61) |
| USDC Prize Pool                  | [0xde9ec95d7708b8319ccca4b8bc92c0a3b70bf416](https://etherscan.io/address/0xde9ec95d7708b8319ccca4b8bc92c0a3b70bf416) |
| USDC Prize Strategy              | [0x3d9946190907ada8b70381b25c71eb9adf5f9b7b](https://etherscan.io/address/0x3d9946190907ada8b70381b25c71eb9adf5f9b7b) |
| USDC POOL Faucet                 | [0xbd537257fad96e977b9e545be583bbf7028f30b9](https://etherscan.io/address/0xbd537257fad96e977b9e545be583bbf7028f30b9) |
| COMP Prize Pool                  | [0xBC82221e131c082336cf698F0cA3EBd18aFd4ce7](https://etherscan.io/address/0xBC82221e131c082336cf698F0cA3EBd18aFd4ce7) |
| COMP Prize Strategy              | [0x3ec4694b65e41f12d6b5d5ba7c2341f4d6859773](https://etherscan.io/address/0x3ec4694b65e41f12d6b5d5ba7c2341f4d6859773) |
| COMP POOL Faucet                 | [0x72F06a78bbAac0489067A1973B0Cef61841D58BC](https://etherscan.io/address/0x72F06a78bbAac0489067A1973B0Cef61841D58BC) |
| Loot Box ERC721                  | [0x4d695c615a7AACf2d7b9C481B66045BB2457Dfde](https://etherscan.io/address/0x4d695c615a7AACf2d7b9C481B66045BB2457Dfde) |
| Loot Box Prize Strategy Listener | [0xfe7205DF55BA42c8801e44B55BF05F06cCe8565E](https://etherscan.io/address/0xfe7205DF55BA42c8801e44B55BF05F06cCe8565E) |
| Reserve                          | [0xdb8E47BEFe4646fCc62BE61EEE5DF350404c124F](https://etherscan.io/address/0xdb8E47BEFe4646fCc62BE61EEE5DF350404c124F) |
| Reserve Registry                 | [0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295](https://etherscan.io/address/0x3e8b9901dBFE766d3FE44B36c180A1bca2B9A295) |

### Governance

**@pooltogether/governance ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/governance)

| Contract                                                                                          | Address                                                                                                               | Artifact                                                                                                            |
| ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [GovernorAlpha](https://github.com/pooltogether/governance/tree/main/contracts/GovernorAlpha.sol) | [0xB3a87172F555ae2a2AB79Be60B336D2F7D0187f0](https://etherscan.io/address/0xB3a87172F555ae2a2AB79Be60B336D2F7D0187f0) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/GovernorAlpha.json)             |
| [Pool](https://github.com/pooltogether/governance/tree/main/contracts/Pool.sol)                   | [0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e](https://etherscan.io/address/0x0cEC1A9154Ff802e7934Fc916Ed7Ca50bDE6844e) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/Pool.json)                      |
| [Timelock](https://github.com/pooltogether/governance/tree/main/contracts/Timelock.sol)           | [0x42cd8312D2BCe04277dD5161832460e95b24262E](https://etherscan.io/address/0x42cd8312D2BCe04277dD5161832460e95b24262E) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/Timelock.json)                  |
| TreasuryVesterForTreasury                                                                         | [0x21950E281bDE1714ffd1062ed17c56D4D8de2359](https://etherscan.io/address/0x21950E281bDE1714ffd1062ed17c56D4D8de2359) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/mainnet/TreasuryVesterForTreasury.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                               | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xb1D89477d1b505C261bab6e73f08fA834544CD21](https://etherscan.io/address/0xb1D89477d1b505C261bab6e73f08fA834544CD21) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mainnet/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F](https://etherscan.io/address/0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mainnet/RNGChainlink.json) |

### Loot Box Contracts

**@pooltogether/loot-box ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/loot-box)

| Contract                                                                                                                                    | Address                                                                                                               | Artifact                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [ERC721ControlledFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/ERC721ControlledFactory.sol)                         | [0x4E869b3A0978fA61DAbd7Da8F9B272AADc745Fb3](https://etherscan.io/address/0x4E869b3A0978fA61DAbd7Da8F9B272AADc745Fb3) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/ERC721ControlledFactory.json)             |
| [LootBoxController](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxController.sol)                                     | [0x2c2a966b7F5448A36EC9f896088DfB99B21d8A24](https://etherscan.io/address/0x2c2a966b7F5448A36EC9f896088DfB99B21d8A24) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/LootBoxController.json)                   |
| [LootBoxPrizeStrategyListenerFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxPrizeStrategyListenerFactory.sol) | [0x25e6a78D93D2935A638fDbd684e7b39565d0B7eA](https://etherscan.io/address/0x25e6a78D93D2935A638fDbd684e7b39565d0B7eA) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/LootBoxPrizeStrategyListenerFactory.json) |

### Retroactive Token Distribution

**@pooltogether/merkle-distributor ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/merkle-distributor)

| Contract                                                                                                          | Address                                                                                                               | Artifact                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [MerkleDistributor](https://github.com/pooltogether/merkle-distributor/tree/main/contracts/MerkleDistributor.sol) | [0xBE1a33519F586A4c8AA37525163Df8d67997016f](https://etherscan.io/address/0xBE1a33519F586A4c8AA37525163Df8d67997016f) | [Artifact](https://github.com/pooltogether/merkle-distributor/tree/main/deployments/mainnet/MerkleDistributor.json) |

## Rinkeby

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.2.1** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract            | Address                                                                                                                       |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Dai Prize Pool      | [0x4706856FA8Bb747D50b4EF8547FE51Ab5Edc4Ac2](https://rinkeby.etherscan.io/address/0x4706856FA8Bb747D50b4EF8547FE51Ab5Edc4Ac2) |
| Dai Prize Strategy  | [0x5E0A6d336667EACE5D1b33279B50055604c3E329](https://rinkeby.etherscan.io/address/0x5E0A6d336667EACE5D1b33279B50055604c3E329) |
| USDC Prize Pool     | [0xde5275536231eCa2Dd506B9ccD73C028e16a9a32](https://rinkeby.etherscan.io/address/0xde5275536231eCa2Dd506B9ccD73C028e16a9a32) |
| USDC Prize Strategy | [0x1b92BC2F339ef25161711e4EafC31999C005aF21](https://rinkeby.etherscan.io/address/0x1b92BC2F339ef25161711e4EafC31999C005aF21) |
| BAT Prize Pool      | [0xab068F220E10eEd899b54F1113dE7E354c9A8eB7](https://rinkeby.etherscan.io/address/0xab068F220E10eEd899b54F1113dE7E354c9A8eB7) |
| BAT Prize Strategy  | [0x41CF0758b7Cc2394b1C2dfF6133FEbb0Ef317C3b](https://rinkeby.etherscan.io/address/0x41CF0758b7Cc2394b1C2dfF6133FEbb0Ef317C3b) |
| Loot Box ERC721     | [0xfbC6677806253dB9739d0F6CBD89b9e7Ed4A5c66](https://rinkeby.etherscan.io/address/0xfbC6677806253dB9739d0F6CBD89b9e7Ed4A5c66) |

### Builders

**@pooltogether/pooltogether-contracts ^3.2.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                           | Address                                                                                                                       | Artifact                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Comptroller](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/comptroller/Comptroller.sol)                                    | [0x4f9fbe1E70Df30Ed8F257962D7CB80531Aba2B16](https://rinkeby.etherscan.io/address/0x4f9fbe1E70Df30Ed8F257962D7CB80531Aba2B16) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/Comptroller.json)                              |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/builders/ControlledTokenBuilder.sol)                 | [0x057Db7C55ffa0E5Eddf1d30F33d1320F5335A2CB](https://rinkeby.etherscan.io/address/0x057Db7C55ffa0E5Eddf1d30F33d1320F5335A2CB) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/ControlledTokenBuilder.json)                   |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/builders/MultipleWinnersBuilder.sol)                 | [0xb14c1661Dc0AbF7C18fa9d81B2E332f86321138d](https://rinkeby.etherscan.io/address/0xb14c1661Dc0AbF7C18fa9d81B2E332f86321138d) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/MultipleWinnersBuilder.json)                   |
| [PermitAndDepositDai](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/permit/PermitAndDepositDai.sol)                         | [0x920169739cD0eB740D78c16841510Ab9F4b28453](https://rinkeby.etherscan.io/address/0x920169739cD0eB740D78c16841510Ab9F4b28453) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/PermitAndDepositDai.json)                      |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/builders/PoolWithMultipleWinnersBuilder.sol) | [0x0780B754aD492040DBe84E0A6664B54e3159C64c](https://rinkeby.etherscan.io/address/0x0780B754aD492040DBe84E0A6664B54e3159C64c) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/PoolWithMultipleWinnersBuilder.json)           |
| [Reserve](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/reserve/Reserve.sol)                                                | [0x6A25ba0331553d2ab21E33AFa12d5f8101Dda50E](https://rinkeby.etherscan.io/address/0x6A25ba0331553d2ab21E33AFa12d5f8101Dda50E) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/Reserve.json)                                  |
| ReserveRegistry                                                                                                                                                    | [0x6F748E75e68DA04dA2E08c2aE5cc160A356a61a6](https://rinkeby.etherscan.io/address/0x6F748E75e68DA04dA2E08c2aE5cc160A356a61a6) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/ReserveRegistry.json)                          |
| [TokenFaucetProxyFactory](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/token-faucet/TokenFaucetProxyFactory.sol)           | [0x3e869a29DC2cd9DcBd9d6d48510fa5B587498B4e](https://rinkeby.etherscan.io/address/0x3e869a29DC2cd9DcBd9d6d48510fa5B587498B4e) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/TokenFaucetProxyFactory.json)                  |
| UnsafeTokenListenerDelegatorProxyFactory                                                                                                                           | [0x80F4612CA16cd0663B8F0ab4391d8e2E5D1912ba](https://rinkeby.etherscan.io/address/0x80F4612CA16cd0663B8F0ab4391d8e2E5D1912ba) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/UnsafeTokenListenerDelegatorProxyFactory.json) |

### Governance

**@pooltogether/governance ^1.0.1** [**npm**](https://www.npmjs.com/package/@pooltogether/governance)

| Contract                                                                                          | Address                                                                                                                       | Artifact                                                                                                            |
| ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [GovernorAlpha](https://github.com/pooltogether/governance/tree/main/contracts/GovernorAlpha.sol) | [0x9B63243CD27102fbEc9FAf67CA1a858dcC16Ee01](https://rinkeby.etherscan.io/address/0x9B63243CD27102fbEc9FAf67CA1a858dcC16Ee01) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/GovernorAlpha.json)             |
| [Pool](https://github.com/pooltogether/governance/tree/main/contracts/Pool.sol)                   | [0xc4E90a8Dc6CaAb329f08ED3C8abc6b197Cf0F40A](https://rinkeby.etherscan.io/address/0xc4E90a8Dc6CaAb329f08ED3C8abc6b197Cf0F40A) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/Pool.json)                      |
| [Timelock](https://github.com/pooltogether/governance/tree/main/contracts/Timelock.sol)           | [0x8Df0AfB54836dc8D0AE795503F837Cff197d3df1](https://rinkeby.etherscan.io/address/0x8Df0AfB54836dc8D0AE795503F837Cff197d3df1) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/Timelock.json)                  |
| TreasuryVesterForTreasury                                                                         | [0x529a916B8B7EC8E01805D45AEd1109C764ea88B9](https://rinkeby.etherscan.io/address/0x529a916B8B7EC8E01805D45AEd1109C764ea88B9) | [Artifact](https://github.com/pooltogether/governance/tree/main/deployments/rinkeby/TreasuryVesterForTreasury.json) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                       | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xA932e74d5263A754Ea04432E5c53658434b0484B](https://rinkeby.etherscan.io/address/0xA932e74d5263A754Ea04432E5c53658434b0484B) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/rinkeby/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0x11D94431718934868C4339aFc5ea27585F46C99A](https://rinkeby.etherscan.io/address/0x11D94431718934868C4339aFc5ea27585F46C99A) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/rinkeby/RNGChainlink.json) |

### Loot Box Contracts

**@pooltogether/loot-box ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/loot-box)

| Contract                                                                                                                                    | Address                                                                                                                       | Artifact                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [ERC721ControlledFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/ERC721ControlledFactory.sol)                         | [0x1D90F79a8515F63881075Ec2C212e18272aD9E38](https://rinkeby.etherscan.io/address/0x1D90F79a8515F63881075Ec2C212e18272aD9E38) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC721ControlledFactory.json)             |
| [LootBoxController](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxController.sol)                                     | [0xb1EAc75da9bc31B078742C5AF9EDe62EFE31299D](https://rinkeby.etherscan.io/address/0xb1EAc75da9bc31B078742C5AF9EDe62EFE31299D) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/LootBoxController.json)                   |
| [LootBoxPrizeStrategyListenerFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxPrizeStrategyListenerFactory.sol) | [0xadB4D93D84b18b5D82063aCf58b21587c92fdfb5](https://rinkeby.etherscan.io/address/0xadB4D93D84b18b5D82063aCf58b21587c92fdfb5) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/LootBoxPrizeStrategyListenerFactory.json) |

### Retroactive Token Distribution

**@pooltogether/merkle-distributor ^1.0.2** [**npm**](https://www.npmjs.com/package/@pooltogether/merkle-distributor)

| Contract                                                                                                          | Address                                                                                                                       | Artifact                                                                                                            |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [MerkleDistributor](https://github.com/pooltogether/merkle-distributor/tree/main/contracts/MerkleDistributor.sol) | [0x93a6540DcE05a4A5E5B906eB97bBCBb723768F2D](https://rinkeby.etherscan.io/address/0x93a6540DcE05a4A5E5B906eB97bBCBb723768F2D) | [Artifact](https://github.com/pooltogether/merkle-distributor/tree/main/deployments/rinkeby/MerkleDistributor.json) |

*This document was generated* [*automatically*](https://github.com/pooltogether/generate-networks-doc)


# Resources

## Tools

* [Prize Pool Builder](https://builder.pooltogether.com) ([Source Code](https://github.com/pooltogether/pooltogether-pool-builder-ui))
* [Prize Pool Reference App](https://reference-app.pooltogether.com) ([Source Code](https://github.com/pooltogether/pooltogether-reference-pool-ui))

## Code

* [Prize Pool Contracts](https://github.com/pooltogether/pooltogether-pool-contracts)
* [Random Number Generator Contracts](https://github.com/pooltogether/pooltogether-rng-contracts)
* [PoolTogether V3 Subgraph](https://github.com/pooltogether/pooltogether-subgraph-v3)
* [Loot Box Contracts](https://github.com/pooltogether/loot-box)
* [OpenZeppelin Defender Award Autotask](https://github.com/pooltogether/defender-autotask-reward)
* [V2 to V3 Migration Contracts](https://github.com/pooltogether/pooltogether-migrate-v3)

### Subgraphs

* [mainnet Subgraph](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-v3_1_0)
* [mainnet LootBox Subgraph](https://thegraph.com/explorer/subgraph/pooltogether/lootbox-v1_0_0)
* [rinkeby Subgraph](https://thegraph.com/explorer/subgraph/pooltogether/rinkeby-v3_1_0)

## Workshops

* [ETHOnline Hackathon Custom Prize Strategy](<https://github.com/pooltogether/ethonline-workshop >)


# Overview

What are No-Loss Prize Games?

No-loss prize games are pools of funds whose accrued interest is distributed as prizes.

The high level protocol architecture is outlined below. The code is available on [Github](https://github.com/pooltogether/pooltogether-pool-contracts).

## How it works

1. Users deposit funds into a Prize Pool.  They receive pool tokens in exchange.
2. The funds earn interest.
3. The interest is distributed by the Prize Strategy as pool tokens.
4. Users withdraw their funds at any time by telling the Prize Pool to burn their pool tokens.

## Architecture

### [Prize Pools](/v3.2.0/protocol/prize-pool)

Prize Pools are the central building block of prize games.  They pool user funds in a **yield source** and expose the yield to their **Prize Strategy**, which then disburses as desired.

Prize Pools can be differentiated in four primary ways:

* The yield source the prize pool uses to generate no loss return
* The prize strategy used to determine frequency and distribution&#x20;
* The rewards offered by the prize pool
* The asset type the prize pool accepts for deposits&#x20;
* The fairness parameters&#x20;

### [Prize Strategies](/v3.2.0/protocol/prize-strategy)

Prize Strategies determine the prize distribution for the Prize Pool.  They can define any logic to allocate tokens that the prize pool accrues.  Specifically they can:

* Award yield in the Prize Pool as pool tokens
* Award ERC20 tokens held by the Prize Pool
* Award ERC721 tokens held by the Prize Pool

### [Builders](broken://pages/-M62EjiYFQOIIF0UDsxg)

Builders make it easy to create pre-configured prize games.  There are currently three Prize Pool types paired with the MultipleWinners, documentation available [here](broken://pages/-M62EjiYFQOIIF0UDsxg).&#x20;

### [Random Number Generator](/v3.2.0/protocol/random-number-generator)

There are many different ways to generate a random number, so we've abstracted them as request-based Random Number Generator services.  Each RNG service has a different security profile, so be sure to use the appropriate one for your game.

## Conventions

Fixed point math is used extensively in PoolTogether.  We used fixed point math with 18 decimal places for all fractional numbers.  You can think of this as being just like Ether and wei: a value of "1" Ether is represented as "1000000000000000000" wei.

When a number is a fixed point 18 number we always suffix the number with *mantissa.*  For example the credit rate is written as *creditRateMantissa*, because it is a fixed point number.


# Prize Pools

Pool deposits and award accrued interest periodically as a prize

## Introduction

Prize Pools allow funds to be pooled together into a no-loss yield source, such as Compound, and have the yield safely exposed to a separate Prize Strategy. They are the primary way through which users interact with PoolTogether prize games.

Prize Pools provide controls to the owner so that participation can be made fair. See [Fairness](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-1612721655/protocol/fairness.md) for more information.

There is a different type of prize pool for each yield source. For example, if you wish to use Compound you will use the Compound Prize Pool.

All Prize Pools share the functionality below.

## Owner

When a Prize Pool is created, the creator is set as the pool's "owner". The owner is able to:

* Add additional pool tokens
* Change the Prize Strategy
* Set the [credit rate and credit limit](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-1612721655/protocol/fairness.md#credit)
* Shutdown the prize pool
* Transfer ownership
* Renounce ownership

**The prize pool is not upgradeable and therefore the owner can never seize the funds deposited into the prize pool**

## Limits

When a Prize Pool is created it is initialized with some hard-coded limits to protect users. See [Fairness](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-1612721655/protocol/fairness.md) for more details.

### **Maximum Timelock Duration**

The maximum timelock duration ensures that a user has to wait at most X amount of time to withdraw their funds loss-lessly. If the owner of a pool sets the credit rate to be way too low, this limit ensures users will still be able to withdraw.

If using the Single Random Winner Prize Strategy, it would make sense to set the maximum timelock duration to 2x the prize period. That way the owner has some flexibility when adjusting the credit limit and credit rate.

### **Maximum Credit Limit**

The maximum credit limit ensures that the credit limit cannot be set higher than this number. This prevents the owner of the Prize Pool from capturing \*all\* of a user's deposit at withdrawal time.

### **Maximum Liquidity Limit**

The maximum liquidity limit allows the PrizePool owner to set a cap on the amount of liquidity the pool can hold. This can be set by calling:

```javascript
function setLiquidityCap(uint256 _liquidityCap) external override onlyOwner
```

## Token Model

A Prize Pool accepts a single type of ERC20 token for deposits. This token depends on the implementation: for a Compound Prize Pool bound to cDai it will be Dai, for a yEarn yUSDC vault it will be USDC. This is the underlying **asset** of the Prize Pool.

Prize Pools use **Controlled Tokens** for their internal accounting. These tokens are minted when depositing or awarding prizes. Controlled Tokens are burned when users withdraw. They are exchanged at a ratio of 1:1 to the asset.

The tokens associated with a PrizePool can be seen by calling:

```javascript
function tokens() external override view returns (address[] memory)
```

### Controlled Tokens

A Controlled Token is a standard ERC20 that is bound to a **Token Controller**.

The Token Controller has the privileged ability to mint and burn tokens on user's behalf, and has a callback that listens for token transfers. Controlled Tokens are expected to trigger this callback on any mint, burns or transfers.

The Prize Pool must be the Token Controller for the controlled tokens that it is initialized with at construction.

The default [Compound Prize Pool Builder](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-1612721655/builders/) creates a Ticket controlled token and a [Sponsorship](/v3.2.0/protocol/tokens/sponsorship) controlled token.

A Controlled Token can added by the PrizePool owner by calling:

```javascript
function addControlledToken(ControlledTokenInterface _controlledToken) 
external override onlyOwner
```

### Minting

When a user deposits into a Prize Pool they must request what type of controlled token they receive in exchange. This token will be minted to them at an exchange rate of 1:1 for the asset.

### Burning

When a user wishes to withdraw from a Prize Pool they must burn controlled tokens.

## Depositing

Users can deposit into the Prize Pool using the **depositTo** function. A user is instantly minted tokens upon deposit.

```javascript
function depositTo(
    address to,
    uint256 amount,
    address controlledToken,
    address referrer
) external;
```

| Parameter       | Description                                                                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| to              | The address to whom the controlled tokens should be minted                                                                                                                                                   |
| amount          | The amount of the underlying asset the user wishes to deposit.  The Prize Pool contract should have been pre-approved by the caller to transfer the underlying ERC20 tokens.                                 |
| controlledToken | The address of the token that they wish to mint.  For our default Prize Strategy this will either be the Ticket address or the Sponsorship address.  Those addresses can be looked up on the Prize Strategy. |
| referrer        | The address that should receive [referral awards](https://app.gitbook.com/s/governance/untitled.md#referral-volume-drips), if any.                                                                           |

Depositing fires the event:

```javascript
event Deposited(
    address indexed operator,
    address indexed to,
    address indexed token,
    uint256 amount
);
```

| Event Data | Description                                                                                   |
| ---------- | --------------------------------------------------------------------------------------------- |
| operator   | The caller that made the deposit                                                              |
| to         | The address that received the minted tokens                                                   |
| token      | The address of the controlled token that was minted                                           |
| amount     | The amount of both the underlying asset that was transferred and the tokens that were minted. |

### Depositing Using Timelocked Funds

If a user wishes to re-deposit their timelocked funds, they can do so using this function:

```javascript
function timelockDepositTo(
    address to,
    uint256 amount,
    address controlledToken
) external;
```

| Parameter       | Description                                                                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| to              | The address to whom the controlled tokens should be minted                                                                                                                                                   |
| amount          | The amount of the underlying asset the user wishes to deposit.  The Prize Pool contract should have been pre-approved by the caller to transfer the underlying ERC20 tokens.                                 |
| controlledToken | The address of the token that they wish to mint.  For our default Prize Strategy this will either be the Ticket address or the Sponsorship address.  Those addresses can be looked up on the Prize Strategy. |

## Withdrawing

When a user withdraws they may need to contribute to the prize according to the [fairness rules](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-1612721655/protocol/fairness.md). They may either cover the contribution by time-locking their funds, or cover the contribution explicitly using funds.

### **Withdraw with Timelock**

Funds can be withdrawn losslessly by time-locking the funds. The withdrawal amount will be unlocked at a later date at which point the funds can be swept back to the user. The timelock duration is calculated based on the users accrued credit, the credit rate, and the fairness fee.

If the user has sufficient credit, the unlockTimestamp may be "now" and the funds are instantly swept to the `from` address.

Tip: You can call this function in a constant way to see when the users funds will be unlocked.

To start a lossless withdrawal a user may call:

```javascript
function withdrawWithTimelockFrom(
    address from,
    uint256 amount,
    address controlledToken
) external returns (uint256 unlockTimestamp);
```

| Parameter Name  | Parameter Description                                                                                                            |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| from            | The user from whom to withdraw.  This means you may withdraw on another user's behalf if they have given you an ERC20 allowance. |
| amount          | The amount of collateral to withdraw.                                                                                            |
| controlledToken | The type of controlled token to withdraw.                                                                                        |

### Checking Timelock Balances

To see how many funds have been timelocked for a `user` call:

```javascript
function timelockBalanceOf(address user) external view returns (uint256)
```

After funds have been time-locked, you can see at what timestamp they'll be available:

```javascript
function timelockBalanceAvailableAt(address user) external view returns (uint256)
```

### Checking Timelock Duration

To calculate a timelocked withdrawal duration and credit consumption call:

```javascript
function calculateTimelockDuration(address from, address controlledToken, uint256 amount) 
external override returns (uint256 durationSeconds,uint256 burnedCredit)
```

| Parameter Name  | Description                               |
| --------------- | ----------------------------------------- |
| from            | The user who is withdrawing.              |
| amount          | The amount the user is withdrawing.       |
| controlledToken | The type of controlled token to withdraw. |

**returns**:

| Returned Parameter Name | Description                               |
| ----------------------- | ----------------------------------------- |
| `durationSeconds`       | The duration of the timelock in seconds   |
| `burned`                | The amount of credit that would be burned |

### Estimating Credit Accrual Time

Similarly it is also possible to calculate how long a user must keep their funds in the pool:

```javascript
function estimateCreditAccrualTime(address _controlledToken,
 uint256 _principal,
 uint256 _interest) 
 external override view returns (uint256 durationSeconds)
```

| Parameter Name    | Parameter Description                               |
| ----------------- | --------------------------------------------------- |
| \_controlledToken | The type of controlled token.                       |
| \_principal       | The principal amount on which interest is accruing. |
| \_interest        | The amount of interest that must accrue.            |

### Sweeping Timelocked Funds

When a user's withdrawal timelocks have ended, the funds may be swept to their wallets:

```javascript
function sweepTimelockBalances(
    address[] memory users
) external returns (uint256 totalWithdrawal);
```

The function accepts an array of addresses and will attempt to sweep the time-locked funds for each one. The funds will be transferred back to the users wallets.

### Withdraw Instantly

If a user would like their tickets right away, they may pay an early exit fee to the prize. The early exit fee is determined by the [Prize Strategy](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-1612721655/prize-strategy/).

The instant withdrawal function returns the amount of the withdrawal that was retained as payment. This means you can call this function in a constant way to check to see what the exit fee will be. When it comes time to run the tx, that exit fee can be passed as the `maximumExitFee` to ensure it doesn't exceed the expected limit.

```javascript
function withdrawInstantlyFrom(
    address from,
    uint256 amount,
    address controlledToken,
    uint256 maximumExitFee
  )
    external
    returns (uint256 exitFee);
```

| Parameter Name  | Parameter Description                                                                                                                  |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| from            | The address to withdraw from.  This means you can withdraw on another user's behalf if you have an allowance for the controlled token. |
| amount          | The amount to withdraw                                                                                                                 |
| controlledToken | The controlled token to withdraw from                                                                                                  |
| maximumExitFee  | The maximum early exit fee the caller is willing to pay.  This prevents the Prize Strategy from changing the fee on-the-fly.           |

This early exit fee can also be calculated by calling:

```javascript
function calculateEarlyExitFee(address from, address controlledToken, uint256 amount)
 external override returns (uint256 exitFee, uint256 burnedCredit)
```

| Parameter Name  | Parameter Description                 |
| --------------- | ------------------------------------- |
| from            | The address to withdraw from          |
| controlledToken | The controlled token to withdraw from |
| amount          | The amount to withdraw                |

returns the `exitFee` that would be paid along with the credit that would be burned (`burnedCredit`).

## Awarding

Only the Prize Strategy can call the award functions. These functions allow prizes to be disbursed to users.

### Awarding Yield

Yield that accrues in the Prize Pool can be awarded by the Prize Strategy. The yield must first be **captured** and then it can be **awarded.**

To capture the yield the prize strategy can call the `captureAwardBalance` function:

```javascript
function captureAwardBalance() external onlyPrizeStrategy returns (uint256);
```

This function will:

* add the current yield balance to the available award balance
* capture a portion for the reserve
* return the total available award balance.

To award the captured yield to an address, the Prize strategy uses the `award` function. The yield must be awarded as one of the controlled tokens configured in the Prize Pool.

```javascript
function award(
    address to,
    uint256 amount,
    address controlledToken
) external onlyPrizeStrategy;
```

| Parameter Name  | Parameter Description                          |
| --------------- | ---------------------------------------------- |
| to              | The address to receive the newly minted tokens |
| amount          | The amount of tokens to mint                   |
| controlledToken | The type of token to mint                      |

### Awarding ERC20s

The Prize Strategy can award ERC20 tokens that are held by the Prize Pool.

```javascript
function awardExternalERC20(
    address to,
    address externalToken,
    uint256 amount
) external onlyPrizeStrategy;
```

However, some tokens are be blacklisted if they need to be held to generate yield (i.e. Compound cTokens).

| Parameter Name | Parameter Description               |
| -------------- | ----------------------------------- |
| to             | The address to receive the transfer |
| externalToken  | The ERC20 to transfer               |
| amount         | The amount of tokens to transfer    |

### Awarding ERC721s (NFTs)

The Prize Strategy can award ERC721 tokens that are held by the Prize Pool.

```javascript
function awardExternalERC721(
    address to,
    address externalToken,
    uint256[] calldata tokenIds
  )
    external
    onlyPrizeStrategy;
```

| Parameter Name | Parameter Description           |
| -------------- | ------------------------------- |
| to             | The address to receive the NFTs |
| externalToken  | The ERC721 contract address     |
| tokenIds       | The NFT token ids to transfer.  |

## Credit

Credit accrues differently for each of the Prize Pool's controlled tokens, so each token will have its own credit rate and credit limit.

### Credit Balance

To get a users credit balance for a controlled token:

```javascript
function balanceOfCredit(
    address user,
    address controlledToken
) external returns (uint256);
```

| Parameter Name  | Parameter Description                                   |
| --------------- | ------------------------------------------------------- |
| user            | The user whose credit balance should be returned        |
| controlledToken | The token for which the credit balance should be pulled |

### Credit Rate

The credit rate for a controlled token can be checked like so:

```javascript
function creditRateOf(
    address controlledToken
) external view returns (
    uint128 creditLimitMantissa,
    uint128 creditRateMantissa
);
```

| Parameter Name  | Parameter Description                                                |
| --------------- | -------------------------------------------------------------------- |
| controlledToken | The controlled token whose credit limit and rate should be returned. |

Note that the returned values are "mantissas": i.e. fixed point numbers with 18 decimal places.

### Credit Plan

The credit plan associated with a `controlledToken` can be found by calling:

```javascript
function creditPlanOf(address controlledToken) external override view returns (uint128 creditLimitMantissa, uint128 creditRateMantissa)
```

## Prizes

### Current Award Balance

The following function returns the amount calculated by `captureAwardBalance()`:

```javascript
function awardBalance() external override view returns (uint256)
```

### Total Balances

The total of all controlled tokens (including timelocked) can be obtained by calling:

```javascript
function accountedBalance() external override view returns (uint256)
```

The total underlying balance of all assets (including both principal and interest) can be obtained by calling:

```javascript
function balance() external returns (uint256)
```

## External Prizes

### Adding Tokens

The owner can add "external" ERC20 tokens as prizes. The strategy will award the entire balance held by the Prize Pool to the winner.

```javascript
function addExternalErc20Award(address _externalErc20) external onlyOwner;
```

The owner can add "external" ERC721 tokens as prizes. These tokens will be transferred to the winner.

```javascript
function addExternalErc721Award(
    address _externalErc721,
    uint256[] calldata _tokenIds
) external onlyOwner
```

### Checking Tokens

Checks with the Prize Pool if a specific token type (`_externalToken`) may be awarded as an external prize:

```javascript
function canAwardExternal(address _externalToken) external view returns (bool)
```

## Prize Time Periods

To retrieve when the current prize started:

```javascript
function prizePeriodStartedAt() external view returns (uint256)
```

To retrieve when the prize will end:

```javascript
function prizePeriodEndAt() external view returns (uint256)
```

## Reserve

### Calculate Reserve Fee

Calculates the reserve portion of the given `amount` of funds. If there is no reserve address, the Reserve fee portion will be zero.

```javascript
function calculateReserveFee(uint256 amount) public view returns (uint256)
```

## Prize Strategy

### Set the Prize Strategy

The associated Prize Strategy can be set by calling:

```javascript
function setPrizeStrategy(TokenListenerInterface _prizeStrategy) external override onlyOwner
```

Only the Prize Pool owner can call this function.


# ⚖️ Fairness

How Prize Pools Ensure Fair Play

When users play a game they want it to be fair. In PoolTogether, this means that everyone has contributed the same amount of interest to prizes they are eligible to win. Interest accrues over time, so the Prize Pool needs to measure and enforce the time that funds are held. Without this mechanism, it would be very easy to game the system by depositing right before a prize, having a chance to win, and withdrawing right after.

Prize Pools measure the duration of time funds are held by accruing **credit** for each user at the **credit rate**. The longer a user holds tokens, the more credit they accrue.

Prize Pools enforce the duration of time funds are held by setting a **credit limit**. Once a credit limit is reached a user can withdraw instantly with no loss. If the credit limit has not been reached the user can either use a withdrawal **timelock** or pay an early exit contribution to the prize.

## Credit

After a user deposits funds they begin to accrue credit according to the credit rate. The credit rate is expressed in tokens per second.

For example: if the user deposits 100 DAI and the credit rate is 0.1, then they will have accrued 1 DAI in credit after 10 seconds. Note that they cannot withdraw the 1 DAI credit; it's simply a measure of their contribution.

Users will accrue credit up until the **credit limit**. The credit limit is a fraction, so a users credit limit is that fraction of their entire balance. For example, if the user holds 100 DAI and the credit limit is 0.1, then they will accrue a maximum of 10 DAI in credit.

Once a deposit has accrued maximum credit, it is considered **matured**.

## Timelock

A deposit can be withdrawn instantly from the Prize Pool if it has matured. Otherwise, upon withdrawal the deposit will be timelocked until it has matured, at which point the funds can be swept back to the user by anyone.

The timelock duration is calculated based on the spare credit the user has. The spare credit for a withdrawal is their credit balance *less the credit limit for their remaining balance of tokens*. For example: let's say a user has 100 DAI and is attempting to withdraw 10 DAI. They currently have 9 DAI in credit and the credit limit is 0.1. The user's spare credit is 9 - (100 - 10) \* 0.1 = 0 DAI. If the user was instead withdrawing 50 DAI, then they would have 9 - (100 - 50) \* 0.1 = 4 DAI in spare credit.

The duration of the timelock is the time it takes for the withdrawal to mature less the spare credit. For example: if the withdrawal amount is 100 DAI, and the user has 5 DAI in spare credit, and the credit rate is 0.1, then the timelock will be ((100 \* 0.1) - 5) / 0.1 = 50 seconds. The spare credit is burned and the funds are placed in a timelock that can be swept after the duration has elapsed.

### Paying Off the Timelock

It's possible for a user to withdraw their funds instantly. Instead of a timelock, the Prize Pool will capture the remaining contribution directly from the withdrawal amount. The user will receive the withdrawal amount less the remaining contribution. Their spare credit will be burned. We call this an **instant withdrawal.**

## What should the credit rate and credit limit for a pool be?

In principal, we want the timelock to be as short as possible and most users should never encounter it. We are trying to prevent abuse of the system by a small subset of users while keeping the smoothest experience for the majority of users.

At first glance the credit limit should simply be equal to the amount of interest a deposit would contribute over a prize period. But there are several factors that can change the cost / benefit balance for depositors, specifically:

* Any subsidies to the prize (whether through sponsored deposits or direct additions)
* Any rewards given to deposits through the token drips
* Fluctuations in the yield rate
* Total amount of outstanding tickets for a given prize
* Gas fees of entering and exiting the pool

To find the ideal credit limit it is best to estimate the **effective APR** a pool is offering.

**Example**

Assume a pool has a yield source that returns 5% APR.  The pool awards prizes weekly, which means that each week approximately 5% / 52 = 0.096% accrues.  A fair credit limit could be 0.1%: if the user decides to game the prize, they will need to contribute 0.1% of their deposit.

However, we want users who have been in the pool since the beginning to not have to pay anything.  Let's say we wish for users to accrue 0.1% credit per week, so that they can withdraw losslessly.  The credit rate is applied per second and does not compound, so we can calculate the credit rate as the credit limit / seconds in a week, or 0.1% / 86400 = 0.0000011574074074074074.

This means that users will need to stay in the pool for a week, otherwise they'll need to pay an early exit fee of 0.1%.  Note, however, that this fee diminishes over time.


# Compound Prize Pool

The Compound Prize Pool is a Prize Pool that uses [Compound](https://compound.finance) as the yield source.  When a Compound Prize Pool is created it is configured with the cToken to use for minting and redeeming.

## Retrieving the Underlying cToken

To access the underlying [cToken](https://compound.finance/docs/ctokens), simply call this function:

```javascript
function cToken() returns (address);
```


# Stake Prize Pool

The Stake Prize Pool is a prize pool that uses an ERC-20 compatible token as the underlying asset.

Users's can stake their tokens to become eligible for whatever prize is defined as the prize strategy for that pool.

This is particularly useful for protocols that are sitting inactively in users's wallets - why not stake them in a pool and become eligible for rewards?

The returned [ticket](/v3.2.0/protocol/tokens/ticket) can be thought of as a "proof-of-liquidity".

### Retrieving the Underlying ERC-20

The underlying staked asset can be retrieved by calling:

```javascript
function token() returns (address);
```


# Custom Yield Sources

Create a Prize Pool that Uses a Custom Yield Source

If you want to generate yield using a protocol that isn't currently supported by PoolTogether, you can build a custom **Yield Source**.  Then when you create a Prize Pool, you can configure it to use your custom yield source.

The yield source just needs these properties:

* &#x20;The deposit asset is the same as the asset that accrues.  I.e. if users deposit Dai into the yield source, then it should yield Dai as well
* Yield must always be increasing.  The mechanics of the Prize Pool require yield to always go up, as it's a no-loss system.  The yield source must protect depositor's collateral.

## Yield Source Interface

The yield source interface is very simple; it just needs to support four functions:

```javascript
interface YieldSourceInterface {

  function token() external view returns (address);

  function balanceOf(address addr) external returns (uint256);

  function supplyTo(uint256 amount, address to) external;

  function redeem(uint256 amount) external returns (uint256);
  
}
```

### token()

The token function must return the ERC20 address of the token used to deposit.  Users will deposit this token into the yield source.

### balanceOf(address)

The balanceOf function returns the balance of the given address, denominated in the ERC20 token mentioned above.  This balance must increase as yield accrues.

### supplyTo(uint256, address)

The supplyTo function allows a user to deposit tokens into the yield source.  The tokens will be the above ERC20 tokens, and they may deposit to themselves or any other Ethereum address.

### redeem(uint256)

The redeem function allows users to withdraw their tokens.  Their withdrawal will be the ERC20 tokens mentioned above and be transferred to them.  The actual amount transferred is the return value of the function, as some yield sources may incur fees.


# Prize Strategies

Customize how a Prize Pool distributes prizes

A Prize Strategy handles prize distribution for a [Prize Pool](/v3.2.0/protocol/prize-pool).  When a Prize Pool is constructed it is configured with a Prize Strategy.  The Prize Strategy has the privileged ability to award tokens from the Prize Pool.

The most popular Prize Strategy offering is the [Multiple Winner](/v3.2.0/protocol/prize-strategy/multiple-winners) strategy. Earlier versions (< v3.1.0) of the protocol used the Single Random Winner strategy, which is now a trivial subset of Multiple Winners (with `numberofWinners = 1`).

Prize Strategies must implement the [Token Listener](/v3.2.0/protocol/tokens/token-listener) interface so that they can be aware of the full token lifecycle.

## Privileged Actions

A [Prize Pool's](/v3.2.0/protocol/prize-pool) Prize Strategy is able to award tokens held by the Prize Pool contract. The Prize Strategy is able to:

* [award yield](/v3.2.0/protocol/prize-pool#awarding-yield) that has accrued in the Prize Pool
* [award any ERC20 balance](/v3.2.0/protocol/prize-pool#awarding-erc-20-s) held by the Prize Pool
* [award any ERC721](/v3.2.0/protocol/prize-pool#awarding-erc-721-s-nfts) owned by the Prize Pool

## Required Behaviour

A Prize Strategy must implement the [Token Listener](/v3.2.0/protocol/tokens/token-listener) interface so that it can listen to pool token mint, transfer and burn actions by the Prize Pool.


# Yield Sources


# Multiple Winners

The Multiple Winners prize strategy periodically selects a predefined number of winners and awards to them an equal share of the prizes available in the Prize Pool.

## Initialization

A Multiple Winners prize strategy is initialized with:

**Prize Period Start:** the timestamp at which the prize period should start

**Prize Period Seconds**: the duration of time between prizes

**PrizePool Address**: the address of the [prize pool](/v3.2.0/protocol/prize-pool) that implements the pool functionality such as deposit and withdraw

[**Ticket**](/v3.2.0/protocol/tokens/ticket)**:** The interface to use to select winners

[**Sponsorship**](/v3.2.0/protocol/tokens/sponsorship)**:** The token that represents sponsorship

[**Random Number Generator**](/v3.2.0/protocol/random-number-generator): used to generate random numbers for winner selection

**Number of Winners**: the number of winners in a prize period. This can be later changed by the owner calling set number of winners.

## Strategy Settings

### Set Number of Winners

The number of winners in a prize period can be set by calling:

```javascript
function setNumberOfWinners(uint256 count) 
external onlyOwner requireAwardNotInProgress
```

* Requires that the Award process is not in progress
* `count` must be greater than 0

### View Number of Winners

The number of winners setting can be viewed by calling:

```javascript
function numberOfWinners() external view returns (uint256
```

### Set Split External ERC-20 Awards

The `SplitExternalErc20Awards` flag can be set by calling:

```javascript
function setSplitExternalErc20Awards(bool _splitExternalErc20Awards) 
external onlyOwner requireAwardNotInProgress
```

This controls how externally added ERC-20's are distributed. Setting to `true` results in the ERC-20's paid out uniformly (similar to the main prize), while `false` does not pay out external ERC-20's for that award.

### Set Random Number Generation Service

The [Random Number Generation](/v3.2.0/protocol/random-number-generator) Service can be set when the award process has not started by the Prize Pool owner by calling:

```javascript
  function setRngService(RNGInterface rngService) 
  external onlyOwner requireAwardNotInProgress 
```

### Set Random Number Generator Request Timeout

The RNG request timeout parameter can be set (in seconds) when the award process has not started by the Prize Pool owner by calling:

```javascript
function setRngRequestTimeout(uint32 _rngRequestTimeout)
external onlyOwner requireAwardNotInProgress {
```

## Prize Period Information

#### View if the Prize Period is Over

To check if the prize period is finished call:

```javascript
function isPrizePeriodOver() external view returns (bool) 
```

Returns `true` if the prize period is over, `false` otherwise.

#### View when the Prize Period Finishes

To check the unix time when the prize period ends call:

```javascript
function prizePeriodEndAt() external view returns (uint256)
```

#### View Estimate of Number of Blocks to Prize Block

To estimate the remaining blocks until the prize given a number of seconds per block call `estimateRemainingBlocksToPrize` with `secondPerBlockMantissa` set to 15 seconds for Ethereum mainnet:

```javascript
function estimateRemainingBlocksToPrize(uint256 secondsPerBlockMantissa) public
view returns (uint256) 
```

#### View Prize Period Remaining Time (in seconds)

To get the number of seconds remaining until the prize can be awarded call:

```javascript
 function prizePeriodRemainingSeconds() external view returns (uint256) 
```

#### View Next Prize Period Start Time

To get the Unix timestamp of when the next prize period will start call `calculateNextPrizePeriodStartTime` with `currentTime` set to the current Unix time:&#x20;

```javascript
function calculateNextPrizePeriodStartTime(uint256 currentTime) 
external view returns (uint256)
```

## Award Process

At the end of the prize period, anyone can begin the award process. This happens in two main stages - `startAward` and `completeAward`. `startAward` triggers the configured Random Number Generator request, which will take some blocks. `completeAward` can then be called, which selects the winners using the RNG result and pushes the tokens out to the winners.&#x20;

### Start Award

The award process can be started by calling `startAward`.  This function starts the award process by starting the configured random number request. The prize period must have ended. The RNG-Request-Fee is expected to be held within this contract before calling this function.&#x20;

```
function startAward() external requireCanStartAward
```

Upon completion this function fires the following event:

```csharp
event PrizePoolAwardStarted(
    address indexed operator,
    address indexed prizePool,
    uint32 indexed rngRequestId,
    uint32 rngLockBlock
);
```

### Complete Award

The award process can be finished by calling `completeAward`. The random number must have been requested and now available (is can be checked by calling `isRngCompleted()`).

```javascript
function completeAward() external requireCanCompleteAward
```

This function fires two events upon completion:

```csharp
event PrizePoolAwarded(
    address indexed operator,
    uint256 randomNumber
);
```

Since Prize Pools are continuously rolling the next prize period is now open:

```csharp
event PrizePoolOpened(
    address indexed operator,
    uint256 indexed prizePeriodStartedAt
);
```

### Cancel Award

This function can be called by anyone to unlock the tickets if the RNG has timed out:

```javascript
function cancelAward() public
```

This function will fire the event:

```csharp
event PrizePoolAwardCancelled(
    address indexed operator,
    address indexed prizePool,
    uint32 indexed rngRequestId,
    uint32 rngLockBlock
);
```

### Listeners

A prize strategy can have both a [token listener](https://github.com/pooltogether/pooltogether-pool-contracts/blob/master/contracts/token/TokenListener.sol) and a periodic prize strategy listener in order execute code for certain callbacks (event hooks).

#### Set Token Listener

The token listener can be set by the prize pool owner when the award process is not in progress by calling `setTokenListener` with the address of the new `tokenList` :

```javascript
function setTokenListener(TokenListenerInterface _tokenListener)
  external onlyOwner requireAwardNotInProgress
```

#### Set Periodic Prize Strategy Listener

The periodic prize strategy listener can be set by the prize pool owner when the award process is not in progress by calling `setPeriodicPrizeStrategyListener` with the address of the new `PeriodicPrizeStrategyListener`:

```javascript
function setPeriodicPrizeStrategyListener(PeriodicPrizeStrategyListenerInterface _periodicPrizeStrategyListener) 
 external onlyOwner requireAwardNotInProgress
```

This function will ensure the Listener Interface is implementing using ERC-165 introspection, and upon completion fire the following event:

```csharp
event PeriodicPrizeStrategyListenerSet(
    PeriodicPrizeStrategyListenerInterface indexed periodicPrizeStrategyListener
);
```

### External ERC20 and ERC721 Awards

External awards can be added to the pool. This is particularly useful in the case of the stake pool. Although still possible for either the token listener or the owner to manually add or remove ERC-20's and ERC-721's, it is recommended to add a single [LootBox](/v3.2.0/protocol/lootbox) per prize period and direct the external awards to this LootBox address.&#x20;

The pool owner or the token listener can add/remove ERC721's by calling:&#x20;

```javascript
function addExternalErc721Award(IERC721Upgradeable _externalErc721,
  uint256[] calldata _tokenIds) 
  external onlyOwnerOrListener requireAwardNotInProgress 
```

```javascript
function removeExternalErc721Award(
  IERC721Upgradeable _externalErc721,
  IERC721Upgradeable _prevExternalErc721)
  external onlyOwner requireAwardNotInProgress
```

The pool owner or the token listener can add/remove ERC20's by calling:&#x20;

```javascript
function addExternalErc20Awards(IERC20Upgradeable[] calldata _externalErc20s) 
    external onlyOwnerOrListener requireAwardNotInProgress
```

```javascript
function removeExternalErc20Award(
  IERC20Upgradeable _externalErc20,
  IERC20Upgradeable _prevExternalErc20) 
  external onlyOwner requireAwardNotInProgress 
```

Corresponding events are fired for each ERC type added or removed:

```csharp
  event ExternalErc721AwardAdded(
    IERC721Upgradeable indexed externalErc721,
    uint256[] tokenIds
  );

  event ExternalErc20AwardAdded(
    IERC20Upgradeable indexed externalErc20
  );

  event ExternalErc721AwardRemoved(
    IERC721Upgradeable indexed externalErc721Award
  );

  event ExternalErc20AwardRemoved(
    IERC20Upgradeable indexed externalErc20Award
  );
```


# 🎟️ Tokens

When users deposit into a Prize Pool they receive an ERC20 compatible [ticket](/v3.2.0/protocol/tokens/ticket).

External ERC721 and ERC20's can also be [added, controlled and removed](/v3.2.0/protocol/prize-strategy/multiple-winners#external-erc20-and-erc721-awards) by Prize Pools.

[Sponsorship](/v3.2.0/protocol/tokens/sponsorship) tokens are created when funds are added to the pool that are not eligible to win any prizes.


# 🎟️ Ticket

The Ticket contract is an [ERC20](https://eips.ethereum.org/EIPS/eip-20)-compatible token that allows users to be selected by a token index.

The contract organizes the balances into a sum tree data structure, so that each address holds a "range" of tokens.  A number can be used as an index within that range, and the holder of the tokens in that range is selected:

```javascript
function draw(uint256 randomNumber) public view returns (address)
```

The **randomNumber** will be used as a token index into a specialized data structure that stores the user balances.  The randomNumber is constrained to the token supply and modulo bias is corrected.

The returned address is the user who holds the token index corresponding to the random number.


# Sponsorship

Users may "sponsor" the prize pool by depositing funds that don't make them eligible to win.

This can be useful for the creators of the pool to bootstrap its liquidity.


# Token Listener

The Token Listener interface allows contracts to "listen" to the complete token lifecycle of mint, transfer and burn.  There are two functions that must be implemented: `beforeTokenMint` and `beforeTokenTransfer`

The beforeTokenMint function must be called whenever a token is minted.

```javascript
function beforeTokenMint(
    address to,
    uint256 amount,
    address controlledToken,
    address referrer
) external;
```

| Paramater Name  | Parameter Description                                 |
| --------------- | ----------------------------------------------------- |
| to              | The address that is receiving the newly minted tokens |
| amount          | The amount of new tokens                              |
| controlledToken | The token being minted                                |
| referrer        | The address that referred the user (for rewards)      |

The beforeTokenTransfer function must be called whenever a token is transferred or burned.

```javascript
function beforeTokenTransfer(
    address from,
    address to,
    uint256 amount,
    address controlledToken
) external;
```

| Paramater Name  | Parameter Description                                                      |
| --------------- | -------------------------------------------------------------------------- |
| from            | The address that is sending the tokens                                     |
| to              | The address that is receiving tokens.  May be the zero address if burning. |
| amount          | The amount of tokens                                                       |
| controlledToken | The token being transferred                                                |


# Random Number Generator

PoolTogether has abstracted the generation of random numbers by creating a request-based Random Number Generator interface.

It functions like so:

1. The user will first get the request fee.  The fee will be expressed using an (address, amount) pair representing the required ERC20 and amount.
2. The user will then approve the RNG to spend that ERC20 of the amount
3. The user will then request the random number.  The RNG will transfer the cost into itself and begin the request.  The request returns a request identifier.
4. The user may check to see if the random number is available using the identifier.
5. When the random number is available the user may retrieve it with the identifier.

Let's look at these functions in detail.

## Get the Request Fee

Many RNG services require tokens in order to operate.  To get the cost of the rng you may do so using:

```javascript
function getRequestFee() external view returns (address feeToken, uint256 requestFee);
```

This function returns two values:

* **feeToken:** the ERC20 that needs to be paid
* **requestFee:** is the amount of the token that needs to be paid

## Request a Random Number

Once the user has approved the RNG service spend, they may request a random number like so:

```javascript
function requestRandomNumber() external returns (uint32 requestId, uint32 lockBlock);
```

This function returns two values:

* **requestId:** the unique id for this RNG request
* **lockBlock:** the commitment block for this RNG request.  Users of the RNG request shouldn't make any changes after the lockBlock, otherwise the RNG may be less secure.  For example, the Prize Strategy will lock all ticket sales and movements after the lockBlock, as they affect the winner selection.  Once the request is complete the Prize Strategy unlocks tickets.

## Check if Request is Complete

The user may check if a request is complete:

```javascript
function isRequestComplete(uint32 requestId) external view returns (bool isCompleted)
```

## Retrieve Random Number

```javascript
function randomNumber(uint32 requestId) external returns (uint256 randomNum);
```

##


# Blockhash

The Blockhash RNG uses a future blockhash as the random number.  This is the least secure method of random number generation, but also the simplest and cheapest.

When a user request a random number their lock block will be the current block.  Their request is considered 'complete' when at least one block has been mined since the lock block.  Upon retrieval the last blockhash will be stored as the random number and returned.

## Usage

A prize strategy can use a [RNGBlockhash](/v3.2.0/networks) RNG service.  No additional work is needed: the blockhash service is free.


# Chainlink VRF

**A verifiable random function is a pseudo-random function whose output is unique and can be publicly verified.**

ChainLink has implemented their VRF using public key cryptography.  It works like so:

1. The user creates a “seed” value
2. A ChainLink operator, who has publicly committed to a keypair, uses their secret to sign the seed value.
3. The user is able to verify that the operator has signed the seed value, and consume the signature as the “random number”. &#x20;

**ChainLink VRF Documentation:** [**https://docs.chain.link/docs/chainlink-vrf**](https://docs.chain.link/docs/chainlink-vrf)

This approach has some benefits in that the operator cannot “lie”: they must sign the seed using the secret they have committed to.  The algorithm is also instantaneous: there is no delay or waiting period to get the answer.&#x20;

## Usage

To use the [RNGChainlink](/v3.2.0/networks) RNG service, create a new prize pool using the service or set it on an existing pool.

🚨🚨🚨 **Chainlink RNG requires 2 LINK tokens per RNG request** 🚨🚨🚨

🚨🚨🚨 **You must deposit LINK into the PRIZE STRATEGY** 🚨🚨🚨


# 🏴‍☠️ Loot Box

What is a PoolTogether Loot Box?

### Overview

The PoolTogether Loot Box is a permission-less token container. A Loot Box allows wallets to be transferred like an ERC721.

Many different tokens can be controlled simply by one counterfactual address. The holding contract is created and destroyed within the same transaction. This cheap deployment and immediate destruction of the contract minimizes the gas overhead involved with containerization.

The code can be found here: <https://github.com/pooltogether/loot-box>

### How it works

A LootBox contract ephemerally exists within a transaction. The owner of an `ERC721` owns the LootBox.

1. A `ERC721` is created by calling `createERC721Controlled()` on the `ERC721ProxyFactory` by anyone:

```javascript
  function createERC721Controlled(
    string memory name,
    string memory symbol,
    string memory baseURI
  ) external returns (ERC721Controlled)
```

1. `mint()` can then be called on the `ControlledERC721` which effectively creates a LootBox with an Owner defined by the `to` field:

```javascript
function mint(address to) external onlyAdmin returns (uint256)
```

2\. The LootBox address is calculated by calling:&#x20;

```javascript
computeAddress(address erc721, uint256 tokenId)
```

3\. Tokens are transferred/minted to this address. In the case of PoolTogether, these are usually external ERC20, ERC721 and ERC1155 rewards for a Prize Period.

4\. Anyone can call `plunder()` on the LootBox controller which will transfer all the passed tokens to the LootBox owner.

```javascript
function plunder(
  address erc721,
  uint256 tokenId,
  address[] calldata erc20s,
  WithdrawERC721[] calldata erc721s,
  WithdrawERC1155[] calldata erc1155s
)
```

where `erc20s` is defined as an array of ERC-20 addresses,

`erc721s` is defined as:

```c
struct WithdrawERC721 {
  address token;
  uint256[] tokenIds;
}
```

and `erc1155s` as:

```c
struct WithdrawERC1155 {
  address token;
  uint256[] ids;
  uint256[] amounts;
  bytes data;
}
```


# Gas Usage

PoolTogether is conscious that to become a truly lossless prize protocol the transaction fees involved must be minimal. The current design utilizes the Minimal Proxy Factory design where possible to reduce gas usage.&#x20;

Note that these fees are paid to the Ethereum Network and not to PoolTogether.  The amount a transaction costs in USD is calculated as: the amount of gas used \* gasPrice \* USD/ETH.

Here is a list of common actions and their costs:

| Function Call                                                                         | Estimated Gas Cost | $USD (40 GWei, $600/ETH) |
| ------------------------------------------------------------------------------------- | ------------------ | ------------------------ |
| **Creating Pools with the Builder**                                                   |                    |                          |
| createCompoundPoolMultipleWinners()                                                   | 1.3M               | 33                       |
| createStakePoolMultipleWinners()                                                      | 1.25M              | 30                       |
| createVaultPoolMultipleWinners()                                                      | 1.2M               | 30                       |
| **Entering and Leaving Pools**                                                        |                    |                          |
| depositTo()                                                                           | 0.5M               | 12                       |
| withdrawInstantlyFrom()                                                               | 0.5M               | 12                       |
| **Award Process**                                                                     |                    |                          |
| RNG request - [Chainlink VRF](/v3.2.0/protocol/random-number-generator/chainlink-vrf) | 2 LINK             | 20 (@ 10 USD/LINK)       |
| startAward()                                                                          | 200k               | 4.8                      |
| completeAward()                                                                       | 250k+ (variable)   | 6                        |
| **Transferring Tickets**                                                              | 290k               | 7                        |


# 🏛️ Overview

The Role of Governance

The PoolTogether Protocol is governed by the POOL token. Any changes to the Protocol are proposed and voted on by POOL token holders. These proposals can include things like adjusting the number of winners, launching new prize pools, integrating new yield sources, implementing scaling solutions and controlling future distribution of POOL to protocol contributors.

## How Governance Works

Changes to the protocol are submitted as governance proposals. Anyone who either holds 10,000 POOL tokens (0.1% of total supply) OR has 10,000 POOL tokens delegated to them can submit a governance proposal. Once submitted governance proposals are voted on for five days. After five days, if the majority of votes are in favor AND at least 100,000 votes have been cast in favor, the proposal will pass. There is a two day “timelock” before the proposal is actually implemented.&#x20;

![](https://3052259770-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M58QPye9-PujrSjSWqv%2F-MTgloZLOm-OnXrBIc0A%2F-MTgoRqxkxdWRu48dBBK%2F1_cU6O0qF_pUrcupmqiuv1AA.png?alt=media\&token=68a985be-dfea-4cad-be29-ba4b3fcaeb76)

## What Proposals Do&#x20;

A proposal can be submitted to do anything but practically speaking, proposals will likely center on a few main topics.

**Controlling governance managed prize pools**

The governance managed prize pools are displayed on app.pooltogether.com. Some parameters on these prize pools are very simple to change, for example, adjusting the number of weekly winners or changing the frequency with which prizes are distributed. We expect proposals will be submitted to adjust these parameters.

**Managing the prize pool builder**&#x20;

All prize pools are generated by the prize pool builder. Currently the only yield source supported by the protocol is the Compound Protocol. Many in the community have expressed a desire to add more yield sources. We expect governance proposals to enable prize pools using new yield sources such as Aave.

**Distributing the POOL token**

The broadest category is controlling future distribution of the POOL token. As more people contribute to the protocol by depositing, referring deposits, developing the protocol and other activities governance should continue to distribute control of the protocol to these people. Practically this can look like a referral rewards program, a grants program, a deposit reward program, or direct transfers!

## **Submitting Proposals**

The best place to start is by discussing it in the [governance forum](http://gov.pooltogether.com) and [community Discord](https://discord.gg/peE3axWSEv).&#x20;

When it comes time to actually make the proposal, you can review the documentation and use the proposal creation interface available on the "vote" section of the PoolTogether app. You can create proposals without this interface but the interface helps make it more simple for non-technical people.&#x20;

[Visit the proposal creation interface!](https://vote.pooltogether.com/proposals/create)


# 🕹️ Controls

A summary of governance-managed controls

PoolTogether governance primarily controls:

* Protocol prize pools
* Token Faucets (liquidity mining)
* Protocol treasury
* Reserve

## Protocol Prize Pools

The protocol owns a subset of the prize pools.  Ownership means that governance can execute privileged actions only available to the owner.

Each prize pool consists of the prize pool contract and the prize strategy contract.  These two contracts can have different owners, but typically the owner is the same.

Prize Pool actions include:

* Setting a prize pool's early exit fees
* Setting a prize pool's liquidity cap
* Setting the prize strategy for a prize pool

Prize Strategy actions include:

* Setting the number of winners
* Setting whether to split external awards among the winners
* Configuring the Random Number Generator
* Managing external awards
* Configuring token and prize listener contracts

## Token Faucets

The protocol owns a set of token faucets, and can create more.  Each faucet is bound to a prize pool as a token listener and drips POOL tokens to the users.  The original program is time-limited, but governance can:

* Deposit more tokens into each faucet
* Change the drip rate of each faucet
* Create new token faucets for new prize pools

## Protocol Treasury

The initial token distribution allocated 60% of the POOL token supply to the protocol treasury.  These tokens will be unlocked over two years by the TreasuryVesterForTreasury contract.  Anyone can execute the vesting contract to disburse more tokens to the protocol treasury.

The protocol treasury is held by the Timelock contract, which is the contract that execute proposals submitted by governance.  Proposals could do things like:

* Transfers POOL tokens to a recipient
* Approve POOL token spend by another contract, and then call the contract

## Reserve

The reserve contract is owned by governance, and determines the portion of interest earned by each prize pool that is captured as reserve funds.  Every prize pool created by the builders is linked to the reserve.  Governance can:

* Change the reserve rate.  This rate is the portion of interest that is captured for the reserve.
* Withdraw the reserve from a prize pool.


# 🗳️ Process

Illustrating governance process with examples

The governance system is very new, so it might be difficult for some people to imagine how it works.  Here we're going to give some example proposals to illustrate how governance could work.  The examples will be both PoolTogether-specific and refer to proposals created in other governance systems.  We'll cover:

* How to create a new protocol-owned prize pool
* How to create a Uniswap-style grants program
* Rewarding contributors with Sablier streams

It's important to mention that a proposal is much more likely to be successful if it is first discussed in the [governance forum](https://gov.pooltogether.com/).  Ideally the outcome of a proposal will be known before it is created.

## Proposal: Create a Protocol Prize Pool

As new assets become available and new types of prize pools are added to the [Builder](broken://pages/-M62EjiYFQOIIF0UDsxg), users may wish to create new governance owned & operated prize pools.  By having ownership only governance will be able to change parameters such as the exit fee and number of winners.  See [Controls](/v3.2.0/governance/controls) for more info.

If POOL holders decide to create a new prize pool after thorough discussion on the governance forums, then they would need to follow these steps:

1. A user creates the appropriate prize pool using the [Prize Pool Builder app](https://builder.pooltogether.com/).
2. Once created, the user transfers the ownership of the resulting prize pool and prize strategy contracts to the Timelock contract (see the Governance section in [Networks](/v3.2.0/networks)).  The only interface for this right now is Etherscan.
3. Finally, the user creates a new governance proposal.  The proposal will include:
   1. Adding the prize pool address to the official Protocol Prize Pool Registry (coming soon!)
   2. Possible compensation for the gas spent by the user that created the pool
   3. Possible compensation for the gas costs of creating the proposal

POOL holders will need to verify that the ownership of the proposed prize pool has, in fact, been transferred to the Timelock contract.  They should also verify that the prize pool is safe and has been created by the builder app.

## Proposal: Create a Grants Program

Many protocols have created a grants program to make it easy to fund the protocol ecosystem.  Typically, grant programs have a trustworthy steward to manage the program.  The [Uniswap Grant Proposal](https://app.uniswap.org/#/vote/3) is a great example.

For Uniswap, a professional grants manager was selected to lead the program.  Him and five other people were added to a Gnosis Safe multisig.  The other people were well-known leaders in the crypto space and proved that they held the wallet addresses.  The multisig was configured to require 4-of-6 confirmations, making it quite secure.

The proposal included:

* Quarterly budget for grants, with two quarters of budget requested at the time of proposal.
* Compensation for the grants manager
* A complete description of the proposed grants program, including timeline, budget and scope.

The actual proposal was a simple token transfer from the treasury to the Gnosis Safe multisig.

## Proposal: Reward Contributors with a Sablier Stream

SushiSwap has formalized their hiring guidelines, and as part of those guidelines new hires will be paid a signing bonus and their "salary" will be sent to them as a Sablier stream.  You can read their [complete hiring process here](https://forum.sushiswapclassic.org/t/sushi-hiring-guidelines-v2/1866).

If a community member wished to apply to work for the protocol and have a salary of X tokens, they could set up a proposal like so:

1. Approve Sablier spending X tokens
2. Create a new stream in Sablier for X tokens for the given timeframe.
3. Include token transfer as a signing bonus (if applicable)


# Risks

Using the protocol includes substantial risks of losing some or all of your funds. The PoolTogether core team and community have made every effort to ensure the security of funds.

This section will help you understand the the types of risk you are taking what has been done to mitigate them and how to mitigate them further.&#x20;

### Protocol Dependency Risk  <a href="#a908" id="a908"></a>

The PoolTogether Protocol uses several other protocols. Therefore the first type of risk is the risk that these other integrated protocols can fail.

Specifically by using PoolTogether you are also taking on the risks of using the Ethereum network, the collateral you are depositing, and the yield service (currently Compound.Finance).

To mitigate this risk the protocol is only integrated with highly reputable and well secured protocols. &#x20;

### Smart Contract Exploit Risk <a href="#a908" id="a908"></a>

The second type of risk is specific to PoolTogether. The risk is that there could be some sort of bug or exploit in the smart contracts that run the PoolTogether Protocol. This is a risk with any product on Ethereum. Depending on what the bug or exploit is, a nefarious person may be able to take some or all of the funds stored in the PoolTogether Protocol. Here’s what we’ve done to mitigate this risk.

1. Professional, third party smart contract auditing. PoolTogether has hired companies to professionally review and audit the smart contract code for any bugs or exploits. These auditors have produced reports with their findings. As PoolTogether continues to grow we’re committed to continuing to pay for audits however, it should be understood that at any given time, 100% of the code base has not been professionally audited.&#x20;
2. Bug Bounty program. PoolTogether offers payment of up to $25,000 for reports of any bugs in the smart contracts. If someone was to discover a bug, this is a way for them to responsibly disclose it to us and be paid rather than exploit it.
3. All the smart contract code is open source, meaning it is publicly readable by anyone. At first this may sound strange but it actually makes the protocol more secure as anyone can review it for bugs and submit a bug bounty.
4. Before we even give our code to auditors we also do extensive internal testing.

### Wallet Loss Risk <a href="#e5cb" id="e5cb"></a>

This risk doesn’t have anything to do with PoolTogether but we wanted to mention it. Using PoolTogether requires you to use an Ethereum wallet that supports Ethereum apps. If you permanently lose access to this wallet, you will not be able to recover your funds. Different wallets have different recovery mechanisms. It’s important for you to know what those are and be able to recover your wallet. [Argent Wallet](https://www.argent.xyz/) is one example of a wallet with good recovery methods.


# Audits & Testing

The PoolTogether Protocol has undergone three formal professional third party audits. Two have been [conducted by Open Zeppelin](https://blog.openzeppelin.com/pooltogether-v3-audit/). And one was [conducted by Ditcraft](https://www.ditcraft.io/blog/pooltogether-v3-smart-contract-audit).

Additionally the PoolTogether core team has a long term security relationship with [ConsenSys Diligence](https://diligence.consensys.net/audits/) including additional code reviews.&#x20;

Notwithstanding, portions of the PoolTogether Protocol codebase will continue to evolve and **it should never be expected that 100% of the deployed code has been formally audited.**

We encourage responsible disclosure of any vulnerabilities in the smart contracts and will pay up to $25,000 for those.  See the [Bounties](/v3.2.0/security/bounties) for more details.


# Bounties

We value contributions from the community to strengthen the security of the core contracts. We want to reward any hackers in good faith who report vulnerabilities.

The scope of this bounty includes the PoolTogether smart contracts. The determination of the bug severity will be made by the PoolTogether team.  We determine the severity of an issue according to the [Smart Contract Security Alliance Severity Levels](https://www.smartcontractsecurityalliance.com/)

Payouts will be as follows:

High: $25,000 DAI\
Medium: $10,000 DAI\
Low: $1,000 DAI

The issue must:

* be a previously unreported, non-public vulnerability.
* include enough detail for us to identify and reproduce the problem

All reports should start with an email to <hello@pooltogether.us> and they will receive a response within 24 hours. Non-security issues are not eligible for this bounty.

Determinations of eligibility and all terms related to this award are at the sole and final discretion of the PoolTogether team.

## Past Bounties

### PermitAndDepositDai Contract: Unrestricted Sender

Severity: Medium / High\
Date: Thursday, October 22nd, 2020\
Reporter: Kevin Foesenek\
Payout: $20,000 USD of WETH ([transaction](https://etherscan.io/tx/0xdd9fcf07a29a376b811c775d34cef4ceddf6e720981da34ac7142a8c38e7e7a6))

**Vulnerability**\
Just prior to launch a security researcher discovered a flaw in the PermitAndDepositDai contract.  This flaw would have allowed an attacker to front-run the "deposit" transaction and take the deposited amount.  This would have affected any new deposits to the system.

**Mitigation**\
References to the contract were removed from the user interface, and a fix was immediately deployed to mainnet and published via NPM.


# Introduction

[![PoolTogether Brand](https://github.com/pooltogether/pooltogether--brand-assets/blob/977e03604c49c63314450b5d432fe57d34747c66/logo/pooltogether-logo--purple-gradient.png?raw=true)](https://github.com/pooltogether/pooltogether--brand-assets)

## ✨ Introduction

PoolTogether is a protocol for no-loss prize games on the Ethereum blockchain. The protocol:

**1) Enables developers to build their own no-loss prize games**\
**2)** **Offers governance-managed no-loss prize games**

Prize games are pools of funds whose accrued interest is distributed as prizes. The concept is well-established and otherwise known as "[no loss lotteries](http://beniverson.org/papers/MaMa.pdf)" or "[prize savings accounts](https://en.wikipedia.org/wiki/Prize-linked_savings_account)".  All prize games created by the protocol share the same key characteristics:

* No loss of deposited funds
* Ability to withdraw at any time
* Fair prize distribution according to a prize strategy

Prize games can be differentiated in the following ways:

* The yield source the prize pool uses to generate no loss return
* The prize strategy used to determine frequency and distribution of prizes&#x20;
* The additional rewards offered by the prize pool
* The asset type the prize pool accepts for deposits&#x20;
* The fairness parameters&#x20;

### Governance

The PoolTogether Protocol governance serves two primary functions.

* Governing the prize pool creation tools
* Governing a sub-set of prize pools

The protocol governed prize pools appear on the official [PoolTogether App](https://app-v3.pooltogether.com). Governance is currently the core PoolTogether team, but very soon governance control will be distributed amongst protocol stakeholders.

####

####


# Networks

*This document was generated* [*automatically*](https://github.com/pooltogether/generate-networks-doc)

## Mainnet

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.1.5** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract                         | Address                                                                                                               |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Dai Prize Pool                   | [0xEBfb47A7ad0FD6e57323C8A42B2E5A6a4F68fc1a](https://etherscan.io/address/0xEBfb47A7ad0FD6e57323C8A42B2E5A6a4F68fc1a) |
| Dai Prize Strategy               | [0x178969A87a78597d303C47198c66F68E8be67Dc2](https://etherscan.io/address/0x178969A87a78597d303C47198c66F68E8be67Dc2) |
| UNI Prize Pool                   | [0x0650d780292142835F6ac58dd8E2a336e87b4393](https://etherscan.io/address/0x0650d780292142835F6ac58dd8E2a336e87b4393) |
| UNI Prize Strategy               | [0xe8726B85236a489a8E84C56c95790d07a368f913](https://etherscan.io/address/0xe8726B85236a489a8E84C56c95790d07a368f913) |
| USDC Prize Pool                  | [0xde9ec95d7708b8319ccca4b8bc92c0a3b70bf416](https://etherscan.io/address/0xde9ec95d7708b8319ccca4b8bc92c0a3b70bf416) |
| USDC Prize Strategy              | [0x3d9946190907ada8b70381b25c71eb9adf5f9b7b](https://etherscan.io/address/0x3d9946190907ada8b70381b25c71eb9adf5f9b7b) |
| Loot Box ERC721                  | [0x4d695c615a7AACf2d7b9C481B66045BB2457Dfde](https://etherscan.io/address/0x4d695c615a7AACf2d7b9C481B66045BB2457Dfde) |
| Loot Box Prize Strategy Listener | [0xfe7205DF55BA42c8801e44B55BF05F06cCe8565E](https://etherscan.io/address/0xfe7205DF55BA42c8801e44B55BF05F06cCe8565E) |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                               | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xb1D89477d1b505C261bab6e73f08fA834544CD21](https://etherscan.io/address/0xb1D89477d1b505C261bab6e73f08fA834544CD21) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mainnet/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F](https://etherscan.io/address/0xB2DC5571f477b1C5b36509a71013BFedD9Cc492F) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/mainnet/RNGChainlink.json) |

### Loot Box Contracts

**@pooltogether/loot-box ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/loot-box)

| Contract                                                                                                                                    | Address                                                                                                               | Artifact                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [ERC721ControlledFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/ERC721ControlledFactory.sol)                         | [0x4E869b3A0978fA61DAbd7Da8F9B272AADc745Fb3](https://etherscan.io/address/0x4E869b3A0978fA61DAbd7Da8F9B272AADc745Fb3) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/ERC721ControlledFactory.json)             |
| [LootBoxController](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxController.sol)                                     | [0x2c2a966b7F5448A36EC9f896088DfB99B21d8A24](https://etherscan.io/address/0x2c2a966b7F5448A36EC9f896088DfB99B21d8A24) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/LootBoxController.json)                   |
| [LootBoxPrizeStrategyListenerFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxPrizeStrategyListenerFactory.sol) | [0x25e6a78D93D2935A638fDbd684e7b39565d0B7eA](https://etherscan.io/address/0x25e6a78D93D2935A638fDbd684e7b39565d0B7eA) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/mainnet/LootBoxPrizeStrategyListenerFactory.json) |

### V2-to-V3 Migration Contract

**@pooltogether/migrate-v3 ^0.1.3** [**Github**](https://github.com/pooltogether/pooltogether-migrate-v3)

| Contract                                                                                                         | Address                                                                                                               | Artifact                                                                                                               |
| ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| [MigrateV2ToV3](https://github.com/pooltogether/pooltogether-migrate-v3/tree/master/contracts/MigrateV2ToV3.sol) | [0x801B4872a635dCCc7E679eEaf04bEf08E562972a](https://etherscan.io/address/0x801B4872a635dCCc7E679eEaf04bEf08E562972a) | [Artifact](https://github.com/pooltogether/pooltogether-migrate-v3/tree/master/deployments/mainnet/MigrateV2ToV3.json) |

## Rinkeby

### PoolTogether Pools & Supporting Contracts

**@pooltogether/current-pool-data ^3.1.5** [**npm**](https://www.npmjs.com/package/@pooltogether/current-pool-data)

| Contract            | Address                                                                                                                       |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Dai Prize Pool      | [0x4706856FA8Bb747D50b4EF8547FE51Ab5Edc4Ac2](https://rinkeby.etherscan.io/address/0x4706856FA8Bb747D50b4EF8547FE51Ab5Edc4Ac2) |
| Dai Prize Strategy  | [0x5E0A6d336667EACE5D1b33279B50055604c3E329](https://rinkeby.etherscan.io/address/0x5E0A6d336667EACE5D1b33279B50055604c3E329) |
| USDC Prize Pool     | [0xde5275536231eCa2Dd506B9ccD73C028e16a9a32](https://rinkeby.etherscan.io/address/0xde5275536231eCa2Dd506B9ccD73C028e16a9a32) |
| USDC Prize Strategy | [0x1b92BC2F339ef25161711e4EafC31999C005aF21](https://rinkeby.etherscan.io/address/0x1b92BC2F339ef25161711e4EafC31999C005aF21) |
| BAT Prize Pool      | [0xab068F220E10eEd899b54F1113dE7E354c9A8eB7](https://rinkeby.etherscan.io/address/0xab068F220E10eEd899b54F1113dE7E354c9A8eB7) |
| BAT Prize Strategy  | [0x41CF0758b7Cc2394b1C2dfF6133FEbb0Ef317C3b](https://rinkeby.etherscan.io/address/0x41CF0758b7Cc2394b1C2dfF6133FEbb0Ef317C3b) |
| Loot Box ERC721     | [0xfbC6677806253dB9739d0F6CBD89b9e7Ed4A5c66](https://rinkeby.etherscan.io/address/0xfbC6677806253dB9739d0F6CBD89b9e7Ed4A5c66) |

### Core Contracts

**@pooltogether/pooltogether-contracts ^3.1.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-contracts)

| Contract                                                                                                                                                           | Address                                                                                                                       | Artifact                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| [CompoundPrizePoolBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/builders/CompoundPrizePoolBuilder.sol)             | [0xA8F32475438733B974CD4F19Ba8f97484EeB95a3](https://rinkeby.etherscan.io/address/0xA8F32475438733B974CD4F19Ba8f97484EeB95a3) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/CompoundPrizePoolBuilder.json)       |
| [Comptroller](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/comptroller/Comptroller.sol)                                    | [0xaF00636E7D943a62CCb87E8153c1C97bF657F11D](https://rinkeby.etherscan.io/address/0xaF00636E7D943a62CCb87E8153c1C97bF657F11D) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/Comptroller.json)                    |
| [ControlledTokenBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/builders/ControlledTokenBuilder.sol)                 | [0x239fC7c69Ba8079ebEC07156F13a6d78d234Fa6B](https://rinkeby.etherscan.io/address/0x239fC7c69Ba8079ebEC07156F13a6d78d234Fa6B) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/ControlledTokenBuilder.json)         |
| [MultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/builders/MultipleWinnersBuilder.sol)                 | [0x32e8D4c9d1B711BC958d0Ce8D14b41F77Bb03a64](https://rinkeby.etherscan.io/address/0x32e8D4c9d1B711BC958d0Ce8D14b41F77Bb03a64) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/MultipleWinnersBuilder.json)         |
| [PermitAndDepositDai](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/permit/PermitAndDepositDai.sol)                         | [0x80768c51cDEd011B64A24Ba91b6d4471bB3Da150](https://rinkeby.etherscan.io/address/0x80768c51cDEd011B64A24Ba91b6d4471bB3Da150) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/PermitAndDepositDai.json)            |
| [PoolWithMultipleWinnersBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/builders/PoolWithMultipleWinnersBuilder.sol) | [0x47a5ABfAcDebf5af312B034B3b748935A0259136](https://rinkeby.etherscan.io/address/0x47a5ABfAcDebf5af312B034B3b748935A0259136) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/PoolWithMultipleWinnersBuilder.json) |
| [Reserve](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/reserve/Reserve.sol)                                                | [0x10f61a36e1327036E5E416D52ff0f4b5c9EfAAA3](https://rinkeby.etherscan.io/address/0x10f61a36e1327036E5E416D52ff0f4b5c9EfAAA3) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/Reserve.json)                        |
| ReserveRegistry                                                                                                                                                    | [0xAD1C620137FA76f520f9a39daAcD7B008D7d2F2D](https://rinkeby.etherscan.io/address/0xAD1C620137FA76f520f9a39daAcD7B008D7d2F2D) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/ReserveRegistry.json)                |
| [StakePrizePoolBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/builders/StakePrizePoolBuilder.sol)                   | [0xdd4d117723C257CEe402285D3aCF218E9A8236E1](https://rinkeby.etherscan.io/address/0xdd4d117723C257CEe402285D3aCF218E9A8236E1) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/StakePrizePoolBuilder.json)          |
| [VaultPrizePoolBuilder](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/contracts/builders/VaultPrizePoolBuilder.sol)                   | [0xd89a09084555a7D0ABe7B111b1f78DFEdDd638Be](https://rinkeby.etherscan.io/address/0xd89a09084555a7D0ABe7B111b1f78DFEdDd638Be) | [Artifact](https://github.com/pooltogether/pooltogether-pool-contracts/tree/version-3/deployments/rinkeby/VaultPrizePoolBuilder.json)          |

### RNG Contracts

**@pooltogether/pooltogether-rng-contracts ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/pooltogether-rng-contracts)

| Contract                                                                                                          | Address                                                                                                                       | Artifact                                                                                                                 |
| ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| [RNGBlockhash](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGBlockhash.sol) | [0xA932e74d5263A754Ea04432E5c53658434b0484B](https://rinkeby.etherscan.io/address/0xA932e74d5263A754Ea04432E5c53658434b0484B) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/rinkeby/RNGBlockhash.json) |
| [RNGChainlink](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/contracts/RNGChainlink.sol) | [0x11D94431718934868C4339aFc5ea27585F46C99A](https://rinkeby.etherscan.io/address/0x11D94431718934868C4339aFc5ea27585F46C99A) | [Artifact](https://github.com/pooltogether/pooltogether-rng-contracts/tree/master/deployments/rinkeby/RNGChainlink.json) |

### Loot Box Contracts

**@pooltogether/loot-box ^1.0.0** [**npm**](https://www.npmjs.com/package/@pooltogether/loot-box)

| Contract                                                                                                                                    | Address                                                                                                                       | Artifact                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [ERC721ControlledFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/ERC721ControlledFactory.sol)                         | [0x1D90F79a8515F63881075Ec2C212e18272aD9E38](https://rinkeby.etherscan.io/address/0x1D90F79a8515F63881075Ec2C212e18272aD9E38) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/ERC721ControlledFactory.json)             |
| [LootBoxController](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxController.sol)                                     | [0xb1EAc75da9bc31B078742C5AF9EDe62EFE31299D](https://rinkeby.etherscan.io/address/0xb1EAc75da9bc31B078742C5AF9EDe62EFE31299D) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/LootBoxController.json)                   |
| [LootBoxPrizeStrategyListenerFactory](https://github.com/pooltogether/loot-box/tree/main/contracts/LootBoxPrizeStrategyListenerFactory.sol) | [0xadB4D93D84b18b5D82063aCf58b21587c92fdfb5](https://rinkeby.etherscan.io/address/0xadB4D93D84b18b5D82063aCf58b21587c92fdfb5) | [Artifact](https://github.com/pooltogether/loot-box/tree/main/deployments/rinkeby/LootBoxPrizeStrategyListenerFactory.json) |


# Resources

## Tools

* [Prize Pool Builder](https://builder.pooltogether.com) ([Source Code](https://github.com/pooltogether/pooltogether-pool-builder-ui))
* [Prize Pool Reference App](https://reference-app.pooltogether.com) ([Source Code](https://github.com/pooltogether/pooltogether-reference-pool-ui))

## Code

* [Prize Pool Contracts](https://github.com/pooltogether/pooltogether-pool-contracts)
* [Random Number Generator Contracts](https://github.com/pooltogether/pooltogether-rng-contracts)
* [PoolTogether V3 Subgraph](https://github.com/pooltogether/pooltogether-subgraph-v3)
* [Loot Box Contracts](https://github.com/pooltogether/loot-box)
* [OpenZeppelin Defender Award Autotask](https://github.com/pooltogether/defender-autotask-reward)
* [V2 to V3 Migration Contracts](https://github.com/pooltogether/pooltogether-migrate-v3)

## Subgraphs

* [mainnet Subgraph](https://thegraph.com/explorer/subgraph/pooltogether/pooltogether-v3_1_0)
* [mainnet LootBox Subgraph](https://thegraph.com/explorer/subgraph/pooltogether/lootbox-v1_0_0)
* [rinkeby Subgraph](https://thegraph.com/explorer/subgraph/pooltogether/rinkeby-v3_1_0)

## Workshops

* [ETHOnline Hackathon Custom Prize Strategy](<https://github.com/pooltogether/ethonline-workshop >)


# Migrating from V2 to V3

Users of PoolTogether V2 can exchange their old tickets for new ones using the [new interface](https://app.pooltogether.com).  See the "accounts" section.

Users can exchange:

* Dai Pool tickets
* USDC Pool tickets
* Dai Pod tickets
* USDC Pod tickets

All of these tickets will be exchange 1:1 for new V3 Pool Dai tickets.  Note that you will not receive USDC back, you will be **exchanging your USDC Tickets for Dai Tickets**.

## Migrating Your Tickets

1. Do an ER20 token transfer to the migration contract.
2. The migration contract will transfer PcDAI to the sender.

PoolTogether V2 tickets and Pod shares are ERC777 tokens; this token standard triggers a callback on the recipient when the recipient is a contract.  When the migration contract is triggered it automatically send PcDAI back to the sender.

For the latest address see the [Networks](/master-1/networks) page.  Look for the Migration contract on mainnet.

## Troubleshooting

The migration contract needs to be stocked with liquidity, so if your ticket exchange fails please contact us on [our Discord](https://discord.gg/hxPhPDW).


# Overview

What are No-Loss Prize Games?

No-loss prize games are pools of funds whose accrued interest is distributed as prizes.

The high level protocol architecture is outlined below. The code is available on [Github](https://github.com/pooltogether/pooltogether-pool-contracts).

## How it works

1. Users deposit funds into a Prize Pool.  They receive pool tokens in exchange.
2. The funds earn interest.
3. The interest is distributed by the Prize Strategy as pool tokens.
4. Users withdraw their funds at any time by telling the Prize Pool to burn their pool tokens.

## Architecture

### [Prize Pools](/master-1/protocol/prize-pool)

Prize Pools are the central building block of prize games.  They pool user funds in a **yield source** and expose the yield to their **Prize Strategy**, which then disburses as desired.

Prize Pools can be differentiated in four primary ways:

* The yield source the prize pool uses to generate no loss return
* The prize strategy used to determine frequency and distribution&#x20;
* The rewards offered by the prize pool
* The asset type the prize pool accepts for deposits&#x20;
* The fairness parameters&#x20;

### [Prize Strategies](/master-1/protocol/prize-strategy)

Prize Strategies determine the prize distribution for the Prize Pool.  They can define any logic to allocate tokens that the prize pool accrues.  Specifically they can:

* Award yield in the Prize Pool as pool tokens
* Award ERC20 tokens held by the Prize Pool
* Award ERC721 tokens held by the Prize Pool

### [Builders](broken://pages/-M62EjiYFQOIIF0UDsxg)

Builders make it easy to create pre-configured prize games.  There are currently three Prize Pool types paired with the MultipleWinners, documentation available [here](broken://pages/-M62EjiYFQOIIF0UDsxg).&#x20;

### [Random Number Generator](/master-1/protocol/random-number-generator)

There are many different ways to generate a random number, so we've abstracted them as request-based Random Number Generator services.  Each RNG service has a different security profile, so be sure to use the appropriate one for your game.

## Conventions

Fixed point math is used extensively in PoolTogether.  We used fixed point math with 18 decimal places for all fractional numbers.  You can think of this as being just like Ether and wei: a value of "1" Ether is represented as "1000000000000000000" wei.

When a number is a fixed point 18 number we always suffix the number with *mantissa.*  For example the credit rate is written as *creditRateMantissa*, because it is a fixed point number.


# Prize Pools

Pool deposits and award accrued interest periodically as a prize

## Introduction

Prize Pools allow funds to be pooled together into a no-loss yield source, such as Compound, and have the yield safely exposed to a separate Prize Strategy. They are the primary way through which users interact with PoolTogether prize games.

Prize Pools provide controls to the owner so that participation can be made fair. See [Fairness](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-887967055/protocol/fairness.md) for more information.

There is a different type of prize pool for each yield source. For example, if you wish to use Compound you will use the Compound Prize Pool.

All Prize Pools share the functionality below.

## Owner

When a Prize Pool is created, the creator is set as the pool's "owner". The owner is able to:

* Add additional pool tokens
* Change the Prize Strategy
* Set the [credit rate and credit limit](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-887967055/protocol/fairness.md#credit)
* Shutdown the prize pool
* Transfer ownership
* Renounce ownership

**The prize pool is not upgradeable and therefore the owner can never seize the funds deposited into the prize pool**

## Limits

When a Prize Pool is created it is initialized with some hard-coded limits to protect users. See [Fairness](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-887967055/protocol/fairness.md) for more details.

### **Maximum Timelock Duration**

The maximum timelock duration ensures that a user has to wait at most X amount of time to withdraw their funds loss-lessly. If the owner of a pool sets the credit rate to be way too low, this limit ensures users will still be able to withdraw.

If using the Single Random Winner Prize Strategy, it would make sense to set the maximum timelock duration to 2x the prize period. That way the owner has some flexibility when adjusting the credit limit and credit rate.

### **Maximum Credit Limit**

The maximum credit limit ensures that the credit limit cannot be set higher than this number. This prevents the owner of the Prize Pool from capturing \*all\* of a user's deposit at withdrawal time.

### **Maximum Liquidity Limit**

The maximum liquidity limit allows the PrizePool owner to set a cap on the amount of liquidity the pool can hold. This can be set by calling:

```javascript
function setLiquidityCap(uint256 _liquidityCap) external override onlyOwner
```

## Token Model

A Prize Pool accepts a single type of ERC20 token for deposits. This token depends on the implementation: for a Compound Prize Pool bound to cDai it will be Dai, for a yEarn yUSDC vault it will be USDC. This is the underlying **asset** of the Prize Pool.

Prize Pools use **Controlled Tokens** for their internal accounting. These tokens are minted when depositing or awarding prizes. Controlled Tokens are burned when users withdraw. They are exchanged at a ratio of 1:1 to the asset.

The tokens associated with a PrizePool can be seen by calling:

```javascript
function tokens() external override view returns (address[] memory)
```

### Controlled Tokens

A Controlled Token is a standard ERC20 that is bound to a **Token Controller**.

The Token Controller has the privileged ability to mint and burn tokens on user's behalf, and has a callback that listens for token transfers. Controlled Tokens are expected to trigger this callback on any mint, burns or transfers.

The Prize Pool must be the Token Controller for the controlled tokens that it is initialized with at construction.

The default [Compound Prize Pool Builder](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-887967055/builders/) creates a Ticket controlled token and a [Sponsorship](/master-1/protocol/tokens/sponsorship) controlled token.

A Controlled Token can added by the PrizePool owner by calling:

```javascript
function addControlledToken(ControlledTokenInterface _controlledToken) 
external override onlyOwner
```

### Minting

When a user deposits into a Prize Pool they must request what type of controlled token they receive in exchange. This token will be minted to them at an exchange rate of 1:1 for the asset.

### Burning

When a user wishes to withdraw from a Prize Pool they must burn controlled tokens.

## Depositing

Users can deposit into the Prize Pool using the **depositTo** function. A user is instantly minted tokens upon deposit.

```javascript
function depositTo(
    address to,
    uint256 amount,
    address controlledToken,
    address referrer
) external;
```

| Parameter       | Description                                                                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| to              | The address to whom the controlled tokens should be minted                                                                                                                                                   |
| amount          | The amount of the underlying asset the user wishes to deposit.  The Prize Pool contract should have been pre-approved by the caller to transfer the underlying ERC20 tokens.                                 |
| controlledToken | The address of the token that they wish to mint.  For our default Prize Strategy this will either be the Ticket address or the Sponsorship address.  Those addresses can be looked up on the Prize Strategy. |
| referrer        | The address that should receive [referral awards](https://app.gitbook.com/s/governance/untitled.md#referral-volume-drips), if any.                                                                           |

Depositing fires the event:

```javascript
event Deposited(
    address indexed operator,
    address indexed to,
    address indexed token,
    uint256 amount
);
```

| Event Data | Description                                                                                   |
| ---------- | --------------------------------------------------------------------------------------------- |
| operator   | The caller that made the deposit                                                              |
| to         | The address that received the minted tokens                                                   |
| token      | The address of the controlled token that was minted                                           |
| amount     | The amount of both the underlying asset that was transferred and the tokens that were minted. |

### Depositing Using Timelocked Funds

If a user wishes to re-deposit their timelocked funds, they can do so using this function:

```javascript
function timelockDepositTo(
    address to,
    uint256 amount,
    address controlledToken
) external;
```

| Parameter       | Description                                                                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| to              | The address to whom the controlled tokens should be minted                                                                                                                                                   |
| amount          | The amount of the underlying asset the user wishes to deposit.  The Prize Pool contract should have been pre-approved by the caller to transfer the underlying ERC20 tokens.                                 |
| controlledToken | The address of the token that they wish to mint.  For our default Prize Strategy this will either be the Ticket address or the Sponsorship address.  Those addresses can be looked up on the Prize Strategy. |

## Withdrawing

When a user withdraws they may need to contribute to the prize according to the [fairness rules](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-887967055/protocol/fairness.md). They may either cover the contribution by time-locking their funds, or cover the contribution explicitly using funds.

### **Withdraw with Timelock**

Funds can be withdrawn losslessly by time-locking the funds. The withdrawal amount will be unlocked at a later date at which point the funds can be swept back to the user. The timelock duration is calculated based on the users accrued credit, the credit rate, and the fairness fee.

If the user has sufficient credit, the unlockTimestamp may be "now" and the funds are instantly swept to the `from` address.

Tip: You can call this function in a constant way to see when the users funds will be unlocked.

To start a lossless withdrawal a user may call:

```javascript
function withdrawWithTimelockFrom(
    address from,
    uint256 amount,
    address controlledToken
) external returns (uint256 unlockTimestamp);
```

| Parameter Name  | Parameter Description                                                                                                            |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| from            | The user from whom to withdraw.  This means you may withdraw on another user's behalf if they have given you an ERC20 allowance. |
| amount          | The amount of collateral to withdraw.                                                                                            |
| controlledToken | The type of controlled token to withdraw.                                                                                        |

### Checking Timelock Balances

To see how many funds have been timelocked for a `user` call:

```javascript
function timelockBalanceOf(address user) external view returns (uint256)
```

After funds have been time-locked, you can see at what timestamp they'll be available:

```javascript
function timelockBalanceAvailableAt(address user) external view returns (uint256)
```

### Checking Timelock Duration

To calculate a timelocked withdrawal duration and credit consumption call:

```javascript
function calculateTimelockDuration(address from, address controlledToken, uint256 amount) 
external override returns (uint256 durationSeconds,uint256 burnedCredit)
```

| Parameter Name  | Description                               |
| --------------- | ----------------------------------------- |
| from            | The user who is withdrawing.              |
| amount          | The amount the user is withdrawing.       |
| controlledToken | The type of controlled token to withdraw. |

**returns**:

| Returned Parameter Name | Description                               |
| ----------------------- | ----------------------------------------- |
| `durationSeconds`       | The duration of the timelock in seconds   |
| `burned`                | The amount of credit that would be burned |

### Estimating Credit Accrual Time

Similarly it is also possible to calculate how long a user must keep their funds in the pool:

```javascript
function estimateCreditAccrualTime(address _controlledToken,
 uint256 _principal,
 uint256 _interest) 
 external override view returns (uint256 durationSeconds)
```

| Parameter Name    | Parameter Description                               |
| ----------------- | --------------------------------------------------- |
| \_controlledToken | The type of controlled token.                       |
| \_principal       | The principal amount on which interest is accruing. |
| \_interest        | The amount of interest that must accrue.            |

### Sweeping Timelocked Funds

When a user's withdrawal timelocks have ended, the funds may be swept to their wallets:

```javascript
function sweepTimelockBalances(
    address[] memory users
) external returns (uint256 totalWithdrawal);
```

The function accepts an array of addresses and will attempt to sweep the time-locked funds for each one. The funds will be transferred back to the users wallets.

### Withdraw Instantly

If a user would like their tickets right away, they may pay an early exit fee to the prize. The early exit fee is determined by the [Prize Strategy](https://app.gitbook.com/s/-M58QPye9-PujrSjSWqv-887967055/prize-strategy/).

The instant withdrawal function returns the amount of the withdrawal that was retained as payment. This means you can call this function in a constant way to check to see what the exit fee will be. When it comes time to run the tx, that exit fee can be passed as the `maximumExitFee` to ensure it doesn't exceed the expected limit.

```javascript
function withdrawInstantlyFrom(
    address from,
    uint256 amount,
    address controlledToken,
    uint256 maximumExitFee
  )
    external
    returns (uint256 exitFee);
```

| Parameter Name  | Parameter Description                                                                                                                  |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| from            | The address to withdraw from.  This means you can withdraw on another user's behalf if you have an allowance for the controlled token. |
| amount          | The amount to withdraw                                                                                                                 |
| controlledToken | The controlled token to withdraw from                                                                                                  |
| maximumExitFee  | The maximum early exit fee the caller is willing to pay.  This prevents the Prize Strategy from changing the fee on-the-fly.           |

This early exit fee can also be calculated by calling:

```javascript
function calculateEarlyExitFee(address from, address controlledToken, uint256 amount)
 external override returns (uint256 exitFee, uint256 burnedCredit)
```

| Parameter Name  | Parameter Description                 |
| --------------- | ------------------------------------- |
| from            | The address to withdraw from          |
| controlledToken | The controlled token to withdraw from |
| amount          | The amount to withdraw                |

returns the `exitFee` that would be paid along with the credit that would be burned (`burnedCredit`).

## Awarding

Only the Prize Strategy can call the award functions. These functions allow prizes to be disbursed to users.

### Awarding Yield

Yield that accrues in the Prize Pool can be awarded by the Prize Strategy. The yield must first be **captured** and then it can be **awarded.**

To capture the yield the prize strategy can call the `captureAwardBalance` function:

```javascript
function captureAwardBalance() external onlyPrizeStrategy returns (uint256);
```

This function will:

* add the current yield balance to the available award balance
* capture a portion for the reserve
* return the total available award balance.

To award the captured yield to an address, the Prize strategy uses the `award` function. The yield must be awarded as one of the controlled tokens configured in the Prize Pool.

```javascript
function award(
    address to,
    uint256 amount,
    address controlledToken
) external onlyPrizeStrategy;
```

| Parameter Name  | Parameter Description                          |
| --------------- | ---------------------------------------------- |
| to              | The address to receive the newly minted tokens |
| amount          | The amount of tokens to mint                   |
| controlledToken | The type of token to mint                      |

### Awarding ERC20s

The Prize Strategy can award ERC20 tokens that are held by the Prize Pool.

```javascript
function awardExternalERC20(
    address to,
    address externalToken,
    uint256 amount
) external onlyPrizeStrategy;
```

However, some tokens are be blacklisted if they need to be held to generate yield (i.e. Compound cTokens).

| Parameter Name | Parameter Description               |
| -------------- | ----------------------------------- |
| to             | The address to receive the transfer |
| externalToken  | The ERC20 to transfer               |
| amount         | The amount of tokens to transfer    |

### Awarding ERC721s (NFTs)

The Prize Strategy can award ERC721 tokens that are held by the Prize Pool.

```javascript
function awardExternalERC721(
    address to,
    address externalToken,
    uint256[] calldata tokenIds
  )
    external
    onlyPrizeStrategy;
```

| Parameter Name | Parameter Description           |
| -------------- | ------------------------------- |
| to             | The address to receive the NFTs |
| externalToken  | The ERC721 contract address     |
| tokenIds       | The NFT token ids to transfer.  |

## Credit

Credit accrues differently for each of the Prize Pool's controlled tokens, so each token will have its own credit rate and credit limit.

### Credit Balance

To get a users credit balance for a controlled token:

```javascript
function balanceOfCredit(
    address user,
    address controlledToken
) external returns (uint256);
```

| Parameter Name  | Parameter Description                                   |
| --------------- | ------------------------------------------------------- |
| user            | The user whose credit balance should be returned        |
| controlledToken | The token for which the credit balance should be pulled |

### Credit Rate

The credit rate for a controlled token can be checked like so:

```javascript
function creditRateOf(
    address controlledToken
) external view returns (
    uint128 creditLimitMantissa,
    uint128 creditRateMantissa
);
```

| Parameter Name  | Parameter Description                                                |
| --------------- | -------------------------------------------------------------------- |
| controlledToken | The controlled token whose credit limit and rate should be returned. |

Note that the returned values are "mantissas": i.e. fixed point numbers with 18 decimal places.

### Credit Plan

The credit plan associated with a `controlledToken` can be found by calling:

```javascript
function creditPlanOf(address controlledToken) external override view returns (uint128 creditLimitMantissa, uint128 creditRateMantissa)
```

## Prizes

### Current Award Balance

The following function returns the amount calculated by `captureAwardBalance()`:

```javascript
function awardBalance() external override view returns (uint256)
```

### Total Balances

The total of all controlled tokens (including timelocked) can be obtained by calling:

```javascript
function accountedBalance() external override view returns (uint256)
```

The total underlying balance of all assets (including both principal and interest) can be obtained by calling:

```javascript
function balance() external returns (uint256)
```

## External Prizes

### Adding Tokens

The owner can add "external" ERC20 tokens as prizes. The strategy will award the entire balance held by the Prize Pool to the winner.

```javascript
function addExternalErc20Award(address _externalErc20) external onlyOwner;
```

The owner can add "external" ERC721 tokens as prizes. These tokens will be transferred to the winner.

```javascript
function addExternalErc721Award(
    address _externalErc721,
    uint256[] calldata _tokenIds
) external onlyOwner
```

### Checking Tokens

Checks with the Prize Pool if a specific token type (`_externalToken`) may be awarded as an external prize:

```javascript
function canAwardExternal(address _externalToken) external view returns (bool)
```

## Prize Time Periods

To retrieve when the current prize started:

```javascript
function prizePeriodStartedAt() external view returns (uint256)
```

To retrieve when the prize will end:

```javascript
function prizePeriodEndAt() external view returns (uint256)
```

## Reserve

### Calculate Reserve Fee

Calculates the reserve portion of the given `amount` of funds. If there is no reserve address, the Reserve fee portion will be zero.

```javascript
function calculateReserveFee(uint256 amount) public view returns (uint256)
```

## Prize Strategy

### Set the Prize Strategy

The associated Prize Strategy can be set by calling:

```javascript
function setPrizeStrategy(TokenListenerInterface _prizeStrategy) external override onlyOwner
```

Only the Prize Pool owner can call this function.


# ⚖️ Fairness

How Prize Pools Ensure Fair Play

When users play a game they want it to be fair. In PoolTogether, this means that everyone has contributed the same amount of interest to prizes they are eligible to win. Interest accrues over time, so the Prize Pool needs to measure and enforce the time that funds are held. Without this mechanism, it would be very easy to game the system by depositing right before a prize, having a chance to win, and withdrawing right after.

Prize Pools measure the duration of time funds are held by accruing **credit** for each user at the **credit rate**. The longer a user holds tokens, the more credit they accrue.

Prize Pools enforce the duration of time funds are held by setting a **credit limit**. Once a credit limit is reached a user can withdraw instantly with no loss. If the credit limit has not been reached the user can either use a withdrawal **timelock** or pay an early exit contribution to the prize.

## Credit

After a user deposits funds they begin to accrue credit according to the credit rate. The credit rate is expressed in tokens per second.

For example: if the user deposits 100 DAI and the credit rate is 0.1, then they will have accrued 1 DAI in credit after 10 seconds. Note that they cannot withdraw the 1 DAI credit; it's simply a measure of their contribution.

Users will accrue credit up until the **credit limit**. The credit limit is a fraction, so a users credit limit is that fraction of their entire balance. For example, if the user holds 100 DAI and the credit limit is 0.1, then they will accrue a maximum of 10 DAI in credit.

Once a deposit has accrued maximum credit, it is considered **matured**.

## Timelock

A deposit can be withdrawn instantly from the Prize Pool if it has matured. Otherwise, upon withdrawal the deposit will be timelocked until it has matured, at which point the funds can be swept back to the user by anyone.

The timelock duration is calculated based on the spare credit the user has. The spare credit for a withdrawal is their credit balance *less the credit limit for their remaining balance of tokens*. For example: let's say a user has 100 DAI and is attempting to withdraw 10 DAI. They currently have 9 DAI in credit and the credit limit is 0.1. The user's spare credit is 9 - (100 - 10) \* 0.1 = 0 DAI. If the user was instead withdrawing 50 DAI, then they would have 9 - (100 - 50) \* 0.1 = 4 DAI in spare credit.

The duration of the timelock is the time it takes for the withdrawal to mature less the spare credit. For example: if the withdrawal amount is 100 DAI, and the user has 5 DAI in spare credit, and the credit rate is 0.1, then the timelock will be ((100 \* 0.1) - 5) / 0.1 = 50 seconds. The spare credit is burned and the funds are placed in a timelock that can be swept after the duration has elapsed.

### Paying Off the Timelock

It's possible for a user to withdraw their funds instantly. Instead of a timelock, the Prize Pool will capture the remaining contribution directly from the withdrawal amount. The user will receive the withdrawal amount less the remaining contribution. Their spare credit will be burned. We call this an **instant withdrawal.**

## What should the credit rate and credit limit for a pool be?

In principal, we want the timelock to be as short as possible and most users should never encounter it. We are trying to prevent abuse of the system by a small subset of users while keeping the smoothest experience for the majority of users.

At first glance the credit limit should simply be equal to the amount of interest a deposit would contribute over a prize period. But there are several factors that can change the cost / benefit balance for depositors, specifically:

* Any subsidies to the prize (whether through sponsored deposits or direct additions)
* Any rewards given to deposits through the token drips
* Fluctuations in the yield rate
* Total amount of outstanding tickets for a given prize
* Gas fees of entering and exiting the pool

To find the ideal credit limit it is best to estimate the **effective APR** a pool is offering.

**Example**

Assume a pool has a yield source that returns 5% APR.  The pool awards prizes weekly, which means that each week approximately 5% / 52 = 0.096% accrues.  A fair credit limit could be 0.1%: if the user decides to game the prize, they will need to contribute 0.1% of their deposit.

However, we want users who have been in the pool since the beginning to not have to pay anything.  Let's say we wish for users to accrue 0.1% credit per week, so that they can withdraw losslessly.  The credit rate is applied per second and does not compound, so we can calculate the credit rate as the credit limit / seconds in a week, or 0.1% / 86400 = 0.0000011574074074074074.

This means that users will need to stay in the pool for a week, otherwise they'll need to pay an early exit fee of 0.1%.  Note, however, that this fee diminishes over time.


# Compound Prize Pool

The Compound Prize Pool is a Prize Pool that uses [Compound](https://compound.finance) as the yield source.  When a Compound Prize Pool is created it is configured with the cToken to use for minting and redeeming.

## Retrieving the Underlying cToken

To access the underlying [cToken](https://compound.finance/docs/ctokens), simply call this function:

```javascript
function cToken() returns (address);
```


# Stake Prize Pool

The Stake Prize Pool is a prize pool that uses an ERC-20 compatible token as the underlying asset.

Users's can stake their tokens to become eligible for whatever prize is defined as the prize strategy for that pool.

This is particularly useful for protocols that are sitting inactively in users's wallets - why not stake them in a pool and become eligible for rewards?

The returned [ticket](/master-1/protocol/tokens/ticket) can be thought of as a "proof-of-liquidity".

### Retrieving the Underlying ERC-20

The underlying staked asset can be retrieved by calling:

```javascript
function token() returns (address);
```


# yVault Prize Pool

The yVault Prize Pool is a prize pool that uses a yEarn [yVault](https://yearn.finance/vaults) as a yield source.  When a yVault Prize Pool is created it is configured with a yVault to deposit and withdraw from.  This particular prize pool retains a small reserve in order to cover yVault withdrawal fees. &#x20;

## Prize Pool Reserve

yVaults may charge users a fee upon withdrawal if the amount exceeds the vault holdings.  In order to compensate for this the yVault Prize Pool retains a reserve at a rate matching the fee.  For example, if the [yVault fee is 0.5%](https://docs.yearn.finance/products/yvaults#delegated-yvaults) then the yVault Prize Pool will retain 0.5% of the deposits as reserve.  The reserve will **not** be exposed to the Prize Strategy for distribution: it will be retained to cover withdrawal fees.

{% hint style="info" %}
It may appear that users will immediately lose 0.5% upon deposit, but it is important to note that the reserve works in tandem with the [credit system](/master-1/protocol/prize-pool/fairness).  The credit system ensures users participate long enough to contribute to the prize and the reserve.
{% endhint %}

The reserve rate can be retrieved using:

```javascript
function reserveRateMantissa() returns (uint256);
```

This returns the reserve rate as a 18 decimal fixed point number (like Ether).

The *owner* of the prize pool can set the reserve rate using the function:

```javascript
function setReserveRateMantissa(
    uint256 _reserveRateMantissa
) external onlyOwner
```

## Retrieving the Underlying yVault

The underlying yVault address can be retrieved using the function:

```javascript
function vault() returns (address);
```




---

[Next Page](/llms-full.txt/1)

