{
 "number": 35984,
 "input_hash": "16158cfd3cbc4c55",
 "model": "openrouter/google/gemini-3.8-flash",
 "batch": false,
 "created": "2026-09-17T21:45:23+00:00",
 "provider": "Google",
 "stop_reason": "end_turn",
 "usage": {
  "input_tokens": 19220,
  "cache_creation_input_tokens": 0,
  "cache_read_input_tokens": 0,
  "output_tokens": 4166
 },
 "cost_usd": 0.030037499999999998,
 "error": null,
 "result": {
  "display": {
   "goal": [
    "Prevent wallet PSBT signing from producing detached SIGHASH_SINGLE signatures",
    "Avoid fund theft when signing inputs whose index has no corresponding transaction output"
   ],
   "reviewability": [
    "Ready to review with clean CI and a small diff"
   ],
   "agreement": [
    "Strong support with an ACK from achow101 and concept support from l0rinc",
    "No objections or concerns raised"
   ],
   "categories": [
    {
     "name": "wallet",
     "why": [
      "P1 because it eliminates a fund-safety vulnerability in PSBT signing",
      "Without this check a signature commits to no outputs and allows funds to be redirected"
     ]
    },
    {
     "name": "rpc",
     "why": [
      "P4 because the RPC interface itself is not modified",
      "Touches functional RPC tests only to verify signing behavior"
     ]
    }
   ]
  },
  "summary": "Moves the SIGHASH_SINGLE input bounds check into `MutableTransactionSignatureCreator::CreateSig`. This ensures both standard transaction signing and PSBT signing refuse to sign an input when no corresponding output exists at that index.",
  "problem": "When an input is signed with SIGHASH_SINGLE without a matching output index, legacy and segwit v0 transactions commit to no outputs at all. This creates a valid signature that an adversary can detach and attach to an arbitrary transaction, redirecting funds without the signer's consent.",
  "discussion": {
   "open_concerns": [],
   "resolved_concerns": [
    "l0rinc asked to link and fix issue #35977, which the author incorporated in the description"
   ],
   "author_status": "active, rebased recently"
  },
  "reviewability": {
   "state": "Ready",
   "label": "Ready",
   "reason": "The change is compact, CI passes cleanly, and there are no unresolved review requests."
  },
  "agreement": {
   "participants": [
    {
     "login": "l0rinc",
     "stance": "support",
     "note": "Concept ACK and suggested adding a characterization test commit"
    },
    {
     "login": "achow101",
     "stance": "support",
     "note": "ACK on earlier commit"
    }
   ],
   "objections": [],
   "support": [
    {
     "reviewer": "achow101",
     "reason": "ACK on code and test changes",
     "substantive": true
    },
    {
     "reviewer": "l0rinc",
     "reason": "Concept ACK for fixing the dangerous signing gap described in #35977",
     "substantive": true
    }
   ],
   "state": "Strong",
   "summary": "Strong consensus with an ACK from achow101 and concept approval from l0rinc",
   "reason": "Multiple maintainers and contributors support closing the signature validation loophole, with zero objections.",
   "evidence": [
    "achow101: 'ACK 0fa39483fb891d7dd0e35942c927646756550132'",
    "l0rinc: 'Concept ACK'"
   ],
   "model_state": "Strong",
   "derivation": "substantive support, no open objection (achow101, l0rinc)",
   "corrections": [],
   "thread_read": {
    "state": "Strong",
    "derived": "Strong",
    "objections": [],
    "support": [
     {
      "reviewer": "l0rinc",
      "reason": "Thanks for pushing a fix for #35977 so quickly (with extra segwit-v0 coverage)",
      "substantive": true
     },
     {
      "reviewer": "achow101",
      "reason": "ACK 0fa39483fb891d7dd0e35942c927646756550132",
      "substantive": false
     }
    ],
    "participants": [
     {
      "login": "l0rinc",
      "stance": "support",
      "note": "Concept ACK and thanked author for fixing #35977; suggested a characterization test"
     },
     {
      "login": "achow101",
      "stance": "support",
      "note": "ACKed commit 0fa3948"
     }
    ],
    "corrections": [],
    "summary": "Strong: l0rinc Concept ACKed for fixing #35977, achow101 ACKed",
    "usage": {
     "input_tokens": 3607,
     "cache_creation_input_tokens": 0,
     "cache_read_input_tokens": 0,
     "output_tokens": 768
    }
   },
   "first_read": {
    "state": "Strong",
    "model_state": "Strong",
    "objections": [],
    "support": [
     {
      "reviewer": "achow101",
      "reason": "ACK on code and test changes",
      "substantive": true
     },
     {
      "reviewer": "l0rinc",
      "reason": "Concept ACK for fixing the dangerous signing gap described in #35977",
      "substantive": true
     }
    ]
   }
  },
  "dependencies": {
   "depends_on": [],
   "enables": [
    "Closes issue #35977"
   ]
  },
  "categories": [
   {
    "name": "wallet",
    "member": true,
    "evidence": "Fixes PSBT signing logic in `src/script/sign.cpp` used directly by wallet signing RPCs like `walletprocesspsbt`.",
    "band": "P1",
    "reason_tag": "fund safety",
    "score": 0.8,
    "factors": {
     "security_stability": 2,
     "bug_severity": 2,
     "performance": 0,
     "user_value": 2,
     "leverage": 0
    },
    "rationale": "P1 because producing an output-independent signature is a fund-safety vulnerability. As described by furszy: 'the signature stays valid even when outputs are swapped, which is a footgun that lets funds be redirected without the owner's consent.'"
   },
   {
    "name": "rpc",
    "member": false,
    "evidence": "Does not change any RPC interface or serialization; only touches `test/functional/rpc_psbt.py` as test coverage for signing.",
    "band": "Unranked",
    "reason_tag": "",
    "score": 0.0,
    "factors": {
     "security_stability": 0,
     "bug_severity": 0,
     "performance": 0,
     "user_value": 0,
     "leverage": 0
    },
    "rationale": "Not an RPC category change; only functional tests exercising the wallet PSBT RPC are updated."
   }
  ],
  "confidence": "high",
  "uncertainties": [],
  "needs": [],
  "card": "This PR moves the check skipping SIGHASH_SINGLE signing for inputs without a corresponding output into CreateSig. Previously, SignTransaction skipped these dangerous inputs but SignPSBTInput did not, allowing walletprocesspsbt to produce detached signatures that commit to no outputs and risk fund theft. The PR has an ACK from achow101 and Concept ACK from l0rinc with no open objections, fixes #35977, and is ready for merge."
 },
 "raw_text": null,
 "prompt_hash": "c1bd47c5",
 "second_read_cost_usd": 0.00558525
}