Skip to content

Commit

Permalink
Add invariant scenario for multiple fund treasury (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
prateek105 authored Aug 16, 2023
1 parent 42bb2ca commit 86bd09c
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 2 deletions.
9 changes: 7 additions & 2 deletions test/invariants/handlers/Handler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ contract Handler is Test, GrantFundTestHelper {
_tokenDeployer = tokenDeployer_;

// instantiate actors
actors = _buildActors(numOfActors_, tokensToDistribute_);
address[] memory newActors = _buildActors(numOfActors_, tokensToDistribute_);
for (uint256 i = 0; i < newActors.length; ++i) {
if (newActors[i] != address(0)) actors.push(newActors[i]);
}

// set Test invariant contract
testContract = ITestBase(testContract_);
Expand Down Expand Up @@ -141,9 +144,11 @@ contract Handler is Test, GrantFundTestHelper {
actors_ = new address[](numOfActors_);
uint256 tokensDistributed = 0;

uint256 existingActors = actors.length;

for (uint256 i = 0; i < numOfActors_; ++i) {
// create actor
address actor = makeAddr(string(abi.encodePacked("Actor", Strings.toString(i))));
address actor = makeAddr(string(abi.encodePacked("Actor", Strings.toString(existingActors + i))));
actors_[i] = actor;

// transfer ajna tokens to the actor
Expand Down
49 changes: 49 additions & 0 deletions test/invariants/handlers/StandardHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,55 @@ contract StandardHandler is Handler {
}
}

function fundTreasury(uint256 actorIndex_, uint256 treasuryAmount_) external useCurrentBlock useRandomActor(actorIndex_) {
numberOfCalls['SFH.fundTreasury']++;

// bound treasury amount
treasuryAmount_ = bound(treasuryAmount_, 0, _ajna.balanceOf(_actor));

if (treasuryAmount_ == 0) return;

uint256 previousTreasury = _grantFund.treasury();

// fund treasury
changePrank(_actor);
_ajna.approve(address(_grantFund), type(uint256).max);
_grantFund.fundTreasury(treasuryAmount_);

// ensure amount is added into treasury
assertEq(_grantFund.treasury(), previousTreasury + treasuryAmount_);
}

function transferAjna(uint256 fromActorIndex_, uint256 toActorIndex_, uint256 amountToTransfer_) external useCurrentBlock useRandomActor(fromActorIndex_) {
numberOfCalls['SFH.transferAjna']++;

// bound actor
toActorIndex_ = bound(toActorIndex_, 0, actors.length - 1);
address toActor = actors[toActorIndex_];

amountToTransfer_ = bound(amountToTransfer_, 0, _ajna.balanceOf(_actor));

if (amountToTransfer_ == 0 || _actor == toActor) return;

_ajna.transfer(toActor, amountToTransfer_);
}

function addActors(uint256 noOfActorsToAdd_, uint256 tokensToDistribute_) external useCurrentBlock {
numberOfCalls['SFH.addActors']++;

// bound tokens to distribute and no of actors to add
noOfActorsToAdd_ = bound(noOfActorsToAdd_, 1, 10);
tokensToDistribute_ = bound(tokensToDistribute_, 0, _ajna.balanceOf(_tokenDeployer));

if (tokensToDistribute_ == 0) return;

address[] memory newActors = _buildActors(noOfActorsToAdd_, tokensToDistribute_);

// add new actors to actors array
for (uint256 i = 0; i < newActors.length; ++i) {
if (newActors[i] != address(0)) actors.push(newActors[i]);
}
}
/**********************************/
/*** External Utility Functions ***/
/**********************************/
Expand Down
85 changes: 85 additions & 0 deletions test/invariants/scenarios/MultipleTreasuryFundingInvariant.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

import { console } from "@std/console.sol";
import { SafeCast } from "@oz/utils/math/SafeCast.sol";

import { Maths } from "../../../src/grants/libraries/Maths.sol";

import { StandardTestBase } from "../base/StandardTestBase.sol";
import { StandardHandler } from "../handlers/StandardHandler.sol";
import { Handler } from "../handlers/Handler.sol";

contract MultipleTreasuryFundingInvariant is StandardTestBase {

// run tests against all functions, having just started a distribution period
function setUp() public virtual override {
super.setUp();

// set the list of function selectors to run
bytes4[] memory selectors = new bytes4[](11);
selectors[0] = _standardHandler.startNewDistributionPeriod.selector;
selectors[1] = _standardHandler.propose.selector;
selectors[2] = _standardHandler.screeningVote.selector;
selectors[3] = _standardHandler.fundingVote.selector;
selectors[4] = _standardHandler.updateSlate.selector;
selectors[5] = _standardHandler.execute.selector;
selectors[6] = _standardHandler.claimDelegateReward.selector;
selectors[7] = _standardHandler.roll.selector;
selectors[8] = _standardHandler.fundTreasury.selector;
selectors[9] = _standardHandler.transferAjna.selector;
selectors[10] = _standardHandler.addActors.selector;

// ensure utility functions are excluded from the invariant runs
targetSelector(FuzzSelector({
addr: address(_standardHandler),
selectors: selectors
}));

// update scenarioType to fast to have larger rolls
_standardHandler.setCurrentScenarioType(Handler.ScenarioType.Fast);

vm.roll(block.number + 100);
currentBlock = block.number;
}

function invariant_all() external useCurrentBlock {
// screening invariants
_invariant_SS1_SS3_SS4_SS5_SS6_SS7_SS8_SS10_SS11_P1_P2(_grantFund, _standardHandler);
_invariant_SS2_SS4_SS9(_grantFund, _standardHandler);

// funding invariants
_invariant_FS1_FS2_FS3(_grantFund, _standardHandler);
_invariant_FS4_FS5_FS6_FS7_FS8(_grantFund, _standardHandler);

// finalize invariants
_invariant_CS1_CS2_CS3_CS4_CS5_CS6_CS7(_grantFund, _standardHandler);
_invariant_ES1_ES2_ES3_ES4_ES5(_grantFund, _standardHandler);
_invariant_DR1_DR2_DR3_DR4_DR5(_grantFund, _standardHandler);

// distribution period invariants
_invariant_DP1_DP2_DP3_DP4_DP5(_grantFund, _standardHandler);
_invariant_DP6(_grantFund, _standardHandler);
_invariant_T1_T2(_grantFund);
}

function invariant_call_summary() external useCurrentBlock {
uint24 distributionId = _grantFund.getDistributionId();

_logger.logCallSummary();
_logger.logTimeSummary();
_logger.logProposalSummary();
console.log("scenario type", uint8(_standardHandler.getCurrentScenarioType()));

while (distributionId > 0) {

_logger.logFundingSummary(distributionId);
_logger.logFinalizeSummary(distributionId);
_logger.logActorSummary(distributionId, true, true);
_logger.logActorDelegationRewards(distributionId);

--distributionId;
}
}
}

0 comments on commit 86bd09c

Please sign in to comment.