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

fix: check supply queue size #237

Merged
merged 6 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/MetaMorpho.sol
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,11 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph
/// @dev The supply queue can be a set containing duplicate markets, but it would only increase the cost of
/// depositing to the vault.
function setSupplyQueue(Id[] calldata newSupplyQueue) external onlyAllocator {
for (uint256 i; i < newSupplyQueue.length; ++i) {
uint256 length = newSupplyQueue.length;

if (length > ConstantsLib.MAX_QUEUE_SIZE) revert ErrorsLib.MaxQueueSizeExceeded();

for (uint256 i; i < length; ++i) {
if (config[newSupplyQueue[i]].cap == 0) revert ErrorsLib.UnauthorizedMarket(newSupplyQueue[i]);
}

Expand Down Expand Up @@ -657,7 +661,10 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph
supplyQueue.push(id);
withdrawQueue.push(id);

if (withdrawQueue.length > ConstantsLib.MAX_QUEUE_SIZE) revert ErrorsLib.MaxQueueSizeExceeded();
if (supplyQueue.length > ConstantsLib.MAX_QUEUE_SIZE || withdrawQueue.length > ConstantsLib.MAX_QUEUE_SIZE)
{
revert ErrorsLib.MaxQueueSizeExceeded();
}

// Safe "unchecked" cast because withdrawQueue.length <= MAX_QUEUE_SIZE.
marketConfig.withdrawRank = uint64(withdrawQueue.length);
Expand Down
26 changes: 26 additions & 0 deletions test/forge/MarketTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,32 @@ contract MarketTest is IntegrationTest {
assertEq(Id.unwrap(vault.supplyQueue(1)), Id.unwrap(allMarkets[2].id()));
}

function testSetSupplyQueueMaxQueueSizeExceeded() public {
Id[] memory supplyQueue = new Id[](ConstantsLib.MAX_QUEUE_SIZE + 1);

vm.prank(ALLOCATOR);
vm.expectRevert(ErrorsLib.MaxQueueSizeExceeded.selector);
vault.setSupplyQueue(supplyQueue);
}

function testAcceptCapMaxQueueSizeExceeded() public {
for (uint256 i; i < ConstantsLib.MAX_QUEUE_SIZE; ++i) {
_setCap(allMarkets[i], CAP);
}

_setTimelock(1 weeks);

MarketParams memory marketParams = allMarkets[ConstantsLib.MAX_QUEUE_SIZE];

vm.prank(CURATOR);
vault.submitCap(marketParams, CAP);

vm.warp(block.timestamp + 1 weeks);

vm.expectRevert(ErrorsLib.MaxQueueSizeExceeded.selector);
vault.acceptCap(marketParams.id());
}

function testSetSupplyQueueUnauthorizedMarket() public {
Id[] memory supplyQueue = new Id[](1);
supplyQueue[0] = allMarkets[0].id();
Expand Down
4 changes: 0 additions & 4 deletions test/forge/MetaMorphoInternalTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ contract MetaMorphoInternalTest is InternalTest {
using SharesMathLib for uint256;
using UtilsLib for uint256;

constructor() {
NB_MARKETS = ConstantsLib.MAX_QUEUE_SIZE + 1;
}

function testSetCapMaxQueueSizeExcedeed() public {
for (uint256 i; i < NB_MARKETS - 1; ++i) {
Id id = allMarkets[i].id();
Expand Down
3 changes: 1 addition & 2 deletions test/forge/helpers/BaseTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,14 @@ uint256 constant BLOCK_TIME = 1;
uint256 constant MIN_TEST_ASSETS = 1e8;
uint256 constant MAX_TEST_ASSETS = 1e28;
uint192 constant CAP = type(uint128).max;
uint256 constant NB_MARKETS = ConstantsLib.MAX_QUEUE_SIZE + 1;

contract BaseTest is Test {
using MathLib for uint256;
using MorphoLib for IMorpho;
using MorphoBalancesLib for IMorpho;
using MarketParamsLib for MarketParams;

uint256 internal immutable NB_MARKETS = 10;

address internal OWNER = makeAddr("Owner");
address internal SUPPLIER = makeAddr("Supplier");
address internal BORROWER = makeAddr("Borrower");
Expand Down
15 changes: 10 additions & 5 deletions test/metamorpho_tests.tree
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@
├── when supplyCap > 0 and marketConfig.withdrawRank == 0
│ ├── it should push id to supplyQueue
│ ├── it should push id to withdrawQueue
│ ├── if supplyQueue.length > MAX_QUEUE_SIZE
│ │ └── revert with MaxQueueSizeExceeded()
│ └── if withdrawQueue.length > MAX_QUEUE_SIZE
│ └── revert with MaxQueueSizeExceeded()
├── it should set config[id].cap to pendingCap[id].value
Expand All @@ -214,11 +216,14 @@
├── when msg.sender not owner or curator or allocator
│ └── revert with NotAllocator()
└── when msg.sender is owner or curator or allocator
├── when some markets of newSupplyQueue have a zero cap
│ └── revert with UnauthorizedMarket()
└── when all the markets of newSupplyQueue have non zero cap
├── it should set supplyQueue to newSupplyQueue
└── it shoud emit SetSupplyQueue(msg.sender, newSupplyQueue)
├── when newSupplyQueue.length > MAX_QUEUE_SIZE
│ └── revert with MaxQueueSizeExceeded()
└── when newSupplyQueue.length <= MAX_QUEUE_SIZE
├── when some markets of newSupplyQueue have a zero cap
│ └── revert with UnauthorizedMarket()
└── when all the markets of newSupplyQueue have non zero cap
├── it should set supplyQueue to newSupplyQueue
└── it shoud emit SetSupplyQueue(msg.sender, newSupplyQueue)

.
└── sortWithdrawQueue(uint256[] calldata indexes) external
Expand Down
Loading