Oracle Fixed Discount Auctioneer (OFDA)

Oracle Fixed Discount Auctioneer allows market creators to sell tokens at a discount to a price provided by an oracle, likely in exchange for vesting the tokens over a certain amount of time. Typically, longer duration vesting will require a larger discount. Additionally, larger discounts may be required for smaller cap tokens or when market demand is low. Unlike the SDA auction variants, it will not adjust price to sell out the capacity over the duration.

Market creators can also set a minimum total discount from the starting price, which creates a hard floor for the market price.

The below chart shows a notional example of how price might evolve over an OFDA market.

The Base OFDA contract has the following data structures, variables, and methods.

Data Structures (Structs)

MarketParams

Parameters to create a new OFDA market. Encoded as bytes and provided as input to createMarket.

struct MarketParams {
    ERC20 payoutToken;
    ERC20 quoteToken;
    address callbackAddr;
    IBondOracle oracle;
    uint48 fixedDiscount;
    uint48 maxDiscountFromCurrent;
    bool capacityInQuote;
    uint256 capacity;
    uint48 depositInterval;
    uint48 vesting;
    uint48 start;
    uint48 duration;
}

BondMarket

BondMarket contains the token, callback, capacity, owner, and purchased/sold amount data for a Oracle Fixed Discount Market.

struct BondMarket {
    address owner; // market owner. sends payout tokens, receives quote tokens (defaults to creator)
    ERC20 payoutToken; // token to pay depositors with
    ERC20 quoteToken; // token to accept as payment
    address callbackAddr; // address to call for any operations on bond purchase. Must inherit to IBondCallback.
    bool capacityInQuote; // capacity limit is in payment token (true) or in payout (false, default)
    uint256 capacity; // capacity remaining
    uint256 maxPayout; // max payout tokens out in one order
    uint256 sold; // payout tokens out
    uint256 purchased; // quote tokens in
}

BondTerms

BondTerms contains the oracle, pricing, and time parameters of an Oracle Fixed Discount Market.

struct BondTerms {
    IBondOracle oracle; // address to call for reference price. Must implement IBondOracle.
    uint48 start; // timestamp when market starts
    uint48 conclusion; // timestamp when market no longer offered
    uint48 vesting; // length of time from deposit to expiry if fixed-term, vesting timestamp if fixed-expiry
    uint48 fixedDiscount; // fixed discount percent for the market
    uint256 minPrice; // minimum price (hard floor for the market)
    uint256 scale; // scaling factor for the market (see MarketParams struct)
    uint256 oracleConversion; // conversion factor for oracle -> market price
}

Public Variables and View Methods

allowNewMarkets

function allowNewMarkets() external view returns (bool)

Whether or not the auctioneer allows new markets to be created

Changing to false will sunset the auctioneer after all active markets end

authority

function authority() external view returns (contract Authority)

Roles authority contract for the bond system which managed access-control to permissioned functions.

callbackAuthorized

function callbackAuthorized(address) external view returns (bool)

Whether or not the market creator is authorized to use a callback address

Parameters

currentCapacity

function currentCapacity(uint256 id_) external view returns (uint256)

Returns current capacity of a market

Parameters

getAggregator

function getAggregator() external view returns (contract IBondAggregator)

Returns the Aggregator that services the Auctioneer

getMarketInfoForPurchase

function getMarketInfoForPurchase(uint256 id_) external view returns (address owner, address callbackAddr, contract ERC20 payoutToken, contract ERC20 quoteToken, uint48 vesting, uint256 maxPayout_)

Provides information for the Teller to execute purchases on a Market

Parameters

Returns

getTeller

function getTeller() external view returns (contract IBondTeller)

Returns the Teller that services the Auctioneer

isInstantSwap

function isInstantSwap(uint256 id_) external view returns (bool)

Does market send payout immediately

Parameters

isLive

function isLive(uint256 id_) external view returns (bool)

Is a given market accepting deposits

Parameters

marketPrice

function marketPrice(uint256 id_) external view returns (uint256)

Calculate current market price. Value returned is the number of quote tokens per payout token. The value is the oracle price scaled by the BondTerms.oracleConversion factor. marketPrice and marketScale can be used to convert between amounts of quote tokens and payout tokens at the current price.

Parameters

marketScale

function marketScale(uint256 id_) external view returns (uint256)

Scale value to use when converting between quote token and payout token amounts with marketPrice()

Parameters

markets

