Detailed description of the impact of this finding.
Vulnerability: Dubious Typecasting in Various Functions
Description:
The vulnerability arises from improper typecasting in several functions, leading to potential data loss or unexpected behavior. Specifically, the conversion from larger data types to smaller ones occurs without proper validation.
Affected Functions and Locations:
getTimeBounds (SequencerInbox.sol lines 216-233):
Issue: Typecasting block.timestamp and block.number to uint64.
Impact: Potential overflow resulting in incorrect time bounds.
Recommendation: Use clear constants and validate values before typecasting.
Impact: Potential data loss or unexpected behavior.
Recommendation: Use clear constants and validate values before typecasting.
packHeader (SequencerInbox.sol lines 637-653):
Issue: Typecasting afterDelayedMessagesRead to uint64.
Impact: Potential overflow resulting in incorrect header formation.
Recommendation: Use clear constants and validate values before typecasting.
General Recommendation:
To mitigate these vulnerabilities, implement validation checks before performing typecasting operations. Ensure that the values being cast do not exceed the maximum limits of the target data types. For example, verify that block.timestamp and block.number are within the allowable range before casting them to uint64. Similarly, validate the lengths of arrays and other data structures prior to typecasting.
Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "forge-std/Test.sol";
import "../src/SequencerInbox.sol";
contract SequencerInboxTest is Test {
SequencerInbox sequencerInbox;
IBridge bridge;
IReader4844 reader4844;
function setUp() public {
bridge = IBridge(address(0x1234)); // Mock address
reader4844 = IReader4844(address(0x5678)); // Mock address
sequencerInbox = new SequencerInbox(128 * 1024, reader4844, false, false);
sequencerInbox.initialize(bridge, ISequencerInbox.MaxTimeVariation(1, 1, 1, 1), BufferConfig(1, 1, 1));
}
function testGetTimeBoundsOverflow() public {
// Set block.timestamp and block.number to values that will cause overflow when cast to uint64
vm.warp(2**64); // Set block.timestamp to 2^64
vm.roll(2**64); // Set block.number to 2^64
// Call getTimeBounds and check for overflow
IBridge.TimeBounds memory bounds = sequencerInbox.getTimeBounds();
assertEq(bounds.minTimestamp, 0, "minTimestamp should overflow to 0");
assertEq(bounds.minBlockNumber, 0, "minBlockNumber should overflow to 0");
}
function testSetValidKeysetOverflow() public {
// Set block.number to a value that will cause overflow when cast to uint64
vm.roll(2**64); // Set block.number to 2^64
// Prepare a dummy keyset
bytes memory keysetBytes = hex"1234";
// Call setValidKeyset and check for overflow
sequencerInbox.setValidKeyset(keysetBytes);
bytes32 ksHash = keccak256(bytes.concat(hex"fe", keccak256(keysetBytes)));
(bool isValid, uint64 creationBlock) = sequencerInbox.dasKeySetInfo(ksHash);
assertEq(creationBlock, 0, "creationBlock should overflow to 0");
}
function testSetBufferConfigOverflow() public {
// Set block.number to a value that will cause overflow when cast to uint64
vm.roll(2**64); // Set block.number to 2^64
// Prepare a dummy buffer config
BufferConfig memory bufferConfig = BufferConfig(1, 1, 1);
// Call setBufferConfig and check for overflow
sequencerInbox.setBufferConfig(bufferConfig);
(uint64 bufferBlocks, , , ) = sequencerInbox.buffer();
assertEq(bufferBlocks, 0, "bufferBlocks should overflow to 0");
}
function testSubmitBatchSpendingReportOverflow() public {
// Prepare dummy data
bytes32 dataHash = keccak256("dummy data");
uint256 seqMessageIndex = 1;
uint256 gasPrice = 1;
uint256 extraGas = 2**64; // Set extraGas to a value that will cause overflow when cast to uint64
// Call submitBatchSpendingReport and check for overflow
sequencerInbox.submitBatchSpendingReport(dataHash, seqMessageIndex, gasPrice, extraGas);
// No direct way to check the overflow, but we can ensure it doesn't revert
}
function testSetMaxTimeVariationOverflow() public {
// Prepare a dummy max time variation with values that will cause overflow when cast to uint64
ISequencerInbox.MaxTimeVariation memory maxTimeVariation = ISequencerInbox.MaxTimeVariation(
2**64, 2**64, 2**64, 2**64
);
// Call setMaxTimeVariation and check for overflow
sequencerInbox.setMaxTimeVariation(maxTimeVariation);
(uint64 delayBlocks, uint64 futureBlocks, uint64 delaySeconds, uint64 futureSeconds) = sequencerInbox.maxTimeVariationInternal();
assertEq(delayBlocks, 0, "delayBlocks should overflow to 0");
assertEq(futureBlocks, 0, "futureBlocks should overflow to 0");
assertEq(delaySeconds, 0, "delaySeconds should overflow to 0");
assertEq(futureSeconds, 0, "futureSeconds should overflow to 0");
}
function testFormCallDataHashOverflow() public {
// Prepare dummy data
bytes memory data = hex"1234";
uint256 afterDelayedMessagesRead = 2**64; // Set afterDelayedMessagesRead to a value that will cause overflow when cast to uint64
// Call formCallDataHash and check for overflow
(bytes32 dataHash, ) = sequencerInbox.formCallDataHash(data, afterDelayedMessagesRead);
// No direct way to check the overflow, but we can ensure it doesn't revert
}
function testPackHeaderOverflow() public {
// Set afterDelayedMessagesRead to a value that will cause overflow when cast to uint64
uint256 afterDelayedMessagesRead = 2**64;
// Call packHeader and check for overflow
(bytes memory header, ) = sequencerInbox.packHeader(afterDelayedMessagesRead);
// No direct way to check the overflow, but we can ensure it doesn't revert
}
}
Tools Used
Slither.
Recommended Mitigation Steps
Recommendation: Resolving Typecasting Issues
General Approach:
To mitigate vulnerabilities from improper typecasting, implement validation checks before typecasting operations. This ensures values do not exceed the maximum limits of the target data types. Below are specific recommendations for each affected function:
getTimeBounds:
Issue: Typecasting block.timestamp and block.number to uint64.
Resolution: Validate block.timestamp and block.number before casting.
Implement validation checks before performing typecasting operations to ensure values do not exceed the maximum limits of the target data types. This will prevent potential data loss or unexpected behavior due to truncation or data loss.
Lines of code
https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/bridge/SequencerInbox.sol#L216-L233 https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/bridge/SequencerInbox.sol#L903-L919 https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/bridge/SequencerInbox.sol#L847-L865 https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/bridge/SequencerInbox.sol#L755-L789 https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/bridge/SequencerInbox.sol#L867-L882 https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/bridge/SequencerInbox.sol#L688-L718 https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/bridge/SequencerInbox.sol#L637-L653
Vulnerability details
Impact
Detailed description of the impact of this finding.
Vulnerability: Dubious Typecasting in Various Functions
Description:
The vulnerability arises from improper typecasting in several functions, leading to potential data loss or unexpected behavior. Specifically, the conversion from larger data types to smaller ones occurs without proper validation.
Affected Functions and Locations:
getTimeBounds (
SequencerInbox.sol
lines 216-233):block.timestamp
andblock.number
touint64
.setValidKeyset (
SequencerInbox.sol
lines 903-919):creationBlock
touint64
._setBufferConfig (
SequencerInbox.sol
lines 847-865):block.number
touint64
.submitBatchSpendingReport (
SequencerInbox.sol
lines 755-789):extraGas
touint64
._setMaxTimeVariation (
SequencerInbox.sol
lines 867-882):maxTimeVariation_
values touint64
.formCallDataHash (
SequencerInbox.sol
lines 688-718):data
tobytes32
.packHeader (
SequencerInbox.sol
lines 637-653):afterDelayedMessagesRead
touint64
.General Recommendation:
To mitigate these vulnerabilities, implement validation checks before performing typecasting operations. Ensure that the values being cast do not exceed the maximum limits of the target data types. For example, verify that
block.timestamp
andblock.number
are within the allowable range before casting them touint64
. Similarly, validate the lengths of arrays and other data structures prior to typecasting.Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
Tools Used
Slither.
Recommended Mitigation Steps
Recommendation: Resolving Typecasting Issues
General Approach:
To mitigate vulnerabilities from improper typecasting, implement validation checks before typecasting operations. This ensures values do not exceed the maximum limits of the target data types. Below are specific recommendations for each affected function:
block.timestamp
andblock.number
touint64
.block.timestamp
andblock.number
before casting.creationBlock
touint64
.creationBlock
before casting.block.number
touint64
.block.number
before casting.extraGas
touint64
.extraGas
before casting.maxTimeVariation_
values touint64
.maxTimeVariation_
values before casting.data
tobytes32
.data
length before casting.afterDelayedMessagesRead
touint64
.afterDelayedMessagesRead
before casting.General Recommendation:
Implement validation checks before performing typecasting operations to ensure values do not exceed the maximum limits of the target data types. This will prevent potential data loss or unexpected behavior due to truncation or data loss.
Assessed type
Context