Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(irm): skip address(0) #640

Merged
merged 12 commits into from
Dec 12, 2023
Merged

feat(irm): skip address(0) #640

merged 12 commits into from
Dec 12, 2023

Conversation

Rubilmax
Copy link
Contributor

@Rubilmax Rubilmax commented Dec 7, 2023

This PR is not related to a cantina issue.

it takes 85k gas to create an idle market while it takes 175k gas to create a standard market

and here is the gas diff between standard markets (left) and idle markets (right):
image

on avg, it costs -9k to supply/withdraw to/from an idle market

@Rubilmax Rubilmax marked this pull request as ready for review December 7, 2023 13:29
@Rubilmax Rubilmax linked an issue Dec 7, 2023 that may be closed by this pull request
src/Morpho.sol Outdated Show resolved Hide resolved
QGarchery
QGarchery previously approved these changes Dec 7, 2023
Copy link
Contributor

@MerlinEgalite MerlinEgalite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be tested i think

@MerlinEgalite
Copy link
Contributor

it breaks certora though

Copy link
Contributor Author

@Rubilmax Rubilmax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do it in the external library too

MerlinEgalite
MerlinEgalite previously approved these changes Dec 8, 2023
src/Morpho.sol Outdated Show resolved Hide resolved
src/Morpho.sol Outdated Show resolved Hide resolved
@Rubilmax Rubilmax changed the base branch from post-cantina to fix/issue-259 December 11, 2023 08:58
Base automatically changed from fix/issue-259 to post-cantina December 11, 2023 09:49
@MerlinEgalite MerlinEgalite dismissed stale reviews from Jean-Grimal, QGarchery, and themself December 11, 2023 09:49

The base branch was changed.

Copy link
Contributor

@MerlinEgalite MerlinEgalite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well not sure now we should do it

@MathisGD
Copy link
Contributor

I just reopened this discussion, please wait a little bit before merging

@MerlinEgalite
Copy link
Contributor

Should we wait for your branch to be merged in it @MathisGD ?

@Rubilmax
Copy link
Contributor Author

I think these 2 PRs are independent

@MerlinEgalite MerlinEgalite merged commit 184fc24 into post-cantina Dec 12, 2023
15 checks passed
@MerlinEgalite MerlinEgalite deleted the feat/skip-irm-0 branch December 12, 2023 15:11
@MathisGD MathisGD mentioned this pull request Dec 12, 2023

emit EventsLib.AccrueInterest(id, borrowRate, interest, feeShares);
emit EventsLib.AccrueInterest(id, borrowRate, interest, feeShares);
}

// Safe "unchecked" cast.
market[id].lastUpdate = uint128(block.timestamp);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the "meaning" of lastUpdate? I'm asking because there's no natspec documentation on the interface, and previously it was updated when there was an interest accrual.

So if I need to give a meaning from the previous code logic, lastUpdate represented the last time that interest was accrued or at least triggered (maybe there was no accrual because of market condition or rounding)

With this change instead, lastUpdate is always updated even if no interest accrual is triggered, and we know for sure that the market has not changed.

Should the market[id].lastUpdate = uint128(block.timestamp); execution be moved inside the if branch?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think now it refers to the timestamp of the block where there was the last interaction that could change the interest. So mostly the main lending entry points except supplyCollateral. I agree that it does not really make the spec simpler in the end, so maybe it's better to use the previous solution of skipping the all function _accrueInterest as soon as the irm is 0

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean something like if (elapsed == 0 || marketParams.irm == address(0)) return;?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We thought about returning even earlier, before computing elapsed, so that we would not have to touch the fee/lastUpdate slot. But this is not such a big optimization actually because this slot is warm anyway (when checking if the market is created). So we thought about your suggestion also.

In the end, because optimizations are not so big, we went for the solution where markets with 0 irm function similarly to regular markets

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that lastUpdate should always be updated (current situation) because it makes the spec simpler (it's always updated when accrueInterest is called). Also I was in favor (but not big deal) of always emitting the event for the same reason. For me when irm=0 we can say that the interest is accrued, but with rate=0.

@@ -160,7 +160,7 @@ contract Morpho is IMorphoStaticTyping {
emit EventsLib.CreateMarket(id, marketParams);

// Call to initialize the IRM in case it is stateful.
IIrm(marketParams.irm).borrowRate(marketParams, market[id]);
if (marketParams.irm != address(0)) IIrm(marketParams.irm).borrowRate(marketParams, market[id]);
Copy link

@StErMi StErMi Dec 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding, this PR is to allow the creation of "idle" markets where there's no IRM. Is my understanding correct?

This allows anyone to create a market where no interest will accrue.

  • borrowers do not need to pay any interest to suppliers
  • suppliers do not accrue and earn any earning from borrowers
  • bad debt socialization can't be "neutralized" by interest accrued in the past

Isn't there any better solution to allow the creation of "idle" markets? Because with this modification and the fact that you are not checking during market creation if the loanToken and collateralToken exists (!= address(0) or address(token).code.length > 0) it could lead to some unwanted behaviors.

Given that you are shaping MB to allow the MM use case (idle markets), I would suggest thinking about:

  1. find the conditions that only allow the creation of an idle market (supply loanToken without allowing borrowing, only withdraw)
  2. does not allow the creation of arbitrary markets that do no make sense for a landing platform
  3. document inside the code that those checks and those markets should be used only for idle liquidity purposes

As I mentioned previously, IMHO, Morpho blue should not be designed and shaped for the needs of externals actors like MetaMorpho. MetaMorpho should be shaped around the basic building block that MB should be.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is my understanding correct?

Correct

As I mentioned previously, IMHO, Morpho blue should not be designed and shaped for the needs of externals actors like MetaMorpho. MetaMorpho should be shaped around the basic building block that MB should be.

Indeed, it's 100% aligned with our general philosophy but we think it makes more sense from a product perspective and we won't change it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows anyone to create a market where no interest will accrue.

borrowers do not need to pay any interest to suppliers
suppliers do not accrue and earn any earning from borrowers
bad debt socialization can't be "neutralized" by interest accrued in the past

correct, but this is not the expected use-case: for an idle market, one would put address zero as collateral and no borrower would be able to deposit collateral (and so borrow). It's only a way to make these idle depositors pay less gas.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused because this change has been done specifically to allow the creation of "idle market" but it also allows the creation of unwanted (as far as I get) markets.

Why don't you narrow the creation of those market to just the one that makes sense to be used as an idle market (as you said)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree that it feels weird, but in Blue you can also created unwanted markets in multiple ways (tokens are not checked, oracles are not checked) so why checking for this thing specifically

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree that it feels weird, but in Blue you can also created unwanted markets in multiple ways (tokens are not checked, oracles are not checked) so why checking for this thing specifically

Because this modification has been made deliberately to allow the creation of an idle market, with the side effects that it allows the creation of non-lending markets.

The final decision is obviously up to you, I just wanted to point out the side effects and that at least those side effects need to be documented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IRM zero
6 participants