Docs / Mechanics / Pricing and allocation

Pricing and allocation

One price, the same for everyone, built from the pool itself. It is the harmonic mean of every active backing plus 2.5%. Under inverse weighting the harmonic mean is the exact expected value of a draw, not an approximation of it.

One price for a random position

Rather than picking a listing, an acquirer pays a single acquisition fee and receives one position drawn at random from every active position in the pool.

So the price has one job: it has to equal the value of an average draw, or the whole thing is either a gift or a trap. The protocol computes that value directly.

The formula

EV = n / sum(1 / backing_i) acquisitionFee = EV * (10000 + surchargeBps) / 10000

EV harmonic mean of every active position backing n number of active positions surchargeBps 250, which is 2.5%

The harmonic mean is what you get by averaging the reciprocals and flipping the result back. It sits well below the ordinary average whenever the numbers are spread out, and it is dragged down hard by the smallest values in the set. That is the correct behaviour here, because the smallest backings are the ones you are most likely to draw.

Why it is exact

Write the weight of position i as w_i = 1e36 / b_i, where b_i is its backing. The constant cancels out of every ratio, so treat it as w_i = 1 / b_i and let W = sum(1 / b_j).

p_i = w_i / W = (1 / b_i) / W E[backing] = sum( p_i * b_i ) = sum( (1 / b_i) * b_i / W ) = sum( 1 / W ) = n / W = n / sum(1 / b_i)

Look at the third line. Every position contributes 1 / W to the expected value, and that term has no b_i left in it. A position backed with 0.05 BNB and a position backed with 1 BNB push the expected value by exactly the same amount, because the small one is drawn proportionally more often in precisely the ratio that cancels its smaller payout.

This is an identity, not an approximation and not a fit. It holds for any set of backings, any number of positions, at any moment. The acquisition fee is the mathematically fair expected value with a fixed surcharge on top, and nothing else.

It also means the expected value has a very cheap form: EV = n / W. The protocol already keeps W as a running sum for the draw, so the price is one division away at all times.

Worked example Illustrative

The same five positions used on the positions page. Nothing here is read from chain.

Expected backing, term by term
# Backing (BNB) 1 / backing Probability Contribution to EV
10.052052.63%0.02631579
20.101026.32%0.02631579
30.20513.16%0.02631579
40.5025.26%0.02631579
51.0012.63%0.02631579
Sum1.8538100.00%0.13157895

The contribution column is identical on every row, which is the identity above showing up in numbers. Five positions, each contributing 1 / 38 of a BNB, gives 5 / 38 = 0.13157895 BNB.

From expected value to the price on screen
LineBNBHow it is arrived at
Expected backing (EV)0.131578955 / 38
Surcharge at 250 bps0.00328947EV * 250 / 10000
Acquisition fee0.13486842what the acquirer pays into the pool

For contrast, the ordinary average of those five backings is 0.37 BNB. Pricing on the ordinary average would charge 2.81x what an acquirer should expect to receive, because it treats the 1 BNB position as if it came up as often as the 0.05 BNB one.

The 2.5% surcharge

The surcharge is the only margin in the acquisition. It is a flat 250 bps on top of the expected value, and it does not change with pool size, position count or how the backings are spread.

The surcharge is then divided three ways.

Where the 0.00328947 BNB surcharge goes Illustrative
DestinationBNBRule
Protocol0.00134868ownerAcquisitionFeeBps 100, which is 1% of the whole acquisition fee
Depositors and the $BWA buy0.00194079Split between the two on the dynamic schedule
Surcharge0.003289472.5% of EV

The protocol cut is taken out of the surcharge, not added to it. An acquirer pays EV * 1.025 whatever the owner fee is set to. Raising or lowering it moves money between the protocol and depositors, and never touches the price.

What is left of the surcharge splits between depositor earnings and buying $BWA, and that split moves with how busy the protocol is. The dynamic surcharge split has the schedule.

Computing EV in constant time

A naive implementation would walk every position to sum the reciprocals, which gets more expensive as the pool grows and eventually fails to fit in a block. The protocol never does that.

totalWeight is a running sum of inverse backings, maintained by one addition when a position becomes active and one subtraction when it leaves.

totalWeight = sum(1e36 / b_i) EV = n * 1e36 / totalWeight

Substituting totalWeight = 1e36 * sum(1 / b_i) gives EV = n / sum(1 / b_i), the harmonic mean, from one multiply and one divide. Pricing costs the same gas with five positions in the pool as with fifty thousand.

The same accumulator drives selection. Scaling the VRF random word by totalWeight and walking to the matching position is the draw. Price and probability are two readings of one number.

Slippage

An acquisition is not instant. The fee is quoted and paid when the request is made, and the position is picked when Chainlink VRF returns. Between those two moments other people deposit and other requests settle, so the pool that gets sampled is not exactly the pool that was quoted.

The protocol snapshots the price at request time and enforces a band around it. The two sides of that band are set by different people, because they protect different people.

DirectionWhat it meansWho is exposedBound
Price drifts up EV rose after the request. The acquirer would receive more than they paid for. Depositors, who would be handing over an above-price position selectionSlippageBps, fixed at 1000, which is 10%
Price drifts down EV fell after the request. The acquirer would receive less than they paid for. The acquirer, who would be overpaying Chosen per request by the acquirer, anywhere from 0% to 100%

The upward cap is a protocol parameter because it is the pool's exposure and every depositor shares it. The downward tolerance is per request because only the acquirer knows how much drift they are willing to eat rather than wait and try again. Setting it to 0% means any drop at all voids the acquisition. Setting it to 100% means settle regardless.

Optional bounds

Two further limits can be attached to a request. Both are optional and both are snapshotted with everything else.

BoundEffect
maxAcquisitionFeeA hard ceiling on what the request may cost. If the fee at settlement is above it, the acquisition does not proceed.
minWeightedValueA floor on the weighted value of the pool being sampled. If the pool has thinned out below it, the acquisition does not proceed.

Refunds

Three situations end a request without a position changing hands.

  1. The pool empties before settlement

    Every active position was drawn or withdrawn while the request was in flight. There is nothing left to sample.

  2. The price moves outside the snapshotted bounds

    EV drifted up past selectionSlippageBps, or down past the tolerance the acquirer set, or one of the optional bounds was breached.

  3. The request expires

    Randomness never arrived. Randomness covers what the protocol does then.

Refunds are pull based

A refund is recorded as a credit against your address. The protocol does not send BNB back to you as part of the failing transaction. You call the withdrawal yourself, whenever you like.

This is deliberate. A push refund can fail if the recipient is a contract that reverts on receipt, and a failed push inside settlement would jam the queue for everyone behind it. Crediting and letting the owner pull means one address's behaviour can never stall another's.

The VRF service fee is separate

Requesting randomness costs money, and that money is spent the moment the request is made whether or not the acquisition ever completes.

The VRF service fee is quoted separately from the pool fee and is never refundable. If a request is refunded, the acquisition fee comes back as a credit. The VRF service fee does not.

Both numbers are shown before you commit, so the total is never a surprise. They are listed apart because they behave differently, not to bury one of them.

Read next