Skip to content

Commit

Permalink
feat: Multiple stakers
Browse files Browse the repository at this point in the history
  • Loading branch information
iamsahu committed Nov 8, 2023
1 parent 63f0343 commit b79a994
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 26 deletions.
9 changes: 5 additions & 4 deletions contracts/test/invariants/Base.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ contract Base is Test, BytesGenerator {
address internal newAdmin;
address internal collector;
address internal newCollector;
address internal allower;
address public allower;
address internal newAllowlist;
address public oracleMember;
address internal bob;
Expand All @@ -97,8 +97,8 @@ contract Base is Test, BytesGenerator {
function setUp() public virtual {
deployProtocol();
deployServices();
addTargetSelectors();
excludeDeployedContracts();
addTargetSelectors();
}

function loadBlockState() public {
Expand Down Expand Up @@ -198,8 +198,10 @@ contract Base is Test, BytesGenerator {
operatorsRegistry = OperatorsRegistryV1(address(operatorsRegistryProxy));
redeemManager = RedeemManagerV1(address(redeemManagerProxy));

vm.prank(admin);
vm.startPrank(admin);
river.setCoverageFund(address(coverageFund));
oracle.addMember(oracleMember, 1);
vm.stopPrank();
}

function deployServices() internal {
Expand All @@ -216,7 +218,6 @@ contract Base is Test, BytesGenerator {
}

function dealETH(address _to, uint256 _amount) public {
console.log("dealing");
vm.deal(_to, _amount);
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/test/invariants/Invariant_river.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ contract Invariant_River is Base {

function invariant_setBalanceToDeposit() public {
uint256 balanceToDepositBefore = river.getBalanceToDeposit();
stakerService.action_stakeAmount(10 ether);
stakerService.action_stakeAmount(10 ether, 10);
uint256 balanceToDepositAfter = river.getBalanceToDeposit();

assertEq(balanceToDepositAfter, balanceToDepositBefore + 10 ether);
Expand Down
9 changes: 8 additions & 1 deletion contracts/test/invariants/handlers/BaseService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

pragma solidity 0.8.10;

import "forge-std/StdInvariant.sol";
import "forge-std/Test.sol";
import "forge-std/StdInvariant.sol";

import {Base} from "../Base.sol";

abstract contract BaseService is Test {
Expand All @@ -29,6 +30,12 @@ abstract contract BaseService is Test {
vm.stopPrank();
}

modifier prankAllower() {
vm.startPrank(base.allower());
_;
vm.stopPrank();
}

constructor(Base _base) {
base = _base;
}
Expand Down
21 changes: 18 additions & 3 deletions contracts/test/invariants/handlers/OperatorService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ contract OperatorService is BaseService, BytesGenerator {
}

function staticOperatorsSetup() internal prankAdmin {
base.oracle().addMember(base.oracleMember(), 1);

operatorOneIndex = base.operatorsRegistry().addOperator(operatorOneName, operatorOne);
operatorTwoIndex = base.operatorsRegistry().addOperator(operatorTwoName, operatorTwo);

Expand All @@ -50,7 +48,24 @@ contract OperatorService is BaseService, BytesGenerator {
}

// function getTargetSelectors() external view override returns (StdInvariant.FuzzSelector memory selectors) {
// bytes4[] memory selectorsArray = new bytes4[](1);
// selectorsArray[0] = this.action_addOperator.selector;
// selectors.selectors = selectorsArray;
// selectors.addr = address(this);
// }

// TODO: Add the dynamic operator management
// function action_addOperator() external prankAdmin recordBlockData {
// string memory operatorName = vm.toString(base.operatorsRegistry().getOperatorCount() + 1);
// uint256 operatorIndex = base.operatorsRegistry().addOperator(operatorName, makeAddr(operatorName));

// bytes memory hundredKeys = genBytes((48 + 96) * 100);
// base.operatorsRegistry().addValidators(operatorIndex, 100, hundredKeys);

// uint256[] memory operatorIndexes = new uint256[](1);
// operatorIndexes[0] = operatorIndex;
// uint32[] memory operatorLimits = new uint32[](1);
// operatorLimits[0] = 100;

// base.operatorsRegistry().setOperatorLimits(operatorIndexes, operatorLimits, block.number);
// }
}
17 changes: 15 additions & 2 deletions contracts/test/invariants/handlers/OracleDaemonService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,33 @@ import {Base} from "../Base.sol";
import {BaseService} from "./BaseService.sol";

import {IOracleManagerV1} from "../../../src/interfaces/components/IOracleManager.1.sol";

contract OracleDaemonService is BaseService {
constructor(Base _base) BaseService(_base) {}

function getTargetSelectors() external view override returns (StdInvariant.FuzzSelector memory selectors) {
bytes4[] memory selectorsArray = new bytes4[](1);
selectorsArray[0] = this.action_report.selector;
selectorsArray[0] = this.action_dummy_report.selector;

selectors.selectors = selectorsArray;
selectors.addr = address(this);
}

function action_report() external prankOracleMember {
function action_dummy_report() external prankOracleMember recordBlockData {
IOracleManagerV1.ConsensusLayerReport memory dummyReport;
dummyReport.stoppedValidatorCountPerOperator = new uint32[](1);
base.oracle().reportConsensusLayerData(dummyReport);
}

// function action_report() external prankOracleMember() recordBlockData {
// // Do we have a check about whether the report is going after the correct amount of duration
// // Do we call time skip to make the report valid?
// // Calculate epoch
// // Get validators balance
// // Get validators skimmed balance
// // Get validators exited balance
// // Get validators exiting balance
// // Get validators count
// // Get Stopped validator count per operator
// }
}
66 changes: 51 additions & 15 deletions contracts/test/invariants/handlers/StakerService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,71 @@ pragma solidity 0.8.10;
import "forge-std/Test.sol";
import "forge-std/console.sol";

import {BaseService} from "./BaseService.sol";
import {Base} from "../Base.sol";
import {BaseService} from "./BaseService.sol";

uint256 constant MAX_STAKERS = 100;

contract StakerService is BaseService {
constructor(Base _base) BaseService(_base) {}
address[] internal stakers;
address internal currentStaker;

modifier useStaker(uint256 index) {
currentStaker = stakers[bound(index, 0, MAX_STAKERS - 1)];
vm.startPrank(currentStaker);
_;
vm.stopPrank();
}

constructor(Base _base) BaseService(_base) {
allowListStakers();
}

function allowListStakers() internal prankAllower {
address[] memory stakerServiceArray = new address[](MAX_STAKERS);
uint256[] memory stakerServiceMask = new uint256[](MAX_STAKERS);

for (uint256 index = 0; index < MAX_STAKERS; index++) {
stakers.push(makeAddr(vm.toString(index)));
stakerServiceArray[index] = stakers[index];
stakerServiceMask[index] = 5;
}

base.allowlist().allow(stakerServiceArray, stakerServiceMask);
}

function getTargetSelectors() external view override returns (StdInvariant.FuzzSelector memory selectors) {
bytes4[] memory selectorsArray = new bytes4[](2);
selectorsArray[0] = this.action_stakeAll.selector;
selectorsArray[1] = this.action_unstakeAll.selector;
bytes4[] memory selectorsArray = new bytes4[](4);
selectorsArray[0] = this.action_stakeAmount.selector;
selectorsArray[1] = this.action_request_redeem.selector;
selectorsArray[2] = this.action_request_redeem_all.selector;
selectorsArray[3] = this.action_claim_redeem_request.selector;

selectors.selectors = selectorsArray;
selectors.addr = address(this);
}

function action_stakeAll() public recordBlockData {
base.dealETH(address(this), 1 ether);
console.log("Staking all funds");
base.river().deposit{value: 1 ether}();
function action_stakeAmount(uint256 amount, uint256 stakerIndex) public recordBlockData useStaker(stakerIndex) {
amount = bound(amount, 1e16, 10000 ether);
console.log("Staking amount of funds");
base.dealETH(currentStaker, amount);
base.river().deposit{value: amount}();
}

function action_unstakeAll() public recordBlockData {
function action_request_redeem(uint256 amount, uint256 stakerIndex) public recordBlockData useStaker(stakerIndex) {
amount = bound(amount, 1e16, base.river().balanceOf(currentStaker));
console.log("Unstaking");
// Keep track of the redeem requests
}

function action_request_redeem_all(uint256 stakerIndex) public recordBlockData useStaker(stakerIndex) {
console.log("Unstaking all funds");
uint256 balance = base.river().balanceOf(currentStaker);
// Keep track of the redeem requests
}

function action_stakeAmount(uint256 amount) public recordBlockData {
amount = bound(amount, 1e16, 10000 ether);
console.log("Staking amount of funds");
base.dealETH(address(this), amount);
base.river().deposit{value: amount}();
function action_claim_redeem_request(uint256 stakerIndex) public recordBlockData useStaker(stakerIndex) {
console.log("Claiming redeem request");
// Do we have a check on whether it is being done after the cooldown period?
}
}

0 comments on commit b79a994

Please sign in to comment.