forked from axieinfinity/ronin-dpos-contracts
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: hardhat test of bridge tracking
- Loading branch information
1 parent
c7170b2
commit 7e8dbae
Showing
4 changed files
with
355 additions
and
13 deletions.
There are no files selected for viewing
209 changes: 209 additions & 0 deletions
209
...bridge/integration/bridge-tracking/EpochE1_VoteIsApprovedInLastEpoch.BridgeTracking.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import { IBridgeTracking } from "@ronin/contracts/interfaces/bridge/IBridgeTracking.sol"; | ||
import { MockGatewayForTracking } from "@ronin/contracts/mocks/MockGatewayForTracking.sol"; | ||
import "../BaseIntegration.t.sol"; | ||
|
||
// Epoch e-1 test: Vote is approved in the last epoch of period | ||
contract EpochE1_VoteIsApprovedInLastEpoch_BridgeTracking_Test is BaseIntegration_Test { | ||
MockGatewayForTracking _mockRoninGatewayV3; | ||
|
||
uint256 _period; | ||
uint256 _receiptId; | ||
IBridgeTracking.VoteKind _receiptKind; | ||
address[] _operators; | ||
|
||
function setUp() public virtual override { | ||
super.setUp(); | ||
_config.switchTo(Network.RoninLocal.key()); | ||
vm.coinbase(makeAddr("coin-base-addr")); | ||
|
||
// upgrade ronin gateway v3 | ||
_mockRoninGatewayV3 = new MockGatewayForTracking(address(_bridgeTracking)); | ||
|
||
bytes memory calldata_ = | ||
abi.encodeCall(IHasContracts.setContract, (ContractType.BRIDGE, address(_mockRoninGatewayV3))); | ||
_roninProposalUtils.functionDelegateCall(address(_bridgeTracking), calldata_); | ||
|
||
vm.deal(address(_bridgeReward), 10 ether); | ||
|
||
_setTimestampToPeriodEnding(); | ||
_wrapUpEpochAndMine(); | ||
|
||
_period = _validatorSet.currentPeriod(); | ||
_receiptId = 1; | ||
_receiptKind = IBridgeTracking.VoteKind.Withdrawal; | ||
|
||
_operators.push(_param.roninBridgeManager.bridgeOperators[0]); | ||
_operators.push(_param.roninBridgeManager.bridgeOperators[1]); | ||
} | ||
|
||
// Epoch e-1: Vote & Approve & Vote > Should not record when not approved yet. Vote in last epoch (e-1). | ||
function test_epochE1_notRecordVoteAndBallot_receiptWithoutApproval() public { | ||
_mockRoninGatewayV3.sendBallot(_receiptKind, _receiptId, _operators); | ||
|
||
assertEq(_bridgeTracking.totalVote(_period), 0); | ||
assertEq(_bridgeTracking.totalBallot(_period), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), 0); | ||
} | ||
|
||
// Epoch e-1: Vote & Approve & Vote > Should not record when approve. Approve in last epoch (e-1). | ||
function test_epochE2_notRecordVoteAndBallot_approveInLastEpoch() public { | ||
test_epochE1_notRecordVoteAndBallot_receiptWithoutApproval(); | ||
|
||
_mockRoninGatewayV3.sendApprovedVote(_receiptKind, _receiptId); | ||
|
||
assertEq(_bridgeTracking.totalVote(_period), 0); | ||
assertEq(_bridgeTracking.totalBallot(_period), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), 0); | ||
} | ||
|
||
// Epoch e-1: Vote & Approve & Vote > Should not record even after approved. Vote in last epoch (e-1). | ||
function test_epochE1_notRecordVoteAndBallot_voteInLastEpoch() public { | ||
test_epochE2_notRecordVoteAndBallot_approveInLastEpoch(); | ||
|
||
_mockRoninGatewayV3.sendBallot(_receiptKind, _receiptId, wrapAddress(_param.roninBridgeManager.bridgeOperators[2])); | ||
|
||
assertEq(_bridgeTracking.totalVote(_period), 0); | ||
assertEq(_bridgeTracking.totalBallot(_period), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[2]), 0); | ||
} | ||
|
||
// Epoch e: vote > Should not record for current period metric when wrapping up period. Query in next epoch (e), for current period (p-1): return 0. | ||
function test_epochE_notRecordForCurrentPeriod_WhenWrappingUpPeriod() public { | ||
test_epochE1_notRecordVoteAndBallot_voteInLastEpoch(); | ||
|
||
_setTimestampToPeriodEnding(); | ||
_wrapUpEpochAndMine(); | ||
|
||
uint256 lastPeriod = _period; | ||
uint256 newPeriod = _validatorSet.currentPeriod(); | ||
_period = newPeriod; | ||
assertTrue(newPeriod != lastPeriod); | ||
|
||
assertEq(_bridgeTracking.totalVote(lastPeriod), 0); | ||
assertEq(_bridgeTracking.totalBallot(lastPeriod), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(lastPeriod, _param.roninBridgeManager.bridgeOperators[0]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(lastPeriod, _param.roninBridgeManager.bridgeOperators[1]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(lastPeriod, _param.roninBridgeManager.bridgeOperators[2]), 0); | ||
} | ||
|
||
// Epoch e: vote > Should record for the buffer metric when wrapping up period. Query in next epoch (e), for next period (p): return >0 (buffer). | ||
function test_epochE_recordBufferMetricForNewPeriod_WhenWrappingUpPeriod() public { | ||
test_epochE_notRecordForCurrentPeriod_WhenWrappingUpPeriod(); | ||
|
||
uint256 expectedTotalVotes = 1; | ||
assertEq(_bridgeTracking.totalVote(_period), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallot(_period), expectedTotalVotes * 3); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[2]), expectedTotalVotes); | ||
} | ||
|
||
// Epoch e: vote > Should record new ballot for the buffer metric | ||
function test_epochE_recordNewBallotForBufferMetric() public { | ||
test_epochE_recordBufferMetricForNewPeriod_WhenWrappingUpPeriod(); | ||
|
||
_mockRoninGatewayV3.sendBallot(_receiptKind, _receiptId, wrapAddress(_param.roninBridgeManager.bridgeOperators[3])); | ||
|
||
uint256 expectedTotalVotes = 1; | ||
assertEq(_bridgeTracking.totalVote(_period), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallot(_period), expectedTotalVotes * 4); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[2]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[3]), expectedTotalVotes); | ||
|
||
_wrapUpEpochAndMine(); | ||
|
||
assertEq(_bridgeTracking.totalVote(_period), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallot(_period), expectedTotalVotes * 4); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[2]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[3]), expectedTotalVotes); | ||
} | ||
|
||
// Epoch 2e-1: vote > Should record new ballot for the buffer metric | ||
function test_epoch2E_1_recordNewBallotForBufferMetric() public { | ||
test_epochE_recordNewBallotForBufferMetric(); | ||
|
||
_mockRoninGatewayV3.sendBallot(_receiptKind, _receiptId, wrapAddress(_param.roninBridgeManager.bridgeOperators[4])); | ||
|
||
uint256 expectedTotalVotes = 1; | ||
assertEq(_bridgeTracking.totalVote(_period), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallot(_period), expectedTotalVotes * 5); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[2]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[3]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[4]), expectedTotalVotes); | ||
|
||
_setTimestampToPeriodEnding(); | ||
_wrapUpEpochAndMine(); | ||
|
||
assertEq(_bridgeTracking.totalVote(_period), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallot(_period), expectedTotalVotes * 5); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[2]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[3]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[4]), expectedTotalVotes); | ||
} | ||
|
||
// Epoch 3e: vote > Should not record new ballot. And the period metric is finalized as in epoch 2e-1. | ||
function test_epoch3E_notRecordNewBallot_periodMetricIsFinalizedAsInEpoch2E_1() public { | ||
test_epoch2E_1_recordNewBallotForBufferMetric(); | ||
|
||
_mockRoninGatewayV3.sendBallot(_receiptKind, _receiptId, wrapAddress(_param.roninBridgeManager.bridgeOperators[5])); | ||
|
||
uint256 expectedTotalVotes = 1; | ||
assertEq(_bridgeTracking.totalVote(_period), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallot(_period), expectedTotalVotes * 5); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[2]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[3]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[4]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[5]), 0); | ||
} | ||
|
||
// Epoch 3e: vote > Should the metric of the new period get reset. | ||
function test_epoch3E_metricOfNewPeriodGetReset() public { | ||
test_epoch3E_notRecordNewBallot_periodMetricIsFinalizedAsInEpoch2E_1(); | ||
|
||
_setTimestampToPeriodEnding(); | ||
_wrapUpEpochAndMine(); | ||
|
||
uint256 lastPeriod = _period; | ||
uint256 newPeriod = _validatorSet.currentPeriod(); | ||
_period = newPeriod; | ||
assertTrue(newPeriod != lastPeriod); | ||
|
||
assertEq(_bridgeTracking.totalVote(newPeriod), 0); | ||
assertEq(_bridgeTracking.totalBallot(newPeriod), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[0]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[1]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[2]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[3]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[4]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[5]), 0); | ||
} | ||
|
||
function _wrapUpEpochAndMine() internal { | ||
_validatorSet.endEpoch(); | ||
vm.prank(block.coinbase); | ||
_validatorSet.wrapUpEpoch(); | ||
// mine a dummy block | ||
vm.roll(block.number + 1); | ||
} | ||
|
||
function _setTimestampToPeriodEnding() internal { | ||
vm.warp(((block.timestamp / 86400) + 1) * 86400); | ||
} | ||
} |
139 changes: 139 additions & 0 deletions
139
...dge/integration/bridge-tracking/EpochE2_VoteIsNotApprovedInLastEpoch.BridgeTracking.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import { IBridgeTracking } from "@ronin/contracts/interfaces/bridge/IBridgeTracking.sol"; | ||
import { MockGatewayForTracking } from "@ronin/contracts/mocks/MockGatewayForTracking.sol"; | ||
import "../BaseIntegration.t.sol"; | ||
|
||
// Epoch e-2 test: Vote is approved NOT in the last epoch | ||
contract EpochE2_VoteIsNotApprovedInLastEpoch_BridgeTracking_Test is BaseIntegration_Test { | ||
MockGatewayForTracking _mockRoninGatewayV3; | ||
|
||
uint256 _period; | ||
uint256 _receiptId; | ||
IBridgeTracking.VoteKind _receiptKind; | ||
address[] _operators; | ||
|
||
function setUp() public virtual override { | ||
super.setUp(); | ||
_config.switchTo(Network.RoninLocal.key()); | ||
vm.coinbase(makeAddr("coin-base-addr")); | ||
|
||
// upgrade ronin gateway v3 | ||
_mockRoninGatewayV3 = new MockGatewayForTracking(address(_bridgeTracking)); | ||
|
||
bytes memory calldata_ = | ||
abi.encodeCall(IHasContracts.setContract, (ContractType.BRIDGE, address(_mockRoninGatewayV3))); | ||
_roninProposalUtils.functionDelegateCall(address(_bridgeTracking), calldata_); | ||
|
||
vm.deal(address(_bridgeReward), 10 ether); | ||
|
||
_setTimestampToPeriodEnding(); | ||
_wrapUpEpochAndMine(); | ||
|
||
_period = _validatorSet.currentPeriod(); | ||
_receiptId = 0; | ||
_receiptKind = IBridgeTracking.VoteKind.Deposit; | ||
|
||
_operators.push(_param.roninBridgeManager.bridgeOperators[0]); | ||
_operators.push(_param.roninBridgeManager.bridgeOperators[1]); | ||
} | ||
|
||
// Epoch e-2: Vote & Approve & Vote. > Should not record the receipts which is not approved yet | ||
function test_epochE2_notRecordVoteAndBallot_receiptWithoutApproval() public { | ||
_mockRoninGatewayV3.sendBallot(_receiptKind, _receiptId, _operators); | ||
|
||
assertEq(_bridgeTracking.totalVote(_period), 0); | ||
assertEq(_bridgeTracking.totalBallot(_period), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), 0); | ||
} | ||
|
||
// Epoch e-2: Vote & Approve & Vote. > Should be able to approve the receipts and not record the approved receipts once the epoch is not yet wrapped up | ||
function test_epochE2_recordVoteAndBallot_receiptIsApproved() public { | ||
test_epochE2_notRecordVoteAndBallot_receiptWithoutApproval(); | ||
|
||
_mockRoninGatewayV3.sendApprovedVote(_receiptKind, _receiptId); | ||
assertEq(_bridgeTracking.totalVote(_period), 0); | ||
assertEq(_bridgeTracking.totalBallot(_period), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), 0); | ||
} | ||
|
||
// Epoch e-1: Continue voting for the vote of e-2 > Should be able to record the approved votes/ballots when the epoch is wrapped up | ||
function test_epochE1_continueVotingForVoteOfE2() public { | ||
test_epochE2_recordVoteAndBallot_receiptIsApproved(); | ||
|
||
_wrapUpEpochAndMine(); | ||
|
||
uint256 expectedTotalVotes = 1; | ||
assertEq(_bridgeTracking.totalVote(_period), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallot(_period), expectedTotalVotes * 2); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), expectedTotalVotes); | ||
} | ||
|
||
// Epoch e-1: Continue voting for the vote of e-2 > Should be able to record the approved votes/ballots when the epoch is wrapped up | ||
function test_epochE1_recordForWhoVoteLately_onceRequestIsApproved() public { | ||
test_epochE1_continueVotingForVoteOfE2(); | ||
|
||
_mockRoninGatewayV3.sendBallot(_receiptKind, _receiptId, wrapAddress(_param.roninBridgeManager.bridgeOperators[2])); | ||
|
||
_wrapUpEpochAndMine(); | ||
uint256 expectedTotalVotes = 1; | ||
assertEq(_bridgeTracking.totalVote(_period), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallot(_period), expectedTotalVotes * 3); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[0]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[1]), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallotOf(_period, _param.roninBridgeManager.bridgeOperators[2]), expectedTotalVotes); | ||
} | ||
|
||
// Epoch e (first epoch of new period): Continue voting for vote in e-2 > Should not record in the next period | ||
function test_epochE_continueVotingForVoteInE2_notRecordInNextPeriod() public { | ||
test_epochE1_recordForWhoVoteLately_onceRequestIsApproved(); | ||
|
||
_setTimestampToPeriodEnding(); | ||
_wrapUpEpochAndMine(); | ||
|
||
uint256 lastPeriod = _period; | ||
uint256 newPeriod = _validatorSet.currentPeriod(); | ||
assertTrue(newPeriod != lastPeriod); | ||
|
||
_mockRoninGatewayV3.sendBallot(_receiptKind, _receiptId, wrapAddress(_param.roninBridgeManager.bridgeOperators[3])); | ||
|
||
uint256 expectedTotalVotes = 1; | ||
assertEq(_bridgeTracking.totalVote(lastPeriod), expectedTotalVotes); | ||
assertEq(_bridgeTracking.totalBallot(lastPeriod), expectedTotalVotes * 3); | ||
assertEq( | ||
_bridgeTracking.totalBallotOf(lastPeriod, _param.roninBridgeManager.bridgeOperators[0]), expectedTotalVotes | ||
); | ||
assertEq( | ||
_bridgeTracking.totalBallotOf(lastPeriod, _param.roninBridgeManager.bridgeOperators[1]), expectedTotalVotes | ||
); | ||
assertEq( | ||
_bridgeTracking.totalBallotOf(lastPeriod, _param.roninBridgeManager.bridgeOperators[2]), expectedTotalVotes | ||
); | ||
assertEq(_bridgeTracking.totalBallotOf(lastPeriod, _param.roninBridgeManager.bridgeOperators[3]), 0); | ||
|
||
_period = newPeriod; | ||
|
||
assertEq(_bridgeTracking.totalVote(newPeriod), 0); | ||
assertEq(_bridgeTracking.totalBallot(newPeriod), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[0]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[1]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[2]), 0); | ||
assertEq(_bridgeTracking.totalBallotOf(newPeriod, _param.roninBridgeManager.bridgeOperators[3]), 0); | ||
} | ||
|
||
function _wrapUpEpochAndMine() internal { | ||
_validatorSet.endEpoch(); | ||
vm.prank(block.coinbase); | ||
_validatorSet.wrapUpEpoch(); | ||
// mine a dummy block | ||
vm.roll(block.number + 1); | ||
} | ||
|
||
function _setTimestampToPeriodEnding() internal { | ||
vm.warp(((block.timestamp / 86400) + 1) * 86400); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.