Skip to main content

PrizePool

Git Source

Inherits: TieredLiquidityDistributor

Author: G9 Software Inc. & PoolTogether Inc. Team

The Prize Pool holds the prize liquidity and allows vaults to claim prizes.

State Variables

_vaultAccumulator

The DrawAccumulator that tracks the exponential moving average of the contributions by a vault.

mapping(address vault => DrawAccumulatorLib.Accumulator accumulator) internal _vaultAccumulator;

_claimedPrizes

Records the claim record for a winner.

mapping(
address vault
=> mapping(
address account
=> mapping(uint24 drawId => mapping(uint8 tier => mapping(uint32 prizeIndex => bool claimed)))
)
) internal _claimedPrizes;

_rewards

Tracks the total rewards accrued for a claimer or draw completer.

mapping(address recipient => uint256 rewards) internal _rewards;

DONATOR

The special value for the donator address. Contributions from this address are excluded from the total odds.

0x000...F2EE because it's free money!

address public constant DONATOR = 0x000000000000000000000000000000000000F2EE;

prizeToken

The token that is being contributed and awarded as prizes.

IERC20 public immutable prizeToken;

twabController

The Twab Controller to use to retrieve historic balances.

TwabController public immutable twabController;

drawPeriodSeconds

The number of seconds between draws.

uint48 public immutable drawPeriodSeconds;

firstDrawOpensAt

The timestamp at which the first draw will open.

uint48 public immutable firstDrawOpensAt;

drawTimeout

The maximum number of draws that can be missed before the prize pool is considered inactive.

uint24 public immutable drawTimeout;

creator

The address that is allowed to set the draw manager

address immutable creator;

_totalAccumulator

The exponential weighted average of all vault contributions.

DrawAccumulatorLib.Accumulator internal _totalAccumulator;

_winningRandomNumber

The winner random number for the last awarded draw.

uint256 internal _winningRandomNumber;

drawManager

The draw manager address.

address public drawManager;

_directlyContributedReserve

Tracks reserve that was contributed directly to the reserve. Always increases.

uint96 internal _directlyContributedReserve;

claimCount

The number of prize claims for the last awarded draw.

uint24 public claimCount;

_totalWithdrawn

The total amount of prize tokens that have been claimed for all time.

uint128 internal _totalWithdrawn;

_totalRewardsToBeClaimed

The total amount of rewards that have yet to be claimed

uint104 internal _totalRewardsToBeClaimed;

shutdownObservation

The observation at which the shutdown balance was recorded

Observation shutdownObservation;

shutdownBalance

The balance available to be withdrawn at shutdown

uint256 shutdownBalance;

_withdrawalObservations

The total contributed observation that was used for the last withdrawal for a vault and account

mapping(address vault => mapping(address account => Observation lastWithdrawalTotalContributedObservation)) internal
_withdrawalObservations;

_shutdownPortions

The shutdown portion of liquidity for a vault and account

mapping(address vault => mapping(address account => ShutdownPortion shutdownPortion)) internal _shutdownPortions;

Functions

constructor

Constructs a new Prize Pool.

constructor(ConstructorParams memory params)
TieredLiquidityDistributor(
params.tierLiquidityUtilizationRate,
params.numberOfTiers,
params.tierShares,
params.canaryShares,
params.reserveShares,
params.grandPrizePeriodDraws
);

Parameters

NameTypeDescription
paramsConstructorParamsA struct of constructor parameters

onlyDrawManager

Modifier that throws if sender is not the draw manager.

modifier onlyDrawManager();

setDrawManager

Sets the Draw Manager contract on the prize pool. Can only be called once by the creator.

function setDrawManager(address _drawManager) external;

Parameters

NameTypeDescription
_drawManageraddressThe address of the Draw Manager contract

contributePrizeTokens

Contributes prize tokens on behalf of the given vault.

The tokens should have already been transferred to the prize pool.

The prize pool balance will be checked to ensure there is at least the given amount to deposit.

function contributePrizeTokens(address _prizeVault, uint256 _amount) public returns (uint256);

Parameters

NameTypeDescription
_prizeVaultaddressThe address of the vault to contribute to
_amountuint256The amount of prize tokens to contribute

Returns