function markets(uint256) external view returns (address owner, contract ERC20 payoutToken, contract ERC20 quoteToken, address callbackAddr, bool capacityInQuote, uint256 capacity, uint256 maxPayout, uint256 sold, uint256 purchased)

Returns the token, callback, capacity, owner, and purchased/sold amount data for a market. See BondMarket.

Parameters

maxAmountAccepted

function maxAmountAccepted(uint256 id_, address referrer_) external view returns (uint256)

Returns maximum amount of quote token accepted by the market

Parameters

maxPayout

function maxPayout(uint256 id_) external view returns (uint256)

Calculate max payout of the market in payout tokens

Returns a dynamically calculated payout or the maximum set by the creator, whichever is less. If the remaining capacity is less than the max payout, then that amount will be returned.

Parameters

minDepositInterval

function minDepositInterval() external view returns (uint48)

Minimum deposit interval for a market

minMarketDuration

function minMarketDuration() external view returns (uint48)

Minimum market duration in seconds

newOwners

function newOwners(uint256) external view returns (address)

New address to designate as market owner. They must accept ownership to transfer permissions.

Parameters

ownerOf

function ownerOf(uint256 id_) external view returns (address)

Returns the address of the market owner

Parameters

payoutFor

function payoutFor(uint256 amount_, uint256 id_, address referrer_) external view returns (uint256)

Payout due for amount of quote tokens at current market price

Parameters

terms

function terms(uint256) external view returns (contract IBondOracle oracle, uint48 start, uint48 conclusion, uint48 vesting, uint48 fixedDiscount, uint256 minPrice, uint256 scale, uint256 oracleConversion)

Information pertaining to oracle, pricing, and time parameters. See BondTerms.

Parameters

State-Mutating Methods

closeMarket

function closeMarket(uint256 id_) external nonpayable

Disable existing bond market. Must be market owner

Parameters

createMarket

function createMarket(bytes params_) external nonpayable returns (uint256)

Creates a new bond market

See MarketParams for the required formatting for the abi-encoded input params.

Parameters

Returns

pullOwnership

function pullOwnership(uint256 id_) external nonpayable

Accept ownership of a marketMust be market newOwner

The existing owner must call pushOwnership prior to the newOwner calling this function

Parameters

purchaseBond

function purchaseBond(uint256 id_, uint256 amount_, uint256 minAmountOut_) external nonpayable returns (uint256 payout)

Exchange quote tokens for a bond in a specified market. Must be teller. End users interact with the Teller contract to purchase.

Parameters

Returns

pushOwnership

function pushOwnership(uint256 id_, address newOwner_) external nonpayable

Designate a new owner of a marketMust be market owner

Doesn't change permissions until newOwner calls pullOwnership

Parameters

setAllowNewMarkets

function setAllowNewMarkets(bool status_) external nonpayable

Change the status of the auctioneer to allow creation of new markets

Setting to false and allowing active markets to end will sunset the auctioneer

Parameters

setCallbackAuthStatus

function setCallbackAuthStatus(address creator_, bool status_) external nonpayable

Change whether a market creator is allowed to use a callback address in their markets or not. Must be guardian

Callback is believed to be safe, but a whitelist is implemented to prevent abuse

Parameters

setMinDepositInterval

function setMinDepositInterval(uint48 depositInterval_) external nonpayable

Set the minimum deposit interval. Access controlled

Parameters

setMinMarketDuration

function setMinMarketDuration(uint48 duration_) external nonpayable

Set the minimum market duration. Access controlled

Parameters

Events

MarketClosed

event MarketClosed(uint256 indexed id)

Parameters

MarketCreated

event MarketCreated(uint256 indexed id, address indexed payoutToken, address indexed quoteToken, uint48 vesting)

Parameters

Errors

The following custom errors are used in the OFDA contract to denote specific revert conditions. The errors are prefixed with "Auctioneer" to denote that it is within this contract when multi-contract actions are performed (such as buying a bond).

error Auctioneer_OnlyMarketOwner();
error Auctioneer_MarketNotActive();
error Auctioneer_MaxPayoutExceeded();
error Auctioneer_AmountLessThanMinimum();
error Auctioneer_NotEnoughCapacity();
error Auctioneer_InvalidCallback();
error Auctioneer_BadExpiry();
error Auctioneer_InvalidParams();
error Auctioneer_NotAuthorized();
error Auctioneer_NewMarketsNotAllowed();
error Auctioneer_OraclePriceZero();