Skip to content

Commit c898195

Browse files
expanded test coverage
1 parent c5b8c57 commit c898195

File tree

2 files changed

+198
-1
lines changed

2 files changed

+198
-1
lines changed

op-e2e/faultproofs/output_alphabet_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ func TestOutputAlphabetGame_ReclaimBond(t *testing.T) {
129129

130130
// Advance the time past the finalization delay
131131
// Finalization delay is the same as the credit unlock delay
132-
sys.TimeTravelClock.AdvanceTime(game.CreditUnlockDuration(ctx))
132+
// But just warp way into the future to be safe
133+
sys.TimeTravelClock.AdvanceTime(game.CreditUnlockDuration(ctx) * 2)
133134
require.NoError(t, wait.ForNextBlock(ctx, l1Client))
134135

135136
// Wait for alice to have no available credit

packages/contracts-bedrock/test/dispute/AnchorStateRegistry.t.sol

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ contract AnchorStateRegistry_IsGameProper_Test is AnchorStateRegistry_Init {
257257
}
258258

259259
/// @notice Tests that isGameProper will return false if the game is not the respected game type.
260+
/// @param _gameType The game type to use for the test.
260261
function testFuzz_isGameProper_isNotRespected_succeeds(GameType _gameType) public {
261262
if (_gameType.raw() == gameProxy.gameType().raw()) {
262263
_gameType = GameType.wrap(_gameType.raw() + 1);
@@ -283,6 +284,7 @@ contract AnchorStateRegistry_IsGameProper_Test is AnchorStateRegistry_Init {
283284
}
284285

285286
/// @notice Tests that isGameProper will return false if the game is retired.
287+
/// @param _retirementTimestamp The retirement timestamp to use for the test.
286288
function testFuzz_isGameProper_isRetired_succeeds(uint64 _retirementTimestamp) public {
287289
// Make sure retirement timestamp is later than the game's creation time.
288290
_retirementTimestamp = uint64(bound(_retirementTimestamp, gameProxy.createdAt().raw() + 1, type(uint64).max));
@@ -298,6 +300,200 @@ contract AnchorStateRegistry_IsGameProper_Test is AnchorStateRegistry_Init {
298300
}
299301
}
300302

303+
contract AnchorStateRegistry_IsGameResolved_Test is AnchorStateRegistry_Init {
304+
/// @notice Tests that isGameResolved will return true if the game is resolved.
305+
/// @param _resolvedAtTimestamp The resolvedAt timestamp to use for the test.
306+
function testFuzz_isGameResolved_challengerWins_succeeds(uint256 _resolvedAtTimestamp) public {
307+
// Bound resolvedAt to be less than or equal to current timestamp.
308+
_resolvedAtTimestamp = bound(_resolvedAtTimestamp, 0, block.timestamp);
309+
310+
// Mock the resolvedAt timestamp.
311+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.resolvedAt, ()), abi.encode(_resolvedAtTimestamp));
312+
313+
// Mock the status to be CHALLENGER_WINS.
314+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.status, ()), abi.encode(GameStatus.CHALLENGER_WINS));
315+
316+
// Game should be resolved.
317+
assertTrue(anchorStateRegistry.isGameResolved(gameProxy));
318+
}
319+
320+
/// @notice Tests that isGameResolved will return true if the game is resolved.
321+
/// @param _resolvedAtTimestamp The resolvedAt timestamp to use for the test.
322+
function testFuzz_isGameResolved_defenderWins_succeeds(uint256 _resolvedAtTimestamp) public {
323+
// Bound resolvedAt to be less than or equal to current timestamp.
324+
_resolvedAtTimestamp = bound(_resolvedAtTimestamp, 0, block.timestamp);
325+
326+
// Mock the resolvedAt timestamp.
327+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.resolvedAt, ()), abi.encode(_resolvedAtTimestamp));
328+
329+
// Mock the status to be DEFENDER_WINS.
330+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.status, ()), abi.encode(GameStatus.DEFENDER_WINS));
331+
332+
// Game should be resolved.
333+
assertTrue(anchorStateRegistry.isGameResolved(gameProxy));
334+
}
335+
336+
/// @notice Tests that isGameResolved will return false if the game is in progress and not resolved.
337+
/// @param _resolvedAtTimestamp The resolvedAt timestamp to use for the test.
338+
function testFuzz_isGameResolved_inProgressNotResolved_succeeds(uint256 _resolvedAtTimestamp) public {
339+
// Bound resolvedAt to be less than or equal to current timestamp.
340+
_resolvedAtTimestamp = bound(_resolvedAtTimestamp, 0, block.timestamp);
341+
342+
// Mock the resolvedAt timestamp.
343+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.resolvedAt, ()), abi.encode(_resolvedAtTimestamp));
344+
345+
// Mock the status to be IN_PROGRESS.
346+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.status, ()), abi.encode(GameStatus.IN_PROGRESS));
347+
348+
// Game should not be resolved.
349+
assertFalse(anchorStateRegistry.isGameResolved(gameProxy));
350+
}
351+
}
352+
353+
contract AnchorStateRegistry_IsGameAirgapped_TestFail is AnchorStateRegistry_Init {
354+
/// @notice Tests that isGameAirgapped will return true if the game is airgapped.
355+
/// @param _resolvedAtTimestamp The resolvedAt timestamp to use for the test.
356+
function testFuzz_isGameAirgapped_isAirgapped_succeeds(uint256 _resolvedAtTimestamp) public {
357+
// Warp forward by disputeGameFinalityDelaySeconds.
358+
vm.warp(block.timestamp + optimismPortal2.disputeGameFinalityDelaySeconds());
359+
360+
// Bound resolvedAt to be at least disputeGameFinalityDelaySeconds in the past.
361+
_resolvedAtTimestamp = bound(_resolvedAtTimestamp, 0, block.timestamp - optimismPortal2.disputeGameFinalityDelaySeconds() - 1);
362+
363+
// Mock the resolvedAt timestamp.
364+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.resolvedAt, ()), abi.encode(_resolvedAtTimestamp));
365+
366+
// Game should be airgapped.
367+
assertTrue(anchorStateRegistry.isGameAirgapped(gameProxy));
368+
}
369+
370+
/// @notice Tests that isGameAirgapped will return false if the game is not airgapped.
371+
/// @param _resolvedAtTimestamp The resolvedAt timestamp to use for the test.
372+
function testFuzz_isGameAirgapped_isNotAirgapped_succeeds(uint256 _resolvedAtTimestamp) public {
373+
// Warp forward by disputeGameFinalityDelaySeconds.
374+
vm.warp(block.timestamp + optimismPortal2.disputeGameFinalityDelaySeconds());
375+
376+
// Bound resolvedAt to be less than disputeGameFinalityDelaySeconds in the past.
377+
_resolvedAtTimestamp = bound(_resolvedAtTimestamp, block.timestamp - optimismPortal2.disputeGameFinalityDelaySeconds(), block.timestamp);
378+
379+
// Mock the resolvedAt timestamp.
380+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.resolvedAt, ()), abi.encode(_resolvedAtTimestamp));
381+
382+
// Game should not be airgapped.
383+
assertFalse(anchorStateRegistry.isGameAirgapped(gameProxy));
384+
}
385+
}
386+
387+
contract AnchorStateRegistry_IsGameClaimValid_Test is AnchorStateRegistry_Init {
388+
/// @notice Tests that isGameClaimValid will return true if the game claim is valid.
389+
/// @param _resolvedAtTimestamp The resolvedAt timestamp to use for the test.
390+
function testFuzz_isGameClaimValid_claimIsValid_succeeds(uint256 _resolvedAtTimestamp) public {
391+
// Warp forward by disputeGameFinalityDelaySeconds.
392+
vm.warp(block.timestamp + optimismPortal2.disputeGameFinalityDelaySeconds());
393+
394+
// Bound resolvedAt to be at least disputeGameFinalityDelaySeconds in the past.
395+
_resolvedAtTimestamp = bound(_resolvedAtTimestamp, 0, block.timestamp - optimismPortal2.disputeGameFinalityDelaySeconds() - 1);
396+
397+
// Mock that the game was respected.
398+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.wasRespectedGameTypeWhenCreated, ()), abi.encode(true));
399+
400+
// Mock the resolvedAt timestamp.
401+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.resolvedAt, ()), abi.encode(_resolvedAtTimestamp));
402+
403+
// Mock the status to be DEFENDER_WINS.
404+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.status, ()), abi.encode(GameStatus.DEFENDER_WINS));
405+
406+
// Claim should be valid.
407+
assertTrue(anchorStateRegistry.isGameClaimValid(gameProxy));
408+
}
409+
410+
/// @notice Tests that isGameClaimValid will return false if the game is not registered.
411+
function testFuzz_isGameClaimValid_notRegistered_succeeds() public {
412+
// Mock the DisputeGameFactory to make it seem that the game was not registered.
413+
vm.mockCall(
414+
address(disputeGameFactory),
415+
abi.encodeCall(
416+
disputeGameFactory.games, (gameProxy.gameType(), gameProxy.rootClaim(), gameProxy.extraData())
417+
),
418+
abi.encode(address(0), 0)
419+
);
420+
421+
// Claim should not be valid.
422+
assertFalse(anchorStateRegistry.isGameClaimValid(gameProxy));
423+
}
424+
425+
/// @notice Tests that isGameClaimValid will return false if the game is not respected.
426+
/// @param _gameType The game type to use for the test.
427+
function testFuzz_isGameClaimValid_isNotRespected_succeeds(GameType _gameType) public {
428+
if (_gameType.raw() == gameProxy.gameType().raw()) {
429+
_gameType = GameType.wrap(_gameType.raw() + 1);
430+
}
431+
432+
// Mock that the game was not respected.
433+
vm.mockCall(
434+
address(gameProxy), abi.encodeCall(gameProxy.wasRespectedGameTypeWhenCreated, ()), abi.encode(false)
435+
);
436+
437+
// Claim should not be valid.
438+
assertFalse(anchorStateRegistry.isGameClaimValid(gameProxy));
439+
}
440+
441+
/// @notice Tests that isGameClaimValid will return false if the game is blacklisted.
442+
function testFuzz_isGameClaimValid_isBlacklisted_succeeds() public {
443+
// Mock the disputeGameBlacklist call to return true.
444+
vm.mockCall(
445+
address(optimismPortal2),
446+
abi.encodeCall(optimismPortal2.disputeGameBlacklist, (gameProxy)),
447+
abi.encode(true)
448+
);
449+
450+
// Claim should not be valid.
451+
assertFalse(anchorStateRegistry.isGameClaimValid(gameProxy));
452+
}
453+
454+
/// @notice Tests that isGameClaimValid will return false if the game is retired.
455+
/// @param _resolvedAtTimestamp The resolvedAt timestamp to use for the test.
456+
function testFuzz_isGameClaimValid_isRetired_succeeds(uint256 _resolvedAtTimestamp) public {
457+
// Make sure retirement timestamp is later than the game's creation time.
458+
_resolvedAtTimestamp = uint64(bound(_resolvedAtTimestamp, gameProxy.createdAt().raw() + 1, type(uint64).max));
459+
460+
// Mock the respectedGameTypeUpdatedAt call to be later than the game's creation time.
461+
vm.mockCall(
462+
address(optimismPortal2),
463+
abi.encodeCall(optimismPortal2.respectedGameTypeUpdatedAt, ()),
464+
abi.encode(_resolvedAtTimestamp)
465+
);
466+
467+
// Claim should not be valid.
468+
assertFalse(anchorStateRegistry.isGameClaimValid(gameProxy));
469+
}
470+
471+
/// @notice Tests that isGameClaimValid will return false if the game is not resolved.
472+
function testFuzz_isGameClaimValid_notResolved_succeeds() public {
473+
// Mock the status to be IN_PROGRESS.
474+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.status, ()), abi.encode(GameStatus.IN_PROGRESS));
475+
476+
// Claim should not be valid.
477+
assertFalse(anchorStateRegistry.isGameClaimValid(gameProxy));
478+
}
479+
480+
/// @notice Tests that isGameClaimValid will return false if the game is not airgapped.
481+
/// @param _resolvedAtTimestamp The resolvedAt timestamp to use for the test.
482+
function testFuzz_isGameClaimValid_notAirgapped_succeeds(uint256 _resolvedAtTimestamp) public {
483+
// Warp forward by disputeGameFinalityDelaySeconds.
484+
vm.warp(block.timestamp + optimismPortal2.disputeGameFinalityDelaySeconds());
485+
486+
// Bound resolvedAt to be less than disputeGameFinalityDelaySeconds in the past.
487+
_resolvedAtTimestamp = bound(_resolvedAtTimestamp, block.timestamp - optimismPortal2.disputeGameFinalityDelaySeconds(), block.timestamp);
488+
489+
// Mock the resolvedAt timestamp.
490+
vm.mockCall(address(gameProxy), abi.encodeCall(gameProxy.resolvedAt, ()), abi.encode(_resolvedAtTimestamp));
491+
492+
// Claim should not be valid.
493+
assertFalse(anchorStateRegistry.isGameClaimValid(gameProxy));
494+
}
495+
}
496+
301497
contract AnchorStateRegistry_SetAnchorState_Test is AnchorStateRegistry_Init {
302498
/// @notice Tests that setAnchorState will succeed if the game is valid, the game block
303499
/// number is greater than the current anchor root block number, and the game is the

0 commit comments

Comments
 (0)