Skip to content

Commit f567abf

Browse files
committed
test
1 parent bb71ed9 commit f567abf

File tree

1 file changed

+200
-13
lines changed

1 file changed

+200
-13
lines changed

src/test/integration/tests/EmissionsController.t.sol

Lines changed: 200 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ contract Integration_EmissionsController_E2E is Integration_EmissionsController_
324324
/// Invariants for pressButton
325325
/// -----------------------------------------------------------------------
326326

327-
/// @dev Assert that all distributions should succeed given valid inputs.
327+
/// @dev Assert that all distributions succeed given valid inputs.
328328
function testFuzz_addDists_pressButton_allDistributionTypes(uint24 r) public rand(r) {
329329
(uint64 startEpoch, uint16 totalWeight,) = _genRandParams();
330330

@@ -353,25 +353,212 @@ contract Integration_EmissionsController_E2E is Integration_EmissionsController_
353353
ic.pressButton(types.length);
354354
}
355355

356-
// /// @dev Assert that the function skips disabled distributions.
357-
// function testFuzz_addDists_pressButton_skipsDisabledDistributions(uint24 r) public rand(r) {}
356+
/// @dev Assert that the function skips disabled distributions.
357+
function testFuzz_addDists_pressButton_skipsDisabledDistributions(uint24 r) public rand(r) {
358+
(uint64 startEpoch, uint16 totalWeight, uint numDistributions) = _genRandParams();
359+
numDistributions = _randUint({min: 2, max: 32}); // Need at least 2 distributions
360+
361+
// Create distribution types (all enabled initially)
362+
DistributionType[] memory types = new DistributionType[](numDistributions);
363+
uint numToDisable = _randUint({min: 1, max: numDistributions - 1}); // At least 1 disabled, at least 1 enabled
364+
365+
for (uint i = 0; i < numDistributions; ++i) {
366+
types[i] = DistributionType(uint8(_randUint({min: 1, max: 5}))); // Non-disabled types
367+
}
368+
369+
// 1. Add distributions (all enabled)
370+
(uint[] memory distributionIds, Distribution[] memory distributions) =
371+
ic.addDistributionsWithTypes(operatorSets, strategies, types, startEpoch, totalWeight);
372+
check_addDists_State(distributionIds, distributions, totalWeight);
373+
374+
// 2. Update some distributions to disabled
375+
for (uint i = 0; i < numToDisable; ++i) {
376+
distributions[i].distributionType = DistributionType.Disabled;
377+
cheats.prank(incentiveCouncil);
378+
emissionsController.updateDistribution(distributionIds[i], distributions[i]);
379+
}
380+
381+
// Note: Disabling distributions doesn't change totalWeight - it just affects processing
382+
check_addDists_State(distributionIds, distributions, totalWeight);
383+
384+
// 3. Warp to start epoch
385+
ic.warpToEpoch(startEpoch);
386+
check_warpToEpoch_State(startEpoch);
387+
388+
// 4. Press button - should only process non-disabled distributions
389+
uint processed = ic.pressButton(numDistributions);
390+
uint expectedProcessed = numDistributions - numToDisable;
391+
assertEq(processed, expectedProcessed, "Should skip disabled distributions");
392+
}
393+
394+
/// @dev Assert that the function skips distributions that have not started yet.
395+
function testFuzz_addDists_pressButton_skipsNotYetStartedDistributions(uint24 r) public rand(r) {
396+
(uint64 startEpoch, uint16 totalWeight, uint numDistributions) = _genRandParams();
397+
numDistributions = _randUint({min: 2, max: 32}); // Need at least 2 distributions
398+
startEpoch = uint64(_randUint({min: 2, max: 2**12 - 1})); // Ensure startEpoch > 0
399+
400+
// Generate random distribution types (non-disabled)
401+
DistributionType[] memory types = new DistributionType[](numDistributions);
402+
for (uint i = 0; i < numDistributions; ++i) {
403+
types[i] = DistributionType(uint8(_randUint({min: 1, max: 5})));
404+
}
405+
406+
// 1. Add distributions with staggered start epochs
407+
(uint[] memory distributionIds, Distribution[] memory distributions) =
408+
ic.addDistributionsWithTypes(operatorSets, strategies, types, startEpoch, totalWeight);
409+
410+
// Manually update some distributions to have later start epochs
411+
uint numLaterStart = _randUint({min: 1, max: numDistributions - 1});
412+
for (uint i = 0; i < numLaterStart; ++i) {
413+
distributions[i].startEpoch = startEpoch + 1; // Start one epoch later
414+
cheats.prank(incentiveCouncil);
415+
emissionsController.updateDistribution(distributionIds[i], distributions[i]);
416+
}
417+
check_addDists_State(distributionIds, distributions, totalWeight);
418+
419+
// 2. Warp to start epoch (some distributions haven't started yet)
420+
ic.warpToEpoch(startEpoch);
421+
check_warpToEpoch_State(startEpoch);
422+
423+
// 3. Press button - should only process distributions that have started
424+
uint processed = ic.pressButton(numDistributions);
425+
uint expectedProcessed = numDistributions - numLaterStart;
426+
assertEq(processed, expectedProcessed, "Should skip distributions that haven't started");
427+
}
428+
429+
/// @dev Assert that the function skips distributions that have ended.
430+
function testFuzz_addDists_pressButton_skipsEndedDistributions(uint24 r) public rand(r) {
431+
(uint64 startEpoch, uint16 totalWeight, uint numDistributions) = _genRandParams();
432+
numDistributions = _randUint({min: 2, max: 32}); // Need at least 2 distributions
433+
startEpoch = uint64(_randUint({min: 1, max: 100})); // Keep epochs reasonable
434+
435+
// Generate random distribution types (non-disabled)
436+
DistributionType[] memory types = new DistributionType[](numDistributions);
437+
for (uint i = 0; i < numDistributions; ++i) {
438+
types[i] = DistributionType(uint8(_randUint({min: 1, max: 5})));
439+
}
440+
441+
// 1. Add distributions (all have totalEpochs = 1 by default, meaning they end after first epoch)
442+
(uint[] memory distributionIds, Distribution[] memory distributions) =
443+
ic.addDistributionsWithTypes(operatorSets, strategies, types, startEpoch, totalWeight);
444+
445+
// Update some distributions to have totalEpochs = 0 (infinite, so they DON'T end)
446+
// The rest keep totalEpochs = 1 (end after startEpoch)
447+
uint numInfinite = _randUint({min: 1, max: numDistributions - 1});
448+
for (uint i = 0; i < numInfinite; ++i) {
449+
distributions[i].totalEpochs = 0; // Infinite - will be active in all epochs
450+
cheats.prank(incentiveCouncil);
451+
emissionsController.updateDistribution(distributionIds[i], distributions[i]);
452+
}
453+
uint numTimeLimited = numDistributions - numInfinite;
454+
check_addDists_State(distributionIds, distributions, totalWeight);
455+
456+
// 2. Warp to the first epoch where time-limited distributions are active
457+
ic.warpToEpoch(startEpoch);
458+
check_warpToEpoch_State(startEpoch);
459+
460+
// 3. Press button - all distributions should be processed
461+
uint processed = ic.pressButton(numDistributions);
462+
assertEq(processed, numDistributions, "All distributions should be processed in their start epoch");
463+
464+
// 4. Verify button is not pressable (all distributions processed for this epoch)
465+
assertFalse(emissionsController.isButtonPressable(), "Button should not be pressable after all distributions processed");
466+
467+
// 5. Warp to the next epoch where time-limited distributions have ended
468+
// Distributions with totalEpochs = 1 end when currentEpoch >= startEpoch + totalEpochs
469+
// i.e., currentEpoch >= startEpoch + 1
470+
ic.warpToEpoch(startEpoch + 1);
471+
check_warpToEpoch_State(startEpoch + 1);
472+
473+
// 6. Press button - should skip ended distributions
474+
// In the new epoch, only infinite distributions (totalEpochs = 0) should be processed
475+
// Time-limited distributions (totalEpochs = 1) have ended
476+
processed = ic.pressButton(numDistributions);
477+
assertEq(processed, numInfinite, "Should skip ended distributions and only process infinite ones");
478+
}
479+
480+
/// @dev Assert that the function skips distributions with zero weight.
481+
function testFuzz_addDists_pressButton_skipsZeroWeightDistributions(uint24 r) public rand(r) {
482+
(uint64 startEpoch, uint16 totalWeight, uint numDistributions) = _genRandParams();
483+
numDistributions = _randUint({min: 2, max: 32}); // Need at least 2 distributions
484+
485+
// Generate random distribution types (non-disabled)
486+
DistributionType[] memory types = new DistributionType[](numDistributions);
487+
for (uint i = 0; i < numDistributions; ++i) {
488+
types[i] = DistributionType(uint8(_randUint({min: 1, max: 5})));
489+
}
490+
491+
// 1. Add distributions
492+
(uint[] memory distributionIds, Distribution[] memory distributions) =
493+
ic.addDistributionsWithTypes(operatorSets, strategies, types, startEpoch, totalWeight);
494+
495+
// Update some distributions to have zero weight
496+
uint numZeroWeight = _randUint({min: 1, max: numDistributions - 1});
497+
for (uint i = 0; i < numZeroWeight; ++i) {
498+
distributions[i].weight = 0;
499+
cheats.prank(incentiveCouncil);
500+
emissionsController.updateDistribution(distributionIds[i], distributions[i]);
501+
}
502+
503+
// Recalculate expected totalWeight after zero-weight updates
504+
uint16 expectedTotalWeight = 0;
505+
for (uint i = 0; i < distributions.length; ++i) {
506+
expectedTotalWeight += uint16(distributions[i].weight);
507+
}
508+
check_addDists_State(distributionIds, distributions, expectedTotalWeight);
509+
510+
// 2. Warp to start epoch
511+
ic.warpToEpoch(startEpoch);
512+
check_warpToEpoch_State(startEpoch);
513+
514+
// 3. Press button - should skip zero-weight distributions
515+
// Note: Zero-weight distributions don't emit DistributionProcessed events
516+
uint processed = ic.pressButton(numDistributions);
517+
uint expectedProcessed = numDistributions - numZeroWeight;
518+
assertEq(processed, expectedProcessed, "Should skip zero-weight distributions");
519+
}
358520

