Mangrove
Mangrove
Mangrove
  • START HERE
    • What is Mangrove?
      • Smart offers
      • Bounty
      • Makers, Takers, Keepers
        • Makers
        • Takers
        • Keepers
    • Why Mangrove?
    • Who is the Mangrove dApp for?
    • Audits
    • FAQ
    • Glossary
    • Terms & Conditions
  • Strategies
    • Kandel
      • What is Kandel?
      • How does Kandel Work?
        • Step-by-step visual explanation
        • Parameters
        • Choosing Kandel parameters
        • Published Liquidity
        • More on failing offers
      • Potential risks
  • DAPP GUIDE
    • Swap
    • Trade
      • How to make an order
        • Market Order
        • Limit Order
        • Amplified Order
        • More on order types
      • Approvals
      • Minimum Volume
      • How to Track and Manage Orders
    • Earn
    • Rewards
    • Bridge
    • Wrap
  • MGV INCENTIVES
    • Fee Rewards
      • How the programs Work
      • Current programs
    • Vault LP programs
      • How the Programs Work
      • Current programs
      • Earning rewards
      • Example
      • Previous programs
    • MS2 Program (closed)
      • How Rewards Are Calculated
        • Reward Rate ρ
        • Takers Rewards
        • Adjusted Volume for Makers
        • How to Maximize Your Score
      • MGV Token Allocation per User Type
        • Specific Allocation for Kandel users and vault managers
        • Community Contributors
        • Incentives with a custom strategy
      • Epochs and Updates
    • MS1 Program (closed)
      • Intro
      • Trading Points
      • Boost
      • Referral Points
      • Community Points
      • Parameters
      • Technical Insights
      • MS1 FAQ
      • Disclaimer
  • Governance
    • General Governance
      • Key Stakeholders
        • Token Holders
          • Builders
        • Builders
        • Pods
      • Guardians
      • Governance Process
        • Initial Discussions
        • Proposals
        • Voting
        • Execution
    • Councils
      • Responsibilities
      • Elections
      • Budgets
    • Guides and resources
      • How to vote on a governance proposal
      • How to delegate my voting power
      • How to access the Builders’ directory
      • How to access the Pods’ directory
      • Snapshot configuration & membership
      • Links and adresses
  • QUICK LINKS
    • Whitepaper
    • Website
    • Feedback
    • Blog
    • GitHub
    • X
    • Discord
    • Telegram
    • Deployment adresses
Powered by GitBook
On this page
  • Summary
  • Balance funding & withdrawal
  • Funding an offer
  • Checking an account balance
  • Withdrawing
  • Balance adjustment when creating/updating offers
  • Provision and offer bounty
  1. Contracts
  2. Technical references
  3. Taking and making offers
  4. Creating & Updating offers

Offer provisions

How taker compensation for failing offers works.

Last updated 2 years ago

Summary

When an offer fails, the caller has wasted some gas. To compensate the caller, Mangrove gives them a bounty in native tokens. Offers must provision enough ethers to maximize the chances that Mangrove can compensate the caller. In more details:

  • Every offer logic that posted an offer has a balance in ethers held by Mangrove. Funds can be freely added to or withdrawn from the balance.

  • Whenever the logic creates or updates an offer, its balance is adjusted so that enough native tokens are locked as the offer's provision.

    • If the offer is retracted that provision is credited back to the logic's account balance.

    • If the offer is executed and fails, part or all of the provision is sent as compensation, to the caller. We call that the bounty. The rest of the provision is credited back to the offer logic's account balance.

Balance funding & withdrawal

Funding an offer

There are three ways an offer logic can credit its balance on Mangrove. (1) The logic may either call the fund function, or (2) make a call to the fallback function with some value, or (3) pay on the fly when a .

function fund(address maker) public payable;
// Offer Maker at address `maker` has been credited of `amount` wei
event Credit(address maker, uint amount);
"mgv/dead" // Mangrove contract is no longer live
fund.sol
import "src/IMangrove.sol";
//context 
IMangrove mgv; // Mangrove contract address
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");
fund.js
const { ethers } = require("ethers");
//context
let MGV; // address of Mangrove
let MGV_abi; // Mangrove contract's abi
let maker_contract_address; // address of the Maker Contract

const Mangrove = new ethers.Contract(
    MGV, 
    MGV_abi, 
    ethers.provider
    );

let overrides = { value: ethers.parseUnits("0.1", 18) };
// provisioning Mangrove on behalf of MakerContract
await Mangrove["fund(address)"](maker_contract_address, overrides);

Inputs

  • maker the offer logic's balance on Mangrove to credit

Do not use send or transfer to credit Mangrove

