IntersectMBO / IntersectMBO/evolution-sdk

Signing: key-hash governance voters are never added to required signers

Aperta
#479 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
bug external-review
Lingua principale
TypeScript
Stelle
22
Fork
30
Merge medio
5h 29m
PR unite (30g)
12

Descrizione

## Summary
`computeRequiredKeyHashesSync` derives the signing keys from inputs, withdrawals, and certificates, but never inspects `votingProcedures` (body key 19) or `proposalProcedures` (key 20). The tx builder's Vote operation likewise only tracks redeemers for *script* voters and never adds a key-hash voter to `requiredSigners`. So a governance vote cast by a key-hash DRep, constitutional-committee member, or stake pool is not signed by the wallet, and the node rejects the under-signed transaction. Fail closed: no fund loss and no unauthorized action (a vkey witness covers the whole body, so nothing is signed that the signer didn't already authorize). The SDK can build a vote it cannot sign.

## Affected
packages/evolution/src/sdk/client/internal/Signing.ts
- computeRequiredKeyHashesSync (L47-184): checks requiredSigners, nativeScripts, inputs, collateralInputs, withdrawals, certificates; no votingProcedures / proposalProcedures branch

packages/evolution/src/sdk/builders/operations/Vote.ts
- createVoteProgram: only tracks redeemers for script voters (isScriptVoter); key-hash voters are never added to state.requiredSigners

## Fix
In `computeRequiredKeyHashesSync`, when `tx.body.votingProcedures` is present, iterate the voters and add the wallet credential on a match, mirroring the existing certificate logic:
- DRepVoter with KeyHash drep -> match against stakeKhHex (same as RegDrepCert handling)
- ConstitutionalCommitteeVoter with KeyHash credential -> match against the wallet's committee credential (same as AuthCommitteeHotCert handling)
- StakePoolVoter -> match poolKeyHash against paymentKhHex (same as PoolRegistration/PoolRetirement handling)

Apply the equivalent for proposalProcedures.

## Regression test
- given: a transaction whose only wallet-relevant field is a votingProcedures entry for a key-hash DRep voter equal to the wallet's stake credential
- before fix: signTx returns an empty witness set (voter key not added)
- after fix: signTx adds the stake-key vkey witness
Must FAIL on main today and PASS after the fix.

## Reference
Reported informally (governance signing gap). The same report also claimed this enables "unauthorized voting"; that part does not hold, since a vkey witness signs the entire transaction body, so a vote riding along in a signed transaction is the ordinary review-before-signing consideration, not a separate escalation.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Start in packages/evolution/src/sdk/client/internal/Signing.ts at computeRequiredKeyHashesSync and compare its certificate handling with the voting and proposal procedure fields. Then inspect packages/evolution/src/sdk/builders/operations/Vote.ts and run the signing regression scenario described in the issue. Done means a key-hash DRep vote causes signTx to include the wallet's stake-key vkey witness, while the test fails before and passes after the fix.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
blockchain
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
68/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.