Assessment reports>Circuit DAO>Critical findings>Broken lineage check due to governance-coin unwrap logic
Category: Business Logic

Broken lineage check due to governance-coin unwrap logic

Critical Severity
Critical Impact
High Likelihood

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.

Zellic © 2025Back to top ↑