Migration applicable to already migrated storage account
Description
migrate_from_0_1_0
allows the top_authority
to migrate the storage
account from the older StorageV010
model to the new Storage
data model. This resizes the account, migrates the trusted_signers
, and sets the treasury
based on a value passed in by the top_authority
. The migration requires a few conditions to be true, but one of the most important bits is that the anchor signature is equivalent to the Storage
account's signature. Notably, this means that the migration does not change the anchor signature, because the name of the type for the account has not changed.
As the preliminary checks that allow the migration to go forward are true both before and after the migration, nothing prevents the top_authority
from rerunning the migration again.
Impact
The top_authority
could reset the treasury
and/or putting the trusted_signers
in a potentially corrupted state. This could be done by causing the num_trusted_signers
to be set to an invalid value, breaking the signature validation logic.
Recommendations
As Anchor's discriminant is primarily dependant on the name of the type of the account, we recommend changing the name of the account from Storage
to a a distinct name such as StorageV2
. The migration step would validate that the account had a discriminant expected for Storage
, but would eventually write StorageV2
's discriminant to the account. This would prevent subsequent migrations as the discriminant of the account would change.
Remediation
This issue has been acknowledged by Pyth Data Association, and a fix was implemented in PR #2250↗.
The PR added a check requiring the size of the Storage
account to match the size of the legacy layout. Since the legacy and new layouts differ in size, this prevents the migration from being performed more than once.
Pyth Data Association subsequently removed the migration feature entirely in commit .