359-
// /// @dev Assert that the function skips distributions that have not started yet.
360-
// function testFuzz_addDists_pressButton_skipsNotYetStartedDistributions(uint24 r) public rand(r) {}
521+
/// @dev Assert that the function processes zero distributions when length is zero.
522+
function testFuzz_addDists_pressButtonLengthZero_NoneProcessed(uint24 r) public rand(r) {
523+
(uint64 startEpoch, uint16 totalWeight, uint numDistributions) = _genRandParams();
361524

362-
// /// @dev Assert that the function skips distributions that have ended.
363-
// function testFuzz_addDists_pressButton_skipsEndedDistributions(uint24 r) public rand(r) {}
525+
// 1. Add distributions
526+
(uint[] memory distributionIds, Distribution[] memory distributions) =
527+
ic.addDistributions(operatorSets, strategies, numDistributions, startEpoch, totalWeight);
528+
check_addDists_State(distributionIds, distributions, totalWeight);
529+
530+
// 2. Warp to start epoch
531+
ic.warpToEpoch(startEpoch);
532+
check_warpToEpoch_State(startEpoch);
364533

365-
// /// @dev Assert that the function skips distributions with zero weight.
366-
// function testFuzz_addDists_pressButton_skipsZeroWeightDistributions(uint24 r) public rand(r) {}
534+
// 3. Press button with length 0 - should process zero distributions
535+
uint processed = ic.pressButton(0);
536+
assertEq(processed, 0, "Should process zero distributions when length is zero");
367537

368-
// /// @dev Assert that the function processes zero distributions when length is zero.
369-
// function testFuzz_addDists_pressButtonLengthZero_NoneProcessed(uint24 r) public rand(r) {}
538+
// 4. Button should still be pressable since distributions remain
539+
assertTrue(emissionsController.isButtonPressable(), "Button should still be pressable");
540+
}
370541

