Commit 66ae120d authored by clabby's avatar clabby Committed by GitHub

fix(ctb): `LibPosition` downcasting (#10150)

* Correct `LibPosition` types

* bindings, locks, etc.
parent f32d1972
This diff is collapsed.
......@@ -112,8 +112,8 @@
"sourceCodeHash": "0x08f34cec56d58ea6ee7a47b5adcbeca6a68a5dd1daa949330b4bde86c2e605f5"
},
"src/dispute/FaultDisputeGame.sol": {
"initCodeHash": "0x98544bd91d1d777bfcfa0d71b81a9ed75f9feb31536aad934b92dcf16bb21ce7",
"sourceCodeHash": "0x06c7f5206e9c121c5c7fa2e6e114f9a80781025954c830bc7641f3ab0a5b2583"
"initCodeHash": "0xac2ea3948d07f6f441ae3b2cb5f5fc2f0d3f71af97ffc396ffca1ffc1ccd8b21",
"sourceCodeHash": "0xad80ee61719eb611d2f015f71d95e29bea1013a78f1f2861301809ab440bd52b"
},
"src/dispute/weth/DelayedWETH.sol": {
"initCodeHash": "0x7b6ec89eaec09e369426e73161a9c6932223bb1f974377190c3f6f552995da35",
......
......@@ -88,8 +88,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
OutputRoot public startingOutputRoot;
/// @notice Semantic version.
/// @custom:semver 0.12.0
string public constant version = "0.12.0";
/// @custom:semver 0.13.0
string public constant version = "0.13.0";
/// @param _gameType The type ID of the game.
/// @param _absolutePrestate The absolute prestate of the instruction trace.
......
......@@ -11,7 +11,7 @@ library LibPosition {
/// @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_) {
function wrap(uint8 _depth, uint128 _indexAtDepth) internal pure returns (Position position_) {
assembly {
// gindex = 2^{_depth} + _indexAtDepth
position_ := add(shl(_depth, 1), _indexAtDepth)
......@@ -22,7 +22,7 @@ library LibPosition {
/// @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_) {
function depth(Position _position) internal pure returns (uint8 depth_) {
// Return the most significant bit offset, which signifies the depth of the gindex.
assembly {
depth_ := or(depth_, shl(6, lt(0xffffffffffffffff, shr(depth_, _position))))
......@@ -53,7 +53,7 @@ library LibPosition {
/// 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_) {
function indexAtDepth(Position _position) internal pure returns (uint128 indexAtDepth_) {
// Return bits p_{msb-1}...p_{0}. This effectively pulls the 2^{depth} out of the gindex,
// leaving only the `indexAtDepth`.
uint256 msb = depth(_position);
......
......@@ -237,7 +237,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Tests that the bond during the bisection game depths is correct.
function test_getRequiredBond_succeeds() public {
for (uint64 i = 0; i < uint64(gameProxy.splitDepth()); i++) {
for (uint8 i = 0; i < uint8(gameProxy.splitDepth()); i++) {
Position pos = LibPosition.wrap(i, 0);
uint256 bond = gameProxy.getRequiredBond(pos);
......@@ -254,7 +254,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Tests that the bond at a depth greater than the maximum game depth reverts.
function test_getRequiredBond_outOfBounds_reverts() public {
Position pos = LibPosition.wrap(uint64(gameProxy.maxGameDepth() + 1), 0);
Position pos = LibPosition.wrap(uint8(gameProxy.maxGameDepth() + 1), 0);
vm.expectRevert(GameDepthExceeded.selector);
gameProxy.getRequiredBond(pos);
}
......
......@@ -7,24 +7,24 @@ import "src/libraries/DisputeTypes.sol";
/// @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
/// @dev Assumes a MAX depth of 126 for the Position type. Any greater depth can cause overflows.
/// @dev At the lowest level of the tree, this allows for 2 ** 126 leaves. In reality, the max game depth
/// will likely be much lower.
uint8 internal constant MAX_DEPTH = 63;
uint8 internal constant MAX_DEPTH = 126;
/// @dev Arbitrary split depth around half way down the tree.
uint8 internal constant SPLIT_DEPTH = 30;
uint8 internal constant SPLIT_DEPTH = 64;
function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal pure returns (uint64) {
function boundIndexAtDepth(uint8 _depth, uint128 _indexAtDepth) internal pure returns (uint128) {
// Index at depth bound: [0, 2 ** _depth-1]
if (_depth > 0) {
return uint64(bound(_indexAtDepth, 0, 2 ** (_depth - 1)));
return uint128(bound(_indexAtDepth, 0, 2 ** (_depth - 1)));
} else {
return 0;
}
}
/// @notice Tests that the `depth` function correctly shifts out the `depth` from a packed `Position` type.
function testFuzz_depth_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_depth_correctness_succeeds(uint8 _depth, uint128 _indexAtDepth) public {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
Position position = LibPosition.wrap(_depth, _indexAtDepth);
......@@ -33,7 +33,7 @@ contract LibPosition_Test is Test {
/// @notice Tests that the `indexAtDepth` function correctly shifts out the `indexAtDepth` from a packed `Position`
/// type.
function testFuzz_indexAtDepth_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_indexAtDepth_correctness_succeeds(uint8 _depth, uint128 _indexAtDepth) public {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
Position position = LibPosition.wrap(_depth, _indexAtDepth);
......@@ -41,19 +41,19 @@ contract LibPosition_Test is Test {
}
/// @notice Tests that the `left` function correctly computes the position of the left child.
function testFuzz_left_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_left_correctness_succeeds(uint8 _depth, uint128 _indexAtDepth) public {
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
Position position = LibPosition.wrap(_depth, _indexAtDepth);
Position left = position.left();
assertEq(left.depth(), uint64(_depth) + 1);
assertEq(left.depth(), _depth + 1);
assertEq(left.indexAtDepth(), _indexAtDepth * 2);
}
/// @notice Tests that the `right` function correctly computes the position of the right child.
function testFuzz_right_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_right_correctness_succeeds(uint8 _depth, uint128 _indexAtDepth) public {
// Depth bound: [0, 63]
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
......@@ -66,7 +66,7 @@ contract LibPosition_Test is Test {
}
/// @notice Tests that the `parent` function correctly computes the position of the parent.
function testFuzz_parent_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_parent_correctness_succeeds(uint8 _depth, uint128 _indexAtDepth) public {
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
......@@ -79,7 +79,7 @@ contract LibPosition_Test is Test {
/// @notice Tests that the `traceAncestor` function correctly computes the position of the
/// highest ancestor that commits to the same trace index.
function testFuzz_traceAncestor_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_traceAncestor_correctness_succeeds(uint8 _depth, uint128 _indexAtDepth) public {
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
......@@ -95,7 +95,7 @@ contract LibPosition_Test is Test {
/// @notice Tests that the `traceAncestorBounded` function correctly computes the position of the
/// highest ancestor (below `SPLIT_DEPTH`) that commits to the same trace index.
function testFuzz_traceAncestorBounded_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_traceAncestorBounded_correctness_succeeds(uint8 _depth, uint128 _indexAtDepth) public {
_depth = uint8(bound(_depth, SPLIT_DEPTH + 1, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
......@@ -116,7 +116,7 @@ contract LibPosition_Test is Test {
/// @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative
/// to a given position.
function testFuzz_rightIndex_correctness_succeeds(uint64 _maxDepth, uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_rightIndex_correctness_succeeds(uint8 _maxDepth, uint8 _depth, uint128 _indexAtDepth) public {
// Max depth bound: [1, 63]
// The max game depth MUST be at least 1.
_maxDepth = uint8(bound(_maxDepth, 1, MAX_DEPTH));
......@@ -138,7 +138,7 @@ contract LibPosition_Test is Test {
/// @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_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_attack_correctness_succeeds(uint8 _depth, uint128 _indexAtDepth) public {
// Depth bound: [0, 63]
_depth = uint8(bound(_depth, 0, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
......@@ -154,7 +154,7 @@ contract LibPosition_Test is Test {
/// 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_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_defend_correctness_succeeds(uint8 _depth, uint128 _indexAtDepth) public {
// Depth bound: [1, 63]
_depth = uint8(bound(_depth, 1, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
......
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