Developers
Program reference
Instructions, accounts and error codes of the Plumb Solana program, for anyone building transactions without the API.
Plumb is a native Rust program, without a framework. Instructions and accounts are encoded with Borsh. The program's address and the PLMB mint are on the Addresses page.
Accounts
| Account | Address | Size |
|---|---|---|
| Branch | PDA ["branch", plmb_mint] |
2,035 bytes |
| Bucket | PDA ["bucket", branch, tick], one per rate, tick 0 to 15 |
1,282 bytes |
| Trove | PDA ["trove", branch, owner] |
68 bytes |
The branch PDA is the mint authority of PLMB and the owner of the JitoSOL vault and the stability pool's PLMB vault. Read debt and collateral from the bucket the trove points to, never from a cached copy: a bucket's interest may not have been settled for a while, and the branch ledger holds what it owes.
Instructions
The first byte selects the instruction; arguments follow as little-endian integers.
| # | Instruction | Arguments | Signer |
|---|---|---|---|
| 0 | Initialize |
Operator | |
| 1 | InitializeBucket |
tick: u8 |
Anyone |
| 2 | Open |
tick: u8, collateral: u64, debt: u64 |
Owner |
| 3 | Adjust |
add: u64, withdraw: u64, borrow: u64, repay: u64 |
Owner |
| 4 | ChangeRate |
tick: u8 |
Owner |
| 5 | Accrue |
Anyone | |
| 6 | Redeem |
amount: u64, min_collateral: u64, max_fee_bps: u64 |
Redeemer |
| 7 | PoolDeposit |
amount: u64 |
Depositor |
| 8 | PoolWithdraw |
amount: u64, collateral: u64 |
Depositor |
| 9 | Liquidate |
Anyone |
Amounts are raw token units. In Adjust, withdraw and repay, and in PoolWithdraw, both amounts, may be u64::MAX (18446744073709551615), meaning the whole balance as settled inside the instruction. Any other value means exactly that amount.
Account lists
The HTTP API and the TypeScript SDK assemble account lists for you. If you build them yourself, note:
- Every price-reading instruction takes the Pyth SOL/USD and JitoSOL/USD accounts, the Jito stake pool and the JitoSOL mint, at their pinned addresses.
Liquidatetakes the target's bucket and then every other bucket whose bit is set in the branch bitmap, once each, in ascending order.PoolDepositandPoolWithdrawtake every bucket whose bit is set, in ascending order, because they settle all of them first.- If the bitmap changes between building and executing, the transaction fails cleanly; read the branch again and rebuild.
Compute
The program allocates from a 256 KiB heap, so every transaction must request it with ComputeBudgetProgram.requestHeapFrame. Request 400,000 compute units for most instructions and 1,400,000 for Liquidate, PoolDeposit and PoolWithdraw.
| Measured case | Compute units |
|---|---|
| Highest single step of a full borrow, pool and repay workflow | 99,907 |
| Liquidation spanning all sixteen rates | 482,036 |
| 256 troves, 16 depositors, a year of unsettled interest, partial pool cover | 1,205,496 |
Errors
The program fails with a custom error code:
| Code | Meaning |
|---|---|
| 1 | A required signer or the position's owner did not sign |
| 2 | An account is not the expected PDA |
| 3 | Invalid program state, account list or argument |
| 4 | Wrong token mint, program, authority, delegate or account state |
| 5 | Collateral ratio check failed, the trove can't be liquidated, or a redemption needs a liquidation first |
| 6 | No free seat at that rate or in the stability pool |
| 7 | Below the minimum debt, or above the branch's debt ceiling |
| 8 | The redemption did not target the lowest rate with debt |
| 9 | Redemption amount, fee limit or minimum JitoSOL not met |
| 10 | A timestamp went backwards relative to recorded state |
| 11 | No trove can receive a liquidation's redistributed debt |
A refused price surfaces as InvalidAccountData, and an amount larger than the balance it draws from as ArithmeticOverflow.
Tokens
Plumb accepts only classic SPL Token accounts. Token-2022 accounts, delegated vaults and frozen accounts are rejected. JitoSOL must be the canonical mint, whose mint authority is the Jito stake pool's withdraw authority.
# Program reference Instructions, accounts and error codes of the Plumb Solana program, for anyone building transactions without the API. Plumb is a native Rust program, without a framework. Instructions and accounts are encoded with Borsh. The program's address and the PLMB mint are on the [Addresses](/docs/addresses) page. ## Accounts | Account | Address | Size | | --- | --- | --- | | Branch | PDA `["branch", plmb_mint]` | 2,035 bytes | | Bucket | PDA `["bucket", branch, tick]`, one per rate, `tick` 0 to 15 | 1,282 bytes | | Trove | PDA `["trove", branch, owner]` | 68 bytes | The branch PDA is the mint authority of PLMB and the owner of the JitoSOL vault and the stability pool's PLMB vault. Read debt and collateral from the bucket the trove points to, never from a cached copy: a bucket's interest may not have been settled for a while, and the branch ledger holds what it owes. ## Instructions The first byte selects the instruction; arguments follow as little-endian integers. | # | Instruction | Arguments | Signer | | --- | --- | --- | --- | | 0 | `Initialize` | | Operator | | 1 | `InitializeBucket` | `tick: u8` | Anyone | | 2 | `Open` | `tick: u8, collateral: u64, debt: u64` | Owner | | 3 | `Adjust` | `add: u64, withdraw: u64, borrow: u64, repay: u64` | Owner | | 4 | `ChangeRate` | `tick: u8` | Owner | | 5 | `Accrue` | | Anyone | | 6 | `Redeem` | `amount: u64, min_collateral: u64, max_fee_bps: u64` | Redeemer | | 7 | `PoolDeposit` | `amount: u64` | Depositor | | 8 | `PoolWithdraw` | `amount: u64, collateral: u64` | Depositor | | 9 | `Liquidate` | | Anyone | Amounts are raw token units. In `Adjust`, `withdraw` and `repay`, and in `PoolWithdraw`, both amounts, may be `u64::MAX` (`18446744073709551615`), meaning the whole balance as settled inside the instruction. Any other value means exactly that amount. ## Account lists The [HTTP API](/docs/api) and the TypeScript SDK assemble account lists for you. If you build them yourself, note: - Every price-reading instruction takes the Pyth SOL/USD and JitoSOL/USD accounts, the Jito stake pool and the JitoSOL mint, at their pinned addresses. - `Liquidate` takes the target's bucket and then every other bucket whose bit is set in the branch bitmap, once each, in ascending order. - `PoolDeposit` and `PoolWithdraw` take every bucket whose bit is set, in ascending order, because they settle all of them first. - If the bitmap changes between building and executing, the transaction fails cleanly; read the branch again and rebuild. ## Compute The program allocates from a 256 KiB heap, so every transaction must request it with `ComputeBudgetProgram.requestHeapFrame`. Request 400,000 compute units for most instructions and 1,400,000 for `Liquidate`, `PoolDeposit` and `PoolWithdraw`. | Measured case | Compute units | | --- | --- | | Highest single step of a full borrow, pool and repay workflow | 99,907 | | Liquidation spanning all sixteen rates | 482,036 | | 256 troves, 16 depositors, a year of unsettled interest, partial pool cover | 1,205,496 | ## Errors The program fails with a custom error code: | Code | Meaning | | --- | --- | | 1 | A required signer or the position's owner did not sign | | 2 | An account is not the expected PDA | | 3 | Invalid program state, account list or argument | | 4 | Wrong token mint, program, authority, delegate or account state | | 5 | Collateral ratio check failed, the trove can't be liquidated, or a redemption needs a liquidation first | | 6 | No free seat at that rate or in the stability pool | | 7 | Below the minimum debt, or above the branch's debt ceiling | | 8 | The redemption did not target the lowest rate with debt | | 9 | Redemption amount, fee limit or minimum JitoSOL not met | | 10 | A timestamp went backwards relative to recorded state | | 11 | No trove can receive a liquidation's redistributed debt | A refused price surfaces as `InvalidAccountData`, and an amount larger than the balance it draws from as `ArithmeticOverflow`. ## Tokens Plumb accepts only classic SPL Token accounts. Token-2022 accounts, delegated vaults and frozen accounts are rejected. JitoSOL must be the canonical mint, whose mint authority is the Jito stake pool's withdraw authority.