Closed howlbot-integration[bot] closed 5 months ago
Unclear POC. Assertion can only be confirmed from lastConfirmed, attacker’s child assertion will never be confirmed and hence the stake would not be withdrawable. Unclear what “delay” mean in the topic which seems to be unrelated to the content.
Picodes marked the issue as unsatisfactory: Insufficient proof
Dear @Picodes ,
I apologize for being unclear due to time constraints and wasting the Sponsor´s and your time.
To rephrase all the above:
C
) challenging the latest confirmed A
A (latest confirmed) - C (Invalid proposed)
\
\
B(invalid child - challenged before)
B
(invalid)C
receives a rival since A
is validchallengePeriod
to pass.confirmEdgeByTime
. But the attacker frontruns this call by calling returnOldDeposit
due to requireInactiveStaker
logic;
Contract: RollupCore.sol
614: function requireInactiveStaker(address stakerAddress) internal view { 615: require(isStaked(stakerAddress), "NOT_STAKED"); 616: // A staker is inactive if 617: // a) their last staked assertion is the latest confirmed assertion 618: // b) their last staked assertion have a child 619: bytes32 lastestAssertion = latestStakedAssertion(stakerAddress); 620: bool isLatestConfirmed = lastestAssertion == latestConfirmed(); 621: > bool haveChild = getAssertionStorage(lastestAssertion).firstChildBlock > 0; 622: require(isLatestConfirmed || haveChild, "STAKE_ACTIVE"); 623: }
Because `lastestAssertion` (`A`) has a child and this allows the attacker to make their funds withdrawable.
This creates a delay for L2 -> L1 withdrawals as per the challenge time.
I am not unable to understand the POC. Here are a list of thing that is incorrectly described:
Lines of code
https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/rollup/RollupCore.sol#L565-L574
Vulnerability details
Impact
Extending the delay of withdrawals
Proof of Concept
The maximum delay for withdrawals from L2 to L1 can be up to approximately 1 week (specifically 6.4 days), primarily due to the challenge period inherent in the optimistic rollup design used by Arbitrum. This challenge period is a security mechanism that allows validators to dispute state assertions before they are finalized on the L1 Ethereum blockchain.
The reason for this delay is rooted in the dispute resolution process. When a state assertion is made on the L2 chain, there is a fixed period during which it can be challenged. This is to ensure that only valid state transitions are confirmed on the L1 chain. If a dispute arises, it must be resolved within this period, and only after the period expires without disputes, or after a dispute is resolved in favor of the assertion, can the withdrawal be finalized on L1.
But this could be somehow bricked with an aditional period of time for specific conditions.
Validators can call
newStakeOnNewAssertion
and their funds will be taken on stake while the new assertion created inRollUpCore
;The function is as below:
L:371 calls
stakeOnNewAssertion
in the same contract.And when the stakers want to withdraw their stakes, the first function to call is as follows:
So the staker should be inactive - validated by
requireInactiveStaker
And the funds should be made withdrawable bywithdrawStaker
The logic of the
requireInactiveStaker
is as below;As can be seen that, the staker´s latest assertion should be latest confirmed one - Honest Stake OR There should be a child block of the new assertion. If any of these suffice, the staker can initiate to withdraw their stakes.
This opens a possibility for the attacker to delay the withdrawals.
When an dishonest actor stakes on a new assertion by
newStakeOnNNewAssertion
for aprevAssertion
, they should be rivaled by edges.If the attacker creates a new stake for an assertion (
prevAssertion
) which was challenged and has childs, they would be eligible to withdraw their funds as perrequireInactiveStaker
function, L:621Since the attacker´s
latestStakedAssertion
has already a child - and registered as_latestConfirmed
inRollupCore.createNewStake
as below, they can just stake and create arbitraryexpectedAssertionHash
.So once the
expectedAssertionHash
is challenged - which they can do with their other account as well, the attacker only need to wait in order no to waste small stakes in bisections and challenges. Accordingly the attacker can frontrunconfirmEdgeByTime
by callingreturnOldDeposit
. This will make the attacker funds withdrawable and the attacker will succeed to make the withdrawals wait for a period of maxchallengePeriod
+ first rivaling time.Tools Used
Manual Review
Recommended Mitigation Steps
Let the withdrawal mechanism have a short timelock
Assessed type
Other