NameTypeDescription
<none>uint256The amount of available prize tokens prior to the contribution.

donatePrizeTokens

Allows a user to donate prize tokens to the prize pool.

function donatePrizeTokens(uint256 _amount) external;

Parameters

NameTypeDescription
_amountuint256The amount of tokens to donate. The amount should already be approved for transfer.

allocateRewardFromReserve

Allows the Manager to allocate a reward from the reserve to a recipient.

function allocateRewardFromReserve(address _to, uint96 _amount) external onlyDrawManager notShutdown;

Parameters

NameTypeDescription
_toaddressThe address to allocate the rewards to
_amountuint96The amount of tokens for the reward

awardDraw

Allows the Manager to award a draw with the winning random number.

Updates the number of tiers, the winning random number and the prize pool reserve.

function awardDraw(uint256 winningRandomNumber_) external onlyDrawManager notShutdown returns (uint24);

Parameters

NameTypeDescription
winningRandomNumber_uint256The winning random number for the draw

Returns

NameTypeDescription
<none>uint24The ID of the awarded draw

claimPrize

Claims a prize for a given winner and tier.

This function takes in an address _winner, a uint8 _tier, a uint96 _claimReward, and an address _claimRewardRecipient. It checks if _winner is actually the winner of the _tier for the calling vault. If so, it calculates the prize size and transfers it to the winner. If not, it reverts with an error message. The function then checks the claim record of _winner to see if they have already claimed the prize for the awarded draw. If not, it updates the claim record with the claimed tier and emits a ClaimedPrize event with information about the claim. Note that this function can modify the state of the contract by updating the claim record, changing the largest tier claimed and the claim count, and transferring prize tokens. The function is marked as external which means that it can be called from outside the contract.

function claimPrize(
address _winner,
uint8 _tier,
uint32 _prizeIndex,
address _prizeRecipient,
uint96 _claimReward,
address _claimRewardRecipient
) external returns (uint256);

Parameters

NameTypeDescription
_winneraddressThe address of the eligible winner
_tieruint8The tier of the prize to be claimed.
_prizeIndexuint32The prize to claim for the winner. Must be less than the prize count for the tier.
_prizeRecipientaddressThe recipient of the prize
_claimRewarduint96The claimReward associated with claiming the prize.
_claimRewardRecipientaddressThe address to receive the claimReward.

Returns

NameTypeDescription
<none>uint256Total prize amount claimed (payout and claimRewards combined).

withdrawRewards

Withdraws earned rewards for the caller.

Claims cannot occur after a draw has been finalized (1 period after a draw closes). This prevents the reserve from changing while the following draw is being awarded.

function withdrawRewards(address _to, uint256 _amount) external;

Parameters

NameTypeDescription
_toaddressThe address to transfer the rewards to
_amountuint256The amount of rewards to withdraw

contributeReserve

Allows anyone to deposit directly into the Prize Pool reserve.

Ensure caller has sufficient balance and has approved the Prize Pool to transfer the tokens

function contributeReserve(uint96 _amount) external notShutdown;

Parameters

NameTypeDescription
_amountuint96The amount of tokens to increase the reserve by

getWinningRandomNumber

Returns the winning random number for the last awarded draw.

function getWinningRandomNumber() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The winning random number

getLastAwardedDrawId

Returns the last awarded draw id.

function getLastAwardedDrawId() external view returns (uint24);

Returns

NameTypeDescription
<none>uint24The last awarded draw id

getContributedBetween

Returns the total prize tokens contributed by a particular vault between the given draw ids, inclusive.

function getContributedBetween(address _vault, uint24 _startDrawIdInclusive, uint24 _endDrawIdInclusive)
external
view
returns (uint256);

Parameters

NameTypeDescription
_vaultaddressThe address of the vault
_startDrawIdInclusiveuint24Start draw id inclusive
_endDrawIdInclusiveuint24End draw id inclusive

Returns

NameTypeDescription
<none>uint256The total prize tokens contributed by the given vault

getDonatedBetween

Returns the total prize tokens donated to the prize pool

function getDonatedBetween(uint24 _startDrawIdInclusive, uint24 _endDrawIdInclusive) external view returns (uint256);

Parameters

NameTypeDescription
_startDrawIdInclusiveuint24Start draw id inclusive
_endDrawIdInclusiveuint24End draw id inclusive

