Lack of constraints specific to transient storage and transaction receipts in the state circuit
Description
In the state circuit, constraints specific to entries of the rw table with tag RwTableTag::AccountTransientStorage
and RwTableTag::TxReceipt
are missing. The two most important constraints missing due to this were the following:
Constraining the
initial_value
column to be zero in the case ofRwTableTag::AccountTransientStorage
Constraining the
state_root
column not to have changed from the previous row in both cases
Even though constraints specific to AccountTransientStorage
and TxReceipt
are missing, the general constraints still apply. These include the following:
Constraining
not_first_access
Constraining the
value
at a first access read to beinitial_value
Constraining the
value
at other reads to be thevalue
in the previous row
Impact
The missing constraint for initial_value
to be zero for AccountTransientStorage
means that an adversary may set any value. This will then result in the first read of that slot to read this value chosen by the adversary. In some applications, smart contracts may rely critically on transient storage slots being initialized as zero.
Lack of constraints for the state_root
column implies an adversary can arbitrarily change the value of state_root
in rows of type AccountTransientStorage
or TxReceipt
. Such a change could then correspond to updating any data stored in the state root, such as the storage of any smart contract address or any account state data.
Recommendations
Implement the missing constraints for AccountTransientStorage
and TxReceipt
rows in the state circuit.
Remediation
We brought up the lack of constraints specific to RwTableTag::AccountTransientStorage
rows in the kick-off call, and the missing constraints were quickly implemented. We then reviewed them as part of our audit. The case of RwTableTag::TxReceipt
was out of scope for this audit.
This issue has been acknowledged by Scroll, and a fix was implemented in commit 92d34c51↗.