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
8478fbfe
Commit
8478fbfe
authored
Jun 21, 2023
by
clabby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change comment style for `dispute` contracts
parent
72c6fb0a
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
411 additions
and
776 deletions
+411
-776
DisputeGameFactory.sol
...ontracts-bedrock/contracts/dispute/DisputeGameFactory.sol
+28
-60
FaultDisputeGame.sol
.../contracts-bedrock/contracts/dispute/FaultDisputeGame.sol
+36
-85
IBondManager.sol
...cts-bedrock/contracts/dispute/interfaces/IBondManager.sol
+33
-48
IDisputeGame.sol
...cts-bedrock/contracts/dispute/interfaces/IDisputeGame.sol
+34
-54
IDisputeGameFactory.sol
...rock/contracts/dispute/interfaces/IDisputeGameFactory.sol
+49
-67
IFaultDisputeGame.sol
...edrock/contracts/dispute/interfaces/IFaultDisputeGame.sol
+27
-42
IInitializable.sol
...s-bedrock/contracts/dispute/interfaces/IInitializable.sol
+4
-8
IVersioned.sol
...racts-bedrock/contracts/dispute/interfaces/IVersioned.sol
+4
-8
LibClock.sol
...ages/contracts-bedrock/contracts/dispute/lib/LibClock.sol
+12
-20
LibHashing.sol
...es/contracts-bedrock/contracts/dispute/lib/LibHashing.sol
+7
-10
LibPosition.sol
...s/contracts-bedrock/contracts/dispute/lib/LibPosition.sol
+37
-54
DisputeErrors.sol
...s/contracts-bedrock/contracts/libraries/DisputeErrors.sol
+21
-51
DisputeTypes.sol
...es/contracts-bedrock/contracts/libraries/DisputeTypes.sol
+36
-66
DisputeGameFactory.t.sol
...contracts-bedrock/contracts/test/DisputeGameFactory.t.sol
+19
-45
FaultDisputeGame.t.sol
...s/contracts-bedrock/contracts/test/FaultDisputeGame.t.sol
+41
-107
LibClock.t.sol
packages/contracts-bedrock/contracts/test/LibClock.t.sol
+3
-9
LibPosition.t.sol
packages/contracts-bedrock/contracts/test/LibPosition.t.sol
+20
-42
No files found.
packages/contracts-bedrock/contracts/dispute/DisputeGameFactory.sol
View file @
8478fbfe
...
@@ -13,73 +13,53 @@ import { IDisputeGame } from "./interfaces/IDisputeGame.sol";
...
@@ -13,73 +13,53 @@ import { IDisputeGame } from "./interfaces/IDisputeGame.sol";
import { IDisputeGameFactory } from "./interfaces/IDisputeGameFactory.sol";
import { IDisputeGameFactory } from "./interfaces/IDisputeGameFactory.sol";
import { IVersioned } from "./interfaces/IVersioned.sol";
import { IVersioned } from "./interfaces/IVersioned.sol";
/**
/// @title DisputeGameFactory
* @title DisputeGameFactory
/// @notice A factory contract for creating `IDisputeGame` contracts. All created dispute games
* @notice A factory contract for creating `IDisputeGame` contracts. All created dispute games
/// are stored in both a mapping and an append only array. The timestamp of the creation
* are stored in both a mapping and an append only array. The timestamp of the creation
/// time of the dispute game is packed tightly into the storage slot with the address of
* time of the dispute game is packed tightly into the storage slot with the address of
/// the dispute game. This is to make offchain discoverability of playable dispute games
* the dispute game. This is to make offchain discoverability of playable dispute games
/// easier.
* easier.
*/
contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersioned {
contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersioned {
/**
/// @dev Allows for the creation of clone proxies with immutable arguments.
* @dev Allows for the creation of clone proxies with immutable arguments.
*/
using ClonesWithImmutableArgs for address;
using ClonesWithImmutableArgs for address;
/**
/// @inheritdoc IDisputeGameFactory
* @inheritdoc IDisputeGameFactory
*/
mapping(GameType => IDisputeGame) public gameImpls;
mapping(GameType => IDisputeGame) public gameImpls;
/**
/// @notice Mapping of a hash of `gameType || rootClaim || extraData` to
* @notice Mapping of a hash of `gameType || rootClaim || extraData` to
/// the deployed `IDisputeGame` clone.
* the deployed `IDisputeGame` clone.
/// @dev Note: `||` denotes concatenation.
* @dev Note: `||` denotes concatenation.
*/
mapping(Hash => GameId) internal _disputeGames;
mapping(Hash => GameId) internal _disputeGames;
/**
/// @notice an append-only array of disputeGames that have been created.
* @notice An append-only array of disputeGames that have been created.
/// @dev this accessor is used by offchain game solvers to efficiently
* @dev This accessor is used by offchain game solvers to efficiently
/// track dispute games
* track dispute games
*/
GameId[] internal _disputeGameList;
GameId[] internal _disputeGameList;
/**
/// @notice constructs a new DisputeGameFactory contract.
* @notice Constructs a new DisputeGameFactory contract.
*/
constructor() OwnableUpgradeable() {
constructor() OwnableUpgradeable() {
initialize(address(0));
initialize(address(0));
}
}
/**
/// @notice Initializes the contract.
* @notice Initializes the contract.
/// @param _owner The owner of the contract.
* @param _owner The owner of the contract.
*/
function initialize(address _owner) public initializer {
function initialize(address _owner) public initializer {
__Ownable_init();
__Ownable_init();
_transferOwnership(_owner);
_transferOwnership(_owner);
}
}
/**
/// @inheritdoc IVersioned
* @inheritdoc IVersioned
/// @custom:semver 0.0.2
* @custom:semver 0.0.2
*/
function version() external pure returns (string memory) {
function version() external pure returns (string memory) {
return "0.0.2";
return "0.0.2";
}
}
/**
/// @inheritdoc IDisputeGameFactory
* @inheritdoc IDisputeGameFactory
*/
function gameCount() external view returns (uint256 gameCount_) {
function gameCount() external view returns (uint256 gameCount_) {
gameCount_ = _disputeGameList.length;
gameCount_ = _disputeGameList.length;
}
}
/**
/// @inheritdoc IDisputeGameFactory
* @inheritdoc IDisputeGameFactory
*/
function games(
function games(
GameType _gameType,
GameType _gameType,
Claim _rootClaim,
Claim _rootClaim,
...
@@ -92,9 +72,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
...
@@ -92,9 +72,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
timestamp_ = timestamp;
timestamp_ = timestamp;
}
}
/**
/// @inheritdoc IDisputeGameFactory
* @inheritdoc IDisputeGameFactory
*/
function gameAtIndex(uint256 _index)
function gameAtIndex(uint256 _index)
external
external
view
view
...
@@ -106,9 +84,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
...
@@ -106,9 +84,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
timestamp_ = timestamp;
timestamp_ = timestamp;
}
}
/**
/// @inheritdoc IDisputeGameFactory
* @inheritdoc IDisputeGameFactory
*/
function create(
function create(
GameType gameType,
GameType gameType,
Claim rootClaim,
Claim rootClaim,
...
@@ -142,9 +118,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
...
@@ -142,9 +118,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
emit DisputeGameCreated(address(proxy), gameType, rootClaim);
emit DisputeGameCreated(address(proxy), gameType, rootClaim);
}
}
/**
/// @inheritdoc IDisputeGameFactory
* @inheritdoc IDisputeGameFactory
*/
function getGameUUID(
function getGameUUID(
GameType gameType,
GameType gameType,
Claim rootClaim,
Claim rootClaim,
...
@@ -181,27 +155,21 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
...
@@ -181,27 +155,21 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
}
}
}
}
/**
/// @inheritdoc IDisputeGameFactory
* @inheritdoc IDisputeGameFactory
*/
function setImplementation(GameType gameType, IDisputeGame impl) external onlyOwner {
function setImplementation(GameType gameType, IDisputeGame impl) external onlyOwner {
gameImpls[gameType] = impl;
gameImpls[gameType] = impl;
emit ImplementationSet(address(impl), gameType);
emit ImplementationSet(address(impl), gameType);
}
}
/**
/// @dev Packs an address and a uint256 into a single bytes32 slot. This
* @dev Packs an address and a uint256 into a single bytes32 slot. This
/// is only safe for up to uint96 values.
* is only safe for up to uint96 values.
*/
function _packSlot(address _addr, uint256 _num) internal pure returns (GameId slot_) {
function _packSlot(address _addr, uint256 _num) internal pure returns (GameId slot_) {
assembly {
assembly {
slot_ := or(shl(0xa0, _num), _addr)
slot_ := or(shl(0xa0, _num), _addr)
}
}
}
}
/**
/// @dev Unpacks an address and a uint256 from a single bytes32 slot.
* @dev Unpacks an address and a uint256 from a single bytes32 slot.
*/
function _unpackSlot(GameId _slot) internal pure returns (address addr_, uint256 num_) {
function _unpackSlot(GameId _slot) internal pure returns (address addr_, uint256 num_) {
assembly {
assembly {
addr_ := and(_slot, 0xffffffffffffffffffffffffffffffffffffffff)
addr_ := and(_slot, 0xffffffffffffffffffffffffffffffffffffffff)
...
...
packages/contracts-bedrock/contracts/dispute/FaultDisputeGame.sol
View file @
8478fbfe
...
@@ -15,70 +15,47 @@ import { LibClock } from "./lib/LibClock.sol";
...
@@ -15,70 +15,47 @@ import { LibClock } from "./lib/LibClock.sol";
import "../libraries/DisputeTypes.sol";
import "../libraries/DisputeTypes.sol";
import "../libraries/DisputeErrors.sol";
import "../libraries/DisputeErrors.sol";
/**
/// @title FaultDisputeGame
* @title FaultDisputeGame
/// @notice An implementation of the `IFaultDisputeGame` interface.
* @notice An implementation of the `IFaultDisputeGame` interface.
*/
contract FaultDisputeGame is IFaultDisputeGame, Clone {
contract FaultDisputeGame is IFaultDisputeGame, Clone {
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// State Vars //
// State Vars //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/**
/// @notice The absolute prestate of the instruction trace. This is a constant that is defined
* @notice The current Semver of the FaultDisputeGame implementation.
/// by the program that is being used to execute the trace.
*/
Claim public immutable ABSOLUTE_PRESTATE;
string internal constant VERSION = "0.0.2";
/// @notice The max depth of the game.
uint256 public immutable MAX_GAME_DEPTH;
/**
/// @notice The duration of the game.
* @notice The duration of the game.
/// @dev TODO: Account for resolution buffer. (?)
* @dev TODO: Account for resolution buffer. (?)
*/
Duration internal constant GAME_DURATION = Duration.wrap(7 days);
Duration internal constant GAME_DURATION = Duration.wrap(7 days);
/**
/// @notice The root claim's position is always at gindex 1.
* @notice The root claim's position is always at gindex 1.
*/
Position internal constant ROOT_POSITION = Position.wrap(1);
Position internal constant ROOT_POSITION = Position.wrap(1);
/**
/// @notice The current Semver of the FaultDisputeGame implementation.
* @notice The absolute prestate of the instruction trace. This is a constant that is defined
string internal constant VERSION = "0.0.2";
* by the program that is being used to execute the trace.
*/
Claim public immutable ABSOLUTE_PRESTATE;
/**
* @notice The max depth of the game.
*/
uint256 public immutable MAX_GAME_DEPTH;
/**
/// @notice The starting timestamp of the game
* @notice The starting timestamp of the game
*/
Timestamp public gameStart;
Timestamp public gameStart;
/**
/// @inheritdoc IDisputeGame
* @inheritdoc IDisputeGame
*/
GameStatus public status;
GameStatus public status;
/**
/// @inheritdoc IDisputeGame
* @inheritdoc IDisputeGame
*/
IBondManager public bondManager;
IBondManager public bondManager;
/**
/// @notice An append-only array of all claims made during the dispute game.
* @notice An append-only array of all claims made during the dispute game.
*/
ClaimData[] public claimData;
ClaimData[] public claimData;
/**
/// @notice An internal mapping to allow for constant-time lookups of existing claims.
* @notice An internal mapping to allow for constant-time lookups of existing claims.
*/
mapping(ClaimHash => bool) internal claims;
mapping(ClaimHash => bool) internal claims;
/**
/// @param _absolutePrestate The absolute prestate of the instruction trace.
* @param _absolutePrestate The absolute prestate of the instruction trace.
*/
constructor(Claim _absolutePrestate, uint256 _maxGameDepth) {
constructor(Claim _absolutePrestate, uint256 _maxGameDepth) {
ABSOLUTE_PRESTATE = _absolutePrestate;
ABSOLUTE_PRESTATE = _absolutePrestate;
MAX_GAME_DEPTH = _maxGameDepth;
MAX_GAME_DEPTH = _maxGameDepth;
...
@@ -88,23 +65,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
...
@@ -88,23 +65,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
// External Logic //
// External Logic //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/**
/// @inheritdoc IFaultDisputeGame
* @inheritdoc IFaultDisputeGame
*/
function attack(uint256 _parentIndex, Claim _pivot) external payable {
function attack(uint256 _parentIndex, Claim _pivot) external payable {
_move(_parentIndex, _pivot, true);
_move(_parentIndex, _pivot, true);
}
}
/**
/// @inheritdoc IFaultDisputeGame
* @inheritdoc IFaultDisputeGame
*/
function defend(uint256 _parentIndex, Claim _pivot) external payable {
function defend(uint256 _parentIndex, Claim _pivot) external payable {
_move(_parentIndex, _pivot, false);
_move(_parentIndex, _pivot, false);
}
}
/**
/// @inheritdoc IFaultDisputeGame
* @inheritdoc IFaultDisputeGame
*/
function step(
function step(
uint256 _stateIndex,
uint256 _stateIndex,
uint256 _claimIndex,
uint256 _claimIndex,
...
@@ -182,12 +153,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
...
@@ -182,12 +153,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
// Internal Logic //
// Internal Logic //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/**
/// @notice Internal move function, used by both `attack` and `defend`.
* @notice Internal move function, used by both `attack` and `defend`.
/// @param _challengeIndex The index of the claim being moved against.
* @param _challengeIndex The index of the claim being moved against.
/// @param _pivot The claim at the next logical position in the game.
* @param _pivot The claim at the next logical position in the game.
/// @param _isAttack Whether or not the move is an attack or defense.
* @param _isAttack Whether or not the move is an attack or defense.
*/
function _move(
function _move(
uint256 _challengeIndex,
uint256 _challengeIndex,
Claim _pivot,
Claim _pivot,
...
@@ -275,9 +244,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
...
@@ -275,9 +244,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
emit Move(_challengeIndex, _pivot, msg.sender);
emit Move(_challengeIndex, _pivot, msg.sender);
}
}
/**
/// @inheritdoc IFaultDisputeGame
* @inheritdoc IFaultDisputeGame
*/
function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) {
function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) {
l2BlockNumber_ = _getArgUint256(0x20);
l2BlockNumber_ = _getArgUint256(0x20);
}
}
...
@@ -286,23 +253,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
...
@@ -286,23 +253,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
// `IDisputeGame` impl //
// `IDisputeGame` impl //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/**
/// @inheritdoc IDisputeGame
* @inheritdoc IDisputeGame
*/
function gameType() public pure override returns (GameType gameType_) {
function gameType() public pure override returns (GameType gameType_) {
gameType_ = GameTypes.FAULT;
gameType_ = GameTypes.FAULT;
}
}
/**
/// @inheritdoc IDisputeGame
* @inheritdoc IDisputeGame
*/
function createdAt() external view returns (Timestamp createdAt_) {
function createdAt() external view returns (Timestamp createdAt_) {
createdAt_ = gameStart;
createdAt_ = gameStart;
}
}
/**
/// @inheritdoc IDisputeGame
* @inheritdoc IDisputeGame
*/
function resolve() external returns (GameStatus status_) {
function resolve() external returns (GameStatus status_) {
// TODO: Do not allow resolution before clocks run out.
// TODO: Do not allow resolution before clocks run out.
...
@@ -361,16 +322,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
...
@@ -361,16 +322,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
emit Resolved(status_);
emit Resolved(status_);
}
}
/**
/// @inheritdoc IDisputeGame
* @inheritdoc IDisputeGame
*/
function rootClaim() public pure returns (Claim rootClaim_) {
function rootClaim() public pure returns (Claim rootClaim_) {
rootClaim_ = Claim.wrap(_getArgFixedBytes(0x00));
rootClaim_ = Claim.wrap(_getArgFixedBytes(0x00));
}
}
/**
/// @inheritdoc IDisputeGame
* @inheritdoc IDisputeGame
*/
function extraData() public pure returns (bytes memory extraData_) {
function extraData() public pure returns (bytes memory extraData_) {
// The extra data starts at the second word within the cwia calldata.
// The extra data starts at the second word within the cwia calldata.
// TODO: What data do we need to pass along to this contract from the factory?
// TODO: What data do we need to pass along to this contract from the factory?
...
@@ -378,9 +335,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
...
@@ -378,9 +335,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
extraData_ = _getArgDynBytes(0x20, 0x20);
extraData_ = _getArgDynBytes(0x20, 0x20);
}
}
/**
/// @inheritdoc IDisputeGame
* @inheritdoc IDisputeGame
*/
function gameData()
function gameData()
external
external
pure
pure
...
@@ -395,9 +350,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
...
@@ -395,9 +350,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
extraData_ = extraData();
extraData_ = extraData();
}
}
/**
/// @inheritdoc IInitializable
* @inheritdoc IInitializable
*/
function initialize() external {
function initialize() external {
// Set the game start
// Set the game start
gameStart = Timestamp.wrap(uint64(block.timestamp));
gameStart = Timestamp.wrap(uint64(block.timestamp));
...
@@ -416,9 +369,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
...
@@ -416,9 +369,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
);
);
}
}
/**
/// @inheritdoc IVersioned
* @inheritdoc IVersioned
*/
function version() external pure override returns (string memory version_) {
function version() external pure override returns (string memory version_) {
version_ = VERSION;
version_ = VERSION;
}
}
...
...
packages/contracts-bedrock/contracts/dispute/interfaces/IBondManager.sol
View file @
8478fbfe
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.15;
/**
/// @title IBondManager
* @title IBondManager
/// @notice The Bond Manager holds ether posted as a bond for a bond id.
* @notice The Bond Manager holds ether posted as a bond for a bond id.
*/
interface IBondManager {
interface IBondManager {
/**
/// @notice BondPosted is emitted when a bond is posted.
* @notice BondPosted is emitted when a bond is posted.
/// @param bondId is the id of the bond.
* @param bondId is the id of the bond.
/// @param owner is the address that owns the bond.
* @param owner is the address that owns the bond.
/// @param expiration is the time at which the bond expires.
* @param expiration is the time at which the bond expires.
/// @param amount is the amount of the bond.
* @param amount is the amount of the bond.
*/
event BondPosted(bytes32 bondId, address owner, uint256 expiration, uint256 amount);
event BondPosted(bytes32 bondId, address owner, uint256 expiration, uint256 amount);
/**
/// @notice BondSeized is emitted when a bond is seized.
* @notice BondSeized is emitted when a bond is seized.
/// @param bondId is the id of the bond.
* @param bondId is the id of the bond.
/// @param owner is the address that owns the bond.
* @param owner is the address that owns the bond.
/// @param seizer is the address that seized the bond.
* @param seizer is the address that seized the bond.
/// @param amount is the amount of the bond.
* @param amount is the amount of the bond.
*/
event BondSeized(bytes32 bondId, address owner, address seizer, uint256 amount);
event BondSeized(bytes32 bondId, address owner, address seizer, uint256 amount);
/**
/// @notice BondReclaimed is emitted when a bond is reclaimed by the owner.
* @notice BondReclaimed is emitted when a bond is reclaimed by the owner.
/// @param bondId is the id of the bond.
* @param bondId is the id of the bond.
/// @param claiment is the address that reclaimed the bond.
* @param claiment is the address that reclaimed the bond.
/// @param amount is the amount of the bond.
* @param amount is the amount of the bond.
*/
event BondReclaimed(bytes32 bondId, address claiment, uint256 amount);
event BondReclaimed(bytes32 bondId, address claiment, uint256 amount);
/**
/// @notice Post a bond with a given id and owner.
* @notice Post a bond with a given id and owner.
/// @dev This function will revert if the provided bondId is already in use.
* @dev This function will revert if the provided bondId is already in use.
/// @param _bondId is the id of the bond.
* @param _bondId is the id of the bond.
/// @param _bondOwner is the address that owns the bond.
* @param _bondOwner is the address that owns the bond.
/// @param _minClaimHold is the minimum amount of time the owner
* @param _minClaimHold is the minimum amount of time the owner
/// must wait before reclaiming their bond.
* must wait before reclaiming their bond.
*/
function post(
function post(
bytes32 _bondId,
bytes32 _bondId,
address _bondOwner,
address _bondOwner,
uint128 _minClaimHold
uint128 _minClaimHold
) external payable;
) external payable;
/**
/// @notice Seizes the bond with the given id.
* @notice Seizes the bond with the given id.
/// @dev This function will revert if there is no bond at the given id.
* @dev This function will revert if there is no bond at the given id.
/// @param _bondId is the id of the bond.
* @param _bondId is the id of the bond.
*/
function seize(bytes32 _bondId) external;
function seize(bytes32 _bondId) external;
/**
/// @notice Seizes the bond with the given id and distributes it to recipients.
* @notice Seizes the bond with the given id and distributes it to recipients.
/// @dev This function will revert if there is no bond at the given id.
* @dev This function will revert if there is no bond at the given id.
/// @param _bondId is the id of the bond.
* @param _bondId is the id of the bond.
/// @param _claimRecipients is a set of addresses to split the bond amongst.
* @param _claimRecipients is a set of addresses to split the bond amongst.
///
*/
function seizeAndSplit(bytes32 _bondId, address[] calldata _claimRecipients) external;
function seizeAndSplit(bytes32 _bondId, address[] calldata _claimRecipients) external;
/**
/// @notice Reclaims the bond of the bond owner.
* @notice Reclaims the bond of the bond owner.
/// @dev This function will revert if there is no bond at the given id.
* @dev This function will revert if there is no bond at the given id.
/// @param _bondId is the id of the bond.
* @param _bondId is the id of the bond.
*/
function reclaim(bytes32 _bondId) external;
function reclaim(bytes32 _bondId) external;
}
}
packages/contracts-bedrock/contracts/dispute/interfaces/IDisputeGame.sol
View file @
8478fbfe
...
@@ -7,77 +7,57 @@ import { IVersioned } from "./IVersioned.sol";
...
@@ -7,77 +7,57 @@ import { IVersioned } from "./IVersioned.sol";
import { IBondManager } from "./IBondManager.sol";
import { IBondManager } from "./IBondManager.sol";
import { IInitializable } from "./IInitializable.sol";
import { IInitializable } from "./IInitializable.sol";
/**
/// @title IDisputeGame
* @title IDisputeGame
/// @notice The generic interface for a DisputeGame contract.
* @notice The generic interface for a DisputeGame contract.
*/
interface IDisputeGame is IInitializable, IVersioned {
interface IDisputeGame is IInitializable, IVersioned {
/**
/// @notice Emitted when the game is resolved.
* @notice Emitted when the game is resolved.
/// @param status The status of the game after resolution.
* @param status The status of the game after resolution.
*/
event Resolved(GameStatus indexed status);
event Resolved(GameStatus indexed status);
/**
/// @notice Returns the timestamp that the DisputeGame contract was created at.
* @notice Returns the timestamp that the DisputeGame contract was created at.
/// @return createdAt_ The timestamp that the DisputeGame contract was created at.
* @return createdAt_ The timestamp that the DisputeGame contract was created at.
*/
function createdAt() external view returns (Timestamp createdAt_);
function createdAt() external view returns (Timestamp createdAt_);
/**
/// @notice Returns the current status of the game.
* @notice Returns the current status of the game.
/// @return status_ The current status of the game.
* @return status_ The current status of the game.
*/
function status() external view returns (GameStatus status_);
function status() external view returns (GameStatus status_);
/**
/// @notice Getter for the game type.
* @notice Getter for the game type.
/// @dev `clones-with-immutable-args` argument #1
* @dev `clones-with-immutable-args` argument #1
/// @dev The reference impl should be entirely different depending on the type (fault, validity)
* @dev The reference impl should be entirely different depending on the type (fault, validity)
/// i.e. The game type should indicate the security model.
* i.e. The game type should indicate the security model.
/// @return gameType_ The type of proof system being used.
* @return gameType_ The type of proof system being used.
*/
function gameType() external pure returns (GameType gameType_);
function gameType() external pure returns (GameType gameType_);
/**
/// @notice Getter for the root claim.
* @notice Getter for the root claim.
/// @dev `clones-with-immutable-args` argument #2
* @dev `clones-with-immutable-args` argument #2
/// @return rootClaim_ The root claim of the DisputeGame.
* @return rootClaim_ The root claim of the DisputeGame.
*/
function rootClaim() external pure returns (Claim rootClaim_);
function rootClaim() external pure returns (Claim rootClaim_);
/**
/// @notice Getter for the extra data.
* @notice Getter for the extra data.
/// @dev `clones-with-immutable-args` argument #3
* @dev `clones-with-immutable-args` argument #3
/// @return extraData_ Any extra data supplied to the dispute game contract by the creator.
* @return extraData_ Any extra data supplied to the dispute game contract by the creator.
*/
function extraData() external pure returns (bytes memory extraData_);
function extraData() external pure returns (bytes memory extraData_);
/**
/// @notice Returns the address of the `BondManager` used.
* @notice Returns the address of the `BondManager` used.
/// @return bondManager_ The address of the `BondManager` used.
* @return bondManager_ The address of the `BondManager` used.
*/
function bondManager() external view returns (IBondManager bondManager_);
function bondManager() external view returns (IBondManager bondManager_);
/**
/// @notice If all necessary information has been gathered, this function should mark the game
* @notice If all necessary information has been gathered, this function should mark the game
/// status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of
* status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of
/// the resolved game. It is at this stage that the bonds should be awarded to the
* the resolved game. It is at this stage that the bonds should be awarded to the
/// necessary parties.
* necessary parties.
/// @dev May only be called if the `status` is `IN_PROGRESS`.
* @dev May only be called if the `status` is `IN_PROGRESS`.
/// @return status_ The status of the game after resolution.
* @return status_ The status of the game after resolution.
*/
function resolve() external returns (GameStatus status_);
function resolve() external returns (GameStatus status_);
/**
/// @notice A compliant implementation of this interface should return the components of the
* @notice A compliant implementation of this interface should return the components of the
/// game UUID's preimage provided in the cwia payload. The preimage of the UUID is
* game UUID's preimage provided in the cwia payload. The preimage of the UUID is
/// constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes
* constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes
/// concatenation.
* concatenation.
/// @return gameType_ The type of proof system being used.
* @return gameType_ The type of proof system being used.
/// @return rootClaim_ The root claim of the DisputeGame.
* @return rootClaim_ The root claim of the DisputeGame.
/// @return extraData_ Any extra data supplied to the dispute game contract by the creator.
* @return extraData_ Any extra data supplied to the dispute game contract by the creator.
*/
function gameData()
function gameData()
external
external
pure
pure
...
...
packages/contracts-bedrock/contracts/dispute/interfaces/IDisputeGameFactory.sol
View file @
8478fbfe
...
@@ -5,105 +5,87 @@ import "../../libraries/DisputeTypes.sol";
...
@@ -5,105 +5,87 @@ import "../../libraries/DisputeTypes.sol";
import { IDisputeGame } from "./IDisputeGame.sol";
import { IDisputeGame } from "./IDisputeGame.sol";
/**
/// @title IDisputeGameFactory
* @title IDisputeGameFactory
/// @notice The interface for a DisputeGameFactory contract.
* @notice The interface for a DisputeGameFactory contract.
*/
interface IDisputeGameFactory {
interface IDisputeGameFactory {
/**
/// @notice Emitted when a new dispute game is created
* @notice Emitted when a new dispute game is created
/// @param disputeProxy The address of the dispute game proxy
* @param disputeProxy The address of the dispute game proxy
/// @param gameType The type of the dispute game proxy's implementation
* @param gameType The type of the dispute game proxy's implementation
/// @param rootClaim The root claim of the dispute game
* @param rootClaim The root claim of the dispute game
*/
event DisputeGameCreated(
event DisputeGameCreated(
address indexed disputeProxy,
address indexed disputeProxy,
GameType indexed gameType,
GameType indexed gameType,
Claim indexed rootClaim
Claim indexed rootClaim
);
);
/**
/// @notice Emitted when a new game implementation added to the factory
* @notice Emitted when a new game implementation added to the factory
/// @param impl The implementation contract for the given `GameType`.
* @param impl The implementation contract for the given `GameType`.
/// @param gameType The type of the DisputeGame.
* @param gameType The type of the DisputeGame.
*/
event ImplementationSet(address indexed impl, GameType indexed gameType);
event ImplementationSet(address indexed impl, GameType indexed gameType);
/**
/// @notice the total number of dispute games created by this factory.
* @notice the total number of dispute games created by this factory.
/// @return _gameCount The total number of dispute games created by this factory.
* @return _gameCount The total number of dispute games created by this factory.
*/
function gameCount() external view returns (uint256 _gameCount);
function gameCount() external view returns (uint256 _gameCount);
/**
/// @notice `games` queries an internal a mapping that maps the hash of
* @notice `games` queries an internal a mapping that maps the hash of
/// `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone.
* `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone.
/// @dev `++` equates to concatenation.
* @dev `++` equates to concatenation.
/// @param gameType The type of the DisputeGame - used to decide the proxy implementation
* @param gameType The type of the DisputeGame - used to decide the proxy implementation
/// @param rootClaim The root claim of the DisputeGame.
* @param rootClaim The root claim of the DisputeGame.
/// @param extraData Any extra data that should be provided to the created dispute game.
* @param extraData Any extra data that should be provided to the created dispute game.
/// @return _proxy The clone of the `DisputeGame` created with the given parameters.
* @return _proxy The clone of the `DisputeGame` created with the given parameters.
/// Returns `address(0)` if nonexistent.
* Returns `address(0)` if nonexistent.
/// @return _timestamp The timestamp of the creation of the dispute game.
* @return _timestamp The timestamp of the creation of the dispute game.
*/
function games(
function games(
GameType gameType,
GameType gameType,
Claim rootClaim,
Claim rootClaim,
bytes calldata extraData
bytes calldata extraData
) external view returns (IDisputeGame _proxy, uint256 _timestamp);
) external view returns (IDisputeGame _proxy, uint256 _timestamp);
/**
/// @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp
* @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp
/// at the given index. Each created dispute game increments the underlying index.
* at the given index. Each created dispute game increments the underlying index.
/// @param _index The index of the dispute game.
* @param _index The index of the dispute game.
/// @return _proxy The clone of the `DisputeGame` created with the given parameters.
* @return _proxy The clone of the `DisputeGame` created with the given parameters.
/// Returns `address(0)` if nonexistent.
* Returns `address(0)` if nonexistent.
/// @return _timestamp The timestamp of the creation of the dispute game.
* @return _timestamp The timestamp of the creation of the dispute game.
*/
function gameAtIndex(uint256 _index)
function gameAtIndex(uint256 _index)
external
external
view
view
returns (IDisputeGame _proxy, uint256 _timestamp);
returns (IDisputeGame _proxy, uint256 _timestamp);
/**
/// @notice `gameImpls` is a mapping that maps `GameType`s to their respective
* @notice `gameImpls` is a mapping that maps `GameType`s to their respective
/// `IDisputeGame` implementations.
* `IDisputeGame` implementations.
/// @param gameType The type of the dispute game.
* @param gameType The type of the dispute game.
/// @return _impl The address of the implementation of the game type.
* @return _impl The address of the implementation of the game type.
/// Will be cloned on creation of a new dispute game with the given `gameType`.
* Will be cloned on creation of a new dispute game with the given `gameType`.
*/
function gameImpls(GameType gameType) external view returns (IDisputeGame _impl);
function gameImpls(GameType gameType) external view returns (IDisputeGame _impl);
/**
/// @notice Creates a new DisputeGame proxy contract.
* @notice Creates a new DisputeGame proxy contract.
/// @param gameType The type of the DisputeGame - used to decide the proxy implementation
* @param gameType The type of the DisputeGame - used to decide the proxy implementation
/// @param rootClaim The root claim of the DisputeGame.
* @param rootClaim The root claim of the DisputeGame.
/// @param extraData Any extra data that should be provided to the created dispute game.
* @param extraData Any extra data that should be provided to the created dispute game.
/// @return proxy The address of the created DisputeGame proxy.
* @return proxy The address of the created DisputeGame proxy.
*/
function create(
function create(
GameType gameType,
GameType gameType,
Claim rootClaim,
Claim rootClaim,
bytes calldata extraData
bytes calldata extraData
) external returns (IDisputeGame proxy);
) external returns (IDisputeGame proxy);
/
**
/
//
*
@notice Sets the implementation contract for a specific `GameType`.
///
@notice Sets the implementation contract for a specific `GameType`.
*
@dev May only be called by the `owner`.
///
@dev May only be called by the `owner`.
*
@param gameType The type of the DisputeGame.
///
@param gameType The type of the DisputeGame.
*
@param impl The implementation contract for the given `GameType`.
///
@param impl The implementation contract for the given `GameType`.
*
/
//
/
function setImplementation(GameType gameType, IDisputeGame impl) external;
function setImplementation(GameType gameType, IDisputeGame impl) external;
/**
/// @notice Returns a unique identifier for the given dispute game parameters.
* @notice Returns a unique identifier for the given dispute game parameters.
/// @dev Hashes the concatenation of `gameType . rootClaim . extraData`
* @dev Hashes the concatenation of `gameType . rootClaim . extraData`
/// without expanding memory.
* without expanding memory.
/// @param gameType The type of the DisputeGame.
* @param gameType The type of the DisputeGame.
/// @param rootClaim The root claim of the DisputeGame.
* @param rootClaim The root claim of the DisputeGame.
/// @param extraData Any extra data that should be provided to the created dispute game.
* @param extraData Any extra data that should be provided to the created dispute game.
/// @return _uuid The unique identifier for the given dispute game parameters.
* @return _uuid The unique identifier for the given dispute game parameters.
*/
function getGameUUID(
function getGameUUID(
GameType gameType,
GameType gameType,
Claim rootClaim,
Claim rootClaim,
...
...
packages/contracts-bedrock/contracts/dispute/interfaces/IFaultDisputeGame.sol
View file @
8478fbfe
...
@@ -5,16 +5,11 @@ import "../../libraries/DisputeTypes.sol";
...
@@ -5,16 +5,11 @@ import "../../libraries/DisputeTypes.sol";
import { IDisputeGame } from "./IDisputeGame.sol";
import { IDisputeGame } from "./IDisputeGame.sol";
/**
/// @title IFaultDisputeGame
* @title IFaultDisputeGame
/// @notice The interface for a fault proof backed dispute game.
* @notice The interface for a fault proof backed dispute game.
*/
interface IFaultDisputeGame is IDisputeGame {
interface IFaultDisputeGame is IDisputeGame {
/**
/// @notice The `ClaimData` struct represents the data associated with a Claim.
* @notice The `ClaimData` struct represents the data associated with a Claim.
/// @dev TODO: Add bond ID information.
* @dev TODO: Pack `Clock` and `Position` into the same slot. Should require 4 64 bit arms.
* @dev TODO: Add bond ID information.
*/
struct ClaimData {
struct ClaimData {
uint32 parentIndex;
uint32 parentIndex;
bool countered;
bool countered;
...
@@ -23,40 +18,32 @@ interface IFaultDisputeGame is IDisputeGame {
...
@@ -23,40 +18,32 @@ interface IFaultDisputeGame is IDisputeGame {
Clock clock;
Clock clock;
}
}
/**
/// @notice Emitted when a new claim is added to the DAG by `claimant`
* @notice Emitted when a new claim is added to the DAG by `claimant`
/// @param parentIndex The index within the `claimData` array of the parent claim
* @param parentIndex The index within the `claimData` array of the parent claim
/// @param pivot The claim being added
* @param pivot The claim being added
/// @param claimant The address of the claimant
* @param claimant The address of the claimant
*/
event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant);
event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant);
/**
/// @notice Attack a disagreed upon `Claim`.
* @notice Attack a disagreed upon `Claim`.
/// @param _parentIndex Index of the `Claim` to attack in `claimData`.
* @param _parentIndex Index of the `Claim` to attack in `claimData`.
/// @param _pivot The `Claim` at the relative attack position.
* @param _pivot The `Claim` at the relative attack position.
*/
function attack(uint256 _parentIndex, Claim _pivot) external payable;
function attack(uint256 _parentIndex, Claim _pivot) external payable;
/**
/// @notice Defend an agreed upon `Claim`.
* @notice Defend an agreed upon `Claim`.
/// @param _parentIndex Index of the claim to defend in `claimData`.
* @param _parentIndex Index of the claim to defend in `claimData`.
/// @param _pivot The `Claim` at the relative defense position.
* @param _pivot The `Claim` at the relative defense position.
*/
function defend(uint256 _parentIndex, Claim _pivot) external payable;
function defend(uint256 _parentIndex, Claim _pivot) external payable;
/**
/// @notice Perform the final step via an on-chain fault proof processor
* @notice Perform the final step via an on-chain fault proof processor
/// @dev This function should point to a fault proof processor in order to execute
* @dev This function should point to a fault proof processor in order to execute
/// a step in the fault proof program on-chain. The interface of the fault proof
* a step in the fault proof program on-chain. The interface of the fault proof
/// processor contract should be generic enough such that we can use different
* processor contract should be generic enough such that we can use different
/// fault proof VMs (MIPS, RiscV5, etc.)
* fault proof VMs (MIPS, RiscV5, etc.)
/// @param _stateIndex The index of the pre/post state of the step within `claimData`.
* @param _stateIndex The index of the pre/post state of the step within `claimData`.
/// @param _claimIndex The index of the challenged claim within `claimData`.
* @param _claimIndex The index of the challenged claim within `claimData`.
/// @param _isAttack Whether or not the step is an attack or a defense.
* @param _isAttack Whether or not the step is an attack or a defense.
/// @param _stateData The stateData of the step is the preimage of the claim @ `prestateIndex`
* @param _stateData The stateData of the step is the preimage of the claim @ `prestateIndex`
/// @param _proof Proof to access memory leaf nodes in the VM.
* @param _proof Proof to access memory leaf nodes in the VM.
*/
function step(
function step(
uint256 _stateIndex,
uint256 _stateIndex,
uint256 _claimIndex,
uint256 _claimIndex,
...
@@ -65,10 +52,8 @@ interface IFaultDisputeGame is IDisputeGame {
...
@@ -65,10 +52,8 @@ interface IFaultDisputeGame is IDisputeGame {
bytes calldata _proof
bytes calldata _proof
) external;
) external;
/**
/// @notice The l2BlockNumber that the `rootClaim` commits to. The trace being bisected within
* @notice The l2BlockNumber that the `rootClaim` commits to. The trace being bisected within
/// the game is from `l2BlockNumber - 1` -> `l2BlockNumber`.
* the game is from `l2BlockNumber - 1` -> `l2BlockNumber`.
/// @return l2BlockNumber_ The l2BlockNumber that the `rootClaim` commits to.
* @return l2BlockNumber_ The l2BlockNumber that the `rootClaim` commits to.
*/
function l2BlockNumber() external view returns (uint256 l2BlockNumber_);
function l2BlockNumber() external view returns (uint256 l2BlockNumber_);
}
}
packages/contracts-bedrock/contracts/dispute/interfaces/IInitializable.sol
View file @
8478fbfe
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.15;
/**
/// @title IInitializable
* @title IInitializable
/// @notice An interface for initializable contracts.
* @notice An interface for initializable contracts.
*/
interface IInitializable {
interface IInitializable {
/**
/// @notice Initializes the contract.
* @notice Initializes the contract.
/// @dev This function may only be called once.
* @dev This function may only be called once.
*/
function initialize() external;
function initialize() external;
}
}
packages/contracts-bedrock/contracts/dispute/interfaces/IVersioned.sol
View file @
8478fbfe
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
pragma solidity ^0.8.15;
/**
/// @title IVersioned
* @title IVersioned
/// @notice An interface for semantically versioned contracts.
* @notice An interface for semantically versioned contracts.
*/
interface IVersioned {
interface IVersioned {
/**
/// @notice Returns the semantic version of the contract
* @notice Returns the semantic version of the contract
/// @return _version The semantic version of the contract
* @return _version The semantic version of the contract
*/
function version() external pure returns (string memory _version);
function version() external pure returns (string memory _version);
}
}
packages/contracts-bedrock/contracts/dispute/lib/LibClock.sol
View file @
8478fbfe
...
@@ -3,28 +3,22 @@ pragma solidity ^0.8.15;
...
@@ -3,28 +3,22 @@ pragma solidity ^0.8.15;
import "../../libraries/DisputeTypes.sol";
import "../../libraries/DisputeTypes.sol";
/**
/// @title LibClock
* @title LibClock
/// @notice This library contains helper functions for working with the `Clock` type.
* @notice This library contains helper functions for working with the `Clock` type.
*/
library LibClock {
library LibClock {
/**
/// @notice Packs a `Duration` and `Timestamp` into a `Clock` type.
* @notice Packs a `Duration` and `Timestamp` into a `Clock` type.
/// @param _duration The `Duration` to pack into the `Clock` type.
* @param _duration The `Duration` to pack into the `Clock` type.
/// @param _timestamp The `Timestamp` to pack into the `Clock` type.
* @param _timestamp The `Timestamp` to pack into the `Clock` type.
/// @return clock_ The `Clock` containing the `_duration` and `_timestamp`.
* @return clock_ The `Clock` containing the `_duration` and `_timestamp`.
*/
function wrap(Duration _duration, Timestamp _timestamp) internal pure returns (Clock clock_) {
function wrap(Duration _duration, Timestamp _timestamp) internal pure returns (Clock clock_) {
assembly {
assembly {
clock_ := or(shl(0x40, _duration), _timestamp)
clock_ := or(shl(0x40, _duration), _timestamp)
}
}
}
}
/**
/// @notice Pull the `Duration` out of a `Clock` type.
* @notice Pull the `Duration` out of a `Clock` type.
/// @param _clock The `Clock` type to pull the `Duration` out of.
* @param _clock The `Clock` type to pull the `Duration` out of.
/// @return duration_ The `Duration` pulled out of `_clock`.
* @return duration_ The `Duration` pulled out of `_clock`.
*/
function duration(Clock _clock) internal pure returns (Duration duration_) {
function duration(Clock _clock) internal pure returns (Duration duration_) {
// Shift the high-order 64 bits into the low-order 64 bits, leaving only the `duration`.
// Shift the high-order 64 bits into the low-order 64 bits, leaving only the `duration`.
assembly {
assembly {
...
@@ -32,11 +26,9 @@ library LibClock {
...
@@ -32,11 +26,9 @@ library LibClock {
}
}
}
}
/**
/// @notice Pull the `Timestamp` out of a `Clock` type.
* @notice Pull the `Timestamp` out of a `Clock` type.
/// @param _clock The `Clock` type to pull the `Timestamp` out of.
* @param _clock The `Clock` type to pull the `Timestamp` out of.
/// @return timestamp_ The `Timestamp` pulled out of `_clock`.
* @return timestamp_ The `Timestamp` pulled out of `_clock`.
*/
function timestamp(Clock _clock) internal pure returns (Timestamp timestamp_) {
function timestamp(Clock _clock) internal pure returns (Timestamp timestamp_) {
// Clean the high-order 192 bits by shifting the clock left and then right again, leaving
// Clean the high-order 192 bits by shifting the clock left and then right again, leaving
// only the `timestamp`.
// only the `timestamp`.
...
...
packages/contracts-bedrock/contracts/dispute/lib/LibHashing.sol
View file @
8478fbfe
...
@@ -3,17 +3,14 @@ pragma solidity ^0.8.15;
...
@@ -3,17 +3,14 @@ pragma solidity ^0.8.15;
import "../../libraries/DisputeTypes.sol";
import "../../libraries/DisputeTypes.sol";
/**
/// @title Hashing
* @title Hashing
/// @notice This library contains all of the hashing utilities used in the Cannon contracts.
* @notice This library contains all of the hashing utilities used in the Cannon contracts.
*/
library LibHashing {
library LibHashing {
/**
* @notice Hashes a claim and a position together.
/// @notice Hashes a claim and a position together.
* @param _claim A Claim type.
/// @param _claim A Claim type.
* @param _position The position of `claim`.
/// @param _position The position of `claim`.
* @return claimHash_ A hash of abi.encodePacked(claim, position);
/// @return claimHash_ A hash of abi.encodePacked(claim, position);
*/
function hashClaimPos(Claim _claim, Position _position) internal pure returns (ClaimHash claimHash_) {
function hashClaimPos(Claim _claim, Position _position) internal pure returns (ClaimHash claimHash_) {
assembly {
assembly {
mstore(0x00, _claim)
mstore(0x00, _claim)
...
...
packages/contracts-bedrock/contracts/dispute/lib/LibPosition.sol
View file @
8478fbfe
...
@@ -3,17 +3,14 @@ pragma solidity ^0.8.15;
...
@@ -3,17 +3,14 @@ pragma solidity ^0.8.15;
import "../../libraries/DisputeTypes.sol";
import "../../libraries/DisputeTypes.sol";
/**
/// @title LibPosition
* @title LibPosition
/// @notice This library contains helper functions for working with the `Position` type.
* @notice This library contains helper functions for working with the `Position` type.
*/
library LibPosition {
library LibPosition {
/**
* @notice Computes a generalized index (2^{depth} + indexAtDepth).
/// @notice Computes a generalized index (2^{depth} + indexAtDepth).
* @param _depth The depth of the position.
/// @param _depth The depth of the position.
* @param _indexAtDepth The index at the depth of the position.
/// @param _indexAtDepth The index at the depth of the position.
* @return position_ The computed generalized index.
/// @return position_ The computed generalized index.
*/
function wrap(uint64 _depth, uint64 _indexAtDepth) internal pure returns (Position position_) {
function wrap(uint64 _depth, uint64 _indexAtDepth) internal pure returns (Position position_) {
assembly {
assembly {
// gindex = 2^{_depth} + _indexAtDepth
// gindex = 2^{_depth} + _indexAtDepth
...
@@ -21,12 +18,10 @@ library LibPosition {
...
@@ -21,12 +18,10 @@ library LibPosition {
}
}
}
}
/**
/// @notice Pulls the `depth` out of a `Position` type.
* @notice Pulls the `depth` out of a `Position` type.
/// @param _position The generalized index to get the `depth` of.
* @param _position The generalized index to get the `depth` of.
/// @return depth_ The `depth` of the `position` gindex.
* @return depth_ The `depth` of the `position` gindex.
/// @custom:attribution Solady <https://github.com/Vectorized/Solady>
* @custom:attribution Solady <https://github.com/Vectorized/Solady>
*/
function depth(Position _position) internal pure returns (uint64 depth_) {
function depth(Position _position) internal pure returns (uint64 depth_) {
// Return the most significant bit offset, which signifies the depth of the gindex.
// Return the most significant bit offset, which signifies the depth of the gindex.
assembly {
assembly {
...
@@ -51,14 +46,12 @@ library LibPosition {
...
@@ -51,14 +46,12 @@ library LibPosition {
}
}
}
}
/**
/// @notice Pulls the `indexAtDepth` out of a `Position` type.
* @notice Pulls the `indexAtDepth` out of a `Position` type.
/// The `indexAtDepth` is the left/right index of a position at a specific depth within
* The `indexAtDepth` is the left/right index of a position at a specific depth within
/// the binary tree, starting from index 0. For example, at gindex 2, the `depth` = 1
* the binary tree, starting from index 0. For example, at gindex 2, the `depth` = 1
/// and the `indexAtDepth` = 0.
* and the `indexAtDepth` = 0.
/// @param _position The generalized index to get the `indexAtDepth` of.
* @param _position The generalized index to get the `indexAtDepth` of.
/// @return indexAtDepth_ The `indexAtDepth` of the `position` gindex.
* @return indexAtDepth_ The `indexAtDepth` of the `position` gindex.
*/
function indexAtDepth(Position _position) internal pure returns (uint64 indexAtDepth_) {
function indexAtDepth(Position _position) internal pure returns (uint64 indexAtDepth_) {
// Return bits p_{msb-1}...p_{0}. This effectively pulls the 2^{depth} out of the gindex,
// Return bits p_{msb-1}...p_{0}. This effectively pulls the 2^{depth} out of the gindex,
// leaving only the `indexAtDepth`.
// leaving only the `indexAtDepth`.
...
@@ -68,46 +61,38 @@ library LibPosition {
...
@@ -68,46 +61,38 @@ library LibPosition {
}
}
}
}
/**
/// @notice Get the left child of `_position`.
* @notice Get the left child of `_position`.
/// @param _position The position to get the left position of.
* @param _position The position to get the left position of.
/// @return left_ The position to the left of `position`.
* @return left_ The position to the left of `position`.
*/
function left(Position _position) internal pure returns (Position left_) {
function left(Position _position) internal pure returns (Position left_) {
assembly {
assembly {
left_ := shl(1, _position)
left_ := shl(1, _position)
}
}
}
}
/**
/// @notice Get the right child of `_position`
* @notice Get the right child of `_position`
/// @param _position The position to get the right position of.
* @param _position The position to get the right position of.
/// @return right_ The position to the right of `position`.
* @return right_ The position to the right of `position`.
*/
function right(Position _position) internal pure returns (Position right_) {
function right(Position _position) internal pure returns (Position right_) {
assembly {
assembly {
right_ := or(1, shl(1, _position))
right_ := or(1, shl(1, _position))
}
}
}
}
/**
/// @notice Get the parent position of `_position`.
* @notice Get the parent position of `_position`.
/// @param _position The position to get the parent position of.
* @param _position The position to get the parent position of.
/// @return parent_ The parent position of `position`.
* @return parent_ The parent position of `position`.
*/
function parent(Position _position) internal pure returns (Position parent_) {
function parent(Position _position) internal pure returns (Position parent_) {
assembly {
assembly {
parent_ := shr(1, _position)
parent_ := shr(1, _position)
}
}
}
}
/**
/// @notice Get the deepest, right most gindex relative to the `position`. This is equivalent to
* @notice Get the deepest, right most gindex relative to the `position`. This is equivalent to
/// calling `right` on a position until the maximum depth is reached.
* calling `right` on a position until the maximum depth is reached.
/// @param _position The position to get the relative deepest, right most gindex of.
* @param _position The position to get the relative deepest, right most gindex of.
/// @param _maxDepth The maximum depth of the game.
* @param _maxDepth The maximum depth of the game.
/// @return rightIndex_ The deepest, right most gindex relative to the `position`.
* @return rightIndex_ The deepest, right most gindex relative to the `position`.
*/
function rightIndex(
function rightIndex(
Position _position,
Position _position,
uint256 _maxDepth
uint256 _maxDepth
...
@@ -119,14 +104,12 @@ library LibPosition {
...
@@ -119,14 +104,12 @@ library LibPosition {
}
}
}
}
/**
/// @notice Get the move position of `_position`, which is the left child of:
* @notice Get the move position of `_position`, which is the left child of:
/// 1. `_position + 1` if `_isAttack` is true.
* 1. `_position + 1` if `_isAttack` is true.
/// 1. `_position` if `_isAttack` is false.
* 1. `_position` if `_isAttack` is false.
/// @param _position The position to get the relative attack/defense position of.
* @param _position The position to get the relative attack/defense position of.
/// @param _isAttack Whether or not the move is an attack move.
* @param _isAttack Whether or not the move is an attack move.
/// @return move_ The move position relative to `position`.
* @return move_ The move position relative to `position`.
*/
function move(Position _position, bool _isAttack) internal pure returns (Position move_) {
function move(Position _position, bool _isAttack) internal pure returns (Position move_) {
assembly {
assembly {
move_ := shl(1, or(iszero(_isAttack), _position))
move_ := shl(1, or(iszero(_isAttack), _position))
...
...
packages/contracts-bedrock/contracts/libraries/DisputeErrors.sol
View file @
8478fbfe
...
@@ -7,95 +7,65 @@ import "./DisputeTypes.sol";
...
@@ -7,95 +7,65 @@ import "./DisputeTypes.sol";
// `DisputeGameFactory` Errors //
// `DisputeGameFactory` Errors //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/**
/// @notice Thrown when a dispute game is attempted to be created with an unsupported game type.
* @notice Thrown when a dispute game is attempted to be created with an unsupported game type.
/// @param gameType The unsupported game type.
* @param gameType The unsupported game type.
*/
error NoImplementation(GameType gameType);
error NoImplementation(GameType gameType);
/**
/// @notice Thrown when a dispute game that already exists is attempted to be created.
* @notice Thrown when a dispute game that already exists is attempted to be created.
/// @param uuid The UUID of the dispute game that already exists.
* @param uuid The UUID of the dispute game that already exists.
*/
error GameAlreadyExists(Hash uuid);
error GameAlreadyExists(Hash uuid);
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// `DisputeGame_Fault.sol` Errors //
// `DisputeGame_Fault.sol` Errors //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/**
/// @notice Thrown when a supplied bond is too low to cover the
* @notice Thrown when a supplied bond is too low to cover the
/// cost of the next possible counter claim.
* cost of the next possible counter claim.
*/
error BondTooLow();
error BondTooLow();
/**
/// @notice Thrown when a defense against the root claim is attempted.
* @notice Thrown when a defense against the root claim is attempted.
*/
error CannotDefendRootClaim();
error CannotDefendRootClaim();
/**
/// @notice Thrown when a claim is attempting to be made that already exists.
* @notice Thrown when a claim is attempting to be made that already exists.
*/
error ClaimAlreadyExists();
error ClaimAlreadyExists();
/**
/// @notice Thrown when a given claim is invalid (0).
* @notice Thrown when a given claim is invalid (0).
*/
error InvalidClaim();
error InvalidClaim();
/**
/// @notice Thrown when an action that requires the game to be `IN_PROGRESS` is invoked when
* @notice Thrown when an action that requires the game to be `IN_PROGRESS` is invoked when
/// the game is not in progress.
* the game is not in progress.
*/
error GameNotInProgress();
error GameNotInProgress();
/**
/// @notice Thrown when a move is attempted to be made after the clock has timed out.
* @notice Thrown when a move is attempted to be made after the clock has timed out.
*/
error ClockTimeExceeded();
error ClockTimeExceeded();
/**
/// @notice Thrown when a move is attempted to be made at or greater than the max depth of the game.
* @notice Thrown when a move is attempted to be made at or greater than the max depth of the game.
*/
error GameDepthExceeded();
error GameDepthExceeded();
/**
/// @notice Thrown when a step is attempted above the maximum game depth.
* @notice Thrown when a step is attempted above the maximum game depth.
*/
error InvalidParent();
error InvalidParent();
/**
/// @notice Thrown when an invalid prestate is supplied to `step`.
* @notice Thrown when an invalid prestate is supplied to `step`.
*/
error InvalidPrestate();
error InvalidPrestate();
/**
/// @notice Thrown when a step is made that computes the expected post state correctly.
* @notice Thrown when a step is made that computes the expected post state correctly.
*/
error ValidStep();
error ValidStep();
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// `AttestationDisputeGame` Errors //
// `AttestationDisputeGame` Errors //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/**
/// @notice Thrown when an invalid signature is submitted to `challenge`.
* @notice Thrown when an invalid signature is submitted to `challenge`.
*/
error InvalidSignature();
error InvalidSignature();
/**
/// @notice Thrown when a signature that has already been used to support the
* @notice Thrown when a signature that has already been used to support the
/// `rootClaim` is submitted to `challenge`.
* `rootClaim` is submitted to `challenge`.
*/
error AlreadyChallenged();
error AlreadyChallenged();
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// `Ownable` Errors //
// `Ownable` Errors //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/**
/// @notice Thrown when a function that is protected by the `onlyOwner` modifier
* @notice Thrown when a function that is protected by the `onlyOwner` modifier
/// is called from an account other than the owner.
* is called from an account other than the owner.
*/
error NotOwner();
error NotOwner();
packages/contracts-bedrock/contracts/libraries/DisputeTypes.sol
View file @
8478fbfe
...
@@ -9,79 +9,57 @@ using LibHashing for Claim global;
...
@@ -9,79 +9,57 @@ using LibHashing for Claim global;
using LibPosition for Position global;
using LibPosition for Position global;
using LibClock for Clock global;
using LibClock for Clock global;
/**
/// @notice A custom type for a generic hash.
* @notice A custom type for a generic hash.
*/
type Hash is bytes32;
type Hash is bytes32;
/**
/// @notice A claim represents an MPT root representing the state of the fault proof program.
* @notice A claim represents an MPT root representing the state of the fault proof program.
*/
type Claim is bytes32;
type Claim is bytes32;
/**
/// @notice A claim hash represents a hash of a claim and a position within the game tree.
* @notice A claim hash represents a hash of a claim and a position within the game tree.
/// @dev Keccak hash of abi.encodePacked(Claim, Position);
* @dev Keccak hash of abi.encodePacked(Claim, Position);
*/
type ClaimHash is bytes32;
type ClaimHash is bytes32;
/**
/// @notice A bondamount represents the amount of collateral that a user has locked up in a claim.
* @notice A bondamount represents the amount of collateral that a user has locked up in a claim.
*/
type BondAmount is uint256;
type BondAmount is uint256;
/**
/// @notice A dedicated timestamp type.
* @notice A dedicated timestamp type.
*/
type Timestamp is uint64;
type Timestamp is uint64;
/**
/// @notice A dedicated duration type.
* @notice A dedicated duration type.
/// @dev Unit: seconds
* @dev Unit: seconds
*/
type Duration is uint64;
type Duration is uint64;
/**
/// @notice A `GameId` represents a packed 12 byte timestamp and a 20 byte address.
* @notice A `GameId` represents a packed 12 byte timestamp and a 20 byte address.
/// @dev The packed layout of this type is as follows:
* @dev The packed layout of this type is as follows:
/// ┌────────────┬────────────────┐
* ┌────────────┬────────────────┐
/// │ Bits │ Value │
* │ Bits │ Value │
/// ├────────────┼────────────────┤
* ├────────────┼────────────────┤
/// │ [0, 96) │ Timestamp │
* │ [0, 96) │ Timestamp │
/// │ [96, 256) │ Address │
* │ [96, 256) │ Address │
/// └────────────┴────────────────┘
* └────────────┴────────────────┘
*/
type GameId is bytes32;
type GameId is bytes32;
/**
/// @notice A `Clock` represents a packed `Duration` and `Timestamp`
* @notice A `Clock` represents a packed `Duration` and `Timestamp`
/// @dev The packed layout of this type is as follows:
* @dev The packed layout of this type is as follows:
/// ┌────────────┬────────────────┐
* ┌────────────┬────────────────┐
/// │ Bits │ Value │
* │ Bits │ Value │
/// ├────────────┼────────────────┤
* ├────────────┼────────────────┤
/// │ [0, 64) │ Duration │
* │ [0, 64) │ Duration │
/// │ [64, 128) │ Timestamp │
* │ [64, 128) │ Timestamp │
/// └────────────┴────────────────┘
* └────────────┴────────────────┘
*/
type Clock is uint128;
type Clock is uint128;
/**
/// @notice A `Position` represents a position of a claim within the game tree.
* @notice A `Position` represents a position of a claim within the game tree.
/// @dev This is represented as a "generalized index" where the high-order bit
* @dev This is represented as a "generalized index" where the high-order bit
/// is the level in the tree and the remaining bits is a unique bit pattern, allowing
* is the level in the tree and the remaining bits is a unique bit pattern, allowing
/// a unique identifier for each node in the tree. Mathematically, it is calculated
* a unique identifier for each node in the tree. Mathematically, it is calculated
/// as 2^{depth} + indexAtDepth.
* as 2^{depth} + indexAtDepth.
*/
type Position is uint128;
type Position is uint128;
/**
/// @notice A `GameType` represents the type of game being played.
* @notice A `GameType` represents the type of game being played.
*/
type GameType is uint8;
type GameType is uint8;
/**
/// @notice The current status of the dispute game.
* @notice The current status of the dispute game.
*/
enum GameStatus {
enum GameStatus {
// The game is currently in progress, and has not been resolved.
// The game is currently in progress, and has not been resolved.
IN_PROGRESS,
IN_PROGRESS,
...
@@ -91,23 +69,15 @@ enum GameStatus {
...
@@ -91,23 +69,15 @@ enum GameStatus {
DEFENDER_WINS
DEFENDER_WINS
}
}
/**
/// @title GameTypes
* @title GameTypes
/// @notice A library that defines the IDs of games that can be played.
* @notice A library that defines the IDs of games that can be played.
*/
library GameTypes {
library GameTypes {
/**
/// @dev The game will use a `IDisputeGame` implementation that utilizes fault proofs.
* @dev The game will use a `IDisputeGame` implementation that utilizes fault proofs.
*/
GameType internal constant FAULT = GameType.wrap(0);
GameType internal constant FAULT = GameType.wrap(0);
/**
/// @dev The game will use a `IDisputeGame` implementation that utilizes validity proofs.
* @dev The game will use a `IDisputeGame` implementation that utilizes validity proofs.
*/
GameType internal constant VALIDITY = GameType.wrap(1);
GameType internal constant VALIDITY = GameType.wrap(1);
/**
/// @dev The game will use a `IDisputeGame` implementation that utilizes attestation proofs.
* @dev The game will use a `IDisputeGame` implementation that utilizes attestation proofs.
*/
GameType internal constant ATTESTATION = GameType.wrap(2);
GameType internal constant ATTESTATION = GameType.wrap(2);
}
}
packages/contracts-bedrock/contracts/test/DisputeGameFactory.t.sol
View file @
8478fbfe
...
@@ -37,10 +37,8 @@ contract DisputeGameFactory_Init is Test {
...
@@ -37,10 +37,8 @@ contract DisputeGameFactory_Init is Test {
}
}
contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
/**
/// @dev Tests that the `create` function succeeds when creating a new dispute game
* @dev Tests that the `create` function succeeds when creating a new dispute game
/// with a `GameType` that has an implementation set.
* with a `GameType` that has an implementation set.
*/
function testFuzz_create_succeeds(
function testFuzz_create_succeeds(
uint8 gameType,
uint8 gameType,
Claim rootClaim,
Claim rootClaim,
...
@@ -70,10 +68,8 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
...
@@ -70,10 +68,8 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
assertEq(timestamp2, block.timestamp);
assertEq(timestamp2, block.timestamp);
}
}
/**
/// @dev Tests that the `create` function reverts when there is no implementation
* @dev Tests that the `create` function reverts when there is no implementation
/// set for the given `GameType`.
* set for the given `GameType`.
*/
function testFuzz_create_noImpl_reverts(
function testFuzz_create_noImpl_reverts(
uint8 gameType,
uint8 gameType,
Claim rootClaim,
Claim rootClaim,
...
@@ -86,9 +82,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
...
@@ -86,9 +82,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
factory.create(gt, rootClaim, extraData);
factory.create(gt, rootClaim, extraData);
}
}
/**
/// @dev Tests that the `create` function reverts when there exists a dispute game with the same UUID.
* @dev Tests that the `create` function reverts when there exists a dispute game with the same UUID.
*/
function testFuzz_create_sameUUID_reverts(
function testFuzz_create_sameUUID_reverts(
uint8 gameType,
uint8 gameType,
Claim rootClaim,
Claim rootClaim,
...
@@ -124,9 +118,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
...
@@ -124,9 +118,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
}
}
contract DisputeGameFactory_SetImplementation_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`.
* @dev Tests that the `setImplementation` function properly sets the implementation for a given `GameType`.
*/
function test_setImplementation_succeeds() public {
function test_setImplementation_succeeds() public {
// There should be no implementation for the `GameTypes.FAULT` enum value, it has not been set.
// There should be no implementation for the `GameTypes.FAULT` enum value, it has not been set.
assertEq(address(factory.gameImpls(GameTypes.FAULT)), address(0));
assertEq(address(factory.gameImpls(GameTypes.FAULT)), address(0));
...
@@ -141,9 +133,7 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
...
@@ -141,9 +133,7 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
assertEq(address(factory.gameImpls(GameTypes.FAULT)), address(1));
assertEq(address(factory.gameImpls(GameTypes.FAULT)), address(1));
}
}
/**
/// @dev Tests that the `setImplementation` function reverts when called by a non-owner.
* @dev Tests that the `setImplementation` function reverts when called by a non-owner.
*/
function test_setImplementation_notOwner_reverts() public {
function test_setImplementation_notOwner_reverts() public {
// Ensure that the `setImplementation` function reverts when called by a non-owner.
// Ensure that the `setImplementation` function reverts when called by a non-owner.
vm.prank(address(0));
vm.prank(address(0));
...
@@ -153,10 +143,8 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
...
@@ -153,10 +143,8 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
}
}
contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init {
contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init {
/**
/// @dev Tests that the `getGameUUID` function returns the correct hash when comparing
* @dev Tests that the `getGameUUID` function returns the correct hash when comparing
/// against the keccak256 hash of the abi-encoded parameters.
* against the keccak256 hash of the abi-encoded parameters.
*/
function testDiff_getGameUUID_succeeds(
function testDiff_getGameUUID_succeeds(
uint8 gameType,
uint8 gameType,
Claim rootClaim,
Claim rootClaim,
...
@@ -173,26 +161,20 @@ contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init {
...
@@ -173,26 +161,20 @@ contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init {
}
}
contract DisputeGameFactory_Owner_Test is DisputeGameFactory_Init {
contract DisputeGameFactory_Owner_Test is DisputeGameFactory_Init {
/**
/// @dev Tests that the `owner` function returns the correct address after deployment.
* @dev Tests that the `owner` function returns the correct address after deployment.
*/
function test_owner_succeeds() public {
function test_owner_succeeds() public {
assertEq(factory.owner(), address(this));
assertEq(factory.owner(), address(this));
}
}
}
}
contract DisputeGameFactory_TransferOwnership_Test is DisputeGameFactory_Init {
contract DisputeGameFactory_TransferOwnership_Test is DisputeGameFactory_Init {
/**
/// @dev Tests that the `transferOwnership` function succeeds when called by the owner.
* @dev Tests that the `transferOwnership` function succeeds when called by the owner.
*/
function test_transferOwnership_succeeds() public {
function test_transferOwnership_succeeds() public {
factory.transferOwnership(address(1));
factory.transferOwnership(address(1));
assertEq(factory.owner(), address(1));
assertEq(factory.owner(), address(1));
}
}
/**
/// @dev Tests that the `transferOwnership` function reverts when called by a non-owner.
* @dev Tests that the `transferOwnership` function reverts when called by a non-owner.
*/
function test_transferOwnership_notOwner_reverts() public {
function test_transferOwnership_notOwner_reverts() public {
vm.prank(address(0));
vm.prank(address(0));
vm.expectRevert("Ownable: caller is not the owner");
vm.expectRevert("Ownable: caller is not the owner");
...
@@ -200,11 +182,9 @@ contract DisputeGameFactory_TransferOwnership_Test is DisputeGameFactory_Init {
...
@@ -200,11 +182,9 @@ contract DisputeGameFactory_TransferOwnership_Test is DisputeGameFactory_Init {
}
}
}
}
/**
/// @title PackingTester
* @title PackingTester
/// @notice Exposes the internal packing functions so that they can be fuzzed
* @notice Exposes the internal packing functions so that they can be fuzzed
/// in a roundtrip manner.
* in a roundtrip manner.
*/
contract PackingTester is DisputeGameFactory {
contract PackingTester is DisputeGameFactory {
function packSlot(address _addr, uint256 _num) external pure returns (GameId) {
function packSlot(address _addr, uint256 _num) external pure returns (GameId) {
return _packSlot(_addr, _num);
return _packSlot(_addr, _num);
...
@@ -215,10 +195,8 @@ contract PackingTester is DisputeGameFactory {
...
@@ -215,10 +195,8 @@ contract PackingTester is DisputeGameFactory {
}
}
}
}
/**
/// @title DisputeGameFactory_PackSlot_Test
* @title DisputeGameFactory_PackSlot_Test
/// @notice Fuzzes the PackingTester contract
* @notice Fuzzes the PackingTester contract
*/
contract DisputeGameFactory_PackSlot_Test is Test {
contract DisputeGameFactory_PackSlot_Test is Test {
PackingTester tester;
PackingTester tester;
...
@@ -226,9 +204,7 @@ contract DisputeGameFactory_PackSlot_Test is Test {
...
@@ -226,9 +204,7 @@ contract DisputeGameFactory_PackSlot_Test is Test {
tester = new PackingTester();
tester = new PackingTester();
}
}
/**
/// @dev Tests that the `packSlot` and `unpackSlot` functions roundtrip correctly.
* @dev Tests that the `packSlot` and `unpackSlot` functions roundtrip correctly.
*/
function testFuzz_packSlot_succeeds(address _addr, uint96 _num) public {
function testFuzz_packSlot_succeeds(address _addr, uint96 _num) public {
GameId slot = tester.packSlot(_addr, uint256(_num));
GameId slot = tester.packSlot(_addr, uint256(_num));
(address addr, uint256 num) = tester.unpackSlot(slot);
(address addr, uint256 num) = tester.unpackSlot(slot);
...
@@ -237,9 +213,7 @@ contract DisputeGameFactory_PackSlot_Test is Test {
...
@@ -237,9 +213,7 @@ contract DisputeGameFactory_PackSlot_Test is Test {
}
}
}
}
/**
/// @dev A fake clone used for testing the `DisputeGameFactory` contract's `create` function.
* @dev A fake clone used for testing the `DisputeGameFactory` contract's `create` function.
*/
contract FakeClone {
contract FakeClone {
function initialize() external {
function initialize() external {
// noop
// noop
...
...
packages/contracts-bedrock/contracts/test/FaultDisputeGame.t.sol
View file @
8478fbfe
This diff is collapsed.
Click to expand it.
packages/contracts-bedrock/contracts/test/LibClock.t.sol
View file @
8478fbfe
...
@@ -5,21 +5,15 @@ import { Test } from "forge-std/Test.sol";
...
@@ -5,21 +5,15 @@ import { Test } from "forge-std/Test.sol";
import { LibClock } from "../dispute/lib/LibClock.sol";
import { LibClock } from "../dispute/lib/LibClock.sol";
import "../libraries/DisputeTypes.sol";
import "../libraries/DisputeTypes.sol";
/**
/// @notice Tests for `LibClock`
* @notice Tests for `LibClock`
*/
contract LibClock_Test is Test {
contract LibClock_Test is Test {
/**
/// @notice Tests that the `duration` function correctly shifts out the `Duration` from a packed `Clock` type.
* @notice Tests that the `duration` function correctly shifts out the `Duration` from a packed `Clock` type.
*/
function testFuzz_duration_succeeds(Duration _duration, Timestamp _timestamp) public {
function testFuzz_duration_succeeds(Duration _duration, Timestamp _timestamp) public {
Clock clock = LibClock.wrap(_duration, _timestamp);
Clock clock = LibClock.wrap(_duration, _timestamp);
assertEq(Duration.unwrap(clock.duration()), Duration.unwrap(_duration));
assertEq(Duration.unwrap(clock.duration()), Duration.unwrap(_duration));
}
}
/**
/// @notice Tests that the `timestamp` function correctly shifts out the `Timestamp` from a packed `Clock` type.
* @notice Tests that the `timestamp` function correctly shifts out the `Timestamp` from a packed `Clock` type.
*/
function testFuzz_timestamp_succeeds(Duration _duration, Timestamp _timestamp) public {
function testFuzz_timestamp_succeeds(Duration _duration, Timestamp _timestamp) public {
Clock clock = LibClock.wrap(_duration, _timestamp);
Clock clock = LibClock.wrap(_duration, _timestamp);
assertEq(Timestamp.unwrap(clock.timestamp()), Timestamp.unwrap(_timestamp));
assertEq(Timestamp.unwrap(clock.timestamp()), Timestamp.unwrap(_timestamp));
...
...
packages/contracts-bedrock/contracts/test/LibPosition.t.sol
View file @
8478fbfe
...
@@ -5,15 +5,11 @@ import { Test } from "forge-std/Test.sol";
...
@@ -5,15 +5,11 @@ import { Test } from "forge-std/Test.sol";
import { LibPosition } from "../dispute/lib/LibPosition.sol";
import { LibPosition } from "../dispute/lib/LibPosition.sol";
import "../libraries/DisputeTypes.sol";
import "../libraries/DisputeTypes.sol";
/**
/// @notice Tests for `LibPosition`
* @notice Tests for `LibPosition`
*/
contract LibPosition_Test is Test {
contract LibPosition_Test is Test {
/**
/// @dev Assumes a MAX depth of 63 for the Position type. Any greater depth can cause overflows.
* @dev Assumes a MAX depth of 63 for the Position type. Any greater depth can cause overflows.
/// @dev At the lowest level of the tree, this allows for 2 ** 63 leaves. In reality, the max game depth
* @dev At the lowest level of the tree, this allows for 2 ** 63 leaves. In reality, the max game depth
/// will likely be much lower.
* will likely be much lower.
*/
uint8 internal constant MAX_DEPTH = 63;
uint8 internal constant MAX_DEPTH = 63;
function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal view returns (uint64) {
function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal view returns (uint64) {
...
@@ -25,9 +21,7 @@ contract LibPosition_Test is Test {
...
@@ -25,9 +21,7 @@ contract LibPosition_Test is Test {
}
}
}
}
/**
/// @notice Tests that the `depth` function correctly shifts out the `depth` from a packed `Position` type.
* @notice Tests that the `depth` function correctly shifts out the `depth` from a packed `Position` type.
*/
function testFuzz_depth_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_depth_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...
@@ -35,9 +29,7 @@ contract LibPosition_Test is Test {
...
@@ -35,9 +29,7 @@ contract LibPosition_Test is Test {
assertEq(position.depth(), _depth);
assertEq(position.depth(), _depth);
}
}
/**
/// @notice Tests that the `indexAtDepth` function correctly shifts out the `indexAtDepth` from a packed `Position` type.
* @notice Tests that the `indexAtDepth` function correctly shifts out the `indexAtDepth` from a packed `Position` type.
*/
function testFuzz_indexAtDepth_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_indexAtDepth_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...
@@ -45,9 +37,7 @@ contract LibPosition_Test is Test {
...
@@ -45,9 +37,7 @@ contract LibPosition_Test is Test {
assertEq(position.indexAtDepth(), _indexAtDepth);
assertEq(position.indexAtDepth(), _indexAtDepth);
}
}
/**
/// @notice Tests that the `left` function correctly computes the position of the left child.
* @notice Tests that the `left` function correctly computes the position of the left child.
*/
function testFuzz_left_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_left_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...
@@ -59,9 +49,7 @@ contract LibPosition_Test is Test {
...
@@ -59,9 +49,7 @@ contract LibPosition_Test is Test {
assertEq(left.indexAtDepth(), _indexAtDepth * 2);
assertEq(left.indexAtDepth(), _indexAtDepth * 2);
}
}
/**
/// @notice Tests that the `right` function correctly computes the position of the right child.
* @notice Tests that the `right` function correctly computes the position of the right child.
*/
function testFuzz_right_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_right_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
// Depth bound: [0, 63]
// Depth bound: [0, 63]
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
...
@@ -74,9 +62,7 @@ contract LibPosition_Test is Test {
...
@@ -74,9 +62,7 @@ contract LibPosition_Test is Test {
assertEq(right.indexAtDepth(), _indexAtDepth * 2 + 1);
assertEq(right.indexAtDepth(), _indexAtDepth * 2 + 1);
}
}
/**
/// @notice Tests that the `parent` function correctly computes the position of the parent.
* @notice Tests that the `parent` function correctly computes the position of the parent.
*/
function testFuzz_parent_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_parent_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...
@@ -88,10 +74,8 @@ contract LibPosition_Test is Test {
...
@@ -88,10 +74,8 @@ contract LibPosition_Test is Test {
assertEq(parent.indexAtDepth(), _indexAtDepth / 2);
assertEq(parent.indexAtDepth(), _indexAtDepth / 2);
}
}
/**
/// @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative
* @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative
/// to a given position.
* to a given position.
*/
function testFuzz_rightIndex_correctness_suceeds(
function testFuzz_rightIndex_correctness_suceeds(
uint64 _maxDepth,
uint64 _maxDepth,
uint8 _depth,
uint8 _depth,
...
@@ -115,11 +99,9 @@ contract LibPosition_Test is Test {
...
@@ -115,11 +99,9 @@ contract LibPosition_Test is Test {
assertEq(Position.unwrap(rightIndex), Position.unwrap(position));
assertEq(Position.unwrap(rightIndex), Position.unwrap(position));
}
}
/**
/// @notice Tests that the `attack` function correctly computes the position of the attack relative to
* @notice Tests that the `attack` function correctly computes the position of the attack relative to
/// a given position.
* a given position.
/// @dev `attack` is an alias for `left`, but we test it separately for completeness.
* @dev `attack` is an alias for `left`, but we test it separately for completeness.
*/
function testFuzz_attack_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_attack_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
// Depth bound: [0, 63]
// Depth bound: [0, 63]
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
...
@@ -132,12 +114,10 @@ contract LibPosition_Test is Test {
...
@@ -132,12 +114,10 @@ contract LibPosition_Test is Test {
assertEq(attack.indexAtDepth(), _indexAtDepth * 2);
assertEq(attack.indexAtDepth(), _indexAtDepth * 2);
}
}
/**
/// @notice Tests that the `defend` function correctly computes the position of the defense relative to
* @notice Tests that the `defend` function correctly computes the position of the defense relative to
/// a given position.
* a given position.
/// @dev A defense can only be given if the position does not belong to the root claim, hence the bound of [1, 127]
* @dev A defense can only be given if the position does not belong to the root claim, hence the bound of [1, 127]
/// on the depth.
* on the depth.
*/
function testFuzz_defend_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_defend_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
// Depth bound: [1, 63]
// Depth bound: [1, 63]
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
...
@@ -150,10 +130,8 @@ contract LibPosition_Test is Test {
...
@@ -150,10 +130,8 @@ contract LibPosition_Test is Test {
assertEq(defend.indexAtDepth(), ((_indexAtDepth / 2) * 2 + 1) * 2);
assertEq(defend.indexAtDepth(), ((_indexAtDepth / 2) * 2 + 1) * 2);
}
}
/**
/// @notice A static unit test for the correctness of all gindicies, (depth, index) combos,
* @notice A static unit test for the correctness of all gindicies, (depth, index) combos,
/// and the trace index in a tree of max depth = 4.
* and the trace index in a tree of max depth = 4.
*/
function test_pos_correctness_succeeds() public {
function test_pos_correctness_succeeds() public {
uint256 maxDepth = 4;
uint256 maxDepth = 4;
...
...
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