Skip to main content

Creating & Updating offers

Posting a new offer​

New offers will mostly be posted by maker contracts able to source liquidity when asked by Mangrove.

Offers posted via maker contracts are called smart offers - as opposed to on-the-fly offers made from EOA's.

Offers on Mangrove can be posted in two ways which differ in how the "price" (ratio) is specified:

  • newOfferByTick: The "price" is specified as a tick.
  • newOfferByVolume: The "price" is specified as the ratio between two volumes, wants/gives.

The *ByVolume variant is a convenience wrapper for the *ByTick variant: The provided volumes are converted to a corresponding tick.

The output from the two functions is the same.

info

Both functions are payable and can be used to credit the maker contract's balance on Mangrove on the fly. A non-zero msg.value will allow Mangrove to credit the maker's balance prior to locking the provision of the newly posted offer.

 function newOfferByTick(
OLKey memory olKey,
Tick tick,
uint gives,
uint gasreq,
uint gasprice
) external payable returns (uint offerId);

function newOfferByVolume(
OLKey memory olKey,
uint wants,
uint gives,
uint gasreq,
uint gasprice
) external payable returns (uint offerId);

Inputs​

The two function only differ in one input. They both functions take these inputs:

  • olKey: identifies the offer list and consists of:
    • outbound_tkn: address of the outbound token (that the offer will send).
    • inbound_tkn: address of the inbound token (that the offer will receive).
    • tickSpacing: specifies the space between allowed ticks (see Ticks, ratios, and prices for details)
  • gives: the amount of outbound tokens promised by the offer. Must fit in 127 bits and be strictly positive. Must provide enough volume w.r.t. to gasreq and offer list's density parameter.
  • gasreq: the amount of gas that will be given to the offer's account. Must fit in 24 bits and be lower than gasmax. Should be sufficient to cover all calls to the maker contract's offer logic (makerExecute) and makerPosthook). Must be compatible with the offered volume gives and the offer list's density parameter. (See also gasreq.)
  • gasprice: gas price override in Mwei/gas used to compute the order provision (see also offer bounties). Any value lower than Mangrove's current gasprice will be ignored (thus 0 means "use Mangrove's current gasprice"). Must fit in 26 bits.

newOfferByTick(olKey, tick, gives, gasreq, gasprice)​

  • tick: the desired "price" tick of the offer. The actual tick of the offer will be the smallest tick offerTick > tick that satisfies offerTick % tickSpacing == 0.

newOfferByVolume(olKey, wants, gives, gasreq, gasprice)​

  • wants: the amount of inbound tokens requested by the offer. Must fit in 127 bits and be strictly positive.
    • The ratio wants/gives (rounded down) specifies the desired "price" ratio and thus tick.

Outputs​

  • offerId the id of the newly created offer. Note that offer ids are scoped to offer lists, so many offers can share the same id if they belong to different offer lists.
Provisioning

Since offers can fail, Mangrove requires each offer to be provisioned in native token. If an offer fails, part of that provision will be sent to the caller that executed the offer, as compensation.

Make sure that your offer is well-provisioned before calling newOffer*, otherwise the call will fail. The easiest way to go is to send a comfortable amount of native token to Mangrove from your offer-posting contract. Mangrove will remember your balance and use it when necessary.

Offer execution
  • If the offer account is a contract, it should implement the IMaker interface. At the very least, it must have a function with signature makerExecute(MgvLib.SingleOrder calldata order) or it will systematically revert when called by Mangrove.
  • gives and gasreq are subject to density constraints on the amount of outbound token provided per gas spent.
  • The offer account will need to give Mangrove a high enough allowance in outbound tokens since Mangrove will use the ERC20 standard's transferFrom function to source your tokens.

Updating an existing offer​

As for newOffer, offers on Mangrove can be updated in two ways which differ in how the "price" (ratio) is specified:

  • updateOfferByTick: The "price" is specified as a tick.
  • updateOfferByVolume: The "price" is specified as the ratio between two volumes, wants/gives.

The *ByVolume variant is a convenience wrapper for the *ByTick variant: The provided volumes are converted to a corresponding tick.

The output from the two functions is the same.

info

Both functions are payable and can be used to credit the maker contract's balance on Mangrove on the fly. A non-zero msg.value will allow Mangrove to credit the maker's balance prior to locking the provision of the updated offer.

function updateOfferByTick( 
OLKey memory olKey,
Tick tick,
uint gives,
uint gasreq,
uint gasprice,
uint offerId
) external payable;

function updateOfferByVolume(
OLKey memory olKey,
uint wants,
uint gives,
uint gasreq,
uint gasprice,
uint offerId
) external payable;

Inputs​

  • offerId is the offer id of the offer to be updated.
  • All other parameters are the same as newOfferByTick and newOfferByVolume - see above.

Outputs​

None.

Offer updater

An offer can only be updated if msg.sender is the account that created the offer.

Reusing offers

After being executed or retracted, an offer is moved out of the offer list. It can still be updated and reinserted in the offer list. It is generally recommended to update offers instead of creating new ones, as it costs much less gas.

Retracting an offer​

An offer can be withdrawn from the order book via the retractOffer function described below.

function retractOffer(
OLKey memory olKey,
uint offerId,
bool deprovision
) external returns (uint provision);

Inputs​

  • olKey: identifies the offer list, see details above.
  • offerId: is the id of the offer to be retracted.
  • deprovision: if true, will free the offer's provision so that you can withdraw them. Otherwise, will leave the provision in the offer.

Outputs​

  • provision: amount of native token deprovisioned for the offer (in wei).
Note

The withdraw(amount) function can be used to withdraw the funds after deprovisioning.