Upon receiving funds, Mangrove will credit the amount sent to maker (or msg.sender if the receive function was called). This involves writing to storage, which consumes more gas than the amount given by send and transfer.

Checking an account balance

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

Inputs

  • who The account of which you want to read the balance.

Outputs

  • balance The available balance of who.

Withdrawing

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 an offer.

function withdraw(uint amount) external returns (bool noRevert);
event Debit(address maker, uint amount);
// Trying to withdraw unavailable funds
"mgv/insufficientProvision"
import "src/IMangrove.sol";
//context 
IMangrove 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 ethers (in wei) one wishes to withdraw from Mangrove's provisions.

Outputs

  • noRevert whether the ether transfer was successful.

Important points

  • The account credited will be msg.sender.

  • amount must be ≤\leq≤ your available balance (available with balanceOf)

Balance adjustment when creating/updating offers

Whenever an offer is created or updated, Mangrove applies to following formula to get the offer's required provision in wei:

provision=max⁡(gaspricemgv,gaspriceofr)×(gasreq+gasbasemgv)×109\textrm{provision} = \max(\textrm{gasprice}_{\textrm{mgv}},\textrm{gasprice}_{\textrm{ofr}}) \times (\textrm{gasreq} + \textrm{gasbase}_{\textrm{mgv}}) \times 10^9provision=max(gaspricemgv​,gaspriceofr​)×(gasreq+gasbasemgv​)×109​

  • gasreq\textrm{gasreq}gasreq is the gasreq argument of the function being called (in gas units).

Mangrove will adjust the balance of the caller to ensure that provision\textrm{provision}provision wei are available as bounty if the offer fails. If the offer was already provisioned, the adjustment may be small, and the balance may actually increase -- for instance, if the gasprice dropped recently.

Incentivized book cleaning

Provisions are calculated so that, within reasonable gas estimates, taking a failing offer should be profitable for the taker.

Gas optimization

If you frequently update your offers, we recommend using a consistent, high gasprice argument, above the actual expected gas prices. Not changing gasprice when you call updateOffer will make the call cheaper (you save one SSTORE).

Provision and offer bounty

getProvision.sol
import "src/IMangrove.sol";
import {MgvStructs} from "src/MgvLib.sol";
//context 
IMangrove mgv;
address outbound_tkn;
address inbound_tkn;
uint offer_gasreq;
(MgvStructs.GlobalPacked global32, MgvStructs.LocalPacked local32) = mgv.config(outbound_tkn, inbound_tkn);

// computing minimal provision to cover an offer requiring `offer_gasreq` gas units 
uint provision = (offer_gasreq + local32.offer_gasbase()) * global32.gasprice() * 10 ** 9;
getProvision.js
const { ethers } = require("ethers");
let outTkn; // address of outbound token ERC20
let inbTkn; // address of inbound token ERC20
let MGV_reader_address; // address of Mangrove reader
let MGV_reader_abi; // Mangrove Reader contract's abi

const MangroveReader = new ethers.Contract(
    MGV_reader_address, 
    MGV_reader_abi, 
    ethers.provider
    );

const ofr_gasreq = ethers.parseUnits("1",5); //100,000 gas units
const bounty = await MangroveReader.getProvision(outTkn, inbTkn, ofr_gasreq,0);

Applied bounty

Suppose an offer requires gofrg_{\mathsf{ofr}}gofr​​ gas units to execute. As explained above, Mangrove will require the logic posting the offer to provision β\betaβ WEI. Suppo se the offer is executed during a Taker Order and fails after gusedg_{\mathsf{used}}gused​gas units (gused<gofrg_\mathsf{used}<g_\mathsf{ofr}gused​<gofr​). The portion of the bounty that will be transferred to the Offer Taker's account is G˙∗(g˙0/n+g˙1+gused)\dot G*(\dot g_0/n+\dot g_1+g_\mathsf{used})G˙∗(g˙​0​/n+g˙​1​+gused​) where G˙\dot GG˙​, g˙0\dot g_0g˙​0​, nnn and g˙1\dot g_1g˙​1​are respectively the global.gasprice, local.overhead_gasbase, the number of offers executed during the take order, and the local.offer_gasbase values at the time the offer is taken (which may differ from their values at the time the offer was posted, as a consequence of some parameter changes by the governance).

gaspricemgv\textrm{gasprice}_{\textrm{mgv}}gaspricemgv​ is the gasprice (in gwei per gas units)

gaspriceofr\textrm{gasprice}_{\textrm{ofr}}gaspriceofr​ is the gasprice argument of the function being called ( or ) also in gwei per gas units.

gasbasemgv\textrm{gasbase}_{\rm mgv}gasbasemgv​is the offer_gasbase .

local governance parameter
global governance parameter
new offer is posted
newOffer
updateOffer