Protocol
Price oracle
How Plumb values JitoSOL, which accounts it reads, and when it refuses a price.
Every action that depends on the value of collateral reads the price inside the transaction: opening, borrowing, withdrawing against debt, changing rate, redeeming and liquidating. There is no off-chain price service and no stored price that someone can update.
The rule
JitoSOL is a claim on staked SOL, so it has two honest valuations:
- its stake value: the SOL price times the SOL each JitoSOL represents in the Jito stake pool, and
- its market price: what JitoSOL itself trades at.
Normally they are within a fraction of a percent. They come apart when holders rush to sell JitoSOL, and that is exactly when lending against the higher one would be dangerous. Plumb takes the lower:
JitoSOL price = min( SOL/USD × stake rate , JitoSOL/USD )The sources
| Input | Read from |
|---|---|
| SOL/USD | Pyth's sponsored SOL/USD price account on Solana |
| JitoSOL/USD | Pyth's sponsored JitoSOL/USD price account on Solana |
| Stake rate | The Jito stake pool account: total staked lamports ÷ JitoSOL supply |
The stake rate is not reported by anyone; the program reads it straight from the stake pool's own account and checks the supply against the JitoSOL mint. Every account is pinned by address and owner in the program. See Addresses.
When the program refuses a price
A price that fails any of these checks is rejected, and the transaction fails without changing anything:
| Check | Limit |
|---|---|
| Age | Each Pyth price at most 120 seconds old, and not more than 5 seconds in the future |
| Confidence | Each Pyth confidence band at most 1% of its price |
| Verification | Only fully verified Pyth updates |
| Stake pool | Updated for the current epoch, with a supply that matches the JitoSOL mint |
| Order | Never older than a price the program has already used |
The last check stops anyone from replaying an older, more convenient price after a newer one has been used.
Rounding
Every conversion rounds against the borrower: prices are cut by their confidence band and rounded down, so collateral is never valued above what the sources support. The program works in whole micro-dollars per JitoSOL and checks every multiplication for overflow.
Epoch boundaries
At the start of every Solana epoch, roughly every two days, the Jito stake pool has to be updated before its exchange rate is current. Until someone runs that update, Plumb won't use the pool's rate, and price-dependent actions wait. The update is permissionless and is normally run shortly after the boundary.
In the app
The price chip in the app's top bar shows the price the program would use right now. Open it to see both valuations side by side and which one is lower. If the program would refuse the price, the chip says why, and the forms that need it explain that they are waiting.
# Price oracle How Plumb values JitoSOL, which accounts it reads, and when it refuses a price. Every action that depends on the value of collateral reads the price inside the transaction: opening, borrowing, withdrawing against debt, changing rate, redeeming and liquidating. There is no off-chain price service and no stored price that someone can update. ## The rule JitoSOL is a claim on staked SOL, so it has two honest valuations: - its **stake value**: the SOL price times the SOL each JitoSOL represents in the Jito stake pool, and - its **market price**: what JitoSOL itself trades at. Normally they are within a fraction of a percent. They come apart when holders rush to sell JitoSOL, and that is exactly when lending against the higher one would be dangerous. Plumb takes the lower: ```text JitoSOL price = min( SOL/USD × stake rate , JitoSOL/USD ) ``` :::figure price | Both values are reduced by their confidence band before the comparison, so the result is conservative twice. ## The sources | Input | Read from | | --- | --- | | SOL/USD | Pyth's sponsored SOL/USD price account on Solana | | JitoSOL/USD | Pyth's sponsored JitoSOL/USD price account on Solana | | Stake rate | The Jito stake pool account: total staked lamports ÷ JitoSOL supply | The stake rate is not reported by anyone; the program reads it straight from the stake pool's own account and checks the supply against the JitoSOL mint. Every account is pinned by address and owner in the program. See [Addresses](/docs/addresses). ## When the program refuses a price A price that fails any of these checks is rejected, and the transaction fails without changing anything: | Check | Limit | | --- | --- | | Age | Each Pyth price at most 120 seconds old, and not more than 5 seconds in the future | | Confidence | Each Pyth confidence band at most 1% of its price | | Verification | Only fully verified Pyth updates | | Stake pool | Updated for the current epoch, with a supply that matches the JitoSOL mint | | Order | Never older than a price the program has already used | The last check stops anyone from replaying an older, more convenient price after a newer one has been used. > [!WARNING] > While the price is refused, borrowing, rate changes, withdrawals against debt, redemptions and liquidations all wait. Repaying, adding collateral, closing a fully repaid trove and the stability pool keep working, because none of them value collateral. ## Rounding Every conversion rounds against the borrower: prices are cut by their confidence band and rounded down, so collateral is never valued above what the sources support. The program works in whole micro-dollars per JitoSOL and checks every multiplication for overflow. ## Epoch boundaries At the start of every Solana epoch, roughly every two days, the Jito stake pool has to be updated before its exchange rate is current. Until someone runs that update, Plumb won't use the pool's rate, and price-dependent actions wait. The update is permissionless and is normally run shortly after the boundary. ## In the app The price chip in the app's top bar shows the price the program would use right now. Open it to see both valuations side by side and which one is lower. If the program would refuse the price, the chip says why, and the forms that need it explain that they are waiting.