From ba4b59d352c8ce74a65530d1bf84d40a38f7a094 Mon Sep 17 00:00:00 2001 From: Trevor Richard Date: Thu, 27 Jun 2024 16:15:15 +0000 Subject: [PATCH] enforce minimum draw timeout and clarify natspec --- src/PrizePool.sol | 19 ++++++++++++++----- test/PrizePool.t.sol | 16 +++++++++++++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/PrizePool.sol b/src/PrizePool.sol index 4cb2971..86bb460 100644 --- a/src/PrizePool.sol +++ b/src/PrizePool.sol @@ -12,6 +12,13 @@ import { DrawAccumulatorLib, Observation, MAX_OBSERVATION_CARDINALITY } from "./ import { TieredLiquidityDistributor, Tier } from "./abstract/TieredLiquidityDistributor.sol"; import { TierCalculationLib } from "./libraries/TierCalculationLib.sol"; +/* ============ Constants ============ */ + +// The minimum draw timeout. A timeout of two is necessary to allow for enough time to close and award a draw. +uint24 constant MINIMUM_DRAW_TIMEOUT = 2; + +/* ============ Errors ============ */ + /// @notice Thrown when the prize pool is constructed with a first draw open timestamp that is in the past error FirstDrawOpensInPast(); @@ -89,8 +96,10 @@ error InvalidPrizeIndex(uint32 invalidPrizeIndex, uint32 prizeCount, uint8 tier) /// @notice Thrown when there are no awarded draws when a computation requires an awarded draw. error NoDrawsAwarded(); -/// @notice Thrown when the Prize Pool is constructed with a draw timeout of zero -error DrawTimeoutIsZero(); +/// @notice Thrown when the prize pool is initialized with an invalid draw timeout. +/// @param drawTimeout The draw timeout that was set +/// @param minimumDrawTimeout The minimum draw timeout +error InvalidDrawTimeout(uint24 drawTimeout, uint24 minimumDrawTimeout); /// @notice Thrown when the Prize Pool is constructed with a draw timeout greater than the grand prize period draws error DrawTimeoutGTGrandPrizePeriodDraws(); @@ -280,7 +289,7 @@ contract PrizePool is TieredLiquidityDistributor { /// @notice The timestamp at which the first draw will open. uint48 public immutable firstDrawOpensAt; - /// @notice The maximum number of draws that can be missed before the prize pool is considered inactive. + /// @notice The maximum number of draws that can pass since the last awarded draw before the prize pool is considered inactive. uint24 public immutable drawTimeout; /// @notice The address that is allowed to set the draw manager @@ -335,8 +344,8 @@ contract PrizePool is TieredLiquidityDistributor { params.grandPrizePeriodDraws ) { - if (params.drawTimeout == 0) { - revert DrawTimeoutIsZero(); + if (params.drawTimeout < MINIMUM_DRAW_TIMEOUT) { + revert InvalidDrawTimeout(params.drawTimeout, MINIMUM_DRAW_TIMEOUT); } if (params.drawTimeout > params.grandPrizePeriodDraws) { diff --git a/test/PrizePool.t.sol b/test/PrizePool.t.sol index 100ab30..3ddd913 100644 --- a/test/PrizePool.t.sol +++ b/test/PrizePool.t.sol @@ -20,7 +20,8 @@ import { PrizeIsZero, ConstructorParams, InsufficientRewardsError, - DrawTimeoutIsZero, + InvalidDrawTimeout, + MINIMUM_DRAW_TIMEOUT, DrawTimeoutGTGrandPrizePeriodDraws, PrizePoolNotShutdown, DidNotWin, @@ -160,9 +161,18 @@ contract PrizePoolTest is Test { assertEq(prizePool.drawPeriodSeconds(), drawPeriodSeconds); } - function testDrawTimeoutIsZero() public { + function testInvalidDrawTimeout() public { params.drawTimeout = 0; - vm.expectRevert(abi.encodeWithSelector(DrawTimeoutIsZero.selector)); + vm.expectRevert(abi.encodeWithSelector(InvalidDrawTimeout.selector, 0, 2)); + new PrizePool(params); + + params.drawTimeout = 1; + vm.expectRevert(abi.encodeWithSelector(InvalidDrawTimeout.selector, 1, 2)); + new PrizePool(params); + + assertEq(MINIMUM_DRAW_TIMEOUT, 2); // validate assumptions + params.drawTimeout = 2; + // no revert new PrizePool(params); }