Submitted by monrel, also found by t0x1c
https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/L1/libs/LibProving.sol#L387-L392 
https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/L1/libs/LibProving.sol#L189-L199 
https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/L1/libs/LibVerifying.sol#L178-L189
Both validity and contests bonds can be wrongfully slashed even if the transition ends up being the correct and verified one.
The issue comes from the fact that the history of the final verified transition is not taken into account.
Example 1: Validity bond is wrongfully burned:
At step 2 Bob loses his bond and is permanentley written out of the history of P1 https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/L1/libs/LibProving.sol#L387-L392
Example 2: Contest bond wrongfully slashed:
Bob was correct and T1 was ultimately proven false. Bob still loses his contest bond.
When the guardian overrides the proof they can not pay back Bobs validity or contesting bond. They are only able to pay back a liveness bond https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/L1/libs/LibProving.sol#L189-L199
These funds are now frozen since they are sent to the Guardian contract which has no ability to recover them.
https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/L1/libs/LibVerifying.sol#L178-L189
ts.prover will be the Guardian since they are the last to prove the block
POC for example 1. Paste the below code into the TaikoL1LibProvingWithTiers.t file and run forge test --match-test testProverLoss -vv
Foundry, VScode
The simplest solution is to allow the guardian to pay back validity and contest bonds in the same manner as for liveness bonds. This keeps the simple design while allowing bonds to be recovered if a prover or contesters action is ultimately proven correct.
Guardian will pass in data in _proof.data that specifies the address, tiers and bond type that should be refunded. Given that Guardians already can verify any proof this does not increase centralization.
We also need to not to not recover any reward when we prove with Guardian and _overrideWithHigherProof() is called. If the ts.validityBond reward is sent to the Guardian it will be locked. Instead we need to keep it in TaikoL1 such that it can be recovered as described above
dantaik (Taiko) commented:
adaki2004 (Taiko) confirmed, but disagreed with severity and commented:
0xean (Judge) commented:
