Impact
All released node versions between versions 4 and 4.2.1 contain a bug which can be triggered by certain transactions involving smart contracts.
This bug can lead to either the node stopping to bake, or to crashing, depending on whether the transaction is part of a block or not.
References
The bug is caused by incorrect balance tracking in the scheduler, specifically in the case of nested contract calls with interruptions.
In order to support the get_receive_self_balance
call the scheduler must keep track of the current balance of the contract during execution of the transaction. This balance can change as a result of both actions of the contract, as well as other accounts or contracts.
A representative scenario where a bug occurs is in a transaction that triggers the following sequence of actions
- Account
A
transfers CCD to contract C
- Contract
C
invokes itself, say an entrypoint E
- Execution of
E
triggers a transfer to some account, A'
.
- After the transfer, in the execution of
E
the contract calls get_receive_self_balance
. If the initial transfer from A
to C
was non-zero then the return value here will be incorrect. Concretely, if the balance of the contract before the transaction was 0
, and the transfer was m
, then the observed balance would be 2m
.
The error in balance tracking here means that the contract is then allowed to invoke, e.g., a transfer of 2m
to an account. This leads to a precondition violation in the scheduler when it tries to affect the transfer, which leads to the node crashing.
Impact
All released node versions between versions 4 and 4.2.1 contain a bug which can be triggered by certain transactions involving smart contracts.
This bug can lead to either the node stopping to bake, or to crashing, depending on whether the transaction is part of a block or not.
References
The bug is caused by incorrect balance tracking in the scheduler, specifically in the case of nested contract calls with interruptions.
In order to support the
get_receive_self_balance
call the scheduler must keep track of the current balance of the contract during execution of the transaction. This balance can change as a result of both actions of the contract, as well as other accounts or contracts.A representative scenario where a bug occurs is in a transaction that triggers the following sequence of actions
A
transfers CCD to contractC
C
invokes itself, say an entrypointE
E
triggers a transfer to some account,A'
.E
the contract callsget_receive_self_balance
. If the initial transfer fromA
toC
was non-zero then the return value here will be incorrect. Concretely, if the balance of the contract before the transaction was0
, and the transfer wasm
, then the observed balance would be2m
.The error in balance tracking here means that the contract is then allowed to invoke, e.g., a transfer of
2m
to an account. This leads to a precondition violation in the scheduler when it tries to affect the transfer, which leads to the node crashing.