How the fee is charged
The wrapper holds jlTokens for its users. Each jlToken is worth more underlying tokens over time, as Jupiter Lend Earn pays yield. The wrapper records the jlToken exchange price at its last checkpoint. At each accrue, it does two things:- It refreshes the Lend exchange price.
- It charges the partner fee on the users’ yield since the last checkpoint, and moves the new checkpoint to the current price.
updatePartnerFee, and every call to the accrue instruction. Anyone can call accrue. It has no signer account, so only the transaction fee payer signs.
Only the users’ balance pays the fee. The partner’s and Jupiter’s balances are already fee income, so their jlTokens keep earning Earn yield with no fee on it.
Integer rounding under-charges the fee by less than one jlToken atom per accrue, in the users’ favour.
How the fee is split
The partner fee ispartnerFeeBps of the users’ yield, at most 1000 bps (10%). Jupiter’s protocol share comes out of the partner fee, not on top of it. The protocol share is at most 2500 bps (25%) of the partner fee, and it is currently 2500 bps.
For example, with a partner fee of 1000 bps and a protocol share of 2500 bps, each 100 units of user yield split as follows: the users keep 90, the partner gets 7.5, and Jupiter gets 2.5.
Jupiter can set a different protocol share for one wrapper. The share that applies to your wrapper is the field protocolFeeShareBps on the wrapper. See Wrapper fields.
Where fees sit until you claim
All of a wrapper’s jlTokens stay in its vault, including the fees. The wrapper tracks the users’ balance and Jupiter’s balance. Your balance is whatever the vault holds beyond those two, and the program computes it when you claim. Two small amounts also add to your balance:- On a redeem, the user’s share of jlTokens can include a fraction of an atom. The wrapper pays whole atoms and leaves the fraction in your balance.
- jlTokens that anyone sends straight to the vault, outside a deposit, add to your balance. They do not change the xToken price.
Effective fee
Each accrue charges the fee on the yield of one interval. The charged jlTokens then compound in the fee balances with no fee. So the more often a wrapper accrues, the larger the share of total yield the fee takes over time. Over a period where the jlToken price rises by a ratio R, with a fee fraction f (partnerFeeBps / 10000), the user’s value grows by:
- 1 + (1 − f)(R − 1), if the wrapper accrues once at the end.
- R(1 − f), if the wrapper accrues continuously.
partnerFeeBps = 1000, the effective fee as a share of gross yield is:
At 5% a year the gap is about 0.2 percentage points. It grows with the yield.
A wrapper with routine user activity accrues often enough to sit at the continuous rate. Quote fees to your users on that basis, not as the nominal
partnerFeeBps.When fee changes take effect
Partner fee.updatePartnerFee accrues at the old fee first, so the new fee applies only to yield earned after the change. The change takes effect at once, with no delay, up to the 10% cap. Your users rely on your conduct within that cap. updatePartnerFee is blocked while the protocol is paused. See Change the partner fee.
Protocol share. When Jupiter changes the protocol share, each wrapper picks up the new share at its next accrue. The yield pending since the last checkpoint splits at the old share. To apply a new share right away, call accrue on the wrapper. An idle wrapper keeps the old share until its next activity.
Share price and the seed
An xToken is a claim on part of the users’ balance. Its value in jlTokens is the users’ balance divided bytotalXShares: the xTokens in circulation plus the locked seed shares described below. The value rises as yield accrues, net of the fee.
Use totalXShares for this math, not the xToken mint supply. A holder can burn xTokens directly through the token program, which lowers the supply without changing totalXShares. The SDK math already uses totalXShares.
Every deposit and withdrawal rounds in the pool’s favour: deposits round the xTokens they mint down, and exact withdrawals round the xTokens they burn up. Both leave small amounts of value in the pool.
When Jupiter creates a wrapper, it deposits a seed: more than 1,000,000 jlToken atoms and at most 10 whole jlTokens. The seed is booked as xToken shares that are never minted to anyone and can never be redeemed. So the wrapper starts at a price of one jlToken atom per xToken atom, and totalXShares never falls to zero.
The seed protects new wrappers against share-price manipulation. An attacker could try to push the share price up with many tiny round trips, so that later deposits lose more to rounding. To raise the price, the attacker has to add value to every share, the locked seed shares included, and that value stays locked with the seed. A larger seed makes the attack cost more.