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
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";
import { IDisputeGameFactory } from "./interfaces/IDisputeGameFactory.sol";
import { IVersioned } from "./interfaces/IVersioned.sol";
/**
* @title DisputeGameFactory
* @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
* 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
* easier.
*/
/// @title DisputeGameFactory
/// @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
/// 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
/// easier.
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;
/**
* @inheritdoc IDisputeGameFactory
*/
/// @inheritdoc IDisputeGameFactory
mapping(GameType => IDisputeGame) public gameImpls;
/**
* @notice Mapping of a hash of `gameType || rootClaim || extraData` to
* the deployed `IDisputeGame` clone.
* @dev Note: `||` denotes concatenation.
*/
/// @notice Mapping of a hash of `gameType || rootClaim || extraData` to
/// the deployed `IDisputeGame` clone.
/// @dev Note: `||` denotes concatenation.
mapping(Hash => GameId) internal _disputeGames;
/**
* @notice An append-only array of disputeGames that have been created.
* @dev This accessor is used by offchain game solvers to efficiently
* track dispute games
*/
/// @notice an append-only array of disputeGames that have been created.
/// @dev this accessor is used by offchain game solvers to efficiently
/// track dispute games
GameId[] internal _disputeGameList;
/**
* @notice Constructs a new DisputeGameFactory contract.
*/
/// @notice constructs a new DisputeGameFactory contract.
constructor() OwnableUpgradeable() {
initialize(address(0));
}
/**
* @notice Initializes the contract.
* @param _owner The owner of the contract.
*/
/// @notice Initializes the contract.
/// @param _owner The owner of the contract.
function initialize(address _owner) public initializer {
__Ownable_init();
_transferOwnership(_owner);
}
/**
* @inheritdoc IVersioned
* @custom:semver 0.0.2
*/
/// @inheritdoc IVersioned
/// @custom:semver 0.0.2
function version() external pure returns (string memory) {
return "0.0.2";
}
/**
* @inheritdoc IDisputeGameFactory
*/
/// @inheritdoc IDisputeGameFactory
function gameCount() external view returns (uint256 gameCount_) {
gameCount_ = _disputeGameList.length;
}
/**
* @inheritdoc IDisputeGameFactory
*/
/// @inheritdoc IDisputeGameFactory
function games(
GameType _gameType,
Claim _rootClaim,
...
...
@@ -92,9 +72,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
timestamp_ = timestamp;
}
/**
* @inheritdoc IDisputeGameFactory
*/
/// @inheritdoc IDisputeGameFactory
function gameAtIndex(uint256 _index)
external
view
...
...
@@ -106,9 +84,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
timestamp_ = timestamp;
}
/**
* @inheritdoc IDisputeGameFactory
*/
/// @inheritdoc IDisputeGameFactory
function create(
GameType gameType,
Claim rootClaim,
...
...
@@ -142,9 +118,7 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
emit DisputeGameCreated(address(proxy), gameType, rootClaim);
}
/**
* @inheritdoc IDisputeGameFactory
*/
/// @inheritdoc IDisputeGameFactory
function getGameUUID(
GameType gameType,
Claim rootClaim,
...
...
@@ -181,27 +155,21 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, IVersion
}
}
/**
* @inheritdoc IDisputeGameFactory
*/
/// @inheritdoc IDisputeGameFactory
function setImplementation(GameType gameType, IDisputeGame impl) external onlyOwner {
gameImpls[gameType] = impl;
emit ImplementationSet(address(impl), gameType);
}
/**
* @dev Packs an address and a uint256 into a single bytes32 slot. This
* is only safe for up to uint96 values.
*/
/// @dev Packs an address and a uint256 into a single bytes32 slot. This
/// is only safe for up to uint96 values.
function _packSlot(address _addr, uint256 _num) internal pure returns (GameId slot_) {
assembly {
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_) {
assembly {
addr_ := and(_slot, 0xffffffffffffffffffffffffffffffffffffffff)
...
...
packages/contracts-bedrock/contracts/dispute/FaultDisputeGame.sol
View file @
8478fbfe
...
...
@@ -15,70 +15,47 @@ import { LibClock } from "./lib/LibClock.sol";
import "../libraries/DisputeTypes.sol";
import "../libraries/DisputeErrors.sol";
/**
* @title FaultDisputeGame
* @notice An implementation of the `IFaultDisputeGame` interface.
*/
/// @title FaultDisputeGame
/// @notice An implementation of the `IFaultDisputeGame` interface.
contract FaultDisputeGame is IFaultDisputeGame, Clone {
////////////////////////////////////////////////////////////////
// State Vars //
////////////////////////////////////////////////////////////////
/**
* @notice The current Semver of the FaultDisputeGame implementation.
*/
string internal constant VERSION = "0.0.2";
/// @notice The absolute prestate of the instruction trace. This is a constant that is defined
/// 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 duration of the game.
* @dev TODO: Account for resolution buffer. (?)
*/
/// @notice The duration of the game.
/// @dev TODO: Account for resolution buffer. (?)
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);
/**
* @notice The absolute prestate of the instruction trace. This is a constant that is defined
* 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 current Semver of the FaultDisputeGame implementation.
string internal constant VERSION = "0.0.2";
/**
* @notice The starting timestamp of the game
*/
/// @notice The starting timestamp of the game
Timestamp public gameStart;
/**
* @inheritdoc IDisputeGame
*/
/// @inheritdoc IDisputeGame
GameStatus public status;
/**
* @inheritdoc IDisputeGame
*/
/// @inheritdoc IDisputeGame
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;
/**
* @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;
/**
* @param _absolutePrestate The absolute prestate of the instruction trace.
*/
/// @param _absolutePrestate The absolute prestate of the instruction trace.
constructor(Claim _absolutePrestate, uint256 _maxGameDepth) {
ABSOLUTE_PRESTATE = _absolutePrestate;
MAX_GAME_DEPTH = _maxGameDepth;
...
...
@@ -88,23 +65,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
// External Logic //
////////////////////////////////////////////////////////////////
/**
* @inheritdoc IFaultDisputeGame
*/
/// @inheritdoc IFaultDisputeGame
function attack(uint256 _parentIndex, Claim _pivot) external payable {
_move(_parentIndex, _pivot, true);
}
/**
* @inheritdoc IFaultDisputeGame
*/
/// @inheritdoc IFaultDisputeGame
function defend(uint256 _parentIndex, Claim _pivot) external payable {
_move(_parentIndex, _pivot, false);
}
/**
* @inheritdoc IFaultDisputeGame
*/
/// @inheritdoc IFaultDisputeGame
function step(
uint256 _stateIndex,
uint256 _claimIndex,
...
...
@@ -182,12 +153,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
// Internal Logic //
////////////////////////////////////////////////////////////////
/**
* @notice Internal move function, used by both `attack` and `defend`.
* @param _challengeIndex The index of the claim being moved against.
* @param _pivot The claim at the next logical position in the game.
* @param _isAttack Whether or not the move is an attack or defense.
*/
/// @notice Internal move function, used by both `attack` and `defend`.
/// @param _challengeIndex The index of the claim being moved against.
/// @param _pivot The claim at the next logical position in the game.
/// @param _isAttack Whether or not the move is an attack or defense.
function _move(
uint256 _challengeIndex,
Claim _pivot,
...
...
@@ -275,9 +244,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
emit Move(_challengeIndex, _pivot, msg.sender);
}
/**
* @inheritdoc IFaultDisputeGame
*/
/// @inheritdoc IFaultDisputeGame
function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) {
l2BlockNumber_ = _getArgUint256(0x20);
}
...
...
@@ -286,23 +253,17 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
// `IDisputeGame` impl //
////////////////////////////////////////////////////////////////
/**
* @inheritdoc IDisputeGame
*/
/// @inheritdoc IDisputeGame
function gameType() public pure override returns (GameType gameType_) {
gameType_ = GameTypes.FAULT;
}
/**
* @inheritdoc IDisputeGame
*/
/// @inheritdoc IDisputeGame
function createdAt() external view returns (Timestamp createdAt_) {
createdAt_ = gameStart;
}
/**
* @inheritdoc IDisputeGame
*/
/// @inheritdoc IDisputeGame
function resolve() external returns (GameStatus status_) {
// TODO: Do not allow resolution before clocks run out.
...
...
@@ -361,16 +322,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
emit Resolved(status_);
}
/**
* @inheritdoc IDisputeGame
*/
/// @inheritdoc IDisputeGame
function rootClaim() public pure returns (Claim rootClaim_) {
rootClaim_ = Claim.wrap(_getArgFixedBytes(0x00));
}
/**
* @inheritdoc IDisputeGame
*/
/// @inheritdoc IDisputeGame
function extraData() public pure returns (bytes memory extraData_) {
// 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?
...
...
@@ -378,9 +335,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
extraData_ = _getArgDynBytes(0x20, 0x20);
}
/**
* @inheritdoc IDisputeGame
*/
/// @inheritdoc IDisputeGame
function gameData()
external
pure
...
...
@@ -395,9 +350,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
extraData_ = extraData();
}
/**
* @inheritdoc IInitializable
*/
/// @inheritdoc IInitializable
function initialize() external {
// Set the game start
gameStart = Timestamp.wrap(uint64(block.timestamp));
...
...
@@ -416,9 +369,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
);
}
/**
* @inheritdoc IVersioned
*/
/// @inheritdoc IVersioned
function version() external pure override returns (string memory version_) {
version_ = VERSION;
}
...
...
packages/contracts-bedrock/contracts/dispute/interfaces/IBondManager.sol
View file @
8478fbfe
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
/**
* @title IBondManager
* @notice The Bond Manager holds ether posted as a bond for a bond id.
*/
/// @title IBondManager
/// @notice The Bond Manager holds ether posted as a bond for a bond id.
interface IBondManager {
/**
* @notice BondPosted is emitted when a bond is posted.
* @param bondId is the id of the bond.
* @param owner is the address that owns the bond.
* @param expiration is the time at which the bond expires.
* @param amount is the amount of the bond.
*/
/// @notice BondPosted is emitted when a bond is posted.
/// @param bondId is the id of the bond.
/// @param owner is the address that owns the bond.
/// @param expiration is the time at which the bond expires.
/// @param amount is the amount of the bond.
event BondPosted(bytes32 bondId, address owner, uint256 expiration, uint256 amount);
/**
* @notice BondSeized is emitted when a bond is seized.
* @param bondId is the id of the bond.
* @param owner is the address that owns the bond.
* @param seizer is the address that seized the bond.
* @param amount is the amount of the bond.
*/
/// @notice BondSeized is emitted when a bond is seized.
/// @param bondId is the id of the bond.
/// @param owner is the address that owns the bond.
/// @param seizer is the address that seized the bond.
/// @param amount is the amount of the bond.
event BondSeized(bytes32 bondId, address owner, address seizer, uint256 amount);
/**
* @notice BondReclaimed is emitted when a bond is reclaimed by the owner.
* @param bondId is the id of the bond.
* @param claiment is the address that reclaimed the bond.
* @param amount is the amount of the bond.
*/
/// @notice BondReclaimed is emitted when a bond is reclaimed by the owner.
/// @param bondId is the id of the bond.
/// @param claiment is the address that reclaimed the bond.
/// @param amount is the amount of the bond.
event BondReclaimed(bytes32 bondId, address claiment, uint256 amount);
/**
* @notice Post a bond with a given id and owner.
* @dev This function will revert if the provided bondId is already in use.
* @param _bondId is the id of the bond.
* @param _bondOwner is the address that owns the bond.
* @param _minClaimHold is the minimum amount of time the owner
* must wait before reclaiming their bond.
*/
/// @notice Post a bond with a given id and owner.
/// @dev This function will revert if the provided bondId is already in use.
/// @param _bondId is the id of the bond.
/// @param _bondOwner is the address that owns the bond.
/// @param _minClaimHold is the minimum amount of time the owner
/// must wait before reclaiming their bond.
function post(
bytes32 _bondId,
address _bondOwner,
uint128 _minClaimHold
) external payable;
/**
* @notice Seizes the bond with 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.
*/
/// @notice Seizes the bond with 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.
function seize(bytes32 _bondId) external;
/**
* @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.
* @param _bondId is the id of the bond.
* @param _claimRecipients is a set of addresses to split the bond amongst.
*/
/// @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.
/// @param _bondId is the id of the bond.
/// @param _claimRecipients is a set of addresses to split the bond amongst.
///
function seizeAndSplit(bytes32 _bondId, address[] calldata _claimRecipients) external;
/**
* @notice Reclaims the bond of the bond owner.
* @dev This function will revert if there is no bond at the given id.
* @param _bondId is the id of the bond.
*/
/// @notice Reclaims the bond of the bond owner.
/// @dev This function will revert if there is no bond at the given id.
/// @param _bondId is the id of the bond.
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";
import { IBondManager } from "./IBondManager.sol";
import { IInitializable } from "./IInitializable.sol";
/**
* @title IDisputeGame
* @notice The generic interface for a DisputeGame contract.
*/
/// @title IDisputeGame
/// @notice The generic interface for a DisputeGame contract.
interface IDisputeGame is IInitializable, IVersioned {
/**
* @notice Emitted when the game is resolved.
* @param status The status of the game after resolution.
*/
/// @notice Emitted when the game is resolved.
/// @param status The status of the game after resolution.
event Resolved(GameStatus indexed status);
/**
* @notice Returns the timestamp that the DisputeGame contract was created at.
* @return createdAt_ 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.
function createdAt() external view returns (Timestamp createdAt_);
/**
* @notice Returns the current status of the game.
* @return status_ The current status of the game.
*/
/// @notice Returns the current status of the game.
/// @return status_ The current status of the game.
function status() external view returns (GameStatus status_);
/**
* @notice Getter for the game type.
* @dev `clones-with-immutable-args` argument #1
* @dev The reference impl should be entirely different depending on the type (fault, validity)
* i.e. The game type should indicate the security model.
* @return gameType_ The type of proof system being used.
*/
/// @notice Getter for the game type.
/// @dev `clones-with-immutable-args` argument #1
/// @dev The reference impl should be entirely different depending on the type (fault, validity)
/// i.e. The game type should indicate the security model.
/// @return gameType_ The type of proof system being used.
function gameType() external pure returns (GameType gameType_);
/**
* @notice Getter for the root claim.
* @dev `clones-with-immutable-args` argument #2
* @return rootClaim_ The root claim of the DisputeGame.
*/
/// @notice Getter for the root claim.
/// @dev `clones-with-immutable-args` argument #2
/// @return rootClaim_ The root claim of the DisputeGame.
function rootClaim() external pure returns (Claim rootClaim_);
/**
* @notice Getter for the extra data.
* @dev `clones-with-immutable-args` argument #3
* @return extraData_ Any extra data supplied to the dispute game contract by the creator.
*/
/// @notice Getter for the extra data.
/// @dev `clones-with-immutable-args` argument #3
/// @return extraData_ Any extra data supplied to the dispute game contract by the creator.
function extraData() external pure returns (bytes memory extraData_);
/**
* @notice Returns the address of the `BondManager` used.
* @return bondManager_ The address of the `BondManager` used.
*/
/// @notice Returns the address of the `BondManager` used.
/// @return bondManager_ The address of the `BondManager` used.
function bondManager() external view returns (IBondManager bondManager_);
/**
* @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
* the resolved game. It is at this stage that the bonds should be awarded to the
* necessary parties.
* @dev May only be called if the `status` is `IN_PROGRESS`.
* @return status_ The status of the game after resolution.
*/
/// @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
/// the resolved game. It is at this stage that the bonds should be awarded to the
/// necessary parties.
/// @dev May only be called if the `status` is `IN_PROGRESS`.
/// @return status_ The status of the game after resolution.
function resolve() external returns (GameStatus status_);
/**
* @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
* constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes
* concatenation.
* @return gameType_ The type of proof system being used.
* @return rootClaim_ The root claim of the DisputeGame.
* @return extraData_ Any extra data supplied to the dispute game contract by the creator.
*/
/// @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
/// constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes
/// concatenation.
/// @return gameType_ The type of proof system being used.
/// @return rootClaim_ The root claim of the DisputeGame.
/// @return extraData_ Any extra data supplied to the dispute game contract by the creator.
function gameData()
external
pure
...
...
packages/contracts-bedrock/contracts/dispute/interfaces/IDisputeGameFactory.sol
View file @
8478fbfe
...
...
@@ -5,105 +5,87 @@ import "../../libraries/DisputeTypes.sol";
import { IDisputeGame } from "./IDisputeGame.sol";
/**
* @title IDisputeGameFactory
* @notice The interface for a DisputeGameFactory contract.
*/
/// @title IDisputeGameFactory
/// @notice The interface for a DisputeGameFactory contract.
interface IDisputeGameFactory {
/**
* @notice Emitted when a new dispute game is created
* @param disputeProxy The address of the dispute game proxy
* @param gameType The type of the dispute game proxy's implementation
* @param rootClaim The root claim of the dispute game
*/
/// @notice Emitted when a new dispute game is created
/// @param disputeProxy The address of the dispute game proxy
/// @param gameType The type of the dispute game proxy's implementation
/// @param rootClaim The root claim of the dispute game
event DisputeGameCreated(
address indexed disputeProxy,
GameType indexed gameType,
Claim indexed rootClaim
);
/**
* @notice Emitted when a new game implementation added to the factory
* @param impl The implementation contract for the given `GameType`.
* @param gameType The type of the DisputeGame.
*/
/// @notice Emitted when a new game implementation added to the factory
/// @param impl The implementation contract for the given `GameType`.
/// @param gameType The type of the DisputeGame.
event ImplementationSet(address indexed impl, GameType indexed gameType);
/**
* @notice the total number of dispute games created by this factory.
* @return _gameCount 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.
function gameCount() external view returns (uint256 _gameCount);
/**
* @notice `games` queries an internal a mapping that maps the hash of
* `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone.
* @dev `++` equates to concatenation.
* @param gameType The type of the DisputeGame - used to decide the proxy implementation
* @param rootClaim The root claim of the DisputeGame.
* @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.
* Returns `address(0)` if nonexistent.
* @return _timestamp The timestamp of the creation of the dispute game.
*/
/// @notice `games` queries an internal a mapping that maps the hash of
/// `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone.
/// @dev `++` equates to concatenation.
/// @param gameType The type of the DisputeGame - used to decide the proxy implementation
/// @param rootClaim The root claim of the DisputeGame.
/// @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.
/// Returns `address(0)` if nonexistent.
/// @return _timestamp The timestamp of the creation of the dispute game.
function games(
GameType gameType,
Claim rootClaim,
bytes calldata extraData
) external view returns (IDisputeGame _proxy, uint256 _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.
* @param _index The index of the dispute game.
* @return _proxy The clone of the `DisputeGame` created with the given parameters.
* Returns `address(0)` if nonexistent.
* @return _timestamp The timestamp of the creation of the dispute game.
*/
/// @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp
/// at the given index. Each created dispute game increments the underlying index.
/// @param _index The index of the dispute game.
/// @return _proxy The clone of the `DisputeGame` created with the given parameters.
/// Returns `address(0)` if nonexistent.
/// @return _timestamp The timestamp of the creation of the dispute game.
function gameAtIndex(uint256 _index)
external
view
returns (IDisputeGame _proxy, uint256 _timestamp);
/**
* @notice `gameImpls` is a mapping that maps `GameType`s to their respective
* `IDisputeGame` implementations.
* @param gameType The type of the dispute game.
* @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`.
*/
/// @notice `gameImpls` is a mapping that maps `GameType`s to their respective
/// `IDisputeGame` implementations.
/// @param gameType The type of the dispute game.
/// @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`.
function gameImpls(GameType gameType) external view returns (IDisputeGame _impl);
/**
* @notice Creates a new DisputeGame proxy contract.
* @param gameType The type of the DisputeGame - used to decide the proxy implementation
* @param rootClaim The root claim of the DisputeGame.
* @param extraData Any extra data that should be provided to the created dispute game.
* @return proxy The address of the created DisputeGame proxy.
*/
/// @notice Creates a new DisputeGame proxy contract.
/// @param gameType The type of the DisputeGame - used to decide the proxy implementation
/// @param rootClaim The root claim of the DisputeGame.
/// @param extraData Any extra data that should be provided to the created dispute game.
/// @return proxy The address of the created DisputeGame proxy.
function create(
GameType gameType,
Claim rootClaim,
bytes calldata extraData
) external returns (IDisputeGame proxy);
/
**
*
@notice Sets the implementation contract for a specific `GameType`.
*
@dev May only be called by the `owner`.
*
@param gameType The type of the DisputeGame.
*
@param impl The implementation contract for the given `GameType`.
*
/
/
//
///
@notice Sets the implementation contract for a specific `GameType`.
///
@dev May only be called by the `owner`.
///
@param gameType The type of the DisputeGame.
///
@param impl The implementation contract for the given `GameType`.
//
/
function setImplementation(GameType gameType, IDisputeGame impl) external;
/**
* @notice Returns a unique identifier for the given dispute game parameters.
* @dev Hashes the concatenation of `gameType . rootClaim . extraData`
* without expanding memory.
* @param gameType The type 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.
* @return _uuid The 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`
/// without expanding memory.
/// @param gameType The type 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.
/// @return _uuid The unique identifier for the given dispute game parameters.
function getGameUUID(
GameType gameType,
Claim rootClaim,
...
...
packages/contracts-bedrock/contracts/dispute/interfaces/IFaultDisputeGame.sol
View file @
8478fbfe
...
...
@@ -5,16 +5,11 @@ import "../../libraries/DisputeTypes.sol";
import { IDisputeGame } from "./IDisputeGame.sol";
/**
* @title IFaultDisputeGame
* @notice The interface for a fault proof backed dispute game.
*/
/// @title IFaultDisputeGame
/// @notice The interface for a fault proof backed dispute game.
interface IFaultDisputeGame is IDisputeGame {
/**
* @notice The `ClaimData` struct represents the data associated with a Claim.
* @dev TODO: Pack `Clock` and `Position` into the same slot. Should require 4 64 bit arms.
* @dev TODO: Add bond ID information.
*/
/// @notice The `ClaimData` struct represents the data associated with a Claim.
/// @dev TODO: Add bond ID information.
struct ClaimData {
uint32 parentIndex;
bool countered;
...
...
@@ -23,40 +18,32 @@ interface IFaultDisputeGame is IDisputeGame {
Clock clock;
}
/**
* @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 pivot The claim being added
* @param claimant The address of the 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 pivot The claim being added
/// @param claimant The address of the claimant
event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant);
/**
* @notice Attack a disagreed upon `Claim`.
* @param _parentIndex Index of the `Claim` to attack in `claimData`.
* @param _pivot The `Claim` at the relative attack position.
*/
/// @notice Attack a disagreed upon `Claim`.
/// @param _parentIndex Index of the `Claim` to attack in `claimData`.
/// @param _pivot The `Claim` at the relative attack position.
function attack(uint256 _parentIndex, Claim _pivot) external payable;
/**
* @notice Defend an agreed upon `Claim`.
* @param _parentIndex Index of the claim to defend in `claimData`.
* @param _pivot The `Claim` at the relative defense position.
*/
/// @notice Defend an agreed upon `Claim`.
/// @param _parentIndex Index of the claim to defend in `claimData`.
/// @param _pivot The `Claim` at the relative defense position.
function defend(uint256 _parentIndex, Claim _pivot) external payable;
/**
* @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
* 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
* fault proof VMs (MIPS, RiscV5, etc.)
* @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 _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 _proof Proof to access memory leaf nodes in the VM.
*/
/// @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
/// 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
/// fault proof VMs (MIPS, RiscV5, etc.)
/// @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 _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 _proof Proof to access memory leaf nodes in the VM.
function step(
uint256 _stateIndex,
uint256 _claimIndex,
...
...
@@ -65,10 +52,8 @@ interface IFaultDisputeGame is IDisputeGame {
bytes calldata _proof
) external;
/**
* @notice The l2BlockNumber that the `rootClaim` commits to. The trace being bisected within
* the game is from `l2BlockNumber - 1` -> `l2BlockNumber`.
* @return l2BlockNumber_ The l2BlockNumber that the `rootClaim` commits to.
*/
/// @notice The l2BlockNumber that the `rootClaim` commits to. The trace being bisected within
/// the game is from `l2BlockNumber - 1` -> `l2BlockNumber`.
/// @return l2BlockNumber_ The l2BlockNumber that the `rootClaim` commits to.
function l2BlockNumber() external view returns (uint256 l2BlockNumber_);
}
packages/contracts-bedrock/contracts/dispute/interfaces/IInitializable.sol
View file @
8478fbfe
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
/**
* @title IInitializable
* @notice An interface for initializable contracts.
*/
/// @title IInitializable
/// @notice An interface for initializable contracts.
interface IInitializable {
/**
* @notice Initializes the contract.
* @dev This function may only be called once.
*/
/// @notice Initializes the contract.
/// @dev This function may only be called once.
function initialize() external;
}
packages/contracts-bedrock/contracts/dispute/interfaces/IVersioned.sol
View file @
8478fbfe
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
/**
* @title IVersioned
* @notice An interface for semantically versioned contracts.
*/
/// @title IVersioned
/// @notice An interface for semantically versioned contracts.
interface IVersioned {
/**
* @notice Returns the semantic version of the contract
* @return _version The semantic version of the contract
*/
/// @notice Returns the semantic version of the contract
/// @return _version The semantic version of the contract
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;
import "../../libraries/DisputeTypes.sol";
/**
* @title LibClock
* @notice This library contains helper functions for working with the `Clock` type.
*/
/// @title LibClock
/// @notice This library contains helper functions for working with the `Clock` type.
library LibClock {
/**
* @notice Packs a `Duration` and `Timestamp` into a `Clock` type.
* @param _duration The `Duration` 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`.
*/
/// @notice Packs a `Duration` and `Timestamp` into a `Clock` type.
/// @param _duration The `Duration` 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`.
function wrap(Duration _duration, Timestamp _timestamp) internal pure returns (Clock clock_) {
assembly {
clock_ := or(shl(0x40, _duration), _timestamp)
}
}
/**
* @notice Pull the `Duration` out of a `Clock` type.
* @param _clock The `Clock` type to pull the `Duration` out of.
* @return duration_ The `Duration` pulled out of `_clock`.
*/
/// @notice Pull the `Duration` out of a `Clock` type.
/// @param _clock The `Clock` type to pull the `Duration` out of.
/// @return duration_ The `Duration` pulled out of `_clock`.
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`.
assembly {
...
...
@@ -32,11 +26,9 @@ library LibClock {
}
}
/**
* @notice Pull the `Timestamp` out of a `Clock` type.
* @param _clock The `Clock` type to pull the `Timestamp` out of.
* @return timestamp_ The `Timestamp` pulled out of `_clock`.
*/
/// @notice Pull the `Timestamp` out of a `Clock` type.
/// @param _clock The `Clock` type to pull the `Timestamp` out of.
/// @return timestamp_ The `Timestamp` pulled out of `_clock`.
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
// only the `timestamp`.
...
...
packages/contracts-bedrock/contracts/dispute/lib/LibHashing.sol
View file @
8478fbfe
...
...
@@ -3,17 +3,14 @@ pragma solidity ^0.8.15;
import "../../libraries/DisputeTypes.sol";
/**
* @title Hashing
* @notice This library contains all of the hashing utilities used in the Cannon contracts.
*/
/// @title Hashing
/// @notice This library contains all of the hashing utilities used in the Cannon contracts.
library LibHashing {
/**
* @notice Hashes a claim and a position together.
* @param _claim A Claim type.
* @param _position The position of `claim`.
* @return claimHash_ A hash of abi.encodePacked(claim, position);
*/
/// @notice Hashes a claim and a position together.
/// @param _claim A Claim type.
/// @param _position The position of `claim`.
/// @return claimHash_ A hash of abi.encodePacked(claim, position);
function hashClaimPos(Claim _claim, Position _position) internal pure returns (ClaimHash claimHash_) {
assembly {
mstore(0x00, _claim)
...
...
packages/contracts-bedrock/contracts/dispute/lib/LibPosition.sol
View file @
8478fbfe
...
...
@@ -3,17 +3,14 @@ pragma solidity ^0.8.15;
import "../../libraries/DisputeTypes.sol";
/**
* @title LibPosition
* @notice This library contains helper functions for working with the `Position` type.
*/
/// @title LibPosition
/// @notice This library contains helper functions for working with the `Position` type.
library LibPosition {
/**
* @notice Computes a generalized index (2^{depth} + indexAtDepth).
* @param _depth The depth of the position.
* @param _indexAtDepth The index at the depth of the position.
* @return position_ The computed generalized index.
*/
/// @notice Computes a generalized index (2^{depth} + indexAtDepth).
/// @param _depth The depth of the position.
/// @param _indexAtDepth The index at the depth of the position.
/// @return position_ The computed generalized index.
function wrap(uint64 _depth, uint64 _indexAtDepth) internal pure returns (Position position_) {
assembly {
// gindex = 2^{_depth} + _indexAtDepth
...
...
@@ -21,12 +18,10 @@ library LibPosition {
}
}
/**
* @notice Pulls the `depth` out of a `Position` type.
* @param _position The generalized index to get the `depth` of.
* @return depth_ The `depth` of the `position` gindex.
* @custom:attribution Solady <https://github.com/Vectorized/Solady>
*/
/// @notice Pulls the `depth` out of a `Position` type.
/// @param _position The generalized index to get the `depth` of.
/// @return depth_ The `depth` of the `position` gindex.
/// @custom:attribution Solady <https://github.com/Vectorized/Solady>
function depth(Position _position) internal pure returns (uint64 depth_) {
// Return the most significant bit offset, which signifies the depth of the gindex.
assembly {
...
...
@@ -51,14 +46,12 @@ library LibPosition {
}
}
/**
* @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 binary tree, starting from index 0. For example, at gindex 2, the `depth` = 1
* and the `indexAtDepth` = 0.
* @param _position The generalized index to get the `indexAtDepth` of.
* @return indexAtDepth_ The `indexAtDepth` of the `position` gindex.
*/
/// @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 binary tree, starting from index 0. For example, at gindex 2, the `depth` = 1
/// and the `indexAtDepth` = 0.
/// @param _position The generalized index to get the `indexAtDepth` of.
/// @return indexAtDepth_ The `indexAtDepth` of the `position` gindex.
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,
// leaving only the `indexAtDepth`.
...
...
@@ -68,46 +61,38 @@ library LibPosition {
}
}
/**
* @notice Get the left child of `_position`.
* @param _position The position to get the left position of.
* @return left_ The position to the left of `position`.
*/
/// @notice Get the left child of `_position`.
/// @param _position The position to get the left position of.
/// @return left_ The position to the left of `position`.
function left(Position _position) internal pure returns (Position left_) {
assembly {
left_ := shl(1, _position)
}
}
/**
* @notice Get the right child of `_position`
* @param _position The position to get the right position of.
* @return right_ The position to the right of `position`.
*/
/// @notice Get the right child of `_position`
/// @param _position The position to get the right position of.
/// @return right_ The position to the right of `position`.
function right(Position _position) internal pure returns (Position right_) {
assembly {
right_ := or(1, shl(1, _position))
}
}
/**
* @notice Get the parent position of `_position`.
* @param _position The position to get the parent position of.
* @return parent_ The parent position of `position`.
*/
/// @notice Get the parent position of `_position`.
/// @param _position The position to get the parent position of.
/// @return parent_ The parent position of `position`.
function parent(Position _position) internal pure returns (Position parent_) {
assembly {
parent_ := shr(1, _position)
}
}
/**
* @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.
* @param _position The position to get the relative deepest, right most gindex of.
* @param _maxDepth The maximum depth of the game.
* @return rightIndex_ The deepest, right most gindex relative to the `position`.
*/
/// @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.
/// @param _position The position to get the relative deepest, right most gindex of.
/// @param _maxDepth The maximum depth of the game.
/// @return rightIndex_ The deepest, right most gindex relative to the `position`.
function rightIndex(
Position _position,
uint256 _maxDepth
...
...
@@ -119,14 +104,12 @@ library LibPosition {
}
}
/**
* @notice Get the move position of `_position`, which is the left child of:
* 1. `_position + 1` if `_isAttack` is true.
* 1. `_position` if `_isAttack` is false.
* @param _position The position to get the relative attack/defense position of.
* @param _isAttack Whether or not the move is an attack move.
* @return move_ The move position relative to `position`.
*/
/// @notice Get the move position of `_position`, which is the left child of:
/// 1. `_position + 1` if `_isAttack` is true.
/// 1. `_position` if `_isAttack` is false.
/// @param _position The position to get the relative attack/defense position of.
/// @param _isAttack Whether or not the move is an attack move.
/// @return move_ The move position relative to `position`.
function move(Position _position, bool _isAttack) internal pure returns (Position move_) {
assembly {
move_ := shl(1, or(iszero(_isAttack), _position))
...
...
packages/contracts-bedrock/contracts/libraries/DisputeErrors.sol
View file @
8478fbfe
...
...
@@ -7,95 +7,65 @@ import "./DisputeTypes.sol";
// `DisputeGameFactory` Errors //
////////////////////////////////////////////////////////////////
/**
* @notice Thrown when a dispute game is attempted to be created with an unsupported game type.
* @param gameType The 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.
error NoImplementation(GameType gameType);
/**
* @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.
*/
/// @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.
error GameAlreadyExists(Hash uuid);
////////////////////////////////////////////////////////////////
// `DisputeGame_Fault.sol` Errors //
////////////////////////////////////////////////////////////////
/**
* @notice Thrown when a supplied bond is too low to cover the
* cost of the next possible counter claim.
*/
/// @notice Thrown when a supplied bond is too low to cover the
/// cost of the next possible counter claim.
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();
/**
* @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();
/**
* @notice Thrown when a given claim is invalid (0).
*/
/// @notice Thrown when a given claim is invalid (0).
error InvalidClaim();
/**
* @notice Thrown when an action that requires the game to be `IN_PROGRESS` is invoked when
* the game is not in progress.
*/
/// @notice Thrown when an action that requires the game to be `IN_PROGRESS` is invoked when
/// the game is not in progress.
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();
/**
* @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();
/**
* @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();
/**
* @notice Thrown when an invalid prestate is supplied to `step`.
*/
/// @notice Thrown when an invalid prestate is supplied to `step`.
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();
////////////////////////////////////////////////////////////////
// `AttestationDisputeGame` Errors //
////////////////////////////////////////////////////////////////
/**
* @notice Thrown when an invalid signature is submitted to `challenge`.
*/
/// @notice Thrown when an invalid signature is submitted to `challenge`.
error InvalidSignature();
/**
* @notice Thrown when a signature that has already been used to support the
* `rootClaim` is submitted to `challenge`.
*/
/// @notice Thrown when a signature that has already been used to support the
/// `rootClaim` is submitted to `challenge`.
error AlreadyChallenged();
////////////////////////////////////////////////////////////////
// `Ownable` Errors //
////////////////////////////////////////////////////////////////
/**
* @notice Thrown when a function that is protected by the `onlyOwner` modifier
* is called from an account other than the owner.
*/
/// @notice Thrown when a function that is protected by the `onlyOwner` modifier
/// is called from an account other than the owner.
error NotOwner();
packages/contracts-bedrock/contracts/libraries/DisputeTypes.sol
View file @
8478fbfe
...
...
@@ -9,79 +9,57 @@ using LibHashing for Claim global;
using LibPosition for Position 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;
/**
* @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;
/**
* @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);
*/
/// @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);
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;
/**
* @notice A dedicated timestamp type.
*/
/// @notice A dedicated timestamp type.
type Timestamp is uint64;
/**
* @notice A dedicated duration type.
* @dev Unit: seconds
*/
/// @notice A dedicated duration type.
/// @dev Unit: seconds
type Duration is uint64;
/**
* @notice A `GameId` represents a packed 12 byte timestamp and a 20 byte address.
* @dev The packed layout of this type is as follows:
* ┌────────────┬────────────────┐
* │ Bits │ Value │
* ├────────────┼────────────────┤
* │ [0, 96) │ Timestamp │
* │ [96, 256) │ 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:
/// ┌────────────┬────────────────┐
/// │ Bits │ Value │
/// ├────────────┼────────────────┤
/// │ [0, 96) │ Timestamp │
/// │ [96, 256) │ Address │
/// └────────────┴────────────────┘
type GameId is bytes32;
/**
* @notice A `Clock` represents a packed `Duration` and `Timestamp`
* @dev The packed layout of this type is as follows:
* ┌────────────┬────────────────┐
* │ Bits │ Value │
* ├────────────┼────────────────┤
* │ [0, 64) │ Duration │
* │ [64, 128) │ Timestamp │
* └────────────┴────────────────┘
*/
/// @notice A `Clock` represents a packed `Duration` and `Timestamp`
/// @dev The packed layout of this type is as follows:
/// ┌────────────┬────────────────┐
/// │ Bits │ Value │
/// ├────────────┼────────────────┤
/// │ [0, 64) │ Duration │
/// │ [64, 128) │ Timestamp │
/// └────────────┴────────────────┘
type Clock is uint128;
/**
* @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
* 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
* as 2^{depth} + indexAtDepth.
*/
/// @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
/// 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
/// as 2^{depth} + indexAtDepth.
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;
/**
* @notice The current status of the dispute game.
*/
/// @notice The current status of the dispute game.
enum GameStatus {
// The game is currently in progress, and has not been resolved.
IN_PROGRESS,
...
...
@@ -91,23 +69,15 @@ enum GameStatus {
DEFENDER_WINS
}
/**
* @title GameTypes
* @notice A library that defines the IDs of games that can be played.
*/
/// @title GameTypes
/// @notice A library that defines the IDs of games that can be played.
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);
/**
* @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);
/**
* @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);
}
packages/contracts-bedrock/contracts/test/DisputeGameFactory.t.sol
View file @
8478fbfe
...
...
@@ -37,10 +37,8 @@ contract DisputeGameFactory_Init is Test {
}
contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
/**
* @dev Tests that the `create` function succeeds when creating a new dispute game
* with a `GameType` that has an implementation set.
*/
/// @dev Tests that the `create` function succeeds when creating a new dispute game
/// with a `GameType` that has an implementation set.
function testFuzz_create_succeeds(
uint8 gameType,
Claim rootClaim,
...
...
@@ -70,10 +68,8 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
assertEq(timestamp2, block.timestamp);
}
/**
* @dev Tests that the `create` function reverts when there is no implementation
* set for the given `GameType`.
*/
/// @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,
...
...
@@ -86,9 +82,7 @@ contract DisputeGameFactory_Create_Test is DisputeGameFactory_Init {
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(
uint8 gameType,
Claim rootClaim,
...
...
@@ -124,9 +118,7 @@ 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`.
*/
/// @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.FAULT` enum value, it has not been set.
assertEq(address(factory.gameImpls(GameTypes.FAULT)), address(0));
...
...
@@ -141,9 +133,7 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
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 {
// Ensure that the `setImplementation` function reverts when called by a non-owner.
vm.prank(address(0));
...
...
@@ -153,10 +143,8 @@ contract DisputeGameFactory_SetImplementation_Test is DisputeGameFactory_Init {
}
contract DisputeGameFactory_GetGameUUID_Test is DisputeGameFactory_Init {
/**
* @dev Tests that the `getGameUUID` function returns the correct hash when comparing
* against the keccak256 hash of the abi-encoded parameters.
*/
/// @dev Tests that the `getGameUUID` function returns the correct hash when comparing
/// against the keccak256 hash of the abi-encoded parameters.
function testDiff_getGameUUID_succeeds(
uint8 gameType,
Claim rootClaim,
...
...
@@ -173,26 +161,20 @@ 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.
*/
/// @dev Tests that the `owner` function returns the correct address after deployment.
function test_owner_succeeds() public {
assertEq(factory.owner(), address(this));
}
}
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 {
factory.transferOwnership(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 {
vm.prank(address(0));
vm.expectRevert("Ownable: caller is not the owner");
...
...
@@ -200,11 +182,9 @@ contract DisputeGameFactory_TransferOwnership_Test is DisputeGameFactory_Init {
}
}
/**
* @title PackingTester
* @notice Exposes the internal packing functions so that they can be fuzzed
* in a roundtrip manner.
*/
/// @title PackingTester
/// @notice Exposes the internal packing functions so that they can be fuzzed
/// in a roundtrip manner.
contract PackingTester is DisputeGameFactory {
function packSlot(address _addr, uint256 _num) external pure returns (GameId) {
return _packSlot(_addr, _num);
...
...
@@ -215,10 +195,8 @@ contract PackingTester is DisputeGameFactory {
}
}
/**
* @title DisputeGameFactory_PackSlot_Test
* @notice Fuzzes the PackingTester contract
*/
/// @title DisputeGameFactory_PackSlot_Test
/// @notice Fuzzes the PackingTester contract
contract DisputeGameFactory_PackSlot_Test is Test {
PackingTester tester;
...
...
@@ -226,9 +204,7 @@ contract DisputeGameFactory_PackSlot_Test is Test {
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 {
GameId slot = tester.packSlot(_addr, uint256(_num));
(address addr, uint256 num) = tester.unpackSlot(slot);
...
...
@@ -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 {
function initialize() external {
// noop
...
...
packages/contracts-bedrock/contracts/test/FaultDisputeGame.t.sol
View file @
8478fbfe
...
...
@@ -13,22 +13,14 @@ import { LibClock } from "../dispute/lib/LibClock.sol";
import { LibPosition } from "../dispute/lib/LibPosition.sol";
contract FaultDisputeGame_Init is DisputeGameFactory_Init {
/**
* @dev The extra data passed to the game for initialization.
*/
/// @dev The extra data passed to the game for initialization.
bytes internal constant EXTRA_DATA = abi.encode(1);
/**
* @dev The type of the game being tested.
*/
/// @dev The type of the game being tested.
GameType internal constant GAME_TYPE = GameType.wrap(0);
/**
* @dev The implementation of the game.
*/
/// @dev The implementation of the game.
FaultDisputeGame internal gameImpl;
/**
* @dev The `Clone` proxy of the game.
*/
/// @dev The `Clone` proxy of the game.
FaultDisputeGame internal gameProxy;
event Move(uint256 indexed parentIndex, Claim indexed pivot, address indexed claimant);
...
...
@@ -48,13 +40,9 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
}
contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/**
* @dev The root claim of the game.
*/
/// @dev The root claim of the game.
Claim internal constant ROOT_CLAIM = Claim.wrap(bytes32(uint256(10)));
/**
* @dev The absolute prestate of the trace.
*/
/// @dev The absolute prestate of the trace.
Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32(uint256(0)));
function setUp() public override {
...
...
@@ -65,37 +53,27 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
// `IDisputeGame` Implementation Tests //
////////////////////////////////////////////////////////////////
/**
* @dev Tests that the game's root claim is set correctly.
*/
/// @dev Tests that the game's root claim is set correctly.
function test_rootClaim_succeeds() public {
assertEq(Claim.unwrap(gameProxy.rootClaim()), Claim.unwrap(ROOT_CLAIM));
}
/**
* @dev Tests that the game's extra data is set correctly.
*/
/// @dev Tests that the game's extra data is set correctly.
function test_extraData_succeeds() public {
assertEq(gameProxy.extraData(), EXTRA_DATA);
}
/**
* @dev Tests that the game's status is set correctly.
*/
/// @dev Tests that the game's status is set correctly.
function test_gameStart_succeeds() public {
assertEq(Timestamp.unwrap(gameProxy.gameStart()), block.timestamp);
}
/**
* @dev Tests that the game's type is set correctly.
*/
/// @dev Tests that the game's type is set correctly.
function test_gameType_succeeds() public {
assertEq(GameType.unwrap(gameProxy.gameType()), GameType.unwrap(GAME_TYPE));
}
/**
* @dev Tests that the game's data is set correctly.
*/
/// @dev Tests that the game's data is set correctly.
function test_gameData_succeeds() public {
(GameType gameType, Claim rootClaim, bytes memory extraData) = gameProxy.gameData();
...
...
@@ -108,9 +86,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
// `IFaultDisputeGame` Implementation Tests //
////////////////////////////////////////////////////////////////
/**
* @dev Tests that the root claim's data is set correctly when the game is initialized.
*/
/// @dev Tests that the root claim's data is set correctly when the game is initialized.
function test_initialRootClaimData_succeeds() public {
(
uint32 parentIndex,
...
...
@@ -130,10 +106,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
);
}
/**
* @dev Tests that a move while the game status is not `IN_PROGRESS` causes the call to revert
* with the `GameNotInProgress` error
*/
/// @dev Tests that a move while the game status is not `IN_PROGRESS` causes the call to revert
/// with the `GameNotInProgress` error
function test_move_gameNotInProgress_reverts() public {
uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS);
...
...
@@ -154,18 +128,14 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.attack(0, Claim.wrap(0));
}
/**
* @dev Tests that an attempt to defend the root claim reverts with the `CannotDefendRootClaim` error.
*/
/// @dev Tests that an attempt to defend the root claim reverts with the `CannotDefendRootClaim` error.
function test_defendRoot_invalidMove_reverts() public {
vm.expectRevert(CannotDefendRootClaim.selector);
gameProxy.defend(0, Claim.wrap(bytes32(uint256(5))));
}
/**
* @dev Tests that an attempt to move against a claim that does not exist reverts with the
* `ParentDoesNotExist` error.
*/
/// @dev Tests that an attempt to move against a claim that does not exist reverts with the
/// `ParentDoesNotExist` error.
function test_move_nonExistentParent_reverts() public {
Claim claim = Claim.wrap(bytes32(uint256(5)));
...
...
@@ -178,10 +148,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.defend(1, claim);
}
/**
* @dev Tests that an attempt to move at the maximum game depth reverts with the
* `GameDepthExceeded` error.
*/
/// @dev Tests that an attempt to move at the maximum game depth reverts with the
/// `GameDepthExceeded` error.
function test_move_gameDepthExceeded_reverts() public {
Claim claim = Claim.wrap(bytes32(uint256(5)));
...
...
@@ -197,10 +165,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
}
}
/**
* @dev Tests that a move made after the clock time has exceeded reverts with the
* `ClockTimeExceeded` error.
*/
/// @dev Tests that a move made after the clock time has exceeded reverts with the
/// `ClockTimeExceeded` error.
function test_move_clockTimeExceeded_reverts() public {
// Warp ahead past the clock time for the first move (3 1/2 days)
vm.warp(block.timestamp + 3 days + 12 hours + 1);
...
...
@@ -208,10 +174,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
}
/**
* @dev Tests that an identical claim cannot be made twice. The duplicate claim attempt should
* revert with the `ClaimAlreadyExists` error.
*/
/// @dev Tests that an identical claim cannot be made twice. The duplicate claim attempt should
/// revert with the `ClaimAlreadyExists` error.
function test_move_duplicateClaim_reverts() public {
Claim claim = Claim.wrap(bytes32(uint256(5)));
...
...
@@ -223,9 +187,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.attack(0, claim);
}
/**
* @dev Static unit test for the correctness of an opening attack.
*/
/// @dev Static unit test for the correctness of an opening attack.
function test_simpleAttack_succeeds() public {
// Warp ahead 5 seconds.
vm.warp(block.timestamp + 5);
...
...
@@ -272,19 +234,15 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
);
}
/**
* @dev Static unit test for the correctness an uncontested root resolution.
*/
/// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontested() public {
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
}
/**
* @dev Static unit test asserting that resolve reverts when the game state is
* not in progress.
*/
/// @dev Static unit test asserting that resolve reverts when the game state is
/// not in progress.
function test_resolve_notInProgress_reverts() public {
uint256 chalWins = uint256(GameStatus.CHALLENGER_WINS);
...
...
@@ -300,9 +258,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.resolve();
}
/**
* @dev Static unit test for the correctness of resolving a single attack game state.
*/
/// @dev Static unit test for the correctness of resolving a single attack game state.
function test_resolve_rootContested() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
...
...
@@ -311,9 +267,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(uint8(gameProxy.status()), uint8(GameStatus.CHALLENGER_WINS));
}
/**
* @dev Static unit test for the correctness of resolving a game with a contested challenge claim.
*/
/// @dev Static unit test for the correctness of resolving a game with a contested challenge claim.
function test_resolve_challengeContested() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6))));
...
...
@@ -323,9 +277,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
}
/**
* @dev Static unit test for the correctness of resolving a game with multiplayer moves.
*/
/// @dev Static unit test for the correctness of resolving a game with multiplayer moves.
function test_resolve_teamDeathmatch() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(0, Claim.wrap(bytes32(uint256(4))));
...
...
@@ -338,11 +290,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
}
}
/**
* @notice A generic game player actor with a configurable trace.
* @dev This actor always responds rationally with respect to their trace. The
* `play` function can be overridden to change this behavior.
*/
/// @notice A generic game player actor with a configurable trace.
/// @dev This actor always responds rationally with respect to their trace. The
/// `play` function can be overridden to change this behavior.
contract GamePlayer {
bool public failedToStep;
FaultDisputeGame public gameProxy;
...
...
@@ -352,9 +302,7 @@ contract GamePlayer {
bytes internal trace;
uint256 internal maxDepth;
/**
* @notice Initializes the player
*/
/// @notice Initializes the player
function init(
FaultDisputeGame _gameProxy,
GamePlayer _counterParty,
...
...
@@ -366,9 +314,7 @@ contract GamePlayer {
maxDepth = _gameProxy.MAX_GAME_DEPTH();
}
/**
* @notice Perform the next move in the game.
*/
/// @notice Perform the next move in the game.
function play(uint256 _parentIndex) public virtual {
// Grab the claim data at the parent index.
(uint32 grandparentIndex, , Claim parentClaim, Position parentPos, ) = gameProxy.claimData(
...
...
@@ -488,40 +434,28 @@ contract GamePlayer {
}
}
/**
* @notice Returns the length of the claim data array.
*/
/// @notice Returns the length of the claim data array.
function claimDataLen() internal view returns (uint256 len_) {
return uint256(vm.load(address(gameProxy), bytes32(uint256(1))));
}
/**
* @notice Returns the player's claim that commits to a given gindex.
*/
/// @notice Returns the player's claim that commits to a given gindex.
function claimAt(Position _position) internal view returns (Claim claim_) {
return claimAt(_position.rightIndex(maxDepth).indexAtDepth());
}
/**
* @notice Returns the player's claim that commits to a given trace index.
*/
/// @notice Returns the player's claim that commits to a given trace index.
function claimAt(uint256 _traceIndex) public view returns (Claim claim_) {
return Claim.wrap(bytes32(uint256(bytes32(trace[_traceIndex]) >> 248)));
}
}
contract OneVsOne_Arena is FaultDisputeGame_Init {
/**
* @dev The absolute prestate of the trace.
*/
/// @dev The absolute prestate of the trace.
Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32(uint256(15)));
/**
* @dev The honest participant.
*/
/// @dev The honest participant.
GamePlayer internal honest;
/**
* @dev The dishonest participant.
*/
/// @dev The dishonest participant.
GamePlayer internal dishonest;
function init(
...
...
packages/contracts-bedrock/contracts/test/LibClock.t.sol
View file @
8478fbfe
...
...
@@ -5,21 +5,15 @@ import { Test } from "forge-std/Test.sol";
import { LibClock } from "../dispute/lib/LibClock.sol";
import "../libraries/DisputeTypes.sol";
/**
* @notice Tests for `LibClock`
*/
/// @notice Tests for `LibClock`
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 {
Clock clock = LibClock.wrap(_duration, _timestamp);
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 {
Clock clock = LibClock.wrap(_duration, _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";
import { LibPosition } from "../dispute/lib/LibPosition.sol";
import "../libraries/DisputeTypes.sol";
/**
* @notice Tests for `LibPosition`
*/
/// @notice Tests for `LibPosition`
contract LibPosition_Test is Test {
/**
* @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
* will likely be much lower.
*/
/// @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
/// will likely be much lower.
uint8 internal constant MAX_DEPTH = 63;
function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal view returns (uint64) {
...
...
@@ -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 {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...
...
@@ -35,9 +29,7 @@ contract LibPosition_Test is Test {
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 {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...
...
@@ -45,9 +37,7 @@ contract LibPosition_Test is Test {
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 {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...
...
@@ -59,9 +49,7 @@ contract LibPosition_Test is Test {
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 {
// Depth bound: [0, 63]
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
...
...
@@ -74,9 +62,7 @@ contract LibPosition_Test is Test {
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 {
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
...
...
@@ -88,10 +74,8 @@ contract LibPosition_Test is Test {
assertEq(parent.indexAtDepth(), _indexAtDepth / 2);
}
/**
* @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative
* to a given position.
*/
/// @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative
/// to a given position.
function testFuzz_rightIndex_correctness_suceeds(
uint64 _maxDepth,
uint8 _depth,
...
...
@@ -115,11 +99,9 @@ contract LibPosition_Test is Test {
assertEq(Position.unwrap(rightIndex), Position.unwrap(position));
}
/**
* @notice Tests that the `attack` function correctly computes the position of the attack relative to
* a given position.
* @dev `attack` is an alias for `left`, but we test it separately for completeness.
*/
/// @notice Tests that the `attack` function correctly computes the position of the attack relative to
/// a given position.
/// @dev `attack` is an alias for `left`, but we test it separately for completeness.
function testFuzz_attack_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
// Depth bound: [0, 63]
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
...
...
@@ -132,12 +114,10 @@ contract LibPosition_Test is Test {
assertEq(attack.indexAtDepth(), _indexAtDepth * 2);
}
/**
* @notice Tests that the `defend` function correctly computes the position of the defense relative to
* 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]
* on the depth.
*/
/// @notice Tests that the `defend` function correctly computes the position of the defense relative to
/// 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]
/// on the depth.
function testFuzz_defend_correctness_suceeds(uint8 _depth, uint64 _indexAtDepth) public {
// Depth bound: [1, 63]
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
...
...
@@ -150,10 +130,8 @@ contract LibPosition_Test is Test {
assertEq(defend.indexAtDepth(), ((_indexAtDepth / 2) * 2 + 1) * 2);
}
/**
* @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.
*/
/// @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.
function test_pos_correctness_succeeds() public {
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