Returns

NameTypeDescription
<none>uint256The total prize tokens donated to the prize pool

getTotalAccumulatorNewestObservation

Returns the newest observation for the total accumulator

function getTotalAccumulatorNewestObservation() external view returns (Observation memory);

Returns

NameTypeDescription
<none>ObservationThe newest observation

getVaultAccumulatorNewestObservation

Returns the newest observation for the specified vault accumulator

function getVaultAccumulatorNewestObservation(address _vault) external view returns (Observation memory);

Parameters

NameTypeDescription
_vaultaddressThe vault to check

Returns

NameTypeDescription
<none>ObservationThe newest observation for the vault

getTierAccrualDurationInDraws

Computes the expected duration prize accrual for a tier.

function getTierAccrualDurationInDraws(uint8 _tier) external view returns (uint24);

Parameters

NameTypeDescription
_tieruint8The tier to check

Returns

NameTypeDescription
<none>uint24The number of draws

totalWithdrawn

The total amount of prize tokens that have been withdrawn as fees or prizes

function totalWithdrawn() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The total amount of prize tokens that have been withdrawn as fees or prizes

pendingReserveContributions

Returns the amount of tokens that will be added to the reserve when next draw to award is awarded.

Intended for Draw manager to use after a draw has closed but not yet been awarded.

function pendingReserveContributions() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256The amount of prize tokens that will be added to the reserve

wasClaimed

Returns whether the winner has claimed the tier for the last awarded draw

function wasClaimed(address _vault, address _winner, uint8 _tier, uint32 _prizeIndex) external view returns (bool);

Parameters

NameTypeDescription
_vaultaddressThe vault to check
_winneraddressThe account to check
_tieruint8The tier to check
_prizeIndexuint32The prize index to check

Returns

NameTypeDescription
<none>boolTrue if the winner claimed the tier for the last awarded draw, false otherwise.

wasClaimed

Returns whether the winner has claimed the tier for the specified draw

function wasClaimed(address _vault, address _winner, uint24 _drawId, uint8 _tier, uint32 _prizeIndex)
external
view
returns (bool);

Parameters

NameTypeDescription
_vaultaddressThe vault to check
_winneraddressThe account to check
_drawIduint24The draw ID to check
_tieruint8The tier to check
_prizeIndexuint32The prize index to check

Returns

NameTypeDescription
<none>boolTrue if the winner claimed the tier for the specified draw, false otherwise.

rewardBalance

Returns the balance of rewards earned for the given address.

function rewardBalance(address _recipient) external view returns (uint256);

Parameters

NameTypeDescription
_recipientaddressThe recipient to retrieve the reward balance for

Returns

NameTypeDescription
<none>uint256The balance of rewards for the given recipient

estimateNextNumberOfTiers

Computes and returns the next number of tiers based on the current prize claim counts. This number may change throughout the draw

function estimateNextNumberOfTiers() external view returns (uint8);

Returns

NameTypeDescription
<none>uint8The next number of tiers

accountedBalance

Computes how many tokens have been accounted for

function accountedBalance() public view returns (uint256);

Returns

NameTypeDescription
<none>uint256The balance of tokens that have been accounted for

getShutdownInfo

Returns the balance available at the time of shutdown, less rewards to be claimed.

This function will compute and store the current balance if it has not yet been set.

function getShutdownInfo() public returns (uint256 balance, Observation memory observation);

Returns

NameTypeDescription
balanceuint256The balance that is available for depositors to withdraw
observationObservationThe observation used to compute the balance

getOpenDrawId

Returns the open draw ID based on the current block timestamp.

Returns 1 if the first draw hasn't opened yet. This prevents any contributions from going to the inaccessible draw zero.

First draw has an ID of 1. This means that if _lastAwardedDrawId is zero, we know that no draws have been awarded yet.

Capped at the shutdown draw ID if the prize pool has shutdown.

function getOpenDrawId() public view returns (uint24);

Returns

NameTypeDescription
<none>uint24The ID of the draw period that the current block is in

getDrawId

Returns the open draw id for the given timestamp

function getDrawId(uint256 _timestamp) public view returns (uint24);

Parameters

NameTypeDescription
_timestampuint256The timestamp to get the draw id for

Returns

NameTypeDescription
<none>uint24The ID of the open draw that the timestamp is in

getDrawIdToAward

Returns the next draw ID that can be awarded.

It's possible for draws to be missed, so the next draw ID to award may be more than one draw ahead of the last awarded draw ID.

function getDrawIdToAward() public view returns (uint24);

Returns

NameTypeDescription
<none>uint24The next draw ID that can be awarded

drawOpensAt

Returns the time at which a draw opens / opened at.

function drawOpensAt(uint24 drawId) public view returns (uint48);

Parameters

NameTypeDescription
drawIduint24The draw to get the timestamp for

Returns

NameTypeDescription
<none>uint48The start time of the draw in seconds

drawClosesAt

Returns the time at which a draw closes / closed at.

function drawClosesAt(uint24 drawId) public view returns (uint48);

Parameters

NameTypeDescription
drawIduint24The draw to get the timestamp for

Returns

NameTypeDescription
<none>uint48The end time of the draw in seconds

isDrawFinalized

Checks if the given draw is finalized.

function isDrawFinalized(uint24 drawId) public view returns (bool);

Parameters

NameTypeDescription
drawIduint24The draw to check

Returns

NameTypeDescription
<none>boolTrue if the draw is finalized, false otherwise

computeNextNumberOfTiers

Calculates the number of tiers given the number of prize claims

This function will use the claim count to determine the number of tiers, then add one for the canary tier.

function computeNextNumberOfTiers(uint32 _claimCount) public view returns (uint8);

Parameters

NameTypeDescription
_claimCountuint32The number of prize claims

Returns

NameTypeDescription
<none>uint8The estimated number of tiers + the canary tier

computeShutdownPortion

Returns the given account and vault's portion of the shutdown balance.

function computeShutdownPortion(address _vault, address _account) public view returns (ShutdownPortion memory);

Parameters

NameTypeDescription
_vaultaddressThe vault whose contributions are measured
_accountaddressThe account whose vault twab is measured

Returns

NameTypeDescription
<none>ShutdownPortionThe portion of the shutdown balance that the account is entitled to.

shutdownBalanceOf

Returns the shutdown balance for a given vault and account. The prize pool must already be shutdown.

The shutdown balance is the amount of prize tokens that a user can claim after the prize pool has been shutdown.

The shutdown balance is calculated using the user's TWAB and the total supply TWAB, whose time ranges are the grand prize period prior to the shutdown timestamp.

function shutdownBalanceOf(address _vault, address _account) public returns (uint256);

Parameters

NameTypeDescription
_vaultaddressThe vault to check
_accountaddressThe account to check

Returns

NameTypeDescription
<none>uint256The shutdown balance for the given vault and account

withdrawShutdownBalance

Withdraws the shutdown balance for a given vault and sender

function withdrawShutdownBalance(address _vault, address _recipient) external returns (uint256);

Parameters

NameTypeDescription
_vaultaddressThe eligible vault to withdraw the shutdown balance from
_recipientaddressThe address to send the shutdown balance to

Returns

NameTypeDescription
<none>uint256The amount of prize tokens withdrawn

getShutdownDrawId

Returns the open draw ID at the time of shutdown.

function getShutdownDrawId() public view returns (uint24);

Returns

NameTypeDescription
<none>uint24The draw id

shutdownAt

Returns the timestamp at which the prize pool will be considered inactive and shutdown

function shutdownAt() public view returns (uint256);

Returns

NameTypeDescription
<none>uint256The timestamp at which the prize pool will be considered inactive

isShutdown

Returns whether the prize pool has been shutdown

function isShutdown() public view returns (bool);

Returns

NameTypeDescription
<none>boolTrue if shutdown, false otherwise

drawTimeoutAt

Returns the timestamp at which the prize pool will be considered inactive

function drawTimeoutAt() public view returns (uint256);

Returns

NameTypeDescription
<none>uint256The timestamp at which the prize pool has timed out and becomes inactive

getTotalContributedBetween

Returns the total prize tokens contributed between the given draw ids, inclusive.

function getTotalContributedBetween(uint24 _startDrawIdInclusive, uint24 _endDrawIdInclusive)
public
view
returns (uint256);

Parameters

