lang: Require zero
accounts to be unique
#3409
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Anchor doesn't guarantee uniqueness of mutable accounts.
Requiring all mutable accounts to be unique could solve the problem, but this would also be redundant in most cases because the uniqueness of the account is usually achieved through other means, e.g. via the
seeds
constraint. It's not so straightforward to figure out all the cases where it makes sense to require uniqueness, especially when composite and optional accounts are involved.A subclass of this problem is being able to pass the same account to accounts that have the
zero
constraint, which was reported by OtterSec during our v0.31 audit. Given it will take some time before we can solve the main problem, this specific problem can be solved in isolation in the meantime.Summary of changes
Require all accounts that have the
zero
constraint to be unique.Note: This change covers regular accounts and composite accounts, but not if they are separate. For example:
In this example,
outer.one
andouter.two
inner.one
andinner.two
is guaranteed to be unique, but
outer.one
andinner.one
can still be the same. This is because proc macros (#[derive(Accounts)]
) only have access to the code underneath them, meaning it's not possible to get information aboutInner
fromOuter
. For this specific case, we may be able to implement a custom trait that we can call internally duringtry_accounts
, but the potential benefits don't seem to be enough to justify the increased complexity in my opinion.