-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: OptimismPortal wd invalidation mitigation #77
base: main
Are you sure you want to change the base?
Conversation
Introduces a proposal that would prevent user withdrawals in the OptimismPortal from being invalidated any time that the fallback is utilized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in favour of this change. The validity checks are still really simple and it gives the guardian significantly more flexibility. The concern about user impact affects the guardian decision making process even if the actual impact winds up being small so providing better tools to simplify the decision making process seems well worth it to me.
|
||
We propose removing the requirement that withdrawals must be finalized against a dispute game of | ||
the `respectedGameType`. Withdrawals that have been previously proven against a dispute game when | ||
that game *was* respected can be finalized even if that dispute game is no longer of the respected |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the impl, although checkWithdrawal
no longer asserts against respectedGameType
, we continue to assert against it in proveWithdrawalTransaction
, implying the withdrawal GameType
was once the respected one. If a GameType
needs to be invalidated, the respectedGameType
is changed and respectedGameTypeUpdatedAt
is updated. This means another DisputeGame
must be created, of the new respectedGameType
and not the invalid GameType
. 👍
the new system given that the variable would not be updating every time that the | ||
`respectedGameType` variable is changed. Alternatively, we could keep `respectedGameTypeUpdatedAt` | ||
untouched and instead introduce a new variable that more accurately reflects the system. This would | ||
also avoid a breaking change to the contract ABI and the semantics of the original variable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this variable could be decoupled from respectedGameType
. Instead it could be called something like gameCreationValidFrom
, and then the check would be like
require(
createdAt >= gameCreationValidFrom,
"OptimismPortal: dispute game created before latest creation validity timestamp"
);
what do you think?
the occurrences of respectedGameTypeUpdatedAt
in the monorepo are low. sorry for the noob question but are there many concerns outside of the monorepo? perhaps integrators would be happy for the breaking change here as their withdrawal validity logic should be updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realistically I think you're correct here -- it's possible we could even keep the semantic meaning of respectedGameTypeUpdatedAt
(as in, we do continue to update it when setRespectedGameType
is called) but add this new variable gameCreationValidFrom
with these new semantics.
Co-authored-by: Ed Mazurek <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me. Simple enough to change up. Also will include some changes to the deputy guardian.
Reminder to self: do not allow invalidation timestamp to be greater than current timestamp |
We propose removing the requirement that withdrawals must be finalized against a dispute game of | ||
the `respectedGameType`. Withdrawals that have been previously proven against a dispute game when | ||
that game *was* respected can be finalized even if that dispute game is no longer of the respected | ||
game type. | ||
|
||
We additionally propose that the `respectedGameTypeUpdatedAt` timestamp not be updated by default. | ||
Instead, the timestamp can be selectively updated if withdrawal invalidation is actually required. | ||
Combined with the first proposed change, this proposal means that older withdrawal proofs can | ||
usually be finalized when the respected game type is changed but withdrawals can still be blanket | ||
invalidated if necessary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An issue can possibly arise if the second case for the withdrawal invalidation without checking the respectGameType
like in the past.
For example, this might be a possible attack vector:
- The guardian make a tx to set the
respectedGameType
to 1 (permissioned game). - The attacker monitors the mempool and frontruns in the same block the call to
setRespectGame(1)
. - In the same block, the attacker create a game using
create()
on theDisputeGameFactory
contract. As, thecreateAt
is a timestamp from the valueblock.timestamp
, this will have the exact same value if we are before or after into the same block. - The attacker call
proveWithdrawalTransaction()
and then wait for thePROOF_MATURITY_DELAY_SECONDS
submit thefinalizeWithdrawalTransaction()
. - As the check (below in solidity) is using greater and equal than
createdAt >= respectedGameTypeUpdatedAt
the attacker might be able to finalize a transaction with the incorrectgameType
. - The impact seems to be really low, but this would make an inconsistent state (as the
optimismPortal
and the Guardian that restricted the to certaingameType
) the Guardian will think that only the certaingameType
would be valid, for the next withdrawal and would invalid the othergameType
but here the othergameType
would be finalized with success at the block.timestamp would be the same).
if (disputeGameProxy.gameType().raw() != respectedGameType.raw()) //@audit: The current design review propose to not use this anymore?
revert InvalidGameType();
require(
createdAt >= respectedGameTypeUpdatedAt, //@audit: Usage of the >= instead of > is a potential issue here?
"OptimismPortal: dispute game created before respected game type was updated"
);
This scenario might be invalid as maybe this is desired from the new design (still strange imo)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah would be worth making that a strict >
. While that will mean that any withdrawals proven against the new game type after the change but in the same block are invalidated when they probably shouldn't be, that's a very unlikely corner case and much lower impact than having a withdrawal be unexpectedly valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, and let a comment but the rest looks a nice initiative to me!
Introduces a proposal that would prevent user withdrawals in the OptimismPortal from being invalidated any time that the fallback is utilized.