NameTypeDescription
_startDrawIdInclusiveuint24Start draw id inclusive
_endDrawIdInclusiveuint24End draw id inclusive

Returns

NameTypeDescription
<none>uint256The total prize tokens contributed by all vaults

isWinner

Checks if the given user has won the prize for the specified tier in the given vault.

function isWinner(address _vault, address _user, uint8 _tier, uint32 _prizeIndex) public view returns (bool);

Parameters

NameTypeDescription
_vaultaddressThe address of the vault to check
_useraddressThe address of the user to check for the prize
_tieruint8The tier for which the prize is to be checked
_prizeIndexuint32The prize index to check. Must be less than prize count for the tier

Returns

NameTypeDescription
<none>boolA boolean value indicating whether the user has won the prize or not

computeRangeStartDrawIdInclusive

Compute the start draw id for a range given the end draw id and range size

function computeRangeStartDrawIdInclusive(uint24 _endDrawIdInclusive, uint24 _rangeSize) public pure returns (uint24);

Parameters

NameTypeDescription
_endDrawIdInclusiveuint24The end draw id (inclusive) of the range
_rangeSizeuint24The size of the range

Returns

NameTypeDescription
<none>uint24The start draw id (inclusive) of the range

getVaultUserBalanceAndTotalSupplyTwab

Returns the time-weighted average balance (TWAB) and the TWAB total supply for the specified user in the given vault over a specified period.

This function calculates the TWAB for a user by calling the getTwabBetween function of the TWAB controller for a specified period of time.

function getVaultUserBalanceAndTotalSupplyTwab(
address _vault,
address _user,
uint24 _startDrawIdInclusive,
uint24 _endDrawIdInclusive
) public view returns (uint256 twab, uint256 twabTotalSupply);

Parameters

NameTypeDescription
_vaultaddressThe address of the vault for which to get the TWAB.
_useraddressThe address of the user for which to get the TWAB.
_startDrawIdInclusiveuint24The starting draw for the range (inclusive)
_endDrawIdInclusiveuint24The end draw for the range (inclusive)

Returns

NameTypeDescription
twabuint256The TWAB for the specified user in the given vault over the specified period.
twabTotalSupplyuint256The TWAB total supply over the specified period.

getVaultPortion

Calculates the portion of the vault's contribution to the prize pool over a specified duration in draws.

function getVaultPortion(address _vault, uint24 _startDrawIdInclusive, uint24 _endDrawIdInclusive)
public
view
returns (SD59x18);

Parameters

NameTypeDescription
_vaultaddressThe address of the vault for which to calculate the portion.
_startDrawIdInclusiveuint24The starting draw ID (inclusive) of the draw range to calculate the contribution portion for.
_endDrawIdInclusiveuint24The ending draw ID (inclusive) of the draw range to calculate the contribution portion for.

Returns

NameTypeDescription
<none>SD59x18The portion of the vault's contribution to the prize pool over the specified duration in draws.

_getVaultShares

function _getVaultShares(address _vault, uint24 _startDrawIdInclusive, uint24 _endDrawIdInclusive)
internal
view
returns (uint256 shares, uint256 totalSupply);

_accountedBalance

function _accountedBalance(Observation memory _observation) internal view returns (uint256);

notShutdown

Modifier that requires the prize pool not to be shutdown

modifier notShutdown();

Events

ClaimedPrize

Emitted when a prize is claimed.

event ClaimedPrize(
address indexed vault,
address indexed winner,
address indexed recipient,
uint24 drawId,
uint8 tier,
uint32 prizeIndex,
uint152 payout,
uint96 claimReward,
address claimRewardRecipient
);

Parameters

NameTypeDescription
vaultaddressThe address of the vault that claimed the prize.
winneraddressThe address of the winner
recipientaddressThe address of the prize recipient
drawIduint24The draw ID of the draw that was claimed.
tieruint8The prize tier that was claimed.
prizeIndexuint32The index of the prize that was claimed
payoutuint152The amount of prize tokens that were paid out to the winner
claimRewarduint96The amount of prize tokens that were paid to the claimer
claimRewardRecipientaddressThe address that the claimReward was sent to

DrawAwarded

Emitted when a draw is awarded.

