Skip to content

Instantly share code, notes, and snippets.

@sdmg15
Last active May 12, 2026 05:59
Show Gist options
  • Select an option

  • Save sdmg15/54ee406e3826ba4acc51312e30054df2 to your computer and use it in GitHub Desktop.

Select an option

Save sdmg15/54ee406e3826ba4acc51312e30054df2 to your computer and use it in GitHub Desktop.

Codes for reproducing vunerabilities report by WizardZine (https://gist.github.com/darosior/4aeb9512d7f1ac7666abc317d6f9453b_

1 - Library crash on raw descriptor

const DB_PATH: &str = "bdk-example-electrum.sqlite";
const NETWORK: Network = Network::Testnet4;
const EXTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/0/*)";
const INTERNAL_DESC: &str = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)";
const ELECTRUM_URL: &str = "ssl://mempool.space:40002";

#[allow(clippy::print_stdout)]
fn main() -> Result<(), anyhow::Error> {

    let mut db = Connection::open(DB_PATH)?;
    let descriptor = "raw(deadbeef)";
    let wallet = Wallet::create_single(descriptor).network(Network::Regtest).create_wallet_no_persist()?;
    Ok(())
}

Panics: Error: Miniscript error: unexpected «raw(1 args) while parsing Miniscript»

2 - Unchecked arithmetic used across the crates

TBD

3 - Wallet::sign invariant assumptions

fn main () -> Result<(), anyhow::Error> {

    let (wallet, _) = get_funded_wallet_wpkh();

    // Create a transaction with 1 input
    let prev_tx = Transaction {
        version: transaction::Version::TWO,
        lock_time: absolute::LockTime::ZERO,
        input: vec![TxIn {
            previous_output: OutPoint::null(),
            script_sig: ScriptBuf::default(),
            sequence: Sequence::MAX,
            witness: Witness::default(),
        }],
        output: vec![TxOut {
            value: Amount::from_sat(50_000),
            script_pubkey: ScriptBuf::default(),
        }],
    };

    let unsigned_tx = Transaction {
        version: transaction::Version::TWO,
        lock_time: absolute::LockTime::ZERO,
        input: vec![TxIn {
            previous_output: OutPoint {
                txid: prev_tx.compute_txid(),
                vout: 0,
            },
            script_sig: ScriptBuf::default(),
            sequence: Sequence::MAX,
            witness: Witness::default(),
        }],
        output: vec![TxOut {
            value: Amount::from_sat(40_000),
            script_pubkey: ScriptBuf::default(),
        }],
    };

    let mut psbt = Psbt::from_unsigned_tx(unsigned_tx).unwrap();

    // Add extra PSBT inputs without adding to transaction
    use bitcoin::psbt::Input;
    psbt.inputs.push(Input {
        non_witness_utxo: Some(prev_tx.clone()),
        ..Default::default()
    });
    psbt.inputs.push(Input {
        non_witness_utxo: Some(prev_tx),
        ..Default::default()
    });

    assert_eq!(psbt.inputs.len(), 3);
    assert_eq!(psbt.unsigned_tx.input.len(), 1);

    let result = wallet.sign(&mut psbt.clone(), SignOptions::default());
}

Panics: InputIndexOutOfRange(IndexOutOfBoundsError { index: 0, len: 0 })

4 -

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment