• Development Details
  • Protocol

Davos Protocol Development Details

The key components of Davos's functions lie between a set of smart contracts that interact across blockchains and existing contracts. Davos created its customized smart contracts based on a fork of the MakerDAO smart contract set.

Modules

Davos consists of 2 main modules:

  • The core module (a MakerDAO fork and Davos's Interaction contract) — provide collateral, borrow DUSD, repay DUSD, withdraw collateral, liquidate collateralized assets.
  • The rewards module — claim rewards in DGT.

Requirements

The minimum amount to borrow:

  • On Arbitrum — 100 DUSD
  • On BNB Smart Chain — 50 DUSD
  • On Ethereum — 300 DUSD
  • On Optimism — 100 DUSD
  • On Polygon — 50 DUSD

Liquidation incentive:

  • On Polygon — $5 (tip) + 0 (chip).
  • On Ethereum — $10 (tip) + 0.01% of the liquidated amount (chip).

Supported networks

  • Arbitrum
  • BNB Smart Chain
  • Ethereum
  • Optimist
  • Polygon

Supported collateral

ℹ️

MATIC collateral support is discontinued. You cannot create new MATIC positions or borrow DUSD on existing ones. Previous borrows are still valid, you can keep them or repay and withdraw MATIC.

  • On Arbitrum:
    • ankrETH
    • rETH
    • stEUR
    • wstETH
  • On BNB Smart Chain:
    • ankrBNB
    • vUSDC
    • vUSDT
  • On Ethereum:
    • ankrETH
    • rETH
    • sDAI
    • sfrxETH
    • swETH
    • wstETH
  • On Optimism:
    • rETH
    • wstETH
  • On Polygon:
    • stMATIC
  • On Polygon zkEVm:
    • ankrETH
    • rETH
    • wstETH

Fees

  • Borrowing rate paid to Davos for borrowing DUSD (fixed number set by the Davos governance):
    • On Arbitrum — 5.25%.
    • On BNB Snart Chain — 5.25%.
    • On Ethereum — 5.25%.
    • On Optimism — 5.25%.
    • On Polygon — 5.25%.
  • Liquidation penalty added to the user's debt in a Dutch auction during the liquidation process (fixed by the Davos governance):
    • On Arbitrum — 10% of the debt.
    • On BNB Snart Chain — 10% of the debt.
    • On Ethereum — 10% of the debt.
    • On Optimism — 10% of the debt.
    • On Polygon — 10% of the debt.

Ratios

Collateral ratio — a percentage of the user's collateral value that determines the maximum borrowing limit for the user. If the loan reaches the collateral ratio, the loan may get liquidated. The collateral ratio is:

  • For vUSC and vUSDT — 93% of the deposited collateral value.
  • For every other supported token — 66% of the deposited collateral value.

Rewards

  • The borrowing reward — users get rewards for borrowing DUSD, in DGT — the Davos governance token. Rewards are calculated dynamically and are the product of the rewards rate and the total user’s debt in DUSD. The rewards rate is a fixed amount set by Davos.
  • The auction start reward — anybody who triggers the liquidation event of a CDP, i.e., start of a Dutch auction, receives a flat fee (tip) and a percentage fee (chip) for just initiating the process. The tip and chip are paid by Davos from the Davos reserves.
  • The auction restart reward — anybody who restarts the Dutch auction, which is part of the liquidation process, receives a flat fee (tip) and a percentage fee (chip). An EOA can restart the auction when the auction time limit is reached or the price decrease has reached a certain threshold. These two limits are set by the Davos governance. The tip and chip are paid by Davos from Davos reserves.

Liquidation Model

The liquidation model is best described by the following example (correct for both Polygon and Ethereum):

Step/VariableValue
Price of 1 unit of collateral$2
Liquidation ratio66%
Price of collateral with liquidation ratio$1.32
User deposits 10 units of collateral10 * 2 = $20
Borrow limituser_deposit * liquidation_ratio = 20 * 0.66 = $13.2
User borrows $13 of DUSD13 DUSD
Price of 1 unit of collateral decreases and now is$1.8
Collateral unit price, with safety margin_current_price_of_collateral_unit * liquidation_ratio = 1.8 * 0.66 = $1.188
Current worth of collateral, with safety marginprice_of_colatteral_with_safety_margin * amount_of_collateral = 1.188 * 10 = $11.88
Trigger for liquidationborrowed_amount - current_worth_of_colateral = 13 - 11.88 = $1.12, which is >$0
Somebody starts a Dutch auction to liquidate the collateral.
Starter is sent tip + chip as a reward for it, from Davos reserves
5 + (14.69 * 0) = $5
User collateral that goes to Dutch auction10 units
chop (liquidation penalty; fixed by Davos governance)10% of the debt
Debt to cover in the auctionborrowed_amount * liquidation_penalty = 13 * 1.13 = $14.69
buf (percentage added to the price of collateral at the start/reset of the Dutch auction, fixed by the Davos governance)10%
top (start auction price of 1 unit of collateral)current_price_of_collateral_unit * buf = 1.8 + (1.8 * 0.18) = $2.124
Auction starts and price gradually decreases.
Anybody can come and buy any amount of the liquidated collateral
tau (time in seconds until price is 0; fixed by Davos governance)21600
dur (time in seconds elapsed since the auction start; fixed by Davos governance)e.g. 600
Linear decrease of price of 1 unit of collateraltop * ((tau - dur) / tau) = 2.124 * ((21600 - 600) / 21600) = $2.065 after 600s of the auction
Somebody restarts the auction based on:
tail (specific amount of time elapsed; fixed by Davos governance)
OR
cusp (% of price drop; fixed by Davos governance)
— no tail is currently used
— 40% of top = 1.98 * 0.40 = $0.792
tip (flat fee given as a reward to auction starter/restarter; fixed by Davos governance)5 DUSD
chip (dynamic fee given as a reward to auction starter/restarter; fixed by Davos governance)0
Restarter is sent tip + chip as a reward, from Davos reserves5 + (14.69 * 0) = $5

Smart Contracts

As a multi-chain version, Davos has its contracts deployed in every supported network:

  • Arbitrum Mainnet/Goerli
  • BNB Smart Chain Mainnet/Testnet
  • Ethereum Mainnet/Goeli
  • Optimism Mainnet/Goerli
  • Polygon Mainnet/Mumbai
  • Polygon zkEVM Mainnet
ℹ️

The smart contracts that implement Davos are:

  • MakerDAO set — the Maker Protocol, also known as the Multi-Collateral Dai (MCD) system, allowing users to generate DUSD by leveraging collateralized assets. DUSD is a decentralized, unbiased, collateral-backed cryptocurrency soft-pegged to the US Dollar.
    • ABACI — price decrease function for Dutch auctions during the liquidation process of user's assets.
    • CLIP — Dutch auction v2.0 mechanics.
      • CLIP (MVT_ceMATIC) — mechanics for MATIC on Polygon.
      • CLIP (MVT_rETH) — mechanics for rETH on Ethereum.
      • CLIP (MVT_sfrxETH) — mechanics for sfrxETH on Ethereum.
      • CLIP (MVT_stMATIC) — mechanics for stMATIC on Polygon.
      • CLIP (MVT_wstETH) — mechanics for wstETH on Ethereum.
    • DOG — starts Dutch auctions during the liquidation process of user's assets.
    • DUSD — stablecoin DUSD users can borrow from Davos.
    • gemJoin — ERC-20 token adapters.
      • DavosJoin — adapter for connecting DUSD and Davos.
      • gemJoin (MVT_ceMATIC) — adapter for connecting the MATIC collateral and Davos.
      • gemJoin (MVT_rETH) — adapter connecting rETH collateral and Davos (entry point for collateral).
      • gemJoin (MVT_sfrxETH) — adapter connecting sfrxETH collateral and Davos (entry point for collateral).
      • gemJoin (MVT_stMATIC) — adapter connecting stMATIC collateral and Davos (entry point for collateral).
      • gemJoin (MVT_wstETH) — adapter connecting wstETH collateral and Davos (entry point for collateral).
    • JUG — collects Davos's borrowing interest for lending DUSD to the user.
    • SPOT — oracle that fetches the price of ankrMATIC, which is an intermediate token used during the process of collateralizing user's assets.
    • VAT — сore vault for collateralized debt positions (CDP).
    • VOW — vault balance sheet. Keeps track of debt or surplus of DUSD.
  • ankrMATIC — liquid yield-bearing token used during the process of collateralizing user's assets.
  • AuctionProxy — entrypoint for Dutch auction methods, which is part of the liquidation process of user's assets. Allow users to start and participate in auctions.
  • cerosRouter — finds the best way to obtain ankrMATIC, which is an intermediate token used during the process of collateralizing user's assets.
  • cerosYieldStrategy — deposits and withdraws wMATIC into yeildConverter; generates yield for Davos.
  • CeVault — stores obtained ankrMATIC, which is an intermediate token used during the process of collateralizing user's assets.
  • DavosBridge — external cross-chain bridge that is deployed on the corresponding chains and linked together (Warp Token is the name to recognize our token). Davos needs to give the bridge the right to mint and burn. Warp token is not a real token, it burns on origin chain and mints on destination chain.
  • DavosOracle — oracle for the DUSD rewards token.
  • DavosProvider — wraps assets and/or sends assets to masterVault.
    • DavosProvider — wraps assets or sends ERC-20 to masterVault on Polygon.
    • DavosProvider (rETH) — sends rETH to masterVault on Ethereum.
    • DavosProvider (sfrxETH) — sends sfrxETH to masterVault on Ethereum.
    • DavosProvider (wstETH) — sends wstETH to masterVault on Ethereum.
  • DGTRewards — rewards distribution, in the DGT rewards token.
  • DGTToken — ERC-20 compatible rewards token DGT given to the user for borrowing DUSD.
  • dMATIC — token minted for the user as a deposit receipt for their collateral.
    • dMATIC (MVT_ceMATIC) — deposit receipt for MATIC.
    • dMATIC (MVT_rETH) — deposit receipt for rETH.
    • dMATIC (MVT_sfrxETH) — deposit receipt for sfrxETH.
    • dMATIC (MVT_wstETH) — deposit receipt for wstETH.
  • Interaction — proxy for the MakerDAO contracts. Provides deposit, withdraw, borrow, payback, and liquidation functions to the end users.
  • Jar — staking contract for the DUSD Redistribution Rate and for redistribution rewards (given in the DUSD token).
  • Oracle — returns the current price of collateral.
    • Oracle (MVT_ceMATIC) — returns the price of MATIC on Polygon.
    • Oracle (MVT_rETH) — returns the price of rETH on Ethereum.
    • Oracle (MVT_sfrxETH) — returns the price of sfrxETH on Ethereum.
    • Oracle (MVT_stMATIC) — returns the price of stMATIC on Polygon.
    • Oracle (MVT_wstETH) — returns the price of wstETH on Ethereum.
  • masterVault — accepts deposits, mints and burns the token that represents the collateral inside Davos.
    • masterVault (MVT_ceMATIC) — wraps MATIC into wMATIC on Polygon; mints or burns ceMATIC, which is the underlying collateral token inside Davos.
    • masterVault (MVT_rETH) — accepts rETH deposits on Ethereum; mints or burns shares (MVT_rETH), which is the underlying collateral token inside Davos.
    • masterVault (MVT_sfrxETH) — accepts sfrxETH deposits on Ethereum; mints or burns shares (MVT_rETH), which is the underlying collateral token inside Davos.
    • masterVault (MVT_stMATIC) — accepts stMATIC deposits on Polygon; mints or burns shares (MVT_stMATIC), which is the underlying collateral token inside Davos.
    • masterVault (MVT_wstETH) — accepts wstETH deposits on Ethereum; mints or burns shares (MVT_wstETH), which is the underlying collateral token inside Davos.
  • swapPool — swaps wMATIC for ankrMATIC if this option is cheaper than exchanging on DEX.
  • waitingPool — keeps track of pending MATIC withdraw requests and fulfills them when liquidity becomes available.

Workflow

Here are the main Davos's operations described in high-level detail.

Providing Collateral

We are going to use stMATIC as an example:

  1. User transfers stMATIC to Davos via DavosProvider::provide({value: amount}).
  2. DavosProvider mints dMATIC for the user as a deposit receipt for their collateral.
  3. DavosProvider gets MVT_stMATIC, running the following logic inside:
    1. Deposit the user's stMATIC to masterVault via masterVault::depositETH({value: amount).
    2. masterVault mints MVT_stMATIC for DavosProvider.
    3. masterVault wraps stMATIC minting wMATIC.
    4. masterVault manager triggers the masterVault::allocate() to deposit the wMATIC to cerosYieldStrategy based on the strategy allocation.
    5. cerosYieldStrategy forwards wMATIC to cerosRouter which exchanges wMATIC for ankrMATIC through the cheapest swapping option (on DEX or via swapPool), via cerosRouter::depositwMatic(amount).
    6. cerosRouter sends the obtained ankrMATIC to CeVault for storing, via CeVault::depositFor(msg.sender, amount after exchange). msg.senderDavosProvider address and amount after exchange — the amount of exchanged ankrMATIC.
  4. DavosProvider collateralizes MVT_stMATIC via Interaction::deposit(account, address(MVT_stMATIC), amount). account — user's account address, address(MVT_stMATIC) — address of MVT_stMATIC smart contract, amount — stMATIC initially collateralized by the user. Interaction runs the following logic inside:
    1. Transfers MVT_stMATIC, which is an ERC-20 token, to the Interaction smart contract, via the transfer() function of the ERC-20 token smart contract.
    2. Transfers the assets to the MakerDAO vault via gem::join(). For more information, refer to the Join docs.
    3. Makes the VAT smart contract fully trust the Interaction smart contract via VAT::behalf().
    4. Locks the assets inside MakerDAO via VAT::frob(), effectively collateralizing them. For more information, refer to the VAT docs.
    5. Emits a deposit event.

Collateralize LSTs to Borrow DUSD on Ethereum

The workflow stays the same for the LSTs accepted on Polygon and Ethereum as collateral.

  1. User transfers wstETH to Davos via DavosProvider::provide({value: amount}).
  2. DavosProvider mints dMATIC for the user as a deposit receipt for their collateral.
  3. DavosProvider gets MVT, running the following logic inside:
    1. Deposit the user's wstETH to masterVault via masterVault::depositETH({value: amount).
    2. masterVault mints MVT for DavosProvider. The minting ratio is not 1:1 because of the growing value of reward-bearing LSTs.
  4. DavosProvider collateralizes MVT via Interaction::deposit(account, address(MVT_stMATIC), amount). account — user's account address, address(MVT) — address of MVT smart contract, amount — wstETH initially collateralized by the user. Interaction runs the following logic inside:
    1. Transfers MVT, which is an ERC-20 token, to the Interaction smart contract, via the transfer() function of the ERC-20 token smart contract.
    2. Transfers the assets to the MakerDAO vault via gem::join(). For more information, refer to the Join docs.
    3. Makes the VAT smart contract fully trust the Interaction smart contract via VAT::behalf().
    4. Locks the assets inside MakerDAO via VAT::frob(), effectively collateralizing them. For more information, refer to the VAT docs.
    5. Emits a deposit event.

Borrow DUSD

  1. Borrow DUSD via Interaction::borrow(). After the transaction is sent, Interaction runs the following logic inside:
    1. Calculate the current DUSD value inside MakerDAO, fed via the Chainlink price feed. While calculating take into consideration the borrowing limit, which is the price of the assets collateralized by the user * loan-to-value ratio (fixed amount set by Davos governance).
    2. Indebt the user equal to the borrowed DUSD amount via VAT::frob(). For more information, refer to the VAT docs.
    3. Transfer the borrowed DUSD via gemJoin::exit(). For more information, refer to the Join docs.
    4. Emit a borrow event.

Bridge DUSD

There are two instances of Davos Protocol — on Ethereum and Polygon.
Also, two bridge contract instances — the same networks.
And two DUSD token contracts, independent of each other in terms on supply, i.e., when bridged, tokens on the source network are burned, and tokens on the destination network are minted.

  1. Before bridging, the user approves the amount to bridge by calling approve(address usr, uint wad) at the DUSD contact.
  2. To bridge from Ethereum to Polygon, the user calls depositToken(address fromToken, uint256 toChain, address toAddress, uint256 amount) at the Ethereum bridge contract. The Ethereum bridge contract burns the approved amount and emits a burn event.
  3. Based on the transaction, our authorized consensus address creates a proof and signature. The output is [encodedProof, rawReceipt, proofSignature, proofHash].
  4. The backend then calls withdraw(bytes calldata, /* encodedProof */ bytes calldata rawReceipt, bytes memory proofSignature) at the Polygon bridge network.
  5. The Polygon bridge network then calls mint(address usr, uint wad) at the DUSD contract.

Repay DUSD

ℹ️

As Davos is testing its multi-chain now on Devnet, there is goign to be a catch settling your debt once the multichain version Mainnet.
The catch is you can use DUSD on any network to settle your debt on this network only if you have a debt on it.
E.g., if you borrowed 10 DUSD on Ethereum and then bridged them to Polygon, you’re indebted on Ethereum only and not on Polygon. So, you cannot, in this case, settle your debt on Polygon and have to bridge 10 DUSD to Ethereum to do it.
However, if you borrowed 10 DUSD on Ethereum and then bridged them to Polygon, and then borrowed 5 more DUSD on Polygon, you now have 15 DUSD on Polygon and can settle your 5 DUSD debt there.

  1. Repay Davos the borrowed DUSD via Interaction::payback(). After the transaction is sent, Interaction runs the following logic inside:
    1. Transfer the DUSD to the Interaction smart contract, via the transfer() function of the ERCs-20 token smart contract.
    2. Transfer the DUSD to the MakerDAO vault via DavosJoin::join(). For more information, refer to the Join docs.
    3. Calculate the current DUSD value inside MakerDAO, fed via the Chainlink price feed.
    4. Subtract the repaid DUSD amount from the user’s debt via VAT::frob(). For more information, refer to the VAT docs.
    5. Emit a payback event.

Withdraw Collateral

  1. User makes a withdrawal request via DavosProvider::release(recipient, amount).
  2. DavosProvider requests MVT_stMATIC to be sent to masterVault via Interaction::withdraw(account, address(MVT_stMATIC), amount). account — user's account address, address(MVT_stMATIC) — address of MVT_stMATIC smart contract, amount — stMATIC initiallly collateralized by the user. Interaction runs the following logic inside:
    1. Unlock the assets via VAT::frob(). For more information, refer to the VAT docs.
    2. Transfer the assets from the CDP engine to the MakerDAO vault via VAT::flux(). For more information, refer to the VAT docs.
    3. Transfer the assets to the user’s wallet via gem::exit(). For more information, refer to the Join docs.
  3. DavosProvider request stMATIC from masterVault.
  4. masterVault checks if the amount is available in masterVault contract. If yes, masterVault burns MVT_stMATIC and sends the stMATIC to DavosProvider, and DavosProvider burns the dMATIC. I no, masterVault withdraws the stMATIC through cerosYieldStrategy , sends it to DavosProvider, and DavosProvider burns the sMATIC; if no liquidity cerosYieldStrategy, masterVault submits the withdraw request to waitingPool, DavosProvider still burns the sMATIC, and next time anyone deposits stMATIC, masteVault fulfills the withdraw request sending stMATIC to waitingPool, and waitingPool sends MATIC further to the user.

Claim Rewards

  1. For borrowing DUSD, claim rewards in DGT to the user’s wallet, via DGTRewards::claim(). After the transaction is sent, DGTRewards runs the following logic inside:
    1. Update the rewards pool size and rewards rate.
    2. Transfer the pending user rewards to the user’s wallet via DGTToken::transfer().

Liquidation

  1. When the current worth of collateral (obtained from the Chainlink price feed) with safety margin < borrowed amount of DUSD, the liquidation process can be triggered by anybody via Interaction::startAuction(token, user, keeper), where token — address of the liquidated assets, user — address of user whose collateral is being liquidated, keeper — address of the user who gets a reward (tip + chip) for starting the auction. Then Interaction runs the following logic inside:
    1. Start a Dutch auction:
      1. Set the starting auction price for the liquidated collateral to be equal (current_collaterral_unit_price * buf).
      2. Let anybody come and buy via buyFromAuction(token, auctionId, collateralAmount, maxPrice, receiverAddress) to buy any amount > than dust (currently 50 DUSD on Polygon and 300 DUSD on Ethereum). token — address of the liquidated assets, auctionId — ID of the auction, collateralAmount — amount to buy, maxPrice — price to pay , receiverAddress — address of the buyer.
      3. If the maxPrice is > current_ auction_collateral_unit_price, sell the requested amount of the user's collateral to the buyer.
      4. Else, incrementally lower the auction price and let anybody buy still. The reason for decreasing from a higher price is because of bots and change of collateral price from oracle to avoid any sudden loss. The auction lasts a fixed amount of time (tau) set by Davo governance. The price is recalculated every second of the auction.
      5. When the auction time limit is reached or the price decrease has reached a certain threshold (the limits are set by Davos governance; currently 40%), let anybody come and restart the auction and get tip+chip for doing it.
    2. Transfer the price paid in #1.3, in DUSD, from the buyer's wallet to Davos.
    3. Exchange MVT_stMATIC for ankrMATIC and send ankrMATIC to the buyer's wallet. Effectively, buyer buys ankrMATIC that they can later exchange for stMATIC.
    4. Cover debt and keep profit (borrowed amount + (borrowing interest + liquidation penalty)).
    5. Calculate the remainder (price paid - debt - profit). Send the remainder to the user’s wallet.