event DrawAwarded(
uint24 indexed drawId,
uint256 winningRandomNumber,
uint8 lastNumTiers,
uint8 numTiers,
uint104 reserve,
uint128 prizeTokensPerShare,
uint48 drawOpenedAt
);

Parameters

NameTypeDescription
drawIduint24The ID of the draw that was awarded
winningRandomNumberuint256The winning random number for the awarded draw
lastNumTiersuint8The previous number of prize tiers
numTiersuint8The number of prize tiers for the awarded draw
reserveuint104The resulting reserve available
prizeTokensPerShareuint128The amount of prize tokens per share for the awarded draw
drawOpenedAtuint48The start timestamp of the awarded draw

AllocateRewardFromReserve

Emitted when any amount of the reserve is rewarded to a recipient.

event AllocateRewardFromReserve(address indexed to, uint256 amount);

Parameters

NameTypeDescription
toaddressThe recipient of the reward
amountuint256The amount of assets rewarded

ContributedReserve

Emitted when the reserve is manually increased.

event ContributedReserve(address indexed user, uint256 amount);

Parameters

NameTypeDescription
useraddressThe user who increased the reserve
amountuint256The amount of assets transferred

ContributePrizeTokens

Emitted when a vault contributes prize tokens to the pool.

event ContributePrizeTokens(address indexed vault, uint24 indexed drawId, uint256 amount);

Parameters

NameTypeDescription
vaultaddressThe address of the vault that is contributing tokens
drawIduint24The ID of the first draw that the tokens will be contributed to
amountuint256The amount of tokens contributed

SetDrawManager

Emitted when the draw manager is set

event SetDrawManager(address indexed drawManager);

Parameters

NameTypeDescription
drawManageraddressThe address of the draw manager

WithdrawRewards

Emitted when an address withdraws their prize claim rewards.

event WithdrawRewards(address indexed account, address indexed to, uint256 amount, uint256 available);

Parameters

NameTypeDescription
accountaddressThe account that is withdrawing rewards
toaddressThe address the rewards are sent to
amountuint256The amount withdrawn
availableuint256The total amount that was available to withdraw before the transfer

IncreaseClaimRewards

Emitted when an address receives new prize claim rewards.

event IncreaseClaimRewards(address indexed to, uint256 amount);

Parameters

NameTypeDescription
toaddressThe address the rewards are given to
amountuint256The amount increased

Structs

ShutdownPortion

A struct to represent a shutdown portion of liquidity for a vault and account

struct ShutdownPortion {
uint256 numerator;
uint256 denominator;
}

Properties

NameTypeDescription
numeratoruint256The numerator of the portion
denominatoruint256The denominator of the portion

ConstructorParams

Constructor Parameters

struct ConstructorParams {
IERC20 prizeToken;
TwabController twabController;
address creator;
uint256 tierLiquidityUtilizationRate;
uint48 drawPeriodSeconds;
uint48 firstDrawOpensAt;
uint24 grandPrizePeriodDraws;
uint8 numberOfTiers;
uint8 tierShares;
uint8 canaryShares;
uint8 reserveShares;
uint24 drawTimeout;
}

Properties

NameTypeDescription
prizeTokenIERC20The token to use for prizes
twabControllerTwabControllerThe Twab Controller to retrieve time-weighted average balances from
creatoraddressThe address that will be permitted to finish prize pool initialization after deployment
tierLiquidityUtilizationRateuint256The rate at which liquidity is utilized for prize tiers. This allows for deviations in prize claims; if 0.75e18 then it is 75% utilization so it can accommodate 25% deviation in more prize claims.
drawPeriodSecondsuint48The number of seconds between draws. E.g. a Prize Pool with a daily draw should have a draw period of 86400 seconds.
firstDrawOpensAtuint48The timestamp at which the first draw will open
grandPrizePeriodDrawsuint24The target number of draws to pass between each grand prize
numberOfTiersuint8The number of tiers to start with. Must be greater than or equal to the minimum number of tiers
tierSharesuint8The number of shares to allocate to each tier
canarySharesuint8The number of shares to allocate to each canary tier
reserveSharesuint8The number of shares to allocate to the reserve
drawTimeoutuint24The number of draws that need to be missed before the prize pool shuts down. The timeout resets when a draw is awarded.