From 38bcccea74ddb5423f4b48012127c9a161d0d9ae Mon Sep 17 00:00:00 2001 From: Rubilmax Date: Thu, 5 Oct 2023 15:21:58 +0200 Subject: [PATCH] fix(reallocate): prevent withdraw inconsistent asset --- src/MetaMorpho.sol | 9 ++++++--- src/libraries/ErrorsLib.sol | 4 ++-- test/forge/MarketTest.sol | 2 +- test/forge/ReallocateWithdrawTest.sol | 10 ++++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/MetaMorpho.sol b/src/MetaMorpho.sol index 1e4cf55e..73e065d6 100644 --- a/src/MetaMorpho.sol +++ b/src/MetaMorpho.sol @@ -214,9 +214,8 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph /* ONLY RISK MANAGER FUNCTIONS */ function submitCap(MarketParams memory marketParams, uint256 newMarketCap) external onlyRiskManager { - if (marketParams.loanToken != asset()) revert ErrorsLib.InconsistentAsset(); - Id id = marketParams.id(); + if (marketParams.loanToken != asset()) revert ErrorsLib.InconsistentAsset(id); if (MORPHO.lastUpdate(id) == 0) revert ErrorsLib.MarketNotCreated(); uint256 marketCap = config[id].cap; @@ -243,7 +242,7 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph uint256 length = newSupplyQueue.length; for (uint256 i; i < length; ++i) { - if (config[newSupplyQueue[i]].cap == 0) revert ErrorsLib.UnauthorizedMarket(); + if (config[newSupplyQueue[i]].cap == 0) revert ErrorsLib.UnauthorizedMarket(newSupplyQueue[i]); } supplyQueue = newSupplyQueue; @@ -302,6 +301,10 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph for (uint256 i; i < nbWithdrawn; ++i) { MarketAllocation memory allocation = withdrawn[i]; + if (allocation.marketParams.loanToken != asset()) { + revert ErrorsLib.InconsistentAsset(allocation.marketParams.id()); + } + (uint256 withdrawnAssets,) = MORPHO.withdraw( allocation.marketParams, allocation.assets, allocation.shares, address(this), address(this) ); diff --git a/src/libraries/ErrorsLib.sol b/src/libraries/ErrorsLib.sol index 5c21d0af..8db4513e 100644 --- a/src/libraries/ErrorsLib.sol +++ b/src/libraries/ErrorsLib.sol @@ -12,9 +12,9 @@ library ErrorsLib { error NotGuardian(); - error UnauthorizedMarket(); + error UnauthorizedMarket(Id id); - error InconsistentAsset(); + error InconsistentAsset(Id id); error SupplyCapExceeded(Id id); diff --git a/test/forge/MarketTest.sol b/test/forge/MarketTest.sol index dac7ee6a..d9073864 100644 --- a/test/forge/MarketTest.sol +++ b/test/forge/MarketTest.sol @@ -36,7 +36,7 @@ contract MarketTest is BaseTest { vm.assume(marketParams.loanToken != address(loanToken)); vm.prank(RISK_MANAGER); - vm.expectRevert(ErrorsLib.InconsistentAsset.selector); + vm.expectRevert(abi.encodeWithSelector(ErrorsLib.InconsistentAsset.selector, marketParams.id())); vault.submitCap(marketParams, 0); } diff --git a/test/forge/ReallocateWithdrawTest.sol b/test/forge/ReallocateWithdrawTest.sol index c37f0f2d..5c64767c 100644 --- a/test/forge/ReallocateWithdrawTest.sol +++ b/test/forge/ReallocateWithdrawTest.sol @@ -46,6 +46,16 @@ contract ReallocateWithdrawTest is BaseTest { assertEq(vault.idle(), INITIAL_DEPOSIT, "vault.idle() 1"); } + function testReallocateWithdrawInconsistentAsset() public { + allMarkets[0].loanToken = address(1); + + withdrawn.push(MarketAllocation(allMarkets[0], 0, 0)); + + vm.prank(ALLOCATOR); + vm.expectRevert(abi.encodeWithSelector(ErrorsLib.InconsistentAsset.selector, allMarkets[0].id())); + vault.reallocate(withdrawn, supplied); + } + function testReallocateWithdrawSupply(uint256[3] memory withdrawnShares, uint256[3] memory suppliedAssets) public { uint256[3] memory sharesBefore = [ morpho.supplyShares(allMarkets[0].id(), address(vault)),