Skip to content

Commit 0b0eee4

Browse files
werner-stacksgitbook-bot
authored andcommitted
GITBOOK: Protocol Bonds: add Bond Troubleshooting and Bond FAQ
1 parent 0a15e15 commit 0b0eee4

4 files changed

Lines changed: 166 additions & 0 deletions

File tree

‎docs/operate/SUMMARY.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,5 @@
4040
* [Opening a Bond Position](protocol-bonds/opening-a-bond-position.md)
4141
* [Verifying and Reclaiming Your Locked Bitcoin](protocol-bonds/verifying-and-reclaiming-your-locked-bitcoin.md)
4242
* [Ending or Changing a Bond Position](protocol-bonds/ending-or-changing-a-bond-position.md)
43+
* [Bond Troubleshooting](protocol-bonds/bond-troubleshooting.md)
44+
* [Bond FAQ](protocol-bonds/bond-faq.md)

‎docs/operate/protocol-bonds/README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ A protocol bond pairs a Bitcoin commitment with an STX lock for a 12-cycle term.
1212
* [Opening a Bond Position](opening-a-bond-position.md): the allowlist, the two Bitcoin legs, the registration deadline, and what the contract checks.
1313
* [Verifying and Reclaiming Your Locked Bitcoin](verifying-and-reclaiming-your-locked-bitcoin.md): checking the lock address before funding, what you need to spend it later, and reclaiming after the timelock.
1414
* [Ending or Changing a Bond Position](ending-or-changing-a-bond-position.md): exiting early, withdrawing sBTC, changing signer-manager, and rolling into a new position.
15+
* [Bond Troubleshooting](bond-troubleshooting.md): why a registration fails, and what to do about it.
16+
* [Bond FAQ](bond-faq.md): short answers, with links to the guides above.
1517
* [Bond pool operator guide](bond-pool-operator-guide.md): running a whitelisted community sBTC pool.
1618

