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

Assembly Memory Safety #859

Merged
merged 2 commits into from
Nov 14, 2024
Merged

Assembly Memory Safety #859

merged 2 commits into from
Nov 14, 2024

Conversation

nlordell
Copy link
Collaborator

This PR does a once-over on memory Safety for the 1.5.0 contracts. In particular, there were a couple of missing memory-safe tags for some assembly blocks which were preventing the IR assembler from working correctly.

Additionally, since the MultiSend* contracts changed anyway in 1.5.0, I took this opportunity to change the assembly to be memory-safe so that we can tag it. Note that it only adds more code in the revert case, so it should not have a negative impact for most use-cases.

Furthermore, I added a comment explaining why we did not make the SafeProxy contract memory-safe (that is one intentional).

Lastly, I noticed that there were some eq(..., 0) assembly calls which can be written as iszero(...) to save some gas and code. Again, it was an opportunistic change as the affected contracts have changed anyway and will be re-audited.

This PR does a once-over on memory Safety for the 1.5.0 contracts. In
particular, there were a couple of missing `memory-safe` tags for some
assembly blocks which were preventing the IR assembler from working
correctly.

Additionally, since the `MultiSend*` contracts changed anyway in 1.5.0,
I took this opportunity to change the assembly to be memory-safe so that
we can tag it. Note that it only adds more code in the revert case, so
it should not have a negative impact for most use-cases.

Furthermore, I added a comment explaining why we did not make the
`SafeProxy` contract memory-safe (that is one intentional).

Lastly, I noticed that there were some `eq(..., 0)` assembly calls which
can be written as `iszero(...)` to save some gas and code.
@nlordell nlordell requested review from remedcu, mmv08 and akshay-ap and removed request for remedcu November 14, 2024 15:23
Copy link
Member

@remedcu remedcu left a comment

Choose a reason for hiding this comment

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

ubernit comment, rest LGTM 👍🏾

contracts/proxies/SafeProxy.sol Outdated Show resolved Hide resolved
@nlordell nlordell merged commit 7f79aaf into main Nov 14, 2024
25 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Nov 14, 2024
@@ -61,9 +62,10 @@ contract MultiSend {
case 1 {
success := delegatecall(gas(), to, data, dataLength, 0, 0)
}
if eq(success, 0) {
Copy link
Member

Choose a reason for hiding this comment

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

I believe the reason we didn't do memory-safe assembly here is the same as the SafeProxy contract, it gets compiled in its unit. Why do we need to make it memory-safe? (not opposed to the change, just wondering)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

it gets compiled in its unit.

It does, but if you use Foundry and deploy MultiSend with other Safe contracts in a script (how I found the issue), then it gets it would get included in the same compilation unit. This is different from the SafeProxy contract, since it gets compiled in a separate unit first for it to be used in the SafeProxyFactory implementation.

@mmv08 mmv08 deleted the fix/memory-safe-assembly branch November 19, 2024 11:22
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants