Operation
with zero joinsplits can be tampered with
Description
When an operation is processed in a transaction submitted by a bundler, it can specify an arbitrary sequence of external calls to do. These calls are checked by calculating the digest of the Operation
struct and then supplying that digest as a public input into the joinsplit circuits. However, if an operation has zero joinsplits, no joinsplit circuits are verified, and so a bundler can freely change the calls executed.
Impact
There is not much impact, because if an operation has no joinsplits, no assets are unwrapped, and so the external calls only have access to the assets present in the contract before the operation (in the typical case, no assets).
Additionally, if an operation has no joinsplits, there is no way to repay the bundler for gas, so a bundler is disincentivized from including it in the bundle in the first place.
However, a user can still submit such an operation, and if they do, the bundler can modify it at will.
Recommendations
Disallow operations with no joinsplits.
Remediation
This issue has been acknowledged by Nocturne, and a fix was implemented in commit 50fe52a9↗.