1719
For the conceptual overview, see [Bitcoin Staking](https://docs.stacks.co/learn/bitcoin-staking).
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
description: >-
3+
Short answers about protocol bonds under PoX-5, with links to the guides that
4+
cover each in full.
5+
---
6+
7+
# Bond FAQ
8+
9+
## How long is a protocol bond?
10+
11+
12 reward cycles, 25,200 Bitcoin blocks, roughly six months. The term is fixed for every bond.
12+
13+
## Can I hold more than one bond, or a bond and an STX-only stake?
14+
15+
No to both. A Stacks principal holds one position at a time. A registration that overlaps an existing bond fails with `ERR_ALREADY_REGISTERED` (u9), and one that overlaps an STX-only stake fails with `ERR_ALREADY_STAKED` (u19). A position that ends before the new one starts can roll into it.
16+
17+
The rule is keyed on the Stacks address, not on your Bitcoin keys, so the same Bitcoin keys can lock BTC for later bonds.
18+
19+
## Can I lock BTC on L1 and sBTC in the same bond?
20+
21+
No. A registration is either native BTC, as up to 10 lock outputs on Bitcoin, or sBTC held by the contract. Each lock output can commit its own unlock height, as long as every one is at or above the bond's minimum.
22+
23+
## Can I add BTC after registering?
24+
25+
No. Commit the full amount when you register. Nothing in pox-5 adds BTC to an existing bond position.
26+
27+
## What am I paid in?
28+
29+
Rewards are paid in sBTC: miner BTC is auto-bridged to sBTC for distribution. If you supplied a Bitcoin payout address and your signer-manager supports it, as the reference signer-manager and compatible ones do, your share is withdrawn to native BTC on L1 when it is claimed.
30+
31+
The payout address is not a `register-for-bond` parameter. It travels in `signer-calldata` to your signer-manager. See [How you are paid](../staking-stx/stack-with-a-pool.md#how-you-are-paid).
32+
33+
## When can I register, and when does registration close?
34+
35+
Registration opens once the bond is set up, which happens within the two reward cycles before it starts. It closes when the prepare phase before the bond's start begins, at least 100 Bitcoin blocks before the start height. See [Opening a Bond Position](opening-a-bond-position.md).
36+
37+
## Can I exit my bond early?
38+
39+
Yes, at any time outside the prepare phase.
40+
41+
* **Native BTC bond.** Call `announce-l1-early-exit` from your own Stacks address; no contract or other party can call it for you. You stop earning from that point, then spend your BTC back through the early-exit branch with a co-signature from the early-exit signer. Your STX stays locked until the bond's original end.
42+
* **sBTC bond.** Withdraw with `unstake-sbtc`.
43+
44+
See [Ending or Changing a Bond Position](ending-or-changing-a-bond-position.md).
45+
46+
## What if my registration fails?
47+
48+
See [Bond Troubleshooting](bond-troubleshooting.md). If you funded the bond's checked lock address, a failed registration does not cost you the BTC: it stays spendable by you through the timelock path.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
description: Why a bond registration fails under PoX-5, and what to do about it.
3+
---
4+
5+
# Bond Troubleshooting
6+
7+
Each section below starts from the error a failed `register-for-bond` returns. The error codes are the `pox-5` contract's unless noted, so you see the same codes whichever app you use.
8+
9+
{% hint style="info" %}
10+
**Check before you send.** `fetchEligibleRegisterForBond` in `@stacks/bitcoin-staking` runs most of the contract's checks read-only against current chain state: allowlist, timing, STX minimum and balance, signer registration, overlap and the roll-over window. It does not yet check the lock script (u42), the amount (u45) or the merkle proof (u41); those are only checked on-chain. A transaction ID only confirms that the transaction was submitted. Confirm the position on-chain before treating it as done.
11+
{% endhint %}
12+
13+
## I missed the registration deadline. Is my BTC lost?
14+
15+
No, as long as you funded the bond's checked lock address. The Bitcoin lock does not depend on the registration succeeding. If your registration fails because the bond has started, your BTC stays locked under its script until the unlock height you built it with, and then you spend it back to yourself through the timelock path. See [Verifying and Reclaiming Your Locked Bitcoin](verifying-and-reclaiming-your-locked-bitcoin.md).
16+
17+
You can still join a later bond as a new registration.
18+
19+
## Timing
20+
21+
### ERR\_BOND\_NOT\_FOUND (u7)
22+
23+
The bond has not been set up yet. `setup-bond` runs once per bond, within the two reward cycles before the bond starts, and registration cannot open before it. Check the bond's status with `fetchBondStatus`: before setup it reports `too-early`, `eligible` or `missed`; after setup it reports `open`, `locked`, `unlocked` or `finished`. These status names are marked experimental in the SDK and may still change.
24+
25+
### ERR\_STAKE\_IN\_PREPARE\_PHASE (u47)
26+
27+
`register-for-bond` is rejected during the prepare phase, the last 100 Bitcoin blocks of every reward cycle. The prepare phase immediately before the bond starts is where most late registrations fail: in practice, registration closes when that prepare phase begins. Earlier prepare phases inside the registration window also block it; send once the next cycle has started.
28+
29+
### ERR\_BOND\_ALREADY\_STARTED (u43)
30+
31+
The bond's start height has passed. There is no grace period. See [I missed the registration deadline](bond-troubleshooting.md#i-missed-the-registration-deadline-is-my-btc-lost).
32+
33+
## Allowlist
34+
35+
### ERR\_NOT\_ALLOWLISTED (u11)
36+
37+
The Stacks address sending the registration has no allowlist entry for this bond. Each bond has its own allowlist, and an entry for one bond does not carry over. Check that you are sending from the exact address you submitted. See [Getting Allowlisted for a Bond](getting-allowlisted-for-a-bond.md).
38+
39+
### ERR\_TOO\_MUCH\_SATS (u10)
40+
41+
The BTC you are registering, summed across your lock outputs, is more than your allowlisted maximum for this bond.
42+
43+
## STX and existing positions
44+
45+
### ERR\_INSUFFICIENT\_STX (u8)
46+
47+
Two checks share this code:
48+
49+
* **The STX amount is below the bond's minimum** for the BTC you are committing. The minimum comes from the bond's own ratio parameters. Compute it with `minUstxForSatsAmount`, or the contract's read-only `min-ustx-for-sats-amount`.
50+
* **Your STX balance is below the amount.** Locked and unlocked STX both count, so STX still locked by an ending bond counts toward a roll-over.
51+
52+
### ERR\_ALREADY\_REGISTERED (u9)
53+
54+
You already hold a bond whose term overlaps this one. A Stacks principal holds one position at a time. A bond that ends no later than the new bond's first cycle does not overlap: that is a roll-over, and it uses the same call.
55+
56+
### ERR\_ALREADY\_STAKED (u19)
57+
58+
You hold an STX-only stake that overlaps this bond. STX-only staking and a protocol bond are mutually exclusive. A stake that ends no later than the bond's first cycle can roll into it. See [STX-only Staking Troubleshooting](../staking-stx/stx-only-staking-troubleshooting.md).
59+
60+
### ERR\_ROLLOVER\_TOO\_EARLY (u48)
61+
62+
You are rolling from an ending bond, but the transaction landed before that bond's L1 unlock height. A roll-over only opens at that height. See [Renewing a native BTC bond](ending-or-changing-a-bond-position.md#renewing-a-native-btc-bond).
63+
64+
## Signer-manager
65+
66+
### ERR\_SIGNER\_NOT\_FOUND (u23)
67+
68+
The signer-manager you named has not registered with pox-5. Check the contract address against the one you were given.
69+
70+
### ERR\_SIGNER\_KEY\_GRANT\_NOT\_FOUND (u17)
71+
72+
The signer-manager is registered, but its signer-key grant is missing or has been revoked. Contact its operator, or choose another manager.
73+
74+
### Errors outside pox-5's range
75+
76+
The signer-manager's own `validate-stake!` runs during registration and can reject it with its own error codes, for example an allowlist of its own or calldata it cannot parse. Those codes are defined by that contract, not by pox-5. Read the manager's source for their meaning.
77+
78+
## The Bitcoin lock and its proof
79+
80+
### ERR\_INVALID\_UNLOCK\_HEIGHT (u52)
81+
82+
The unlock height committed in a lock output is not acceptable:
83+
84+
* It is below the bond's minimum unlock height (`get-bond-l1-unlock-height`), or
85+
* it is 500,000,000 or higher, which Bitcoin would read as a Unix timestamp rather than a block height, or
86+
* it is 2³⁹ or higher, beyond what the lock script can encode.
87+
88+
`buildLockScript` and `fetchConstructLockupOutputScript` reject the last case before you fund the address.
89+
90+
### ERR\_INVALID\_LOCKUP\_SCRIPT (u42)
91+
92+
The output you proved does not pay the script the contract rebuilds from your Stacks address, unlock height, unlock script and the bond's early-unlock script. If you have not funded yet, check the address first: see [Verifying and Reclaiming Your Locked Bitcoin](verifying-and-reclaiming-your-locked-bitcoin.md). If you have funded a mismatched address, the BTC cannot be registered for this bond, and whether you can spend it depends on what that address actually encodes.
93+
94+
### ERR\_INVALID\_LOCKUP\_AMOUNT (u45)
95+
96+
The amount in your proof does not equal the value of the output on Bitcoin.
97+
98+
### ERR\_DUPLICATE\_LOCKUP\_OUTPOINT (u46)
99+
100+
The same output (transaction ID and output index) appears twice in your registration. A registration takes at most 10 lock outputs, each listed once.
101+
102+
### ERR\_INVALID\_BTC\_HEADER (u40) or ERR\_INVALID\_MERKLE\_PROOF (u41)
103+
104+
The proof does not match Bitcoin: u40 means the block header does not match the canonical header at that height, u41 means the transaction is not in that block according to the merkle path. Rebuild the proof with `buildLockProof` (Esplora-shaped indexer responses) or `buildLockProofFromBlock` (`bitcoind`-shaped), which handle witness stripping and byte order. To isolate the failing part, `fetchVerifyBlockHeader`, `fetchParseBlockHeader`, `fetchReversedTxid` and `fetchBurnBlockHeaderHash` run the contract's own helpers read-only.
105+
106+
### (err u1), (err u2) or (err u3) while reading the transaction
107+
108+
These come from Clarity's `get-bitcoin-tx-output?`, not from pox-5, even though pox-5 uses the same numbers for unrelated errors: u1 means the transaction bytes did not decode, u2 means the output index is out of range, and u3 means the output's script is over 1,024 bytes. The usual cause is passing the segwit serialization instead of the legacy one; `buildLockProof` strips the witness for you.
109+
110+
## Related
111+
112+
* [Opening a Bond Position](opening-a-bond-position.md)
113+
* [Ending or Changing a Bond Position](ending-or-changing-a-bond-position.md)
114+
* [Bond FAQ](bond-faq.md)

0 commit comments

Comments
 (0)