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

Always revert when there is a value already pending #353

Merged
merged 16 commits into from
Dec 28, 2023

Conversation

MathisGD
Copy link
Contributor

@MathisGD MathisGD commented Dec 15, 2023

@MathisGD MathisGD changed the base branch from main to post-cantina December 15, 2023 14:14
@MathisGD MathisGD self-assigned this Dec 15, 2023
@MathisGD MathisGD requested review from a team, adhusson, Rubilmax, QGarchery, MerlinEgalite and Jean-Grimal and removed request for a team December 15, 2023 14:16
Copy link
Contributor

@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.

This design relies on the fact the pending value is deleted every time a value is set

src/MetaMorpho.sol Show resolved Hide resolved
src/MetaMorpho.sol Outdated Show resolved Hide resolved
test/forge/MarketTest.sol Outdated Show resolved Hide resolved
src/MetaMorpho.sol Outdated Show resolved Hide resolved
src/MetaMorpho.sol Show resolved Hide resolved
src/MetaMorpho.sol Show resolved Hide resolved
Copy link
Contributor

@Jean-Grimal Jean-Grimal left a comment

Choose a reason for hiding this comment

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

The natspec should be updated

Copy link
Contributor

@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.

Pointing out that being consistent with #348 requires to revert in submitMarketRemoval and submitCap

Jean-Grimal
Jean-Grimal previously approved these changes Dec 19, 2023
Copy link
Contributor

@Jean-Grimal Jean-Grimal left a comment

Choose a reason for hiding this comment

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

A test on submitting a guardian while there is already a pending guardian should be added

src/MetaMorpho.sol Show resolved Hide resolved
src/MetaMorpho.sol Show resolved Hide resolved
src/MetaMorpho.sol Show resolved Hide resolved
src/libraries/ErrorsLib.sol Outdated Show resolved Hide resolved
src/libraries/ErrorsLib.sol Outdated Show resolved Hide resolved
src/interfaces/IMetaMorpho.sol Outdated Show resolved Hide resolved
src/MetaMorpho.sol Show resolved Hide resolved
adhusson
adhusson previously approved these changes Dec 27, 2023
adhusson
adhusson previously approved these changes Dec 27, 2023
MerlinEgalite
MerlinEgalite previously approved these changes Dec 28, 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.

I still think the naming change was not necessary

src/MetaMorpho.sol Outdated Show resolved Hide resolved
@MerlinEgalite
Copy link
Contributor

@MathisGD can you revert back the naming and fix the conflicts please?

@MathisGD MathisGD dismissed stale reviews from MerlinEgalite and adhusson via b3602c1 December 28, 2023 12:33
@MerlinEgalite MerlinEgalite merged commit 15f96c1 into post-cantina Dec 28, 2023
6 checks passed
@MerlinEgalite MerlinEgalite deleted the refactor/revert-already-pending branch December 28, 2023 13:56
@Jean-Grimal Jean-Grimal mentioned this pull request Dec 28, 2023
@@ -214,14 +214,12 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph
/// @inheritdoc IMetaMorphoBase
function submitTimelock(uint256 newTimelock) external onlyOwner {
if (newTimelock == timelock) revert ErrorsLib.AlreadySet();
if (pendingTimelock.validAt != 0) revert ErrorsLib.AlreadyPending();
Copy link

@StErMi StErMi Dec 30, 2023

Choose a reason for hiding this comment

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

Before, you could have a pending value (decrease of timelock) that could have been deleted by another submitTimelock that set the new timelock to a new one (higher timelock)

Now you won't be able to do that, and you are forced to wait for the timelock to expire or revoke it and call it again.

The same goes for submitting an even lower timelock when one pending timelock was already submitted.

Is this the intended new behavior?

Copy link
Contributor

Choose a reason for hiding this comment

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

yes we enforce to revoke every pending values before submitting a new one.

@@ -281,16 +276,14 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph
Id id = marketParams.id();
if (marketParams.loanToken != asset()) revert ErrorsLib.InconsistentAsset(id);
if (MORPHO.lastUpdate(id) == 0) revert ErrorsLib.MarketNotCreated();

if (pendingCap[id].validAt != 0) revert ErrorsLib.AlreadyPending();
if (config[id].removableAt != 0) revert ErrorsLib.PendingRemoval();
Copy link

Choose a reason for hiding this comment

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

I think that this is a welcome check because the removal of a market is a very strong operation that also has a timelock that is different compared to the cap timelock (and previously they were non correlated within the logic). Now if a market is marked as "to-be-removed" such operation has the priority and will lock any changes to the cap.

Now as soon as a market is marked as to-be-removed, there's no way to re-enable the cap (that is already set to zero) unless you explicitly call revokePendingMarketRemoval

@@ -281,16 +276,14 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph
Id id = marketParams.id();
if (marketParams.loanToken != asset()) revert ErrorsLib.InconsistentAsset(id);
if (MORPHO.lastUpdate(id) == 0) revert ErrorsLib.MarketNotCreated();

if (pendingCap[id].validAt != 0) revert ErrorsLib.AlreadyPending();
Copy link

Choose a reason for hiding this comment

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

Like for the submitTimelock, this new check brings some side effects. Unless you revoke the previous pending proposal, or you wait for the timelock + accept it, you cannot

  • create a new proposal
  • insta-change the supply cap (when the new cap is lower)

In general, you are giving much more priority and power to the pending proposals. Is this the intended behavior?

Copy link
Contributor

Choose a reason for hiding this comment

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

yes it is. What we'll do is that in the frontend we can leverage the multicall functionality to bundle a revoke + submit in a single tx to perform the required actions.

@StErMi
Copy link

StErMi commented Dec 30, 2023

Would you mind confirming the logic of the behavior? Because otherwise, I'm trying to reverse engineering it and could arrive at the wrong conclusion.

The new logic allows the submission of a change to the

  • timelock
  • guardian
  • supply
  • market removal

Only if there's no direct or indirect pending proposal currently in action.

To be more clear

  • direct: you can't submit a cap proposal if there's already one
  • indirect: you can't submit a cap proposal if there's a pending market removal proposal

Moreover, there are some "custom" requirements (that still need to be documented), like for example

  • you can't require a market removal if the cap is not already set to zero. In general, you don't want to execute implicit logic, but the state must be already "ready" to perform the action once the timelock has ended.

Would you mind confirming or detailing more/correct my recap?

@StErMi
Copy link

StErMi commented Dec 30, 2023

Giving the immutable nature of MM (you can't upgrade and change the logic) it could make sense to create utility contracts to manage it.

Like for example an external contract (with the owner or curator role) that perform all the actions needed to be able to execute MM.submitMarketRemoval

  • if the cap is not 0 and there's a pending proposal, revoke it and set it to zero
  • call the submitMarketRemoval

@MerlinEgalite
Copy link
Contributor

I confirm your first comment. We wanted submit*, revoke* and accept* functions to be single purpose functions with less side effects than previously.

For the second comment, the vault inherits from Multicall which allows to extract that logic offchain, so what you proposed will be done in Morpho Blue's frontend. Nonetheless, some vault curators are likely to write their own logic but we won't write it ourselves.

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.

[protocol review] Possible accidental removal of pending transactions
7 participants