# sBTC Withdrawal

## Overview

The [sBTC Withdrawal contract](https://github.com/stacks-network/sbtc/blob/main/contracts/contracts/sbtc-withdrawal.clar) (`sbtc-withdrawal.clar`) manages the withdrawal process for the sBTC system. It handles the initiation, acceptance, and rejection of withdrawal requests, ensuring proper validation and interaction with other sBTC contracts.

## Constants

### Error Codes

* `ERR_INVALID_ADDR_VERSION` (u500): Invalid address version.
* `ERR_INVALID_ADDR_HASHBYTES` (u501): Invalid address hashbytes.
* `ERR_DUST_LIMIT` (u502): Withdrawal amount below dust limit.
* `ERR_INVALID_REQUEST` (u503): Invalid withdrawal request ID.
* `ERR_INVALID_CALLER` (u504): Caller is not the current signer principal.
* `ERR_ALREADY_PROCESSED` (u505): Withdrawal request already processed.
* `ERR_FEE_TOO_HIGH` (u505): Paid fee higher than requested.
* `ERR_WITHDRAWAL_INDEX_PREFIX`: Prefix for withdrawal index errors.
* `ERR_WITHDRAWAL_INDEX` (u506): General withdrawal index error.

### Other Constants

* `MAX_ADDRESS_VERSION` (u6): Maximum value of an address version.
* `MAX_ADDRESS_VERSION_BUFF_20` (u4): Maximum version for 20-byte hashbytes.
* `MAX_ADDRESS_VERSION_BUFF_32` (u6): Maximum version for 32-byte hashbytes.
* `DUST_LIMIT` (u546): Minimum amount of sBTC for withdrawal.

## Public Functions

### initiate-withdrawal-request

Initiates a new withdrawal request.

* Parameters:
  * `amount`: `uint` - Amount of sBTC to withdraw
  * `recipient`: `{ version: (buff 1), hashbytes: (buff 32) }` - Bitcoin address details
  * `max-fee`: `uint` - Maximum fee for the withdrawal
* Returns: `(response uint uint)`

### accept-withdrawal-request

Accepts a withdrawal request.

* Parameters:
  * `request-id`: `uint` - Withdrawal request ID
  * `bitcoin-txid`: `(buff 32)` - Bitcoin transaction ID
  * `signer-bitmap`: `uint` - Bitmap of signers
  * `output-index`: `uint` - Output index in the Bitcoin transaction
  * `fee`: `uint` - Actual fee paid
* Returns: `(response bool uint)`

### reject-withdrawal-request

Rejects a withdrawal request.

* Parameters:
  * `request-id`: `uint` - Withdrawal request ID
  * `signer-bitmap`: `uint` - Bitmap of signers
* Returns: `(response bool uint)`

### complete-withdrawals

Processes multiple withdrawal requests (accept or reject).

* Parameters:
  * `withdrawals`: `(list 600 {...})` - List of withdrawal details
* Returns: `(response uint uint)`

## Read-only Functions

### validate-recipient

Validates the recipient's Bitcoin address format.

* Parameters:
  * `recipient`: `{ version: (buff 1), hashbytes: (buff 32) }` - Bitcoin address details
* Returns: `(response bool uint)`

## Private Functions

### complete-individual-withdrawal-helper

Helper function to process individual withdrawals in the batch operation.

* Parameters:
  * `withdrawal`: `{...}` - Individual withdrawal details
  * `helper-response`: `(response uint uint)` - Accumulator for processing
* Returns: `(response uint uint)`

## Interactions with Other Contracts

* `.sbtc-token`: Calls `protocol-lock`, `protocol-burn-locked`, `protocol-mint`, and `protocol-unlock` for token operations.
* `.sbtc-registry`: Calls `create-withdrawal-request`, `get-withdrawal-request`, `get-current-signer-data`, `complete-withdrawal-accept`, and `complete-withdrawal-reject` for managing withdrawal requests and signer data.

## Security Considerations

{% stepper %}
{% step %}
**Access Control**

Only the current signer principal can accept or reject withdrawal requests.
{% endstep %}

{% step %}
**Dust Limit**

Enforces a minimum withdrawal amount to prevent spam and ensure economic viability.
{% endstep %}

{% step %}
**Fee Management**

Ensures that the actual fee doesn't exceed the maximum fee set by the user.
{% endstep %}

{% step %}
**Address Validation**

Implements thorough validation of Bitcoin address formats.
{% endstep %}

{% step %}
**State Management**

Prevents double-processing of withdrawal requests.
{% endstep %}
{% endstepper %}

## Bitcoin Address Types

The contract supports various Bitcoin address types, including:

* P2PKH (Pay-to-Public-Key-Hash)
* P2SH (Pay-to-Script-Hash)
* P2SH-P2WPKH (P2SH nested P2WPKH)
* P2SH-P2WSH (P2SH nested P2WSH)
* P2WPKH (Pay-to-Witness-Public-Key-Hash)
* P2WSH (Pay-to-Witness-Script-Hash)
* P2TR (Pay-to-Taproot)

Each address type is represented by a specific version byte and hashbytes format in the recipient structure.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.stacks.co/learn/sbtc/clarity-contracts/sbtc-withdrawal.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
