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

TimelockController 'salt' is unrecoverable yet required for execution #3216

Closed
0x0scion opened this issue Feb 22, 2022 · 6 comments · Fixed by #4001
Closed

TimelockController 'salt' is unrecoverable yet required for execution #3216

0x0scion opened this issue Feb 22, 2022 · 6 comments · Fixed by #4001
Assignees
Milestone

Comments

@0x0scion
Copy link

0x0scion commented Feb 22, 2022

When scheduling a transaction using the TimelockController, one is required to provide a salt to distinguish otherwise identical transactions. The salt parameter is not emitted in the CallScheduled event which makes it impossible to recover. Yet salt is required for executing the scheduled transaction transaction, even though it isn't necessary and more gas efficient if id is used instead.

💻 Environment

Openzeppelin v4.5.0 / hardhat

📝 Details

salt is missing from the CallScheduled event:

salt is required for the execute & executeBatch calls:

Instead of salt the execute methods should be consuming the hashed operation (id) directly, since that id is readily available via event data. This would also save on gas since there is no need to re-run the hashing operation.

Happy to submit a PR

@Amxx
Copy link
Collaborator

Amxx commented Feb 22, 2022

Hello @0x0scion and thanks for raising this issue

Instead of salt the execute methods should be consuming the hashed operation (id) directly, since that id is readily available via event data. This would also save on gas since there is no need to re-run the hashing operation.

If we don't run the hashing operation, how do we check that the other parameters (target, value, data) match the id that was scheduled? If we don't check that, you could possibly use any scheduled operation's id with unrelated params, and execute another operation.

It's true that the salt not being present in the event is disturbing. I wonder how we missed that / if we had a reason for not including it.

@0x0scion
Copy link
Author

0x0scion commented Feb 23, 2022

If we don't run the hashing operation, how do we check that the other parameters (target, value, data) match the id that was scheduled? If we don't check that, you could possibly use any scheduled operation's id with unrelated params, and execute another operation.

Ah, yes, did not think this through all the way - striking out that suggestion above.
So just a matter of salt not being in the event.

@0x0scion 0x0scion changed the title TimelockController 'salt' is unrecoverable yet unnecessarily required for execution TimelockController 'salt' is unrecoverable yet required for execution Feb 23, 2022
@ashwinYardi
Copy link
Contributor

If we don't run the hashing operation, how do we check that the other parameters (target, value, data) match the id that was scheduled? If we don't check that, you could possibly use any scheduled operation's id with unrelated params, and execute another operation.

@Amxx @0x0scion Hey guys! I was wondering, doesn't this logic also apply to cancel method? cancel method, at the moment, only accepts id as a param. So, its totally possible that, proposer can possibly cancel any other scheduled operation with unrelated params.

@Amxx
Copy link
Collaborator

Amxx commented Mar 1, 2022

@ashwinYardi Cancel doesn't have other params. It just cancels the proposal that has a given ID.

We could have required the cancel call to send all the details, hash them, and cancel that, but it would have been more expensive, and not safer.

In short

  • execute: we are actually executing, so we need the execution details and we have to validate them;
  • cancel: we are just internally canceling, we don't need the execution details.

@frangio
Copy link
Contributor

frangio commented Mar 1, 2022

So we need to emit the salt in an event, but we can't change the existing event because it changes the event selector, which is a little concerning because any monitoring infrastructure in place will not see the new event.

We can emit the salt in a new event ProposalSalt(uint256 indexed proposalId, bytes32 salt).

@frangio frangio added this to the 4.9 milestone Sep 5, 2022
@frangio
Copy link
Contributor

frangio commented Jan 19, 2023

I would assume it's common to use salt=0. Feels like we could emit the event only when it isn't 0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants