Skip to content

Commit

Permalink
test(medusa): property-id 2
Browse files Browse the repository at this point in the history
  • Loading branch information
0xJabberwock committed Nov 20, 2024
1 parent 730db68 commit 24f492c
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 21 deletions.
6 changes: 4 additions & 2 deletions test/invariants/handlers/BaseHandler.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {Actors} from '../helpers/Actors.t.sol';
contract BaseHandler is Setup, Actors {
// Track all created request IDs
bytes32[] internal _ghost_requests;
// Track all created request IDs per epoch and chainId
mapping(uint256 _epoch => mapping(string _chainId => bytes32[] _requestIds)) internal _ghost_requestsPerEpochChainId;

// Track request details
mapping(bytes32 _requestId => IOracle.Request _data) internal _ghost_requestData;
Expand All @@ -33,7 +35,7 @@ contract BaseHandler is Setup, Actors {
mapping(address _pledger => mapping(bytes32 _disputeId => uint256 _pledgedAmount)) internal _ghost_pledgesAgainst;

// Helper functions
function _boundEpoch(uint256 _epoch) internal view returns (uint256) {
function _boundEpoch(uint256 _epoch) internal pure returns (uint256) {
return bound(_epoch, START_EPOCH, START_EPOCH + 1000);
}

Expand All @@ -50,7 +52,7 @@ contract BaseHandler is Setup, Actors {
return chains[_seed % 3];
}

function _getRandomRequest(uint256 _seed) internal view returns (bytes32) {
function _getRandomRequestId(uint256 _seed) internal view returns (bytes32) {
if (_ghost_requests.length == 0) return bytes32(0);
return _ghost_requests[_seed % _ghost_requests.length];
}
Expand Down
6 changes: 3 additions & 3 deletions test/invariants/handlers/HandlerBondEscalationModule.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {BaseHandler, IOracle} from './BaseHandler.t.sol';

contract HandlerBondEscalationModule is BaseHandler {
function handlePledgeForDispute(uint256 _requestSeed, uint256 _disputeIndex, uint256 _actorSeed) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand All @@ -22,7 +22,7 @@ contract HandlerBondEscalationModule is BaseHandler {
}

function handlePledgeAgainstDispute(uint256 _requestSeed, uint256 _disputeIndex, uint256 _actorSeed) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand All @@ -39,7 +39,7 @@ contract HandlerBondEscalationModule is BaseHandler {
}

function handleSettleBondEscalation(uint256 _requestSeed, uint256 _disputeIndex) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand Down
2 changes: 1 addition & 1 deletion test/invariants/handlers/HandlerBondedResponseModule.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {BaseHandler, IOracle} from './BaseHandler.t.sol';

contract HandlerBondedResponseModule is BaseHandler {
function handleReleaseUnutilizedResponse(uint256 _requestSeed) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Response memory response = _getRandomActiveResponse(requestId, _requestSeed);
Expand Down
2 changes: 1 addition & 1 deletion test/invariants/handlers/HandlerCouncilArbitrator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {BaseHandler, IOracle} from './BaseHandler.t.sol';

contract HandlerCouncilArbitrator is BaseHandler {
function handleArbitrateDispute(uint256 _requestSeed, uint256 _disputeIndex, uint256 _statusSeed) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand Down
4 changes: 1 addition & 3 deletions test/invariants/handlers/HandlerEBORequestCreator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ contract HandlerEBORequestCreator is BaseHandler {
_epoch = _boundEpoch(_epoch);
string memory chainId = _generateChainId(_chainIdSeed);

// Prevent duplicate chainId for same epoch
if (_ghost_epochChainIds[_epoch][chainId]) return;

// Create request via EBORequestCreator
eboRequestCreator.createRequest(_epoch, chainId);

Expand All @@ -37,6 +34,7 @@ contract HandlerEBORequestCreator is BaseHandler {

// Track the request
_ghost_requests.push(requestId);
_ghost_requestsPerEpochChainId[_epoch][chainId].push(requestId);
_ghost_requestData[requestId] = requestData;
_ghost_validRequests[requestId] = true;
_ghost_epochChainIds[_epoch][chainId] = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ contract HandlerHorizonAccountingExtension is BaseHandler {

function handlePledge(uint256 _pledgerSeed, uint256 _requestSeed, uint256 _disputeIndex, uint256 _amount) external {
address pledger = _pickActor(_pledgerSeed);
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand All @@ -32,7 +32,7 @@ contract HandlerHorizonAccountingExtension is BaseHandler {
uint256 _amountPerPledger,
uint256 _winningPledgersLength
) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand All @@ -45,7 +45,7 @@ contract HandlerHorizonAccountingExtension is BaseHandler {
}

function handleClaimEscalationReward(uint256 _requestSeed, uint256 _disputeIndex, uint256 _actorSeed) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand All @@ -68,7 +68,7 @@ contract HandlerHorizonAccountingExtension is BaseHandler {
uint256 _usersToSlash,
uint256 _maxUsersToCheck
) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand Down
12 changes: 6 additions & 6 deletions test/invariants/handlers/HandlerOracle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {BaseHandler, IOracle} from './BaseHandler.t.sol';

contract HandlerOracle is BaseHandler {
function handleCreateRequest(uint256 _requestSeed, bytes32 _previousId) external returns (bytes32) {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return bytes32(0);

return oracle.createRequest(_ghost_requestData[requestId], _previousId);
Expand All @@ -16,7 +16,7 @@ contract HandlerOracle is BaseHandler {
uint256 _blockNumber,
uint256 _actorSeed
) external returns (bytes32) {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0) || !_ghost_validRequests[requestId]) {
return bytes32(0);
}
Expand All @@ -40,7 +40,7 @@ contract HandlerOracle is BaseHandler {
}

function handleDisputeResponseOracle(uint256 _requestSeed, uint256 _actorSeed) external returns (bytes32) {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0) || !_ghost_validRequests[requestId]) {
return bytes32(0);
}
Expand Down Expand Up @@ -70,7 +70,7 @@ contract HandlerOracle is BaseHandler {
}

function handleEscalateDispute(uint256 _requestSeed, uint256 _disputeIndex) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand All @@ -83,7 +83,7 @@ contract HandlerOracle is BaseHandler {
}

function handleResolveDispute(uint256 _requestSeed, uint256 _disputeIndex) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

IOracle.Dispute memory dispute = _getRandomDispute(requestId, _disputeIndex);
Expand All @@ -94,7 +94,7 @@ contract HandlerOracle is BaseHandler {
}

function handleFinalize(uint256 _requestSeed) external {
bytes32 requestId = _getRandomRequest(_requestSeed);
bytes32 requestId = _getRandomRequestId(_requestSeed);
if (requestId == bytes32(0)) return;

if (_ghost_activeResponses[requestId].length == 0) return;
Expand Down
38 changes: 38 additions & 0 deletions test/invariants/helpers/Utils.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ contract Utils {
}
}

function assertNotEq(uint256 a, uint256 b) internal {
assertNotEq(a, b, 'assertNotEq: a == b');
}

function assertNotEq(uint256 a, uint256 b, string memory reason) internal {
if (a == b) {
emit TestFailure(reason);
assert(false);
}
}

function assertEq(address a, address b) internal {
assertEq(a, b, 'assertEq: a != b');
}
Expand All @@ -79,6 +90,17 @@ contract Utils {
}
}

function assertNotEq(address a, address b) internal {
assertNotEq(a, b, 'assertNotEq: a == b');
}

function assertNotEq(address a, address b, string memory reason) internal {
if (a == b) {
emit TestFailure(reason);
assert(false);
}
}

function assertEq(bytes memory a, bytes memory b) internal {
assertEq(a, b, 'assertEq: a != b');
}
Expand All @@ -96,6 +118,22 @@ contract Utils {
}
}

function assertNotEq(bytes memory a, bytes memory b) internal {
assertNotEq(a, b, 'assertNotEq: a == b');
}

function assertNotEq(bytes memory a, bytes memory b, string memory reason) internal {
if (a.length == b.length) {
for (uint256 i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return;
}
}
emit TestFailure(reason);
assert(false);
}
}

function assertTrue(bool a) internal {
assertTrue(a, 'assertTrue: !a');
}
Expand Down
29 changes: 28 additions & 1 deletion test/invariants/properties/PropertyEBORequestCreator.t.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import {IEBORequestModule, IOracle} from '../Setup.t.sol';
import {HandlerParent} from '../handlers/HandlerParent.t.sol';

contract PropertyEBORequestCreator is HandlerParent {
Expand All @@ -10,9 +11,35 @@ contract PropertyEBORequestCreator is HandlerParent {
/// @custom:property-id 1
/// @custom:property Requester can always create a request as long as the same chainId/epoch isn't requested yet
function property_canAlwaysCreateRequest(uint256 _epoch, uint256 _chainIdSeed) external {
try HandlerParent(this).handleCreateRequest(_epoch, _chainIdSeed) {}
_epoch = _boundEpoch(_epoch);
string memory chainId = _generateChainId(_chainIdSeed);

// Prevent duplicate chainId for same epoch
if (_ghost_epochChainIds[_epoch][chainId]) return;

// Create request via EBORequestCreator
try eboRequestCreator.createRequest(_epoch, chainId) {}
catch {
assert(false);
}
}

/// @custom:property-id 2
/// @custom:property There can only be one active request per chainId/epoch at a time
function property_onlyOneActiveRequest(uint256 _requestIdSeed) external {
bytes32 requestId = _getRandomRequestId(_requestIdSeed);
if (requestId == bytes32(0)) return;

IOracle.Request memory requestData = _ghost_requestData[requestId];
IEBORequestModule.RequestParameters memory requestParams =
abi.decode(requestData.requestModuleData, (IEBORequestModule.RequestParameters));

uint256 requestsPerEpochChainId = _ghost_requestsPerEpochChainId[requestParams.epoch][requestParams.chainId].length;
if (requestsPerEpochChainId < 2) return;

for (uint256 i; i < requestsPerEpochChainId - 1; ++i) {
requestId = _ghost_requestsPerEpochChainId[requestParams.epoch][requestParams.chainId][i];
assertNotEq(oracle.finalizedAt(requestId), 0);
}
}
}

0 comments on commit 24f492c

Please sign in to comment.