ReferenceCurve_v1 contract that issues an issuance token in exchange for a collateral token, at prices set by a step curve over the issuance token’s supply.
The price of the next token depends only on the current supply. As supply grows, the price on the curve rises or stays level. A buy increases supply and a sell decreases it, and the next price is read from the curve at the new supply.
Parts of a market
The curve
The curve is a list of segments. Each segment is a run of equal-sized steps, and every token in a step has the same price. A segment has four values:
The contract checks these rules each time the segments are set:
- A curve has at least 2 and at most 10 segments.
- The first segment has exactly one step and a price increase of zero.
- A segment with one step has a price increase of zero.
- Each segment’s initial price is at or above the price of the previous segment’s last step.
- Total capacity, the sum over all segments of steps × supply per step, is at least the current supply.
getReferencePrice). The segments after it are the premium segments (getPremiumSections). Curve shape describes how the premium segments are configured.
Price at a given supply
The price at supply is the price of the step that holds the -th token: where:- is the segment that holds the -th token
- is the step within segment , counted from 0
- is the segment’s initial price (
initialPriceOfSegment) - is the segment’s price increase per step (
priceIncreasePerStep)
getStaticPriceForSelling). The buy price is , the price of the next token (getStaticPriceForBuying).
Cost of supply
The cost of supply is the sum, over every token from the first to the -th, of the price of the step that holds it: where:- is the price of step
- is the number of tokens of step that lie at or below (the full supply per step, or less for the last, partly filled step)
Buying
A buyer deposits collateral. The market takes the buy fee from the deposit, then mints tokens step by step at each step’s price until the rest of the deposit is spent. where:- is the deposit, in collateral
- is the buy fee in basis points (
getBuyFee) - is the supply before the buy
- is the number of tokens minted
- a reference segment of 1,000 tokens at a reference price of 1.00
- a premium segment that starts at 1.20, rises 0.20 per step, and has 100 tokens per step
After the buy:
- supply is 1,223.125
- the sell price is 1.60
- the reserve is 1,000 × 1.00 + 297.00 = 1,297.00
Selling
A seller returns tokens. The market burns them and pays out the cost of that supply at the curve’s prices, less the sell fee. where:- is the number of tokens sold
- is the collateral released from the reserve
- is the sell fee in basis points (
getSellFee)
After the sell:
- supply is 1,100
- the sell price is 1.20, the price of the last filled step
- the reserve is 1,297.00 − 177.00 = 1,120.00
Selling into the reference segment
When a sell takes supply below the reference segment’s size, the market shrinks the reference segment to the new supply in the same transaction (_adjustReferenceToSupply). The reference price does not change. The premium segments keep their prices and step sizes, and they now start at the lower supply.
Example. On the curve above, supply is 1,000 and an address sells 100 tokens at a sell fee of 0.
- The seller receives 100 × 1.00 = 100.00.
- The reference segment becomes 900 tokens at 1.00.
- The next buy pays 1.20 for the 901st token, where before the sell the 1,001st token was the first at 1.20.
Trading switches
Buying and selling each have an open/closed switch.- A disable call closes the switch and increments that direction’s disable epoch. Every call increments it, including when the switch is already closed. Disable calls work while the market is frozen.
- An enable call takes the current disable epoch as an argument and reverts if it does not match. An enable call prepared before a later disable therefore reverts.
- The enable functions without an argument always revert on this contract.
reconfigureSegments) requires both switches to be closed.
Parameters
Who can call
buy and sell is set by the market’s authorizer. At launch, sell is open to every address from the start, and buy is opened to every address after early access closes. The variants that send to another address, buyFor and sellTo, are not granted. Authority lists every role.
Edge cases
- Fee rounds to zero. If the fee is above 0 bps but the computed fee rounds down to 0, the trade reverts.
- Zero inputs. A deposit, sell amount or minimum amount out of 0 reverts.
- Buy past capacity. If a deposit would buy past the curve’s total capacity, the market mints up to capacity, charges the fee only on the collateral spent, and refunds the rest in the same transaction.
- Rounding. Each step’s cost is rounded up. Tokens from a partly bought final step are rounded down.
- Last token sold. When a sell takes supply to 0 and the reserve manager records no outstanding draws, the market sets the virtual collateral supply to 0 and sends any collateral left on the contract to the fee treasury. While an outstanding draw exists, that sell reverts.
- Reference price decrease. A new curve with a lower reference price reverts while any supply or outstanding draw exists.
- Endowed markets. On a market with the endowed option, buys and sells revert while endowment setup is open, and sells revert while reference sells are closed. See Endowed reference segment.
Code
Source:
house-markets/contracts at 0ebbc89a (branch integration/v12-post-qa).