Skip to content

Commit

Permalink
Merge pull request #33 from GenerationSoftware/gen-1816-84-claims-rev…
Browse files Browse the repository at this point in the history
…ert-if-daily-prize-is-zero

Add zero-daily prize fallback fee
  • Loading branch information
trmid authored Jul 8, 2024
2 parents 7416bb3 + 9b2803a commit 52299ab
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 31 deletions.
59 changes: 28 additions & 31 deletions src/Claimer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,33 @@ contract Claimer is ReentrancyGuard {
return prizePool.getTierPrizeSize(_tier);
}
uint8 numberOfTiers = prizePool.numberOfTiers();
uint256 targetFee = _computeFeeTarget(numberOfTiers);
SD59x18 decayConstant = _computeDecayConstant(targetFee, numberOfTiers);
uint256 _maxFee = _computeMaxFee(_tier);
uint256 maxFee = _computeMaxFee(_tier);

// we expect the fee to be somewhere between the first and second canary tier prize sizes,
// so we set it to the lower of the two.
uint256 targetFee = prizePool.getTierPrizeSize(numberOfTiers - 1);

// scope to avoid stack too deep error
SD59x18 decayConstant;
{
// the fee should never need to go beyond the full daily prize size under normal operating conditions
uint256 highFee = prizePool.getTierPrizeSize(numberOfTiers - 3);

// handle the case where the target fee is zero, high fee is zero, or high fee is less than the target fee
if (targetFee == 0 || highFee < targetFee) {

// we fall back to a tier-specific ramp up from 1% of the max fee to 100% of the max fee
targetFee = maxFee / 100;
highFee = maxFee;
}
decayConstant = LinearVRGDALib.getDecayConstant(
LinearVRGDALib.getMaximumPriceDeltaScale(
targetFee,
highFee,
timeToReachMaxFee
)
);
}
SD59x18 perTimeUnit = LinearVRGDALib.getPerTimeUnit(
prizePool.estimatedPrizeCountWithBothCanaries(),
timeToReachMaxFee
Expand All @@ -235,7 +259,7 @@ contract Claimer is ReentrancyGuard {
perTimeUnit,
elapsed,
_claimedCount + i,
_maxFee
maxFee
);
}

Expand All @@ -253,33 +277,6 @@ contract Claimer is ReentrancyGuard {
}
}

/// @notice Compute the target fee for prize claims
/// @param _numberOfTiers The current number of tiers for the prize pool
/// @return The target fee for prize claims
function _computeFeeTarget(uint8 _numberOfTiers) internal view returns (uint256) {
// we expect the fee to be somewhere between the first and second canary tier prize sizes,
// so we set it to the lower of the two.
return prizePool.getTierPrizeSize(_numberOfTiers - 1);
}

/// @notice Computes the decay constant for the VRGDA.
/// @dev This is a decay constant that ensures the fee will grow from the target to the max fee within the time frame
/// @param _targetFee The target fee
/// @param _numberOfTiers The current number of tiers for the prize pool
/// @return The decay constant
function _computeDecayConstant(uint256 _targetFee, uint8 _numberOfTiers) internal view returns (SD59x18) {
// the max fee should never need to go beyond the full daily prize size under normal operating
// conditions.
uint maximumFee = prizePool.getTierPrizeSize(_numberOfTiers - 3);
return LinearVRGDALib.getDecayConstant(
LinearVRGDALib.getMaximumPriceDeltaScale(
_targetFee,
maximumFee,
timeToReachMaxFee
)
);
}

/// @notice Computes the max fee given the tier
/// @param _tier The tier to compute the max fee for
/// @return The maximum fee that will be charged for a prize claim for the given tier
Expand Down
19 changes: 19 additions & 0 deletions test/Claimer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,25 @@ contract ClaimerTest is Test {
assertEq(claimer.computeTotalFees(2, 1), PRIZE_SIZE_C1);
}

function testComputeTotalFees_zeroDailyPrize() public {
mockGetTierPrizeSize(1, 0);
mockGetTierPrizeSize(2, 0);
mockGetTierPrizeSize(3, 0);
mockPrizePool(1, -100, 0);
// even though all other prizes are zero, the claim fee for the GP should still be non-zero
assertGt(claimer.computeTotalFees(0, 1, 0), 0);
}

function testComputeTotalFees_zeroCanaryPrize() public {
mockGetTierPrizeSize(2, 0);
mockGetTierPrizeSize(3, 0);
mockPrizePool(1, -100, 0);
// even though canaries are zero, the claim fee for the GP should still be non-zero
assertGt(claimer.computeTotalFees(0, 1, 0), 0);
// even though canaries are zero, the claim fee for the daily prizes should still be non-zero
assertGt(claimer.computeTotalFees(1, 1, 0), 0);
}

function testComputeMaxFee_normalPrizes() public {
assertEq(claimer.computeMaxFee(0), PRIZE_SIZE_GP / 2);
assertEq(claimer.computeMaxFee(1), PRIZE_SIZE_DAILY / 2);
Expand Down

0 comments on commit 52299ab

Please sign in to comment.