In the list() function, which adds assets for a buyer during a specific round, the function checks whether the asset count equals the maximum asset count (maxAssetCount) before allowing new listings. However, when a new _marketParameters is added via setMarketParameters(), this value immediately applies as the current limit.
If the new limit is lower than the current number of listed assets, the equality-based check fails to catch it, allowing listings to further exceed the limit.
The list() function checks if the number of assets listed by a buyer during a round meets the maxAssetCount limit by comparing it with the current count using an == condition:
When a new _marketParameters with a lower maxAssetCount is pushed to the marketParameters array using setMarketParameters(), it takes effect immediately as the “current” parameter:
If the current number of assets already exceeds the newly set maxAssetCount, the equality check (==) fails to detect this, allowing further listings even though the limit should have already been met.
This is because getCurrentMarketParameters() points to the last element in the array.
Scenario:
Alice lists 3 assets during Round 1 when maxAssetCount is set to 5.
Owner later calls setMarketParameters() and pushes a new market parameter with maxAssetCount equal to 2 within the same round.
Since Alice already listed three assets (more than the new limit of 2), any new attempt by her to list assets should be blocked. However, the equality check fails to catch this, allowing her to list more assets despite exceeding the new limit.
This undermines the enforcement of maxAssetCount, potentially allowing sellers to further exceed asset limits intended.
Manual Review
Use (>=) condition to enforce maxAssetCount strictly:
SwanManager::setMarketParameters pushes the new parameters `marketParameters.push(_marketParameters);` After that, when user calls list the protocol computes the round and the phase `(uint256 round, BuyerAgent.Phase phase,) = buyer.getRoundPhase();` Inside the getRoundPhase function you have this if statement on top: `if (marketParams.length == marketParameterIdx + 1) {`. The setMarketParameters call changed the `marketParams` length, thing which will case the first case to be false and run the else statement. At the end of that statement we see there is a new round. So the second element of this check `(getCurrentMarketParameters().maxAssetCount == assetsPerBuyerRound[_buyer][round].length` is zero, because the [round] is fresh.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.