371542
/// -----------------------------------------------------------------------
372543
/// Edge cases
373544
/// -----------------------------------------------------------------------
374545

375-
// /// @dev Assert that the function processes zero distributions when there are no distributions.
376-
// function testFuzz_noDistributions_pressButton_NoneProcessed_sweep_AllEmissionsShouldBeSwept(uint24 r) public rand(r) {}
546+
/// @dev Assert that sweep returns false when there are no distributions and no emissions minted.
547+
function testFuzz_noDistributions_pressButton_NoneProcessed_sweep_AllEmissionsShouldBeSwept(uint24 r) public rand(r) {
548+
uint64 startEpoch = uint64(_randUint({min: 0, max: 100}));
549+
550+
// 1. Warp to start epoch (no distributions added)
551+
ic.warpToEpoch(startEpoch);
552+
check_warpToEpoch_State(startEpoch);
553+
554+
// 2. When there are no distributions, pressButton should revert with AllDistributionsProcessed
555+
// because totalProcessable = 0 and totalProcessed = 0 (i.e., all 0 distributions are "processed")
556+
vm.expectRevert(IEmissionsControllerErrors.AllDistributionsProcessed.selector);
557+
ic.pressButton(1);
558+
559+
// 3. Sweep - since pressButton was never successfully called, no emissions were minted,
560+
// so sweep should return false (nothing to sweep)
561+
bool swept = ic.sweep();
562+
assertFalse(swept, "Should not sweep when no emissions were minted");
563+
}
377564
}

0 commit comments

Comments
 (0)