You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using available_primary_key from multi_index to determine the account ID of a new account is not safe since an account can be deleted (via selfdestruct) which can cause the new account to reuse an account ID that was previously used by another account.
This can cause a serious issue because contract state is not immediately erased but is instead marked for garbage collection. The expectation with the garbage collection mechanism was that account IDs would never be repeated. But if they are repeated, it is possible for a new contract account to inherit the state from a deleted contract account (the state as of when the contract called selfdestruct or possibly some subset of it if the gc action was called).
A simple solution to avoid repeating the account ID is to keep track of the next account ID to use in a variable next_account_id stored in a singleton table. (This could be in a new table for that purpose or it could be added as a binary extension to the existing config table.) Instead of using available_primary_key(), the contract would use next_account_id and would ensure it is incremented so that subsequent created accounts continue using an appropriate unique ID.
This bug should be fixed in a way that is compatible with the contracts already deployed on testnet and mainnet, whether this bug was exploited or not on those networks. This means it should be possible for the contract to determine whether a next_account_id exists already or not; it would not exist if this is the first time a new account is created after deployment of a contract that includes the code changes to fix this bug. If it does not exist, it is important to set an initial value that is likely to be safe. For example the value of available_primary_key() could be used as the initial value.
The text was updated successfully, but these errors were encountered:
Using
available_primary_key
frommulti_index
to determine the account ID of a new account is not safe since an account can be deleted (viaselfdestruct
) which can cause the new account to reuse an account ID that was previously used by another account.This can cause a serious issue because contract state is not immediately erased but is instead marked for garbage collection. The expectation with the garbage collection mechanism was that account IDs would never be repeated. But if they are repeated, it is possible for a new contract account to inherit the state from a deleted contract account (the state as of when the contract called
selfdestruct
or possibly some subset of it if thegc
action was called).A simple solution to avoid repeating the account ID is to keep track of the next account ID to use in a variable
next_account_id
stored in a singleton table. (This could be in a new table for that purpose or it could be added as a binary extension to the existingconfig
table.) Instead of usingavailable_primary_key()
, the contract would usenext_account_id
and would ensure it is incremented so that subsequent created accounts continue using an appropriate unique ID.This bug should be fixed in a way that is compatible with the contracts already deployed on testnet and mainnet, whether this bug was exploited or not on those networks. This means it should be possible for the contract to determine whether a
next_account_id
exists already or not; it would not exist if this is the first time a new account is created after deployment of a contract that includes the code changes to fix this bug. If it does not exist, it is important to set an initial value that is likely to be safe. For example the value ofavailable_primary_key()
could be used as the initial value.The text was updated successfully, but these errors were encountered: