Offer Provisions

Overview

When an offer fails, the taker (caller) consumes gas during execution. To compensate them, Mangrove pays a bounty in native tokens (e.g., ETH).

To ensure this compensation is possible, each offer must lock a provision, an amount of native tokens held by Mangrove on behalf of the offer’s maker.

Key Points

  • Each maker contract has a native token balance managed by Mangrove.

  • The maker’s balance is adjusted whenever offers are created, updated, or retracted.

  • If an offer fails, part (or all) of its provision is paid as a bounty to the taker.

  • The remaining provision is credited back to the maker’s Mangrove balance.

Funding an offer

function fund(address maker) public payable;

You can credit a maker contract’s balance on Mangrove in three ways:

  1. Call fund(address maker) directly.

  2. Send native tokens to Mangrove’s fallback function.

  3. Pay on the fly when creating or updating an offer.

Example

import {IMangrove} from "@mgv/src/IMangrove.sol";

//context 
// IMangrove mgv = IMangrove(payable(<address of Mangrove>));
IMangrove mgv = IMangrove(payable(mgv)); // Mangrove contract
address maker_contract; // address of the maker contract one is willing to provision

// funding maker_contract
mgv.fund{value: 0.1 ether}(maker_contract);

// if funding oneself one can use the overload:
mgv.fund{value: 0.1 ether}();
// which is equivalent to `msg.fund{value:0.1 ether}(address(this))

// to avoid erreoneous transfer of native tokens to Mangrove, the fallback function will also credit `msg.sender`:
(bool noRevert,) = address(mgv).call{value: amount}("");
require(noRevert, "transfer failed");

Inputs

maker — Address of the maker credited with msg.value on Mangrove.

Danger: Do not use send or transfer to fund Mangrove. Mangrove’s receive and fund functions perform storage writes, which require more gas than send/transfer allow.

Outputs

None.

Events

// Offer Maker at address `maker` has been credited of `amount` wei
event Credit(address maker, uint amount);

Emitted when a maker’s account on Mangrove is credited with native tokens.

Error Codes

Code
Meaning

"mgv/dead"

The Mangrove contract is no longer live.

Checking an Account Balance

function balanceOf(address maker) external view returns (uint balance);

Inputs

  • maker — is the account of which you want to read the balance.

Outputs

  • balance — is the available balance of maker.

Withdrawing Funds

function withdraw(uint amount) external returns (bool noRevert);

At any time, your available balance can be withdrawn. It may be less than what you deposited: Your balance adjusts every time you create/update/retract an offer.

Example

import {IMangrove} from "@mgv/src/IMangrove.sol";

//context 
// IMangrove mgv = IMangrove(payable(<address of Mangrove>));
IMangrove mgv = IMangrove(payable(mgv)); // Mangrove contract

uint wei_balance = mgv.balanceOf(address(this));
require(mgv.withdraw(wei_balance), "Mangrove failed to transfer funds");

Inputs

amount — The amount of native token (in wei) to withdraw from Mangrove.

Outputs

noRevert — Indicates whether the withdrawal succeeded.

Events

event Debit(address maker, uint amount);

Emitted when a maker withdraws funds from Mangrove.

Error Codes

Code
Meaning

"mgv/insufficientProvision"

Attempted to withdraw more than available balance.

Important Notes

  • The account credited on withdrawal is always msg.sender.

  • amount must be ≤ your available balance (see balanceOf).

  • Your balance may fluctuate automatically as offers are posted, updated, or retracted.

Provision calculation

Mangrove requires a provision (in wei) for every active offer, ensuring sufficient funds are available to pay a bounty if the offer fails.

provision=max(gaspricemgv,gaspriceofr)×(gasreq+gasbasemgv)×106\textrm{provision} = \max(\textrm{gasprice}_{\textrm{mgv}},\textrm{gasprice}_{\textrm{ofr}}) \times (\textrm{gasreq} + \textrm{gasbase}_{\textrm{mgv}}) \times 10^6
Variable
Description

gaspricemgv\textrm{gasprice}_{\textrm{mgv}}

Global gas price set by Mangrove governance (Mwei per gas).

gaspriceofr\textrm{gasprice}_{\textrm{ofr}}

Offer-specific gas price parameter (Mwei per gas).

gasreq\textrm{gasreq}

Gas required to execute the offer logic.

gasbasemgv\textrm{gasbase}_{\rm mgv}

Local governance parameter representing Mangrove’s overhead.

Behavior on Offer Updates

When an offer is created or updated, Mangrove recalculates its provision and adjusts the maker’s balance:

  • If more provision is required, Mangrove debits the maker’s balance.

  • If less is required (e.g., gas price dropped), the balance is credited.

This ensures that the offer always has enough locked funds to pay a bounty if it fails.

Optimization Tip

If you frequently update offers:

  • Use a consistent, high gasprice argument above expected real gas prices.

  • Avoid changing gasprice unnecessarily to reduce storage costs (SSTORE).

Bounty Calculation

If an offer fails, the taker receives a bounty in native tokens as compensation for gas spent.

bounty=min(offer.provision,(gasused+gasbasemgv)×gaspricemgv×106)\textrm{bounty} = \min(\textrm{offer.provision},(\textrm{gasused} + \textrm{gasbase}_{\textrm{mgv}}) \times \textrm{gasprice}_{\textrm{mgv}} \times 10^6)
Variable
Description

offer.provision\textrm{offer.provision}

Provision amount locked when the offer was posted.

offer.provision\textrm{offer.provision}

Actual gas consumed during offer execution before failure.

gasbasemgv\textrm{gasbase}_{\textrm{mgv}}

Local governance gas base.

gaspricemgv\textrm{gasprice}_{\textrm{mgv}}

Mangrove’s global gas price at time of execution.

Thus the bounty is capped at the offer's original provision.

Last updated