Skip to content
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

Make Gateway entry points nonreantrant #1358

Merged
merged 11 commits into from
Jan 10, 2025

Conversation

alistair-singh
Copy link
Contributor

@alistair-singh alistair-singh commented Dec 24, 2024

Update to solidity 0.8.28 and Cancun EVM version. Make the entry points to the Gateway nonreantrant.

Resolves: https://linear.app/snowfork/issue/SNO-1222

modifier nonreentrant() {
assembly {
// Check if flag is set and if true revert because it means the function is currently executing.
if tload(0) { revert(0, 0) }
Copy link
Contributor

@yrong yrong Jan 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use that pattern. But in the V2 code we use slot 0? Is this an issue?

Copy link
Contributor Author

@alistair-singh alistair-singh Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be fine because all our variables except for DISPATCH_OVERHEAD_GAS are constant or immutable. DISPATCH_OVERHEAD_GAS is neither constant or immutable but we never write to it, so storage slot 0 is never used in Gateway.
Just to be safe I made DISPATCH_OVERHEAD_GAS constant in:
6148116
And added a storage slot for the reentrancy guard so that we do not mistakenly re-use that slot 0 in future by adding variables to the mutable Gateway.
266a350

Nice catch!

Copy link
Collaborator

@vgeddes vgeddes Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Transient storage lives in a separate data location from normal storage, at least that's what the internet says. So transient slot 0 is separate from normal storage slot 0. Can check this with a test.

I generally don't like the way OpenZeppelin code is implemented, its verbose.

@yrong yrong mentioned this pull request Jan 1, 2025
@alistair-singh alistair-singh force-pushed the alistair/nonreantrant-entry-points branch from 41f01ba to 6148116 Compare January 7, 2025 22:54
@alistair-singh alistair-singh requested a review from yrong January 7, 2025 23:43
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems overly complicated compared to the version in Contracts V2, which is defined inline in the Gateway contract:

modifier nonreentrant {
    assembly {
        if tload(0) { revert(0, 0) }
        tstore(0, 1)
    }
    _;
    assembly {
        tstore(0, 0)
    }
}

Copy link
Contributor Author

@alistair-singh alistair-singh Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think using slot 0 is the right thing to do even for V2. See this comment: #1358 (comment)

If someone adds a mutable variable to the Gateway contract at a later stage, is it not possible that the compiler will assign it to slot 0 and clash with the reentrancy guard? Or is my understanding of this incorrect?

So the only reason I moved this code to a library is because of the use of an explicit slot for reentrancy, but I can move the implementation with the explicit slot back to Gateway.sol?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Transient storage is a separate data location from normal storage. They don't overlap. So its not possible to overwrite normal storage. You check this with a test.

So yeah, am in favour of moving back to Gateway contract.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, so basically i misunderstood the storage slot.

Reverted in 4ec8b97

Copy link
Contributor

@yrong yrong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@alistair-singh alistair-singh merged commit 7cdd60a into main Jan 10, 2025
2 checks passed
@alistair-singh alistair-singh deleted the alistair/nonreantrant-entry-points branch January 10, 2025 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants