Skip to main content

Manage the vault exposure

tip

Be sure to have read the previous section and that you are aware of the different functions behavior.

Set the Supply Queue

Let's consider that someone applied all steps from the previous section such that the supplyQueue is thus composed of 3 market Ids:

0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41; // 0: wstETH/WETH(94.5%)
0x3c83f77bde9541f8d3d82533b19bbc1f97eb2f1098bb991728acbfbede09cc5d; // 1: rETH/WETH(94.5%)
0x58e212060645d18eab6d9b2af3d56fbc906a92ff5667385f616f662c70372284; // 2: Idle Market - WETH

One can verify it by putting 0, 1, 2, etc... numbers on the supplyQueue function on the vault itself.

To change the supplyQueue, one can call the setSupplyQueue with a new set of Id, by moving market 1 and 2 for instance:

0x3c83f77bde9541f8d3d82533b19bbc1f97eb2f1098bb991728acbfbede09cc5d; // 0: rETH/WETH(94.5%)
0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41; // 1: wstETH/WETH(94.5%)
0x58e212060645d18eab6d9b2af3d56fbc906a92ff5667385f616f662c70372284; // 2: Idle Market - WETH

And call the setSupplyQueue function with the object:

setSupplyQueue([0x3c...523,0x30...5a0,0xd9...a84])

Then one can verify that this worked as expected by querying again the supplyQueue function on the vault, one should see that the order changed.

Idle market

Please keep in mind that it could be relevant to put the "idle" market as last element of the supplyQueue.

Update the Withdraw Queue

Let's assume a vault has the following withdrawQueue:

0x58e212060645d18eab6d9b2af3d56fbc906a92ff5667385f616f662c70372284; // 0: Idle Market - WETH
0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41; // 1: wstETH/WETH(94.5%)
0x3c83f77bde9541f8d3d82533b19bbc1f97eb2f1098bb991728acbfbede09cc5d; // 2: rETH/WETH(94.5%)

As a curator, if one wants to change the position of the last 2 markets:
-> call the function: updateWithdrawQueue with: ["0","2","1"].

The new withdrawQueue will be:

0x58e212060645d18eab6d9b2af3d56fbc906a92ff5667385f616f662c70372284; // 0: Idle Market - WETH
0x3c83f77bde9541f8d3d82533b19bbc1f97eb2f1098bb991728acbfbede09cc5d; // 1: rETH/WETH(94.5%)
0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41; // 2: wstETH/WETH(94.5%)
Idle market

Please keep in mind that it could be relevant to put the "idle" market as first element of the withdrawQueue.

Remove a market

To force remove a market, one can call submitMarketRemoval.

warning
  • Submits a forced market removal from the vault, eventually losing all funds supplied to the market.
  • Note that funds can be recovered by enabling this market again and withdrawing from it (using reallocate), but funds will be distributed pro-rata to the shares at the time of withdrawal, not at the time of removal.
  • This forced removal is expected to be used as an emergency process in case a market constantly reverts.
  • To softly remove a sane market, the curator role is expected to bundle a reallocation that empties the market first (using reallocate), followed by the removal of the market (using updateWithdrawQueue).
  • Reverts for non-zero cap or if there is a pending cap. Successfully submitting a zero cap wil prevent such reverts.

Let's assume a vault has the following withdrawQueue:

0x58e212060645d18eab6d9b2af3d56fbc906a92ff5667385f616f662c70372284; // 0: Idle Market - WETH
0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41; // 1: wstETH/WETH(94.5%)
0x3c83f77bde9541f8d3d82533b19bbc1f97eb2f1098bb991728acbfbede09cc5d; // 2: rETH/WETH(94.5%)

As a curator, if one wants to remove the last market, one can call the function: submitMarketRemoval with the marketParams of the market Id: 0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41. Here are the following steps that need to be done:

1. Retrieve the marketParams data

Jump into the Morpho Blue contract, and in the read functions section, call the idToMarketParams function with the market Id you are expecting to remove as input:

input:
"0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41"; // wstETH/WETH(94.5%)

output:
"loanToken":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"collateralToken":"0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"oracle":"0x2a01EB9496094dA03c4E364Def50f5aD1280AD72",
"irm":"0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
"lltv":"945000000000000000"

The value retrieved are the market parameters (marketParams) of the market you want to remove.

2. Send submitCap transaction

As the curator, send a submitCap transaction with a cap of 0 to the market you want to remove.
a. The marketParams one is expecting to remove, retrieved in 1.
b. The cap value, which has to be set to 0.


input:
[
[ // marketParams tuple
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"0x2a01EB9496094dA03c4E364Def50f5aD1280AD72",
"0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
"945000000000000000"
]
,0 // cap value, 0
]

3. Send submitMarketRemoval transaction

Paste again the marketParams retrieved in 1, and call the submitMarketRemoval function with those parameters:

[
"loanToken":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"collateralToken":"0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"oracle":"0x2a01EB9496094dA03c4E364Def50f5aD1280AD72",
"irm":"0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
"lltv":"945000000000000000"
]

4. Send an updateWithdrawQueue transaction

One wants to keep only the market of the withdrawQueue that are in position 0 and position 2 as per the example: After timelock (otherwise, the transaction will revert), put [0,2] in the updateWithdrawQueue function.

This is it, one can verify in the withdrawQueue that there no longer is the market that was removed.

Reallocation examples

Any address that has the onlyAllocatorRole will be able to execute the reallocate function which thus reallocates the vault's liquidity so as to reach a given allocation of assets on each given market.
The allocator can withdraw from any market, even if it's not in the withdraw queue, as long as the loan token of the market is the same as the vault's asset.

note

Be sure to have read the technical reference definition of the reallocatefunction before proceeding.

The function takes into input the MarketAllocation[], with MarketAllocation implemented like this:

struct MarketAllocation {
MarketParams marketParams;
uint256 assets;
}:

and MarketParams implemented like this:

struct MarketParams {
address loanToken;
address collateralToken;
address oracle;
address irm;
uint256 lltv;
}

A basic Etherscan exemple that would use the reallocate function would be to replace the following input with the right addresses and values: Don't forget to update the lines that are commented.

[
{
"marketParams":
{
"loanToken":"LOAN_TOKEN_ADDRESS", // To adapt
"collateralToken":"COLLATERAL_TOKEN_ADDRESS", // To adapt
"oracle":"ORACLE_ADDRESS", // To adapt
"irm":"IRM_ADDRESS", // To adapt
"lltv":"900000000000000000" // To adapt, this value corresponds to 90% (18 decimals precision)
},
"assets":"NB_OF_ASSET" // To adapt
},
{
"marketParams":
{
"loanToken":"LOAN_TOKEN_ADDRESS", // To adapt
"collateralToken":"COLLATERAL_TOKEN_ADDRESS", // To adapt
"oracle":"ORACLE_ADDRESS", // To adapt
"irm":"IRM_ADDRESS", // To adapt
"lltv":"900000000000000000" // To adapt, this value corresponds to 90% (18 decimals precision)
},
"assets":"NB_OF_ASSET" // To adapt
},
{
"marketParams": // Possibility: add the idle markets
{
"loanToken":"LOAN_TOKEN_ADDRESS", // To adapt
"collateralToken":"0x0000000000000000000000000000000000000000",
"oracle":"0x0000000000000000000000000000000000000000",
"irm":"0x0000000000000000000000000000000000000000",
"lltv":"0"
},
"assets":"115792089237316195423570985008687907853269984665640564039457584007913129639935" // 2^256-1
}
]