From 37f29143ef08345192dd545cd181532443ed55d9 Mon Sep 17 00:00:00 2001 From: Dylan DesRosier Date: Fri, 30 Jun 2023 20:01:05 +0100 Subject: [PATCH] Update code documentation --- script/generateConstants.s.sol | 2 + src/PrizePool.sol | 626 +++++++++++--------- src/abstract/TieredLiquidityDistributor.sol | 67 ++- src/libraries/DrawAccumulatorLib.sol | 26 +- src/libraries/TierCalculationLib.sol | 10 +- 5 files changed, 389 insertions(+), 342 deletions(-) diff --git a/script/generateConstants.s.sol b/script/generateConstants.s.sol index 6c0c328..887cb42 100644 --- a/script/generateConstants.s.sol +++ b/script/generateConstants.s.sol @@ -20,6 +20,7 @@ contract GenerateConstants is Script { ); console.log("\n"); + console.log("/// @notice The estiamted number of prizes given X tiers."); uint8 MIN_TIERS = 2; uint8 MAX_TIERS = 14; // Precompute the prizes per draw @@ -32,6 +33,7 @@ contract GenerateConstants is Script { } console.log("\n"); + console.log("/// @notice The odds for each tier and number of tiers pair."); MIN_TIERS = 3; MAX_TIERS = 16; // Precompute the odds for each tier diff --git a/src/PrizePool.sol b/src/PrizePool.sol index 3829d9b..adbe822 100644 --- a/src/PrizePool.sol +++ b/src/PrizePool.sol @@ -15,10 +15,10 @@ import { TieredLiquidityDistributor, Tier } from "./abstract/TieredLiquidityDist import { TierCalculationLib } from "./libraries/TierCalculationLib.sol"; import { BitLib } from "./libraries/BitLib.sol"; -/// @notice Emitted when someone tries to set the draw manager +/// @notice Emitted when someone tries to set the draw manager. error DrawManagerAlreadySet(); -/// @notice Emitted when someone tries to claim a prize that was already claimed +/// @notice Emitted when someone tries to claim a prize that was already claimed. /// @param winner The winner of the prize /// @param tier The prize tier error AlreadyClaimedPrize( @@ -29,60 +29,60 @@ error AlreadyClaimedPrize( address recipient ); -/// @notice Emitted when someone tries to withdraw too many rewards +/// @notice Emitted when someone tries to withdraw too many rewards. /// @param requested The requested reward amount to withdraw /// @param available The total reward amount available for the caller to withdraw error InsufficientRewardsError(uint256 requested, uint256 available); -/// @notice Emitted when an address did not win the specified prize on a vault +/// @notice Emitted when an address did not win the specified prize on a vault when claiming. /// @param winner The address checked for the prize /// @param vault The vault address /// @param tier The prize tier /// @param prizeIndex The prize index error DidNotWin(address vault, address winner, uint8 tier, uint32 prizeIndex); -/// @notice Emitted when the fee being claimed is larger than the max allowed fee +/// @notice Emitted when the fee being claimed is larger than the max allowed fee. /// @param fee The fee being claimed /// @param maxFee The max fee that can be claimed error FeeTooLarge(uint256 fee, uint256 maxFee); -/// @notice Emitted when the initialized smoothing number is not less than one +/// @notice Emitted when the initialized smoothing number is not less than one. /// @param smoothing The unwrapped smoothing value that exceeds the limit error SmoothingGTEOne(int64 smoothing); -/// @notice Emitted when the contributed amount is more than the available, un-accounted balance +/// @notice Emitted when the contributed amount is more than the available, un-accounted balance. /// @param amount The contribution amount that is being claimed /// @param available The available un-accounted balance that can be claimed as a contribution error ContributionGTDeltaBalance(uint256 amount, uint256 available); -/// @notice Emitted when the withdraw amount is greater than the available reserve +/// @notice Emitted when the withdraw amount is greater than the available reserve. /// @param amount The amount being withdrawn /// @param reserve The total reserve available for withdrawal error InsufficientReserve(uint104 amount, uint104 reserve); -/// @notice Emitted when the winning random number is zero +/// @notice Emitted when the winning random number is zero. error RandomNumberIsZero(); -/// @notice Emitted when the draw cannot be completed since it has not finished +/// @notice Emitted when the draw cannot be completed since it has not finished. /// @param drawEndsAt The timestamp in seconds at which the draw ends /// @param errorTimestamp The timestamp in seconds at which the error occured error DrawNotFinished(uint64 drawEndsAt, uint64 errorTimestamp); -/// @notice Emitted when prize index is greater or equal to the max prize count for the tier +/// @notice Emitted when prize index is greater or equal to the max prize count for the tier. /// @param invalidPrizeIndex The invalid prize index /// @param prizeCount The prize count for the tier /// @param tier The tier number error InvalidPrizeIndex(uint32 invalidPrizeIndex, uint32 prizeCount, uint8 tier); -/// @notice Emitted when there are no completed draws when a computation requires a completed draw +/// @notice Emitted when there are no completed draws when a computation requires a completed draw. error NoCompletedDraw(); -/// @notice Emitted when a tier does not exist +/// @notice Emitted when attempting to claim from a tier that does not exist. /// @param tier The tier number that does not exist /// @param numberOfTiers The current number of tiers error InvalidTier(uint8 tier, uint8 numberOfTiers); -/// @notice Emitted when the caller is not the draw manager +/// @notice Emitted when the caller is not the draw manager. /// @param caller The caller address /// @param drawManager The drawManager address error CallerNotDrawManager(address caller, address drawManager); @@ -123,6 +123,8 @@ struct ConstructorParams { contract PrizePool is TieredLiquidityDistributor { using SafeERC20 for IERC20; + /* ============ Events ============ */ + /// @notice Emitted when a prize is claimed. /// @param vault The address of the vault that claimed the prize. /// @param winner The address of the winner @@ -175,75 +177,79 @@ contract PrizePool is TieredLiquidityDistributor { /// @param amount The amount of tokens contributed event ContributePrizeTokens(address indexed vault, uint16 indexed drawId, uint256 amount); - /// @notice Emitted when an address withdraws their claim rewards + /// @notice Emitted when an address withdraws their prize claim rewards. /// @param to The address the rewards are sent to /// @param amount The amount withdrawn /// @param available The total amount that was available to withdraw before the transfer event WithdrawClaimRewards(address indexed to, uint256 amount, uint256 available); - /// @notice Emitted when an address receives new claim rewards + /// @notice Emitted when an address receives new prize claim rewards. /// @param to The address the rewards are given to /// @param amount The amount increased event IncreaseClaimRewards(address indexed to, uint256 amount); - /// @notice Emitted when the drawManager is set + /// @notice Emitted when the drawManager is set. /// @param drawManager The draw manager event DrawManagerSet(address indexed drawManager); - /// @notice The DrawAccumulator that tracks the exponential moving average of the contributions by a vault + /* ============ State ============ */ + + /// @notice The DrawAccumulator that tracks the exponential moving average of the contributions by a vault. mapping(address => DrawAccumulatorLib.Accumulator) internal vaultAccumulator; - /// @notice Records the claim record for a winner + /// @notice Records the claim record for a winner. /// @dev account => drawId => tier => prizeIndex => claimed mapping(address => mapping(uint16 => mapping(uint8 => mapping(uint32 => bool)))) internal claimedPrizes; - /// @notice Tracks the total fees accrued to each claimer + /// @notice Tracks the total fees accrued to each claimer. mapping(address => uint256) internal claimerRewards; /// @notice The degree of POOL contribution smoothing. 0 = no smoothing, ~1 = max smoothing. Smoothing spreads out vault contribution over multiple draws; the higher the smoothing the more draws. SD1x18 public immutable smoothing; - /// @notice The token that is being contributed and awarded as prizes + /// @notice The token that is being contributed and awarded as prizes. IERC20 public immutable prizeToken; /// @notice The Twab Controller to use to retrieve historic balances. TwabController public immutable twabController; - /// @notice The draw manager address + /// @notice The draw manager address. address public drawManager; - /// @notice The number of seconds between draws + /// @notice The number of seconds between draws. uint32 public immutable drawPeriodSeconds; - // percentage of prizes that must be claimed to bump the number of tiers - // 64 bits + /// @notice Percentage of prizes that must be claimed to bump the number of tiers. UD2x18 public immutable claimExpansionThreshold; - /// @notice The exponential weighted average of all vault contributions + /// @notice The exponential weighted average of all vault contributions. DrawAccumulatorLib.Accumulator internal totalAccumulator; + /// @notice The total amount of prize tokens that have been claimed for all time. uint256 internal _totalWithdrawn; - /// @notice The winner random number for the last completed draw + /// @notice The winner random number for the last completed draw. uint256 internal _winningRandomNumber; - /// @notice The number of prize claims for the last completed draw + /// @notice The number of prize claims for the last completed draw. uint32 public claimCount; - /// @notice The number of canary prize claims for the last completed draw + /// @notice The number of canary prize claims for the last completed draw. uint32 public canaryClaimCount; - /// @notice The largest tier claimed so far for the last completed draw + /// @notice The largest tier claimed so far for the last completed draw. uint8 public largestTierClaimed; - /// @notice The timestamp at which the last completed draw started + /// @notice The timestamp at which the last completed draw started. uint64 internal _lastCompletedDrawStartedAt; - /// @notice The timestamp at which the last completed draw was awarded + /// @notice The timestamp at which the last completed draw was awarded. uint64 internal _lastCompletedDrawAwardedAt; - /// @notice Constructs a new Prize Pool + /* ============ Constructor ============ */ + + /// @notice Constructs a new Prize Pool. /// @param params A struct of constructor parameters constructor( ConstructorParams memory params @@ -271,7 +277,9 @@ contract PrizePool is TieredLiquidityDistributor { } } - /// @notice Modifier that throws if sender is not the draw manager + /* ============ Modifiers ============ */ + + /// @notice Modifier that throws if sender is not the draw manager. modifier onlyDrawManager() { if (msg.sender != drawManager) { revert CallerNotDrawManager(msg.sender, drawManager); @@ -279,7 +287,9 @@ contract PrizePool is TieredLiquidityDistributor { _; } - /// @notice Allows a caller to set the DrawManager if not already set + /* ============ External Write Functions ============ */ + + /// @notice Allows a caller to set the DrawManager if not already set. /// @dev Notice that this can be front-run: make sure to verify the drawManager after construction /// @param _drawManager The draw manager function setDrawManager(address _drawManager) external { @@ -291,56 +301,6 @@ contract PrizePool is TieredLiquidityDistributor { emit DrawManagerSet(_drawManager); } - /// @notice Returns the winning random number for the last completed draw - /// @return The winning random number - function getWinningRandomNumber() external view returns (uint256) { - return _winningRandomNumber; - } - - /// @notice Returns the last completed draw id - /// @return The last completed draw id - function getLastCompletedDrawId() external view returns (uint256) { - return lastCompletedDrawId; - } - - /// @notice Returns the total prize tokens contributed between the given draw ids, inclusive. Note that this is after smoothing is applied. - /// @return The total prize tokens contributed by all vaults - function getTotalContributedBetween( - uint16 _startDrawIdInclusive, - uint16 _endDrawIdInclusive - ) external view returns (uint256) { - return - DrawAccumulatorLib.getDisbursedBetween( - totalAccumulator, - _startDrawIdInclusive, - _endDrawIdInclusive, - smoothing.intoSD59x18() - ); - } - - /// @notice Returns the total prize tokens contributed by a particular vault between the given draw ids, inclusive. Note that this is after smoothing is applied. - /// @return The total prize tokens contributed by the given vault - function getContributedBetween( - address _vault, - uint16 _startDrawIdInclusive, - uint16 _endDrawIdInclusive - ) external view returns (uint256) { - return - DrawAccumulatorLib.getDisbursedBetween( - vaultAccumulator[_vault], - _startDrawIdInclusive, - _endDrawIdInclusive, - smoothing.intoSD59x18() - ); - } - - /// @notice Returns the - /// @return The number of draws - function getTierAccrualDurationInDraws(uint8 _tier) external view returns (uint16) { - return - uint16(TierCalculationLib.estimatePrizeFrequencyInDraws(_tierOdds(_tier, numberOfTiers))); - } - /// @notice 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. /// @return The amount of available prize tokens prior to the contribution. @@ -365,43 +325,6 @@ contract PrizePool is TieredLiquidityDistributor { return _deltaBalance; } - /// @notice Computes how many tokens have been accounted for - /// @return The balance of tokens that have been accounted for - function _accountedBalance() internal view returns (uint256) { - Observation memory obs = DrawAccumulatorLib.newestObservation(totalAccumulator); - return (obs.available + obs.disbursed) - _totalWithdrawn; - } - - /// @notice The total amount of prize tokens that have been claimed for all time - /// @return The total amount of prize tokens that have been claimed for all time - function totalWithdrawn() external view returns (uint256) { - return _totalWithdrawn; - } - - /// @notice Computes how many tokens have been accounted for - /// @return The balance of tokens that have been accounted for - function accountedBalance() external view returns (uint256) { - return _accountedBalance(); - } - - /// @notice Returns the start time of the last completed draw. If there was no completed draw, then it will be zero. - /// @return The start time of the last completed draw - function lastCompletedDrawStartedAt() external view returns (uint64) { - return lastCompletedDrawId != 0 ? _lastCompletedDrawStartedAt : 0; - } - - /// @notice Returns the end time of the last completed draw. If there was no completed draw, then it will be zero. - /// @return The end time of the last completed draw - function lastCompletedDrawEndedAt() external view returns (uint64) { - return lastCompletedDrawId != 0 ? _lastCompletedDrawStartedAt + drawPeriodSeconds : 0; - } - - /// @notice Returns the time at which the last completed draw was awarded. - /// @return The time at which the last completed draw was awarded - function lastCompletedDrawAwardedAt() external view returns (uint64) { - return lastCompletedDrawId != 0 ? _lastCompletedDrawAwardedAt : 0; - } - // @notice Allows the Manager to withdraw tokens from the reserve /// @param _to The address to send the tokens to /// @param _amount The amount of tokens to withdraw @@ -414,73 +337,6 @@ contract PrizePool is TieredLiquidityDistributor { emit WithdrawReserve(_to, _amount); } - /// @notice Returns whether the next draw has finished - function hasNextDrawFinished() external view returns (bool) { - return block.timestamp >= _nextDrawEndsAt(); - } - - /// @notice Returns the start time of the draw for the next successful completeAndStartNextDraw - function nextDrawStartsAt() external view returns (uint64) { - return _nextDrawStartsAt(); - } - - /// @notice Returns the time at which the next draw ends - function nextDrawEndsAt() external view returns (uint64) { - return _nextDrawEndsAt(); - } - - /// @notice Returns the start time of the draw for the next successful completeAndStartNextDraw - function _nextDrawStartsAt() internal view returns (uint64) { - return _nextDrawEndsAt() - drawPeriodSeconds; - } - - /// @notice Returns the time at which the next draw end. - function _nextDrawEndsAt() internal view returns (uint64) { - // If this is the first draw, we treat _lastCompletedDrawStartedAt as the start of this draw - uint64 _nextExpectedEndTime = _lastCompletedDrawStartedAt + - (lastCompletedDrawId == 0 ? 1 : 2) * - drawPeriodSeconds; - - if (block.timestamp > _nextExpectedEndTime) { - // Use integer division to get the number of draw periods passed between the expected end time and now - // Offset the end time by the total duration of the missed draws - // drawPeriodSeconds * numMissedDraws - _nextExpectedEndTime += - drawPeriodSeconds * - (uint64((block.timestamp - _nextExpectedEndTime) / drawPeriodSeconds)); - } - - return _nextExpectedEndTime; - } - - function _computeNextNumberOfTiers(uint8 _numTiers) internal view returns (uint8) { - UD2x18 _claimExpansionThreshold = claimExpansionThreshold; - - uint8 _nextNumberOfTiers = largestTierClaimed + 2; // canary tier, then length - _nextNumberOfTiers = _nextNumberOfTiers > MINIMUM_NUMBER_OF_TIERS - ? _nextNumberOfTiers - : MINIMUM_NUMBER_OF_TIERS; - - // check to see if we need to expand the number of tiers - if (_nextNumberOfTiers >= _numTiers) { - if ( - canaryClaimCount >= - fromUD60x18( - intoUD60x18(_claimExpansionThreshold).mul(_canaryPrizeCountFractional(_numTiers).floor()) - ) && - claimCount >= - fromUD60x18( - intoUD60x18(_claimExpansionThreshold).mul(toUD60x18(_estimatedPrizeCount(_numTiers))) - ) - ) { - // increase the number of tiers to include a new tier - _nextNumberOfTiers = _numTiers + 1; - } - } - - return _nextNumberOfTiers; - } - /// @notice Allows the Manager to complete the current prize period and starts the next one, updating the number of tiers, the winning random number, and the prize pool reserve /// @param winningRandomNumber_ The winning random number for the current draw /// @return The ID of the completed draw @@ -525,54 +381,6 @@ contract PrizePool is TieredLiquidityDistributor { return lastCompletedDrawId; } - /// @notice Returns the amount of tokens that will be added to the reserve on the next draw. - /// @dev Intended for Draw manager to use after the draw has ended but not yet been completed. - /// @return The amount of prize tokens that will be added to the reserve - function reserveForNextDraw() external view returns (uint256) { - uint8 _numTiers = numberOfTiers; - uint8 _nextNumberOfTiers = _numTiers; - - if (lastCompletedDrawId != 0) { - _nextNumberOfTiers = _computeNextNumberOfTiers(_numTiers); - } - - (, uint104 newReserve, ) = _computeNewDistributions( - _numTiers, - _nextNumberOfTiers, - uint96(_contributionsForDraw(lastCompletedDrawId + 1)) - ); - - return newReserve; - } - - /// @notice Computes the tokens to be disbursed from the accumulator for a given draw. - function _contributionsForDraw(uint16 _drawId) internal view returns (uint256) { - return - DrawAccumulatorLib.getDisbursedBetween( - totalAccumulator, - _drawId, - _drawId, - smoothing.intoSD59x18() - ); - } - - /// @notice Calculates the total liquidity available for the current completed draw. - function getTotalContributionsForCompletedDraw() external view returns (uint256) { - return _contributionsForDraw(lastCompletedDrawId); - } - - /// @notice Returns whether the winner has claimed the tier for the last completed draw - /// @param _winner The account to check - /// @param _tier The tier to check - /// @return True if the winner claimed the tier for the current draw, false otherwise. - function wasClaimed( - address _winner, - uint8 _tier, - uint32 _prizeIndex - ) external view returns (bool) { - return claimedPrizes[_winner][lastCompletedDrawId][_tier][_prizeIndex]; - } - /** @dev Claims a prize for a given winner and tier. This function takes in an address _winner, a uint8 _tier, a uint96 _fee, and an @@ -668,11 +476,6 @@ contract PrizePool is TieredLiquidityDistributor { return tierLiquidity.prizeSize; } - function _transfer(address _to, uint256 _amount) internal { - _totalWithdrawn += _amount; - prizeToken.safeTransfer(_to, _amount); - } - /** * @notice Withdraws the claim fees for the caller. * @param _to The address to transfer the claim fees to. @@ -690,6 +493,140 @@ contract PrizePool is TieredLiquidityDistributor { emit WithdrawClaimRewards(_to, _amount, _available); } + /* ============ External Read Functions ============ */ + + /// @notice Returns the winning random number for the last completed draw. + /// @return The winning random number + function getWinningRandomNumber() external view returns (uint256) { + return _winningRandomNumber; + } + + /// @notice Returns the last completed draw id. + /// @return The last completed draw id + function getLastCompletedDrawId() external view returns (uint256) { + return lastCompletedDrawId; + } + + /// @notice Returns the total prize tokens contributed between the given draw ids, inclusive. Note that this is after smoothing is applied. + /// @return The total prize tokens contributed by all vaults + function getTotalContributedBetween( + uint16 _startDrawIdInclusive, + uint16 _endDrawIdInclusive + ) external view returns (uint256) { + return + DrawAccumulatorLib.getDisbursedBetween( + totalAccumulator, + _startDrawIdInclusive, + _endDrawIdInclusive, + smoothing.intoSD59x18() + ); + } + + /// @notice Returns the total prize tokens contributed by a particular vault between the given draw ids, inclusive. Note that this is after smoothing is applied. + /// @return The total prize tokens contributed by the given vault + function getContributedBetween( + address _vault, + uint16 _startDrawIdInclusive, + uint16 _endDrawIdInclusive + ) external view returns (uint256) { + return + DrawAccumulatorLib.getDisbursedBetween( + vaultAccumulator[_vault], + _startDrawIdInclusive, + _endDrawIdInclusive, + smoothing.intoSD59x18() + ); + } + + /// @notice Returns the + /// @return The number of draws + function getTierAccrualDurationInDraws(uint8 _tier) external view returns (uint16) { + return + uint16(TierCalculationLib.estimatePrizeFrequencyInDraws(_tierOdds(_tier, numberOfTiers))); + } + + /// @notice The total amount of prize tokens that have been claimed for all time + /// @return The total amount of prize tokens that have been claimed for all time + function totalWithdrawn() external view returns (uint256) { + return _totalWithdrawn; + } + + /// @notice Computes how many tokens have been accounted for + /// @return The balance of tokens that have been accounted for + function accountedBalance() external view returns (uint256) { + return _accountedBalance(); + } + + /// @notice Returns the start time of the last completed draw. If there was no completed draw, then it will be zero. + /// @return The start time of the last completed draw + function lastCompletedDrawStartedAt() external view returns (uint64) { + return lastCompletedDrawId != 0 ? _lastCompletedDrawStartedAt : 0; + } + + /// @notice Returns the end time of the last completed draw. If there was no completed draw, then it will be zero. + /// @return The end time of the last completed draw + function lastCompletedDrawEndedAt() external view returns (uint64) { + return lastCompletedDrawId != 0 ? _lastCompletedDrawStartedAt + drawPeriodSeconds : 0; + } + + /// @notice Returns the time at which the last completed draw was awarded. + /// @return The time at which the last completed draw was awarded + function lastCompletedDrawAwardedAt() external view returns (uint64) { + return lastCompletedDrawId != 0 ? _lastCompletedDrawAwardedAt : 0; + } + + /// @notice Returns whether the next draw has finished + function hasNextDrawFinished() external view returns (bool) { + return block.timestamp >= _nextDrawEndsAt(); + } + + /// @notice Returns the start time of the draw for the next successful completeAndStartNextDraw + function nextDrawStartsAt() external view returns (uint64) { + return _nextDrawStartsAt(); + } + + /// @notice Returns the time at which the next draw ends + function nextDrawEndsAt() external view returns (uint64) { + return _nextDrawEndsAt(); + } + + /// @notice Returns the amount of tokens that will be added to the reserve on the next draw. + /// @dev Intended for Draw manager to use after the draw has ended but not yet been completed. + /// @return The amount of prize tokens that will be added to the reserve + function reserveForNextDraw() external view returns (uint256) { + uint8 _numTiers = numberOfTiers; + uint8 _nextNumberOfTiers = _numTiers; + + if (lastCompletedDrawId != 0) { + _nextNumberOfTiers = _computeNextNumberOfTiers(_numTiers); + } + + (, uint104 newReserve, ) = _computeNewDistributions( + _numTiers, + _nextNumberOfTiers, + uint96(_contributionsForDraw(lastCompletedDrawId + 1)) + ); + + return newReserve; + } + + /// @notice Calculates the total liquidity available for the current completed draw. + function getTotalContributionsForCompletedDraw() external view returns (uint256) { + return _contributionsForDraw(lastCompletedDrawId); + } + + /// @notice Returns whether the winner has claimed the tier for the last completed draw + /// @param _winner The account to check + /// @param _tier The tier to check + /// @return True if the winner claimed the tier for the current draw, false otherwise. + function wasClaimed( + address _winner, + uint8 _tier, + uint32 _prizeIndex + ) external view returns (bool) { + return claimedPrizes[_winner][lastCompletedDrawId][_tier][_prizeIndex]; + } + /** * @notice Returns the balance of fees for a given claimer * @param _claimer The claimer to retrieve the fee balance for @@ -721,6 +658,147 @@ contract PrizePool is TieredLiquidityDistributor { return _isWinner(_vault, _user, _tier, _prizeIndex, vaultPortion, tierOdds, drawDuration); } + /*** + * @notice Calculates the start and end timestamps of the time-weighted average balance (TWAB) for the specified tier. + * @param _tier The tier for which to calculate the TWAB timestamps. + * @return The start and end timestamps of the TWAB. + */ + function calculateTierTwabTimestamps( + uint8 _tier + ) external view returns (uint64 startTimestamp, uint64 endTimestamp) { + endTimestamp = _lastCompletedDrawStartedAt + drawPeriodSeconds; + + // endTimestamp - (drawDuration * drawPeriodSeconds) + startTimestamp = uint64( + endTimestamp - + TierCalculationLib.estimatePrizeFrequencyInDraws(_tierOdds(_tier, numberOfTiers)) * + drawPeriodSeconds + ); + } + + /** + * @notice Returns the time-weighted average balance (TWAB) and the TWAB total supply for the specified user in the given vault over a specified period. + * @param _vault The address of the vault for which to get the TWAB. + * @param _user The address of the user for which to get the TWAB. + * @param _drawDuration The duration of the period over which to calculate the TWAB, in number of draw periods. + * @return The TWAB and the TWAB total supply for the specified user in the given vault over the specified period. + */ + function getVaultUserBalanceAndTotalSupplyTwab( + address _vault, + address _user, + uint256 _drawDuration + ) external view returns (uint256, uint256) { + return _getVaultUserBalanceAndTotalSupplyTwab(_vault, _user, _drawDuration); + } + + /** + * @notice Returns the portion of a vault's contributions in a given draw range. + * This function takes in an address _vault, a uint16 startDrawId, and a uint16 endDrawId. + * It calculates the portion of the _vault's contributions in the given draw range by calling the internal + * _getVaultPortion function with the _vault argument, startDrawId as the drawId_ argument, + * endDrawId - startDrawId as the _durationInDraws argument, and smoothing.intoSD59x18() as the _smoothing + * argument. The function then returns the resulting SD59x18 value representing the portion of the + * vault's contributions. + * @param _vault The address of the vault to calculate the contribution portion for. + * @param _startDrawId The starting draw ID of the draw range to calculate the contribution portion for. + * @param _endDrawId The ending draw ID of the draw range to calculate the contribution portion for. + * @return The portion of the _vault's contributions in the given draw range as an SD59x18 value. + */ + function getVaultPortion( + address _vault, + uint16 _startDrawId, + uint16 _endDrawId + ) external view returns (SD59x18) { + return _getVaultPortion(_vault, _startDrawId, _endDrawId, smoothing.intoSD59x18()); + } + + /* ============ Internal Functions ============ */ + + /// @notice Computes how many tokens have been accounted for + /// @return The balance of tokens that have been accounted for + function _accountedBalance() internal view returns (uint256) { + Observation memory obs = DrawAccumulatorLib.newestObservation(totalAccumulator); + return (obs.available + obs.disbursed) - _totalWithdrawn; + } + + /// @notice Returns the start time of the draw for the next successful completeAndStartNextDraw + function _nextDrawStartsAt() internal view returns (uint64) { + return _nextDrawEndsAt() - drawPeriodSeconds; + } + + /// @notice Returns the time at which the next draw end. + function _nextDrawEndsAt() internal view returns (uint64) { + // If this is the first draw, we treat _lastCompletedDrawStartedAt as the start of this draw + uint64 _nextExpectedEndTime = _lastCompletedDrawStartedAt + + (lastCompletedDrawId == 0 ? 1 : 2) * + drawPeriodSeconds; + + if (block.timestamp > _nextExpectedEndTime) { + // Use integer division to get the number of draw periods passed between the expected end time and now + // Offset the end time by the total duration of the missed draws + // drawPeriodSeconds * numMissedDraws + _nextExpectedEndTime += + drawPeriodSeconds * + (uint64((block.timestamp - _nextExpectedEndTime) / drawPeriodSeconds)); + } + + return _nextExpectedEndTime; + } + + /// @notice Calculates the number of tiers for the next draw + /// @param _numTiers The current number of tiers + /// @return The number of tiers for the next draw + function _computeNextNumberOfTiers(uint8 _numTiers) internal view returns (uint8) { + UD2x18 _claimExpansionThreshold = claimExpansionThreshold; + + uint8 _nextNumberOfTiers = largestTierClaimed + 2; // canary tier, then length + _nextNumberOfTiers = _nextNumberOfTiers > MINIMUM_NUMBER_OF_TIERS + ? _nextNumberOfTiers + : MINIMUM_NUMBER_OF_TIERS; + + // check to see if we need to expand the number of tiers + if (_nextNumberOfTiers >= _numTiers) { + if ( + canaryClaimCount >= + fromUD60x18( + intoUD60x18(_claimExpansionThreshold).mul(_canaryPrizeCountFractional(_numTiers).floor()) + ) && + claimCount >= + fromUD60x18( + intoUD60x18(_claimExpansionThreshold).mul(toUD60x18(_estimatedPrizeCount(_numTiers))) + ) + ) { + // increase the number of tiers to include a new tier + _nextNumberOfTiers = _numTiers + 1; + } + } + + return _nextNumberOfTiers; + } + + /// @notice Computes the tokens to be disbursed from the accumulator for a given draw. + /// @param _drawId The ID of the draw to compute the disbursement for. + /// @return The amount of tokens contributed to the accumulator for the given draw. + function _contributionsForDraw(uint16 _drawId) internal view returns (uint256) { + return + DrawAccumulatorLib.getDisbursedBetween( + totalAccumulator, + _drawId, + _drawId, + smoothing.intoSD59x18() + ); + } + + /** + * @notice Transfers the given amount of prize tokens to the given address. + * @param _to The address to transfer to + * @param _amount The amount to transfer + */ + function _transfer(address _to, uint256 _amount) internal { + _totalWithdrawn += _amount; + prizeToken.safeTransfer(_to, _amount); + } + /** * @notice Checks if the given user has won the prize for the specified tier in the given vault. * @param _vault The address of the vault to check. @@ -766,6 +844,16 @@ contract PrizePool is TieredLiquidityDistributor { ); } + /** + * @notice Computes the data needed for determining a winner of a prize from a specific vault for a specific draw. + * @param _vault The address of the vault to check. + * @param _tier The tier for which the prize is to be checked. + * @param _numberOfTiers The number of tiers in the draw. + * @param _lastCompletedDrawId The ID of the last completed draw. + * @return vaultPortion The portion of the prizes that are going to this vault. + * @return tierOdds The odds of winning the prize for the given tier. + * @return drawDuration The duration of the draw. + */ function _computeVaultTierDetails( address _vault, uint8 _tier, @@ -789,24 +877,6 @@ contract PrizePool is TieredLiquidityDistributor { ); } - /*** - * @notice Calculates the start and end timestamps of the time-weighted average balance (TWAB) for the specified tier. - * @param _tier The tier for which to calculate the TWAB timestamps. - * @return The start and end timestamps of the TWAB. - */ - function calculateTierTwabTimestamps( - uint8 _tier - ) external view returns (uint64 startTimestamp, uint64 endTimestamp) { - endTimestamp = _lastCompletedDrawStartedAt + drawPeriodSeconds; - - // endTimestamp - (drawDuration * drawPeriodSeconds) - startTimestamp = uint64( - endTimestamp - - TierCalculationLib.estimatePrizeFrequencyInDraws(_tierOdds(_tier, numberOfTiers)) * - drawPeriodSeconds - ); - } - /** * @notice Returns the time-weighted average balance (TWAB) and the TWAB total supply for the specified user in the given vault over a specified period. * @dev This function calculates the TWAB for a user by calling the getTwabBetween function of the TWAB controller for a specified period of time. @@ -833,21 +903,6 @@ contract PrizePool is TieredLiquidityDistributor { ); } - /** - * @notice Returns the time-weighted average balance (TWAB) and the TWAB total supply for the specified user in the given vault over a specified period. - * @param _vault The address of the vault for which to get the TWAB. - * @param _user The address of the user for which to get the TWAB. - * @param _drawDuration The duration of the period over which to calculate the TWAB, in number of draw periods. - * @return The TWAB and the TWAB total supply for the specified user in the given vault over the specified period. - */ - function getVaultUserBalanceAndTotalSupplyTwab( - address _vault, - address _user, - uint256 _drawDuration - ) external view returns (uint256, uint256) { - return _getVaultUserBalanceAndTotalSupplyTwab(_vault, _user, _drawDuration); - } - /** * @notice Calculates the portion of the vault's contribution to the prize pool over a specified duration in draws. * @param _vault The address of the vault for which to calculate the portion. @@ -886,25 +941,4 @@ contract PrizePool is TieredLiquidityDistributor { return sd(0); } } - - /** - @notice Returns the portion of a vault's contributions in a given draw range. - This function takes in an address _vault, a uint16 startDrawId, and a uint16 endDrawId. - It calculates the portion of the _vault's contributions in the given draw range by calling the internal - _getVaultPortion function with the _vault argument, startDrawId as the drawId_ argument, - endDrawId - startDrawId as the _durationInDraws argument, and smoothing.intoSD59x18() as the _smoothing - argument. The function then returns the resulting SD59x18 value representing the portion of the - vault's contributions. - @param _vault The address of the vault to calculate the contribution portion for. - @param _startDrawId The starting draw ID of the draw range to calculate the contribution portion for. - @param _endDrawId The ending draw ID of the draw range to calculate the contribution portion for. - @return The portion of the _vault's contributions in the given draw range as an SD59x18 value. - */ - function getVaultPortion( - address _vault, - uint16 _startDrawId, - uint16 _endDrawId - ) external view returns (SD59x18) { - return _getVaultPortion(_vault, _startDrawId, _endDrawId, smoothing.intoSD59x18()); - } } diff --git a/src/abstract/TieredLiquidityDistributor.sol b/src/abstract/TieredLiquidityDistributor.sol index 8d086a9..156f541 100644 --- a/src/abstract/TieredLiquidityDistributor.sol +++ b/src/abstract/TieredLiquidityDistributor.sol @@ -10,14 +10,14 @@ import { SD1x18, unwrap, UNIT } from "prb-math/SD1x18.sol"; import { UD34x4, fromUD60x18 as fromUD60x18toUD34x4, intoUD60x18 as fromUD34x4toUD60x18, toUD34x4 } from "../libraries/UD34x4.sol"; import { TierCalculationLib } from "../libraries/TierCalculationLib.sol"; -/// @notice Struct that tracks tier liquidity information +/// @notice Struct that tracks tier liquidity information. struct Tier { uint16 drawId; uint96 prizeSize; UD34x4 prizeTokenPerShare; } -/// @notice Emitted when the number of tiers is less than the minimum number of tiers +/// @notice Emitted when the number of tiers is less than the minimum number of tiers. /// @param numTiers The invalid number of tiers error NumberOfTiersLessThanMinimum(uint8 numTiers); @@ -46,11 +46,12 @@ contract TieredLiquidityDistributor { UD60x18 internal immutable CANARY_PRIZE_COUNT_FOR_14_TIERS; //////////////////////// START GENERATED CONSTANTS //////////////////////// - // Constants are precomputed using the script/generateConstants.s.sol script. + // The following constants are precomputed using the script/generateConstants.s.sol script. /// @notice The number of draws that should statistically occur between grand prizes. uint16 internal constant GRAND_PRIZE_PERIOD_DRAWS = 365; + /// @notice The estiamted number of prizes given X tiers. uint32 internal constant ESTIMATED_PRIZES_PER_DRAW_FOR_2_TIERS = 4; uint32 internal constant ESTIMATED_PRIZES_PER_DRAW_FOR_3_TIERS = 16; uint32 internal constant ESTIMATED_PRIZES_PER_DRAW_FOR_4_TIERS = 66; @@ -65,6 +66,7 @@ contract TieredLiquidityDistributor { uint32 internal constant ESTIMATED_PRIZES_PER_DRAW_FOR_13_TIERS = 19805536; uint32 internal constant ESTIMATED_PRIZES_PER_DRAW_FOR_14_TIERS = 79777187; + /// @notice The odds for each tier and number of tiers pair. SD59x18 internal constant TIER_ODDS_0_3 = SD59x18.wrap(2739726027397260); SD59x18 internal constant TIER_ODDS_1_3 = SD59x18.wrap(52342392259021369); SD59x18 internal constant TIER_ODDS_2_3 = SD59x18.wrap(1000000000000000000); @@ -201,32 +203,32 @@ contract TieredLiquidityDistributor { //////////////////////// END GENERATED CONSTANTS //////////////////////// - /// @notice The Tier liquidity data + /// @notice The Tier liquidity data. mapping(uint8 => Tier) internal _tiers; - /// @notice The number of shares to allocate to each prize tier + /// @notice The number of shares to allocate to each prize tier. uint8 public immutable tierShares; - /// @notice The number of shares to allocate to the canary tier + /// @notice The number of shares to allocate to the canary tier. uint8 public immutable canaryShares; - /// @notice The number of shares to allocate to the reserve + /// @notice The number of shares to allocate to the reserve. uint8 public immutable reserveShares; - /// @notice The current number of prize tokens per share + /// @notice The current number of prize tokens per share. UD34x4 public prizeTokenPerShare; /// @notice The number of tiers for the last completed draw. The last tier is the canary tier. uint8 public numberOfTiers; - /// @notice The draw id of the last completed draw + /// @notice The draw id of the last completed draw. uint16 internal lastCompletedDrawId; - /// @notice The amount of available reserve + /// @notice The amount of available reserve. uint104 internal _reserve; /** - * @notice Constructs a new Prize Pool + * @notice Constructs a new Prize Pool. * @param _numberOfTiers The number of tiers to start with. Must be greater than or equal to the minimum number of tiers. * @param _tierShares The number of shares to allocate to each tier * @param _canaryShares The number of shares to allocate to the canary tier. @@ -322,7 +324,7 @@ contract TieredLiquidityDistributor { } } - /// @notice Adjusts the number of tiers and distributes new liquidity + /// @notice Adjusts the number of tiers and distributes new liquidity. /// @param _nextNumberOfTiers The new number of tiers. Must be greater than minimum /// @param _prizeTokenLiquidity The amount of fresh liquidity to distribute across the tiers and reserve function _nextDraw(uint8 _nextNumberOfTiers, uint96 _prizeTokenLiquidity) internal { @@ -436,21 +438,21 @@ contract TieredLiquidityDistributor { ); } - /// @notice Returns the prize size for the given tier + /// @notice Returns the prize size for the given tier. /// @param _tier The tier to retrieve /// @return The prize size for the tier function getTierPrizeSize(uint8 _tier) external view returns (uint96) { return _getTier(_tier, numberOfTiers).prizeSize; } - /// @notice Returns the estimated number of prizes for the given tier + /// @notice Returns the estimated number of prizes for the given tier. /// @param _tier The tier to retrieve /// @return The estimated number of prizes function getTierPrizeCount(uint8 _tier) external view returns (uint32) { return _getTierPrizeCount(_tier, numberOfTiers); } - /// @notice Returns the estimated number of prizes for the given tier and number of tiers + /// @notice Returns the estimated number of prizes for the given tier and number of tiers. /// @param _tier The tier to retrieve /// @param _numberOfTiers The number of tiers, should match the current number of tiers /// @return The estimated number of prizes @@ -458,7 +460,7 @@ contract TieredLiquidityDistributor { return _getTierPrizeCount(_tier, _numberOfTiers); } - /// @notice Returns the number of available prizes for the given tier + /// @notice Returns the number of available prizes for the given tier. /// @param _tier The tier to retrieve /// @param _numberOfTiers The number of tiers, should match the current number of tiers /// @return The number of available prizes @@ -469,7 +471,7 @@ contract TieredLiquidityDistributor { : uint32(TierCalculationLib.prizeCount(_tier)); } - /// @notice Retrieves an up-to-date Tier struct for the given tier + /// @notice Retrieves an up-to-date Tier struct for the given tier. /// @param _tier The tier to retrieve /// @param _numberOfTiers The number of tiers, should match the current. Passed explicitly as an optimization /// @return An up-to-date Tier struct; if the prize is outdated then it is recomputed based on available liquidity and the draw id updated. @@ -490,13 +492,13 @@ contract TieredLiquidityDistributor { return tier; } - /// @notice Computes the total shares in the system. That is `(number of tiers * tier shares) + canary shares + reserve shares` + /// @notice Computes the total shares in the system. That is `(number of tiers * tier shares) + canary shares + reserve shares`. /// @return The total shares function getTotalShares() external view returns (uint256) { return _getTotalShares(numberOfTiers); } - /// @notice Computes the total shares in the system given the number of tiers. That is `(number of tiers * tier shares) + canary shares + reserve shares` + /// @notice Computes the total shares in the system given the number of tiers. That is `(number of tiers * tier shares) + canary shares + reserve shares`. /// @param _numberOfTiers The number of tiers to calculate the total shares for /// @return The total shares function _getTotalShares(uint8 _numberOfTiers) internal view returns (uint256) { @@ -507,7 +509,7 @@ contract TieredLiquidityDistributor { uint256(reserveShares); } - /// @notice Computes the number of shares for the given tier. If the tier is the canary tier, then the canary shares are returned. Normal tier shares otherwise. + /// @notice Computes the number of shares for the given tier. If the tier is the canary tier, then the canary shares are returned. Normal tier shares otherwise. /// @param _tier The tier to request share for /// @param _numTiers The number of tiers. Passed explicitly as an optimization /// @return The number of shares for the given tier @@ -552,7 +554,7 @@ contract TieredLiquidityDistributor { return _tierStruct; } - /// @notice Computes the prize size of the given tier + /// @notice Computes the prize size of the given tier. /// @param _tier The tier to compute the prize size of /// @param _numberOfTiers The current number of tiers /// @param _tierPrizeTokenPerShare The prizeTokenPerShare of the Tier struct @@ -586,7 +588,7 @@ contract TieredLiquidityDistributor { return prizeSize; } - /// @notice Computes the prize size with the given parameters + /// @notice Computes the prize size with the given parameters. /// @param _tierPrizeTokenPerShare The prizeTokenPerShare of the Tier struct /// @param _prizeTokenPerShare The global prizeTokenPerShare /// @param _fractionalPrizeCount The prize count as UD60x18 @@ -610,7 +612,7 @@ contract TieredLiquidityDistributor { return _tier == _numberOfTiers - 1; } - /// @notice Reclaims liquidity from tiers, starting at the highest tier + /// @notice Reclaims liquidity from tiers, starting at the highest tier. /// @param _numberOfTiers The existing number of tiers /// @param _nextNumberOfTiers The next number of tiers. Must be less than _numberOfTiers /// @return The total reclaimed liquidity @@ -645,7 +647,7 @@ contract TieredLiquidityDistributor { return fromUD60x18(reclaimedLiquidity); } - /// @notice Computes the remaining liquidity available to a tier + /// @notice Computes the remaining liquidity available to a tier. /// @param _tier The tier to compute the liquidity for /// @return The remaining liquidity function getTierRemainingLiquidity(uint8 _tier) external view returns (uint256) { @@ -660,7 +662,7 @@ contract TieredLiquidityDistributor { ); } - /// @notice Computes the remaining tier liquidity + /// @notice Computes the remaining tier liquidity. /// @param _shares The number of shares that the tier has (can be tierShares or canaryShares) /// @param _tierPrizeTokenPerShare The prizeTokenPerShare of the Tier struct /// @param _prizeTokenPerShare The global prizeTokenPerShare @@ -683,7 +685,7 @@ contract TieredLiquidityDistributor { return lastCompletedDrawId + 1; } - /// @notice Estimates the number of prizes that will be awarded + /// @notice Estimates the number of prizes that will be awarded. /// @return The estimated prize count function estimatedPrizeCount() external view returns (uint32) { return _estimatedPrizeCount(numberOfTiers); @@ -703,12 +705,15 @@ contract TieredLiquidityDistributor { return _canaryPrizeCountFractional(numTiers); } - /// @notice Computes the number of canary prizes for the last completed draw + /// @notice Computes the number of canary prizes for the last completed draw. + /// @return The number of canary prizes function canaryPrizeCount() external view returns (uint32) { return _canaryPrizeCount(numberOfTiers); } /// @notice Computes the number of canary prizes for the last completed draw + /// @param _numberOfTiers The number of tiers + /// @return The number of canary prizes function _canaryPrizeCount(uint8 _numberOfTiers) internal view returns (uint32) { return uint32(fromUD60x18(_canaryPrizeCountFractional(_numberOfTiers).floor())); } @@ -720,13 +725,13 @@ contract TieredLiquidityDistributor { return _canaryPrizeCount(_numTiers); } - /// @notice Returns the balance of the reserve + /// @notice Returns the balance of the reserve. /// @return The amount of tokens that have been reserved. function reserve() external view returns (uint256) { return _reserve; } - /// @notice Estimates the prize count for the given tier + /// @notice Estimates the prize count for the given tier. /// @param numTiers The number of prize tiers /// @return The estimated total number of prizes function _estimatedPrizeCount(uint8 numTiers) internal pure returns (uint32) { @@ -794,7 +799,7 @@ contract TieredLiquidityDistributor { return ud(0); } - /// @notice Computes the odds for a tier given the number of tiers + /// @notice Computes the odds for a tier given the number of tiers. /// @param _tier The tier to compute odds for /// @param _numTiers The number of prize tiers /// @return The odds of the tier @@ -802,7 +807,7 @@ contract TieredLiquidityDistributor { return _tierOdds(_tier, _numTiers); } - /// @notice Computes the odds for a tier given the number of tiers + /// @notice Computes the odds for a tier given the number of tiers. /// @param _tier The tier to compute odds for /// @param _numTiers The number of prize tiers /// @return The odds of the tier diff --git a/src/libraries/DrawAccumulatorLib.sol b/src/libraries/DrawAccumulatorLib.sol index f42cca7..8414a75 100644 --- a/src/libraries/DrawAccumulatorLib.sol +++ b/src/libraries/DrawAccumulatorLib.sol @@ -5,20 +5,20 @@ pragma solidity 0.8.17; import { RingBufferLib } from "ring-buffer-lib/RingBufferLib.sol"; import { E, SD59x18, sd, unwrap, toSD59x18, fromSD59x18 } from "prb-math/SD59x18.sol"; -/// @notice Emitted when adding balance for draw zero +/// @notice Emitted when adding balance for draw zero. error AddToDrawZero(); -/// @notice Emitted when an action can't be done on a closed draw +/// @notice Emitted when an action can't be done on a closed draw. /// @param drawId The ID of the closed draw /// @param newestDrawId The newest draw ID error DrawClosed(uint16 drawId, uint16 newestDrawId); -/// @notice Emitted when a draw range is not strictly increasing +/// @notice Emitted when a draw range is not strictly increasing. /// @param startDrawId The start draw ID of the range /// @param endDrawId The end draw ID of the range error InvalidDrawRange(uint16 startDrawId, uint16 endDrawId); -/// @notice Emitted when the end draw ID for a disbursed range is invalid (too old) +/// @notice Emitted when the end draw ID for a disbursed range is invalid (too old). /// @param endDrawId The end draw ID for the range error InvalidDisbursedEndDrawId(uint16 endDrawId); @@ -36,17 +36,20 @@ library DrawAccumulatorLib { /// @notice The maximum number of observations that can be recorded. uint24 internal constant MAX_CARDINALITY = 366; + /// @notice The metadata for using the ring buffer. struct RingBufferInfo { uint16 nextIndex; uint16 cardinality; } + /// @notice An accumulator for a draw. struct Accumulator { RingBufferInfo ringBufferInfo; uint16[MAX_CARDINALITY] drawRingBuffer; mapping(uint256 => Observation) observations; } + /// @notice A pair of uint16s. struct Pair32 { uint16 first; uint16 second; @@ -132,6 +135,9 @@ library DrawAccumulatorLib { return integrateInf(_alpha, _startDrawId - newestDrawId_, newestObservation_.available); } + /// @notice Returns the newest draw id from the accumulator. + /// @param accumulator The accumulator to get the newest draw id from + /// @return The newest draw id function newestDrawId(Accumulator storage accumulator) internal view returns (uint256) { return accumulator.drawRingBuffer[ @@ -139,7 +145,7 @@ library DrawAccumulatorLib { ]; } - /// @notice Retrieves the newest observation from the accumulator + /// @notice Retrieves the newest observation from the accumulator. /// @param accumulator The accumulator to retrieve the newest observation from /// @return The newest observation function newestObservation( @@ -330,7 +336,7 @@ library DrawAccumulatorLib { return amount; } - /// @notice Computes the first and last indices of observations for the given ring buffer info + /// @notice Computes the first and last indices of observations for the given ring buffer info. /// @param ringBufferInfo The ring buffer info to compute for /// @return A pair of indices, where the first is the oldest index and the second is the newest index function computeIndices( @@ -351,7 +357,7 @@ library DrawAccumulatorLib { }); } - /// @notice Retrieves the draw ids for the given accumulator observation indices + /// @notice Retrieves the draw ids for the given accumulator observation indices. /// @param accumulator The accumulator to retrieve from /// @param indices The indices to retrieve /// @return A pair of draw ids, where the first is the draw id of the pair's first index and the second is the draw id of the pair's second index @@ -366,7 +372,7 @@ library DrawAccumulatorLib { }); } - /// @notice Integrates from the given x to infinity for the exponential weighted average + /// @notice Integrates from the given x to infinity for the exponential weighted average. /// @param _alpha The exponential weighted average smoothing parameter. /// @param _x The x value to integrate from. /// @param _k The k value to scale the sum (this is the total available balance). @@ -375,7 +381,7 @@ library DrawAccumulatorLib { return uint256(fromSD59x18(computeC(_alpha, _x, _k))); } - /// @notice Integrates from the given start x to end x for the exponential weighted average + /// @notice Integrates from the given start x to end x for the exponential weighted average. /// @param _alpha The exponential weighted average smoothing parameter. /// @param _start The x value to integrate from. /// @param _end The x value to integrate to @@ -392,7 +398,7 @@ library DrawAccumulatorLib { return uint256(fromSD59x18(sd(start - end))); } - /// @notice Computes the interim value C for the EWA + /// @notice Computes the interim value C for the EWA. /// @param _alpha The exponential weighted average smoothing parameter. /// @param _x The x value to compute for /// @param _k The total available balance diff --git a/src/libraries/TierCalculationLib.sol b/src/libraries/TierCalculationLib.sol index 7384156..e237642 100644 --- a/src/libraries/TierCalculationLib.sol +++ b/src/libraries/TierCalculationLib.sol @@ -9,7 +9,7 @@ import { UD60x18, toUD60x18, fromUD60x18 } from "prb-math/UD60x18.sol"; /// @author PoolTogether Inc. Team /// @notice Provides helper functions to assist in calculating tier prize counts, frequency, and odds. library TierCalculationLib { - /// @notice Calculates the odds of a tier occurring + /// @notice Calculates the odds of a tier occurring. /// @param _tier The tier to calculate odds for /// @param _numberOfTiers The total number of tiers /// @param _grandPrizePeriod The number of draws between grand prizes @@ -26,14 +26,14 @@ library TierCalculationLib { return E.pow(_k.mul(sd(int8(_tier) - (int8(_numberOfTiers) - 1)))); } - /// @notice Estimates the number of draws between a tier occurring + /// @notice Estimates the number of draws between a tier occurring. /// @param _tierOdds The odds for the tier to calculate the frequency of /// @return The estimated number of draws between the tier occurring function estimatePrizeFrequencyInDraws(SD59x18 _tierOdds) internal pure returns (uint256) { return uint256(fromSD59x18(sd(1e18).div(_tierOdds).ceil())); } - /// @notice Computes the number of prizes for a given tier + /// @notice Computes the number of prizes for a given tier. /// @param _tier The tier to compute for /// @return The number of prizes function prizeCount(uint8 _tier) internal pure returns (uint256) { @@ -63,7 +63,7 @@ library TierCalculationLib { return multiplier.mul(toUD60x18(prizeCount(_numberOfTiers))); } - /// @notice Determines if a user won a prize tier + /// @notice Determines if a user won a prize tier. /// @param _userSpecificRandomNumber The random number to use as entropy /// @param _userTwab The user's time weighted average balance /// @param _vaultTwabTotalSupply The vault's time weighted average total supply @@ -95,7 +95,7 @@ library TierCalculationLib { return constrainedRandomNumber < winningZone; } - /// @notice Calculates a pseudo-random number that is unique to the user, tier, and winning random number + /// @notice Calculates a pseudo-random number that is unique to the user, tier, and winning random number. /// @param _user The user /// @param _tier The tier /// @param _prizeIndex The particular prize index they are checking