Broken lineage check due to governance-coin unwrap logic
Description
Governance coins are CRT CAT singletons with the governance.clsp puzzle as their inner puzzle. These coins are created from standard CRT coins on an ad hoc basis. The coin allows the coins inside it to be exited to the INNER_PUZZLE_HASH
argument curried in the puzzle.
If the puzzle hash of the INNER_PUZZLE_HASH
is same as that of the governance, the coin could be spent like a governance coin and its lineage would be verified as the previous coin that created it was the governance itself. Therefore, by setting INNER_PUZZLE_HASH
to the puzzle hash of a governance puzzle with the BILL
argument already curried inside it and the INNER_PUZZLE_HASH
of the inner argument to be 0
, an attacker could exit the original governance to a fake governance that has the BILL
already curried inside it.
If the veto_conditions
passed to the inner governance is CREATE_COIN
with the puzzle hash as 0
and a REMARK
condition, which has the args required for a veto-condition operation, the final_bill
would be set as 0
as the veto condition resets the bill. The filter-conditions
in the inner governance will thus return a CREATE_COIN
condition with the puzzle hash as 0
and a REMARK
condition as shown below:
REMARK PROTOCOL_PREFIX bill_operation () ()
As the inner governance act is just like an inner puzzle for the outer governance, the conditions returned from it, REMARK
and CREATE_COIN
, will be used to find the bill condition — REMARK
will be used to get the values of statutes_inner_puzzle_hash
, bill_operation
, and args
, and CREATE_COIN
will be used to get the new_coin_amount
.
As per the REMARK
condition returned from inner governance, the bill_operation
will be set to ()
. Therefore, no operations will be run, and CREATE_COIN
will be used to exit the governance to the inner puzzle (which is the inner governance) because the CREATE_COIN
's puzzle hash is 0
.
Therefore, the exited governance puzzle will be the inner governance puzzle with the BILL
already curried in it, and lineage could be proved.
Impact
If a governance puzzle is launched with the BILL
already curried inside, it will be possible to spend the governance coin along with statutes to change the value of any statute (the global variables) to the desired value immediately.
Recommendations
Instead of allowing exiting to INNER_PUZZLE_HASH
, the coins could be sent with the help of a settlement puzzle.
Remediation
This issue has been acknowledged by Voltage Technologies Ltd., and a fix was implemented in commit ccd7ef02↗.