Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
cf9579a9
Unverified
Commit
cf9579a9
authored
Feb 07, 2024
by
clabby
Committed by
GitHub
Feb 07, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Dispute game factory test updates (#9400)
parent
64e7d9ac
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
68 additions
and
73 deletions
+68
-73
DisputeGameFactory.t.sol
...s/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol
+59
-65
FaultDisputeGame.t.sol
...ges/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol
+9
-8
No files found.
packages/contracts-bedrock/test/dispute/DisputeGameFactory.t.sol
View file @
cf9579a9
...
...
@@ -11,7 +11,6 @@ import { Proxy } from "src/universal/Proxy.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
contract DisputeGameFactory_Init is CommonTest {
DisputeGameFactory factory;
FakeClone fakeClone;
event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim);
...
...
@@ -19,19 +18,13 @@ contract DisputeGameFactory_Init is CommonTest {
event InitBondUpdated(GameType indexed gameType, uint256 indexed newBond);
function setUp() public virtual override {
super.enableFaultProofs();
super.setUp();
Proxy proxy = new Proxy(address(this));
DisputeGameFactory impl = new DisputeGameFactory();
proxy.upgradeToAndCall({
_implementation: address(impl),
_data: abi.encodeCall(impl.initialize, (address(this)))
});
factory = DisputeGameFactory(address(proxy));
vm.label(address(factory), "DisputeGameFactoryProxy");
fakeClone = new FakeClone();
// Transfer ownership of the factory to the test contract.
vm.prank(deploy.mustGetAddress("SystemOwnerSafe"));
disputeGameFactory.transferOwnership(address(this));
}
}
...
...
@@ -54,24 +47,24 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
// Set all three implementations to the same `FakeClone` contract.
for (uint8 i; i < 3; i++) {
GameType lgt = GameType.wrap(i);
f
actory.setImplementation(lgt, IDisputeGame(address(fakeClone)));
f
actory.setInitBond(lgt, _value);
disputeGameF
actory.setImplementation(lgt, IDisputeGame(address(fakeClone)));
disputeGameF
actory.setInitBond(lgt, _value);
}
vm.deal(address(this), _value);
vm.expectEmit(false, true, true, false);
emit DisputeGameCreated(address(0), gt, rootClaim);
IDisputeGame proxy =
f
actory.create{ value: _value }(gt, rootClaim, extraData);
IDisputeGame proxy =
disputeGameF
actory.create{ value: _value }(gt, rootClaim, extraData);
(IDisputeGame game, Timestamp timestamp) =
f
actory.games(gt, rootClaim, extraData);
(IDisputeGame game, Timestamp timestamp) =
disputeGameF
actory.games(gt, rootClaim, extraData);
// Ensure that the dispute game was assigned to the `disputeGames` mapping.
assertEq(address(game), address(proxy));
assertEq(Timestamp.unwrap(timestamp), block.timestamp);
assertEq(
f
actory.gameCount(), 1);
assertEq(
disputeGameF
actory.gameCount(), 1);
(, Timestamp timestamp2, IDisputeGame game2) =
f
actory.gameAtIndex(0);
(, Timestamp timestamp2, IDisputeGame game2) =
disputeGameF
actory.gameAtIndex(0);
assertEq(address(game2), address(proxy));
assertEq(Timestamp.unwrap(timestamp2), block.timestamp);
...
...
@@ -95,24 +88,25 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
// Set all three implementations to the same `FakeClone` contract.
for (uint8 i; i < 3; i++) {
GameType lgt = GameType.wrap(i);
f
actory.setImplementation(lgt, IDisputeGame(address(fakeClone)));
f
actory.setInitBond(lgt, 1 ether);
disputeGameF
actory.setImplementation(lgt, IDisputeGame(address(fakeClone)));
disputeGameF
actory.setInitBond(lgt, 1 ether);
}
vm.expectRevert(InsufficientBond.selector);
f
actory.create(gt, rootClaim, extraData);
disputeGameF
actory.create(gt, rootClaim, extraData);
}
/// @dev Tests that the `create` function reverts when there is no implementation
/// set for the given `GameType`.
function testFuzz_create_noImpl_reverts(uint8 gameType, Claim rootClaim, bytes calldata extraData) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values.
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
function testFuzz_create_noImpl_reverts(uint32 gameType, Claim rootClaim, bytes calldata extraData) public {
// Ensure that the `gameType` is within the bounds of the `GameType` enum's possible values. We skip over
// game type = 0, since the deploy script set the implementation for that game type.
GameType gt = GameType.wrap(uint32(bound(gameType, 1, type(uint32).max)));
// Ensure the rootClaim has a VMStatus that disagrees with the validity.
rootClaim = changeClaimStatus(rootClaim, VMStatuses.INVALID);
vm.expectRevert(abi.encodeWithSelector(NoImplementation.selector, gt));
f
actory.create(gt, rootClaim, extraData);
disputeGameF
actory.create(gt, rootClaim, extraData);
}
/// @dev Tests that the `create` function reverts when there exists a dispute game with the same UUID.
...
...
@@ -124,24 +118,24 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
// Set all three implementations to the same `FakeClone` contract.
for (uint8 i; i < 3; i++) {
f
actory.setImplementation(GameType.wrap(i), IDisputeGame(address(fakeClone)));
disputeGameF
actory.setImplementation(GameType.wrap(i), IDisputeGame(address(fakeClone)));
}
// Create our first dispute game - this should succeed.
vm.expectEmit(false, true, true, false);
emit DisputeGameCreated(address(0), gt, rootClaim);
IDisputeGame proxy =
f
actory.create(gt, rootClaim, extraData);
IDisputeGame proxy =
disputeGameF
actory.create(gt, rootClaim, extraData);
(IDisputeGame game, Timestamp timestamp) =
f
actory.games(gt, rootClaim, extraData);
(IDisputeGame game, Timestamp timestamp) =
disputeGameF
actory.games(gt, rootClaim, extraData);
// Ensure that the dispute game was assigned to the `disputeGames` mapping.
assertEq(address(game), address(proxy));
assertEq(Timestamp.unwrap(timestamp), block.timestamp);
// Ensure that the `create` function reverts when called with parameters that would result in the same UUID.
vm.expectRevert(
abi.encodeWithSelector(GameAlreadyExists.selector,
f
actory.getGameUUID(gt, rootClaim, extraData))
abi.encodeWithSelector(GameAlreadyExists.selector,
disputeGameF
actory.getGameUUID(gt, rootClaim, extraData))
);
f
actory.create(gt, rootClaim, extraData);
disputeGameF
actory.create(gt, rootClaim, extraData);
}
function changeClaimStatus(Claim _claim, VMStatus _status) public pure returns (Claim out_) {
...
...
@@ -154,17 +148,14 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
/// @dev Tests that the `setImplementation` function properly sets the implementation for a given `GameType`.
function test_setImplementation_succeeds() public {
// There should be no implementation for the `GameTypes.CANNON` enum value, it has not been set.
assertEq(address(factory.gameImpls(GameTypes.CANNON)), address(0));
vm.expectEmit(true, true, true, true, address(factory));
vm.expectEmit(true, true, true, true, address(disputeGameFactory));
emit ImplementationSet(address(1), GameTypes.CANNON);
// Set the implementation for the `GameTypes.CANNON` enum value.
f
actory.setImplementation(GameTypes.CANNON, IDisputeGame(address(1)));
disputeGameF
actory.setImplementation(GameTypes.CANNON, IDisputeGame(address(1)));
// Ensure that the implementation for the `GameTypes.CANNON` enum value is set.
assertEq(address(
f
actory.gameImpls(GameTypes.CANNON)), address(1));
assertEq(address(
disputeGameF
actory.gameImpls(GameTypes.CANNON)), address(1));
}
/// @dev Tests that the `setImplementation` function reverts when called by a non-owner.
...
...
@@ -172,7 +163,7 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
// Ensure that the `setImplementation` function reverts when called by a non-owner.
vm.prank(address(0));
vm.expectRevert("Ownable: caller is not the owner");
f
actory.setImplementation(GameTypes.CANNON, IDisputeGame(address(1)));
disputeGameF
actory.setImplementation(GameTypes.CANNON, IDisputeGame(address(1)));
}
}
...
...
@@ -180,16 +171,16 @@ contract DisputeGameFactory_SetInitBond_Test is DisputeGameFactory_Init {
/// @dev Tests that the `setInitBond` function properly sets the init bond for a given `GameType`.
function test_setInitBond_succeeds() public {
// There should be no init bond for the `GameTypes.CANNON` enum value, it has not been set.
assertEq(
f
actory.initBonds(GameTypes.CANNON), 0);
assertEq(
disputeGameF
actory.initBonds(GameTypes.CANNON), 0);
vm.expectEmit(true, true, true, true, address(
f
actory));
vm.expectEmit(true, true, true, true, address(
disputeGameF
actory));
emit InitBondUpdated(GameTypes.CANNON, 1 ether);
// Set the init bond for the `GameTypes.CANNON` enum value.
f
actory.setInitBond(GameTypes.CANNON, 1 ether);
disputeGameF
actory.setInitBond(GameTypes.CANNON, 1 ether);
// Ensure that the init bond for the `GameTypes.CANNON` enum value is set.
assertEq(
f
actory.initBonds(GameTypes.CANNON), 1 ether);
assertEq(
disputeGameF
actory.initBonds(GameTypes.CANNON), 1 ether);
}
/// @dev Tests that the `setInitBond` function reverts when called by a non-owner.
...
...
@@ -197,7 +188,7 @@ contract DisputeGameFactory_SetInitBond_Test is DisputeGameFactory_Init {
// Ensure that the `setInitBond` function reverts when called by a non-owner.
vm.prank(address(0));
vm.expectRevert("Ownable: caller is not the owner");
f
actory.setInitBond(GameTypes.CANNON, 1 ether);
disputeGameF
actory.setInitBond(GameTypes.CANNON, 1 ether);
}
}
...
...
@@ -209,7 +200,8 @@ contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init {
GameType gt = GameType.wrap(uint8(bound(gameType, 0, 2)));
assertEq(
Hash.unwrap(factory.getGameUUID(gt, rootClaim, extraData)), keccak256(abi.encode(gt, rootClaim, extraData))
Hash.unwrap(disputeGameFactory.getGameUUID(gt, rootClaim, extraData)),
keccak256(abi.encode(gt, rootClaim, extraData))
);
}
}
...
...
@@ -217,22 +209,22 @@ contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init {
contract DisputeGameFactory_Owner_Test is DisputeGameFactory_Init {
/// @dev Tests that the `owner` function returns the correct address after deployment.
function test_owner_succeeds() public {
assertEq(
f
actory.owner(), address(this));
assertEq(
disputeGameF
actory.owner(), address(this));
}
}
contract DisputeGameFactory_TransferOwnership_Test is DisputeGameFactory_Init {
/// @dev Tests that the `transferOwnership` function succeeds when called by the owner.
function test_transferOwnership_succeeds() public {
f
actory.transferOwnership(address(1));
assertEq(
f
actory.owner(), address(1));
disputeGameF
actory.transferOwnership(address(1));
assertEq(
disputeGameF
actory.owner(), address(1));
}
/// @dev Tests that the `transferOwnership` function reverts when called by a non-owner.
function test_transferOwnership_notOwner_reverts() public {
vm.prank(address(0));
vm.expectRevert("Ownable: caller is not the owner");
f
actory.transferOwnership(address(1));
disputeGameF
actory.transferOwnership(address(1));
}
}
...
...
@@ -243,8 +235,8 @@ contract DisputeGameFactory_FindLatestGames_Test is DisputeGameFactory_Init {
// Set three implementations to the same `FakeClone` contract.
for (uint8 i; i < 3; i++) {
GameType lgt = GameType.wrap(i);
f
actory.setImplementation(lgt, IDisputeGame(address(fakeClone)));
f
actory.setInitBond(lgt, 0);
disputeGameF
actory.setImplementation(lgt, IDisputeGame(address(fakeClone)));
disputeGameF
actory.setInitBond(lgt, 0);
}
}
...
...
@@ -253,15 +245,16 @@ contract DisputeGameFactory_FindLatestGames_Test is DisputeGameFactory_Init {
function testFuzz_findLatestGames_greaterThanLength_succeeds(uint256 _start) public {
// Create some dispute games of varying game types.
for (uint256 i; i < 1 << 5; i++) {
f
actory.create(GameType.wrap(uint8(i % 2)), Claim.wrap(bytes32(i)), abi.encode(i));
disputeGameF
actory.create(GameType.wrap(uint8(i % 2)), Claim.wrap(bytes32(i)), abi.encode(i));
}
// Bound the starting index to a number greater than the length of the game list.
uint256 gameCount =
f
actory.gameCount();
uint256 gameCount =
disputeGameF
actory.gameCount();
_start = bound(_start, gameCount, type(uint256).max);
// The array's length should always be 0.
IDisputeGameFactory.GameSearchResult[] memory games = factory.findLatestGames(GameTypes.CANNON, _start, 1);
IDisputeGameFactory.GameSearchResult[] memory games =
disputeGameFactory.findLatestGames(GameTypes.CANNON, _start, 1);
assertEq(games.length, 0);
}
...
...
@@ -269,28 +262,28 @@ contract DisputeGameFactory_FindLatestGames_Test is DisputeGameFactory_Init {
function test_findLatestGames_static_succeeds() public {
// Create some dispute games of varying game types.
for (uint256 i; i < 1 << 5; i++) {
f
actory.create(GameType.wrap(uint8(i % 3)), Claim.wrap(bytes32(i)), abi.encode(i));
disputeGameF
actory.create(GameType.wrap(uint8(i % 3)), Claim.wrap(bytes32(i)), abi.encode(i));
}
uint256 gameCount =
f
actory.gameCount();
uint256 gameCount =
disputeGameF
actory.gameCount();
IDisputeGameFactory.GameSearchResult[] memory games;
games =
f
actory.findLatestGames(GameType.wrap(0), gameCount - 1, 1);
games =
disputeGameF
actory.findLatestGames(GameType.wrap(0), gameCount - 1, 1);
assertEq(games.length, 1);
assertEq(games[0].index, 30);
(GameType gameType, Timestamp createdAt, IDisputeGame game) = games[0].metadata.unpack();
assertEq(gameType.raw(), 0);
assertEq(createdAt.raw(), block.timestamp);
games =
f
actory.findLatestGames(GameType.wrap(1), gameCount - 1, 1);
games =
disputeGameF
actory.findLatestGames(GameType.wrap(1), gameCount - 1, 1);
assertEq(games.length, 1);
assertEq(games[0].index, 31);
(gameType, createdAt, game) = games[0].metadata.unpack();
assertEq(gameType.raw(), 1);
assertEq(createdAt.raw(), block.timestamp);
games =
f
actory.findLatestGames(GameType.wrap(2), gameCount - 1, 1);
games =
disputeGameF
actory.findLatestGames(GameType.wrap(2), gameCount - 1, 1);
assertEq(games.length, 1);
assertEq(games[0].index, 29);
(gameType, createdAt, game) = games[0].metadata.unpack();
...
...
@@ -302,20 +295,20 @@ contract DisputeGameFactory_FindLatestGames_Test is DisputeGameFactory_Init {
/// available.
function test_findLatestGames_lessThanNAvailable_succeeds() public {
// Create some dispute games of varying game types.
f
actory.create(GameType.wrap(1), Claim.wrap(bytes32(0)), abi.encode(0));
f
actory.create(GameType.wrap(1), Claim.wrap(bytes32(uint256(1))), abi.encode(1));
disputeGameF
actory.create(GameType.wrap(1), Claim.wrap(bytes32(0)), abi.encode(0));
disputeGameF
actory.create(GameType.wrap(1), Claim.wrap(bytes32(uint256(1))), abi.encode(1));
for (uint256 i; i < 1 << 3; i++) {
f
actory.create(GameType.wrap(0), Claim.wrap(bytes32(i)), abi.encode(i));
disputeGameF
actory.create(GameType.wrap(0), Claim.wrap(bytes32(i)), abi.encode(i));
}
uint256 gameCount =
f
actory.gameCount();
uint256 gameCount =
disputeGameF
actory.gameCount();
IDisputeGameFactory.GameSearchResult[] memory games;
games =
f
actory.findLatestGames(GameType.wrap(2), gameCount - 1, 5);
games =
disputeGameF
actory.findLatestGames(GameType.wrap(2), gameCount - 1, 5);
assertEq(games.length, 0);
games =
f
actory.findLatestGames(GameType.wrap(1), gameCount - 1, 5);
games =
disputeGameF
actory.findLatestGames(GameType.wrap(1), gameCount - 1, 5);
assertEq(games.length, 2);
assertEq(games[0].index, 1);
assertEq(games[1].index, 0);
...
...
@@ -336,12 +329,13 @@ contract DisputeGameFactory_FindLatestGames_Test is DisputeGameFactory_Init {
// Create `_numGames` dispute games, with at least `_numSearchedGames` games.
for (uint256 i; i < _numGames; i++) {
uint8 gameType = i < _numSearchedGames ? 0 : 1;
f
actory.create(GameType.wrap(gameType), Claim.wrap(bytes32(i)), abi.encode(i));
disputeGameF
actory.create(GameType.wrap(gameType), Claim.wrap(bytes32(i)), abi.encode(i));
}
// Ensure that the correct number of games are returned.
uint256 start = _numGames == 0 ? 0 : _numGames - 1;
IDisputeGameFactory.GameSearchResult[] memory games = factory.findLatestGames(GameType.wrap(0), start, _n);
IDisputeGameFactory.GameSearchResult[] memory games =
disputeGameFactory.findLatestGames(GameType.wrap(0), start, _n);
assertEq(games.length, _n);
}
}
...
...
packages/contracts-bedrock/test/dispute/FaultDisputeGame.t.sol
View file @
cf9579a9
...
...
@@ -63,9 +63,9 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
_vm: _vm
});
// Register the game implementation with the factory.
f
actory.setImplementation(GAME_TYPE, gameImpl);
disputeGameF
actory.setImplementation(GAME_TYPE, gameImpl);
// Create a new game.
gameProxy = FaultDisputeGame(address(
f
actory.create(GAME_TYPE, rootClaim, extraData)));
gameProxy = FaultDisputeGame(address(
disputeGameF
actory.create(GAME_TYPE, rootClaim, extraData)));
// Check immutables
assertEq(gameProxy.gameType().raw(), GAME_TYPE.raw());
...
...
@@ -174,7 +174,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
Claim claim = _dummyClaim();
vm.expectRevert(abi.encodeWithSelector(UnexpectedRootClaim.selector, claim));
gameProxy = FaultDisputeGame(address(
f
actory.create(GAME_TYPE, claim, abi.encode(_blockNumber))));
gameProxy = FaultDisputeGame(address(
disputeGameF
actory.create(GAME_TYPE, claim, abi.encode(_blockNumber))));
}
/// @dev Tests that the proxy receives ETH from the dispute game factory.
...
...
@@ -183,7 +183,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
vm.deal(address(this), _value);
assertEq(address(gameProxy).balance, 0);
gameProxy = FaultDisputeGame(address(factory.create{ value: _value }(GAME_TYPE, ROOT_CLAIM, abi.encode(1))));
gameProxy =
FaultDisputeGame(address(disputeGameFactory.create{ value: _value }(GAME_TYPE, ROOT_CLAIM, abi.encode(1))));
assertEq(address(gameProxy).balance, _value);
}
...
...
@@ -206,7 +207,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
Claim claim = _dummyClaim();
vm.expectRevert(abi.encodeWithSelector(ExtraDataTooLong.selector));
gameProxy = FaultDisputeGame(address(
f
actory.create(GAME_TYPE, claim, _extraData)));
gameProxy = FaultDisputeGame(address(
disputeGameF
actory.create(GAME_TYPE, claim, _extraData)));
}
/// @dev Tests that the game is initialized with the correct data.
...
...
@@ -629,7 +630,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(address(gameProxy).balance, 0);
// Ensure that the init bond for the game is 0, in case we change it in the test suite in the future.
assertEq(
f
actory.initBonds(GAME_TYPE), 0);
assertEq(
disputeGameF
actory.initBonds(GAME_TYPE), 0);
}
/// @dev Static unit test asserting that resolve pays out bonds on step, output bisection, and execution trace
...
...
@@ -691,7 +692,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(address(gameProxy).balance, 0);
// Ensure that the init bond for the game is 0, in case we change it in the test suite in the future.
assertEq(
f
actory.initBonds(GAME_TYPE), 0);
assertEq(
disputeGameF
actory.initBonds(GAME_TYPE), 0);
}
/// @dev Static unit test asserting that resolve pays out bonds on moves to the leftmost actor
...
...
@@ -743,7 +744,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(address(gameProxy).balance, 0);
// Ensure that the init bond for the game is 0, in case we change it in the test suite in the future.
assertEq(
f
actory.initBonds(GAME_TYPE), 0);
assertEq(
disputeGameF
actory.initBonds(GAME_TYPE), 0);
}
/// @dev Static unit test asserting that credit may not be drained past allowance through reentrancy.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment