0xDjango - Chess Clock can be gamed, leading to theft of ETH bonds #208
Labels
Non-Reward
This issue will not receive a payout
Sponsor Confirmed
The sponsor acknowledged this issue is valid
Will Fix
The sponsor confirmed this issue will be fixed
0xDjango
high
Chess Clock can be gamed, leading to theft of ETH bonds
Summary
A user is able to defend any claim by gaming the chess clock mechanism. For the scope of this submission, this results in a user being able to steal the ETH bond of any attack, even if it is valid.
Vulnerability Detail
Assume the following simple claim tree:
Alice
is the defender who has created the game and submitted the root claim, A.Bob
is the challenger who correctly demonstrates that the root claim is invalid, B. Alice attacks B with C.Because of how the game clock mechanism works, Alice can ALWAYS win this scenario and steal Bob's bond from B.
For simplicity, imagine Bob submits his valid claim immediately after the game starts. Alice now has
GAME_DURATION / 2
seconds to make her move. AssumeGAME_DURATION = 7 days
.Alice waits exactly
3 days 12 hours
and attacks Bob's claim B with claim C. 1 second later, she can now immediately resolve claim C to receive her bond back, resolve claim B which she challenged and will resolve in her favor, and resolve the root claim in her favor.In all instances, the attacker will want to wait until the last second of the chess clock and then attack, at which time they can resolve immediately.
This vulnerability arises because the chess clock doesn't check each side's (defender/challenger) clock correctly upon resolution. During each
move
, the clock accurately assesses if the party has time on their clock by adding the grandfather move duration and the difference betweenblock.timestamp
and the parent duration. In simple terms, how much time has the current side that is callingmove
used from their clock?However, during resolution, the parent claim's clock timestamp is simply checked against
block.timestamp
which doesn't accurately assess how much time the other party actually used up. It simply checks that 3 days 12 hours has passed since that move.Impact
Code Snippet
https://github.com/sherlock-audit/2024-02-optimism-2024/blob/main/optimism/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol#L409-L416
Tool used
Manual Review
Recommendation
The chess clock needs to check that the party of the claim to be resolved has used their time, otherwise any opposing party can wait out the duration while it is their turn, submit a move at the last moment, and then resolve the parent claim.
Scope validity
The contest handbook states:
However, please note that the game resolution logic within the FaultDisputeGame is not in scope for this contest. We have chosen to have these components reviewed separately given the complexity of the game resolution logic and its dependencies (including MIPS.sol and others). Although reports about incorrect resolution are appreciated, they will not be considered valid reports for this contest. Participants should assume that the games can resolve incorrectly and should confirm that key invariants hold nonetheless.
Top-Level Invariants
Invariants listed below are the critical, high-level goals that should be satisfied by the contracts that are in scope of this contest. Always keep these invariants in mind.
FaultDisputeGame
FaultDisputeGame
.This submission does not describe incorrect game resolution. Instead it demonstrates how the key invariant that users are not able to withdraw the correct amount of ETH is broken. This is in-scope based on the last line of the Scope section: "Participants should assume that the games can resolve incorrectly and should confirm that key invariants hold nonetheless."
POC
This POC demonstrates:
Duplicate of #144
The text was updated successfully, but these errors were encountered: