-
Notifications
You must be signed in to change notification settings - Fork 6k
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
Warn when the storage layout base is near the end of storage (2^64 slots or less) #15912
base: develop
Are you sure you want to change the base?
Conversation
a13d53e
to
f27af62
Compare
3683a32
to
9d77c0f
Compare
9d77c0f
to
acb5733
Compare
if ( | ||
u256 slotsLeft = std::numeric_limits<u256>::max() - *storageLayoutSpecifier->annotation().baseSlot; | ||
slotsLeft <= u256(1) << 64 | ||
) |
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.
Now that I think of it, this check is not really limited to contracts with a layout. The dangerous thing is leaving too few slots between the last storage variable and the storage end, regardless of the base slot. It's more likely to happen if you have a non-zero base slot, but technically, you could end up in that situation also by just having large enough variables. And you should get this warning even if you're already getting the one for oversized variables because they warn about different issues.
Let's do this:
- Check base slot + size rather than just base slot.
- Perform the check for both storage and transient storage.
- Do this check even if the layout specifier is not present.
- If the contract has no layout specifier, point at the contract itself in the error.
- If contract has storage/transient variables, point at the last one, saying how close that variable is to the edge.
- Do it only if there are no previous errors reported. This way we won't be unnecessarily reporting it when the base slot + size goes past the edge and the contract won't compile anyway.
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.
Actually, not sure about transient storage. There are no upgradability issues there so I wonder if we should not warn there or if the fact that this is so close to the edge still warrants a warning...
3495_error, | ||
storageLayoutSpecifier->baseSlotExpression().location(), | ||
fmt::format( | ||
"There are {} slots before the end of the contract storage when this specified base layout is used.", |
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.
How about this?
"There are {} slots before the end of the contract storage when this specified base layout is used.", | |
"This contract is very close to the end of storage. This limits its future upgradability.", |
Like I said above, I'd put the number of slots left in the secondary message, pointing at a specific variable.
0c0c671
to
1423298
Compare
part of #15727.