Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: medusa tests #51

Draft
wants to merge 29 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5d5fd14
chore: properties md update
simon-something Oct 29, 2024
3b77715
test(medusa): handlers and working setup
simon-something Nov 10, 2024
1b53763
test(medusa): add lib to crytic compile
simon-something Nov 10, 2024
98de161
test(medusa): prop 0 sanity check ok
simon-something Nov 10, 2024
92a50e3
test(medusa): git ignore corpus
simon-something Nov 10, 2024
1e78bdb
test(medusa): git ignore corpus
simon-something Nov 10, 2024
efc8876
test(medusa): typo medusa json
simon-something Nov 10, 2024
e4cf1e5
test(medusa): rm corpus
simon-something Nov 10, 2024
c0ffee6
test(medusa): natspec
simon-something Nov 11, 2024
c0ffee7
test(medusa): rm non-sensical handlers onlyoracle etc
simon-something Nov 11, 2024
c0ffeed
test(medusa): ghosts refactor
simon-something Nov 13, 2024
c0ffee6
test(medusa): more handler fixes
simon-something Nov 13, 2024
c0ffeee
test(medusa): properties md update
simon-something Nov 20, 2024
9c8dce2
test(medusa): requester properties (#57)
0xJabberwock Nov 28, 2024
c0ffee9
test(medusa): dispute window in prop6
simon-something Nov 28, 2024
c0ffeef
test(medusa): fix approveModule
simon-something Nov 28, 2024
c0ffeeb
test(medusa): fix approveModule
simon-something Nov 28, 2024
97fff3c
test(medusa): rename PropertyDispute to PropertyDisputer
0xJabberwock Nov 29, 2024
80d145f
test(medusa): correct prop-6
0xJabberwock Nov 29, 2024
1d45342
test(medusa): assert prop-7
0xJabberwock Nov 29, 2024
c0ffee6
test(medusa): properties 13
simon-something Nov 30, 2024
c0ffee9
test(medusa): fix prop1 for empty finalized req
simon-something Dec 7, 2024
c0ffee7
test(medusa): fix fp
simon-something Dec 11, 2024
7218056
test(medusa): proposer properties
0xJabberwock Dec 13, 2024
2b8bc63
test(medusa): fix prop8b
simon-something Dec 11, 2024
c0ffee2
test(medusa): false pos fix
simon-something Dec 16, 2024
c0ffeea
test(medusa): false pos fix
simon-something Dec 16, 2024
a3b8f1c
Merge branch 'dev' into test/handler-cov
simon-something Dec 18, 2024
c0ffee8
Revert "Merge branch 'dev' into test/handler-cov"
simon-something Dec 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions test/invariants/FuzzTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,4 @@ contract FuzzTest is PropertyParent {
}
}
}

//solhint-disable no-empty-blocks
function test_debug() public {}
}
36 changes: 36 additions & 0 deletions test/invariants/Reproducers.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

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

contract Reproducers is FuzzTest {
function test_debug() public {
vm.roll(55_341);
vm.warp(292_791);
vm.prank(0x0000000000000000000000000000000000080000);
this.property_requesterCanAlwaysCreateRequest(
0, 91_936_153_333_790_985_814_765_645_281_331_945_670_085_017_288_440_355_350_976_283_151_607_122_591_831
);

vm.roll(114_433);
vm.warp(791_132);
vm.prank(0x0000000000000000000000000000000000080000);
this.property_finalizeAfterDeadline(
13_479_973_333_575_319_897_333_507_543_509_815_336_818_572_211_270_290_147_286_325_345_251,
107_839_786_668_602_559_178_668_057_886_353_385_264_177_471_300_505_974_851_760_065_510_272
);

vm.roll(164_579);
vm.warp(1_050_332);
vm.prank(0x00000000000000000000000000000000000a0000);
this.property_requesterCanAlwaysCreateRequest(0, 300_000_000_001_847_143);

vm.roll(225_050);
vm.warp(1_491_370);
vm.prank(0x00000000000000000000000000000000000a0000);
this.property_requesterCanAlwaysCreateRequest(
0, 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_456_584_007_913_130_122_499
);
}
}
43 changes: 0 additions & 43 deletions test/invariants/handlers/HandlerEBORequestCreator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,47 +26,4 @@ contract HandlerEBORequestCreator is BaseHandler {
_ghost_chainIdToChain[keccak256(abi.encodePacked(INITIAL_CHAINS[i]))] = INITIAL_CHAINS[i];
}
}

function handleCreateRequest(uint256 _epoch, uint256 _chainIdSeed) external {
_epoch = bound(_epoch, START_EPOCH, block.timestamp);

string memory chainId = _getRandomChain(_chainIdSeed);
if (bytes(chainId).length == 0) return;

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

// Get current request data
IOracle.Request memory requestData = eboRequestCreator.getRequestData();

// Build request module parameters
IEBORequestModule.RequestParameters memory requestParams =
abi.decode(requestData.requestModuleData, (IEBORequestModule.RequestParameters));
requestParams.epoch = _epoch;
requestParams.chainId = chainId;
requestData.requestModuleData = abi.encode(requestParams);

// Calculate request ID using same logic as Oracle
bytes32 requestId = keccak256(abi.encode(requestData));

// Track the request
_ghost_requests.push(requestId);
_ghost_requestsPerEpochChainId[_epoch][chainId].push(requestId);
_ghost_requestData[requestId] = requestData;
_ghost_validRequests[requestId] = true;

emit RequestCreated(requestId, _epoch, chainId);
}

