# The decision to return the liveness bond depends solely on the last guardian

GuardianProver's approval hash omits _proof, so the last guardian alone controls whether the liveness bond is returned to the assigned prover.

- Payout: Contest reward
- Severity: medium
- Program: Taiko
- Credited: alexfilippov314
- Disclosed: 2024-04-26
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2024-03-taiko-findings/issues/205
- Library page: https://bugbountylibrary.com/r/c4%3A2024-03-taiko%3AM-10
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:governance

**Target:** GuardianProver multisig / LibProving proof contest flow
**Root cause:** The guardian approval hash is keccak256(abi.encode(_meta,_tran)) and excludes _proof, but LibProving reads _proof.data to decide whether to return the liveness bond.
**Steps:**
1. Guardians call `approve(_meta,_tran,_proof)`; hash = `keccak256(abi.encode(_meta,_tran))` excludes `_proof`.
2. When the approval threshold is reached, the final guardian's call triggers `proveBlock(_meta.id, abi.encode(_meta,_tran,_proof))`.
3. The last guardian sets `_proof.data = RETURN_LIVENESS_BOND` (32 bytes) or any other value.
4. LibProving checks `_proof.data.length == 32 && bytes32(_proof.data) == RETURN_LIVENESS_BOND` and transfers `blk.livenessBond` to the assigned prover or not.
**How found:** Code reading of GuardianProver.approve and LibProving: noticed the signed/approved hash omits _proof while _proof.data drives bond-return logic.
**Exploitation:** The last guardian to approve can unilaterally choose the _proof payload, deciding whether the assigned prover's liveness bond is refunded, bypassing the multisig consensus intent.
**Insight:** When a multisig approves a hash, verify every parameter that downstream logic consumes is inside the hash; look for fields passed alongside the signed message but read later (like proof data) as a last-signer-controlled lever.
