Commit 8478fbfe authored by clabby's avatar clabby

Change comment style for `dispute` contracts

parent 72c6fb0a
...@@ -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)
......
...@@ -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;
} }
......
// 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;
} }
...@@ -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
......
...@@ -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,
......
...@@ -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_);
} }
// 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;
} }
// 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);
} }
...@@ -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`.
......
...@@ -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)
......
...@@ -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))
......
...@@ -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();
...@@ -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);
} }
...@@ -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
......
...@@ -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));
......
...@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment