diff --git a/src/lib/verifier/DAVerifier.sol b/src/lib/verifier/DAVerifier.sol index d10d02b6..a102e78c 100644 --- a/src/lib/verifier/DAVerifier.sol +++ b/src/lib/verifier/DAVerifier.sol @@ -64,7 +64,11 @@ library DAVerifier { /// @notice The verifier data length isn't equal to the number of shares in the shares proofs. UnequalDataLengthAndNumberOfSharesProofs, /// @notice The number of leaves in the binary merkle proof is not divisible by 4. - InvalidNumberOfLeavesInProof + InvalidNumberOfLeavesInProof, + /// @notice The provided range is invalid. + InvalidRange, + /// @notice The provided range is out of bounds. + OutOfBoundsRange } /////////////// @@ -107,12 +111,13 @@ library DAVerifier { uint256 cursor = 0; for (uint256 i = 0; i < _sharesProof.shareProofs.length; i++) { uint256 sharesUsed = _sharesProof.shareProofs[i].endKey - _sharesProof.shareProofs[i].beginKey; + (bytes[] memory s, ErrorCodes err) = slice(_sharesProof.data, cursor, cursor + sharesUsed); + if (err != ErrorCodes.NoError) { + return (false, err); + } if ( !NamespaceMerkleTree.verifyMulti( - _sharesProof.rowRoots[i], - _sharesProof.shareProofs[i], - _sharesProof.namespace, - slice(_sharesProof.data, cursor, cursor + sharesUsed) + _sharesProof.rowRoots[i], _sharesProof.shareProofs[i], _sharesProof.namespace, s ) ) { return (false, ErrorCodes.InvalidSharesToRowsProof); @@ -235,11 +240,21 @@ library DAVerifier { /// @param _begin The beginning of the range (inclusive). /// @param _end The ending of the range (exclusive). /// @return _ the sliced data. - function slice(bytes[] memory _data, uint256 _begin, uint256 _end) internal pure returns (bytes[] memory) { + function slice(bytes[] memory _data, uint256 _begin, uint256 _end) + internal + pure + returns (bytes[] memory, ErrorCodes) + { + if (_begin > _end) { + return (_data, ErrorCodes.InvalidRange); + } + if (_begin > _data.length || _end > _data.length) { + return (_data, ErrorCodes.OutOfBoundsRange); + } bytes[] memory out = new bytes[](_end-_begin); for (uint256 i = _begin; i < _end; i++) { - out[i] = _data[i]; + out[i - _begin] = _data[i]; } - return out; + return (out, ErrorCodes.NoError); } } diff --git a/src/lib/verifier/test/DAVerifier.t.sol b/src/lib/verifier/test/DAVerifier.t.sol index 0c610960..e68149cc 100644 --- a/src/lib/verifier/test/DAVerifier.t.sol +++ b/src/lib/verifier/test/DAVerifier.t.sol @@ -194,6 +194,46 @@ contract DAVerifierTest is DSTest { assertEq(actualSquareSize, expectedSquareSize); } + function testValidSlice() public { + bytes[] memory data = new bytes[](4); + data[0] = "a"; + data[1] = "b"; + data[2] = "c"; + data[3] = "d"; + + (bytes[] memory result, DAVerifier.ErrorCodes error) = DAVerifier.slice(data, 1, 3); + + assertEq(uint256(error), uint256(DAVerifier.ErrorCodes.NoError)); + assertEq(string(result[0]), string(data[1])); + assertEq(string(result[1]), string(data[2])); + } + + function testInvalidSliceBeginEnd() public { + bytes[] memory data = new bytes[](4); + data[0] = "a"; + data[1] = "b"; + data[2] = "c"; + data[3] = "d"; + + (bytes[] memory result, DAVerifier.ErrorCodes error) = DAVerifier.slice(data, 2, 1); + + assertEq(uint256(error), uint256(DAVerifier.ErrorCodes.InvalidRange)); + } + + function testOutOfBoundsSlice() public { + bytes[] memory data = new bytes[](4); + data[0] = "a"; + data[1] = "b"; + data[2] = "c"; + data[3] = "d"; + + (bytes[] memory result, DAVerifier.ErrorCodes error) = DAVerifier.slice(data, 2, 5); + assertEq(uint256(error), uint256(DAVerifier.ErrorCodes.OutOfBoundsRange)); + + (result, error) = DAVerifier.slice(data, 6, 8); + assertEq(uint256(error), uint256(DAVerifier.ErrorCodes.OutOfBoundsRange)); + } + function computeValidatorSetHash(Validator[] memory _validators) private pure returns (bytes32) { return keccak256(abi.encode(_validators)); }