function handleAddChain(string memory _chainId) external {
eboRequestCreator.addChain(_chainId);

// Track the chain
_ghost_chainIdToChain[keccak256(abi.encodePacked(_chainId))] = _chainId;
}

// function handleRemoveChain(uint256 _chainIdSeed) external {
// string memory chainId = _getRandomChainId(_chainIdSeed);
// eboRequestCreator.removeChain(chainId);
// }
}
47 changes: 26 additions & 21 deletions test/invariants/properties/PropertyRequester.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ contract PropertyRequester is HandlerParent {
constructor() {}

event Test(bool);
event TestUint(uint256);

/// @custom:property-id 1
/// @custom:property Requester can always create a request as long as the same chainId/epoch isn't already finalized with response
Expand All @@ -21,17 +22,26 @@ contract PropertyRequester is HandlerParent {
if (bytes(chainId).length == 0) return;

uint256 requestsPerEpochChainId = _ghost_requestsPerEpochChainId[_epoch][chainId].length;
bytes32 requestId;
uint256 activeRequests;
bool isFinalizedWithResponse;

// Calculate request ID using same logic as Oracle
// Get current request data
IOracle.Request memory requestData = eboRequestCreator.getRequestData();
IEBORequestModule.RequestParameters memory requestParams =
abi.decode(requestData.requestModuleData, (IEBORequestModule.RequestParameters));
requestParams.epoch = _epoch;
requestParams.chainId = chainId;
requestData.requestModuleData = abi.encode(requestParams);
bytes32 requestId = keccak256(abi.encode(requestData));
emit TestUint(_epoch);
// Create request via EBORequestCreator
try eboRequestCreator.createRequest(_epoch, chainId) {
// Check if there are active requests and a request finalized with response
for (uint256 i; i < requestsPerEpochChainId; ++i) {
requestId = _ghost_requestsPerEpochChainId[_epoch][chainId][i];
if (oracle.finalizedAt(requestId) == 0) ++activeRequests;
if (oracle.finalizedResponseId(requestId) != 0) {
bytes32 _currRequestId = _ghost_requestsPerEpochChainId[_epoch][chainId][i];
if (oracle.finalizedAt(_currRequestId) == 0) ++activeRequests;
if (oracle.finalizedResponseId(_currRequestId) != 0) {
isFinalizedWithResponse = true;
break;
}
Expand All @@ -42,19 +52,6 @@ contract PropertyRequester is HandlerParent {
// property 2
assertEq(activeRequests, 0, 'prop-2: same chainId/epoch active request');

// Get current request data
IOracle.Request memory requestData = eboRequestCreator.getRequestData();

// Build request module parameters
IEBORequestModule.RequestParameters memory requestParams =
abi.decode(requestData.requestModuleData, (IEBORequestModule.RequestParameters));
requestParams.epoch = _epoch;
requestParams.chainId = chainId;
requestData.requestModuleData = abi.encode(requestParams);

// Calculate request ID using same logic as Oracle
bytes32 requestId = keccak256(abi.encode(requestData));

// Track the request
_ghost_requests.push(requestId);
_ghost_requestsPerEpochChainId[_epoch][chainId].push(requestId);
Expand All @@ -65,16 +62,24 @@ contract PropertyRequester is HandlerParent {
} catch {
// Check if there are active requests and a request finalized with response
for (uint256 i; i < requestsPerEpochChainId; ++i) {
requestId = _ghost_requestsPerEpochChainId[_epoch][chainId][i];
if (requestId != bytes32(0) && oracle.finalizedAt(requestId) == 0) ++activeRequests;
if (requestId != bytes32(0) && oracle.finalizedResponseId(requestId) != 0) {
bytes32 currRequestId = _ghost_requestsPerEpochChainId[_epoch][chainId][i];

// active because not finalized
if (oracle.finalizedAt(currRequestId) == 0) ++activeRequests;

// active because finalized without answer
if ((oracle.finalizedAt(currRequestId) != 0 && oracle.finalizedResponseId(currRequestId) == 0)) {
++activeRequests;
Comment on lines +70 to +72
Copy link
Member

@0xJabberwock 0xJabberwock Dec 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that a request is active after it has been created but before it has been finalized. A finalized request, be it with or without response, shouldn't be counted as an active request.

In fact, if so happens, EBORequestCreator wouldn't permit to create same chainId/epoch requests after a previous one has finalized without response – which I think is the opposite of what is wanted. Consider the assertion of this catch block: assertTrue(isFinalizedWithResponse || activeRequests > 0).

}

// not active
if (oracle.finalizedResponseId(currRequestId) != 0) {
isFinalizedWithResponse = true;
break;
}
}

// property 1 and 2
emit RequestCreated(requestId, _epoch, chainId);
emit Test(isFinalizedWithResponse);
emit Test(activeRequests > 0);
assertTrue(isFinalizedWithResponse || activeRequests > 0, 'prop-1-2: create request reverted');
Expand Down
Loading