## Summary
`Swan.list()` function using the curremnt market `maxAssetCount` parameter to check for the buyer assets count instead of using the `maxAssetCount` market parameter at the time when the buer agent contract was deployed.
## Vulnerability Details
- Any seller can list an asset/assets to any buyer agent via `Swan.list()`, where the seller determines to which agent this asset to be listed and for which price, and befor the asset is added to the `Swan.ssetsPerBuyerRound[_buyer][round]` of the buyer, a check is made to ensure that the currently listed assets number for this buyer at his current round doesn't exceed the maximum assets allowed to be listed for buyers determined by the **current market parameters**:
```javascript
function list(
string calldata _name,
string calldata _symbol,
bytes calldata _desc,
uint256 _price,
address _buyer
) external {
//...
if (getCurrentMarketParameters().maxAssetCount == assetsPerBuyerRound[_buyer][round].length) {
revert AssetLimitExceeded(getCurrentMarketParameters().maxAssetCount);
}
//...
}
```
- But the buyer agent contract uses the market parameters at the time that buyer agent is deployed, indicated by the `marketParameterIdx`:
```javascript
constructor(
string memory _name,
string memory _description,
uint96 _royaltyFee,
uint256 _amountPerRound,
address _operator,
address _owner
) Ownable(_owner) {
//...
//! to get the current marketParameters at the time of deployment
marketParameterIdx = swan.getMarketParameters().length - 1;
//...
}
```
- Same issue in the `Swan.relist()` function.
## Impact
So this would result in using the `maxAssetCount` of the **current** market parameters to check for the current listed assets of the buyer instead of using the `maxAssetCount` of the market **at the time the buyer agent was deployed**.
## Proof of Concept
[Swan.list() function/ L168-L170](https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/swan/Swan.sol#L168C9-L170C10)
```javascript
function list(
string calldata _name,
string calldata _symbol,
bytes calldata _desc,
uint256 _price,
address _buyer
) external {
//...
if (getCurrentMarketParameters().maxAssetCount == assetsPerBuyerRound[_buyer][round].length) {
revert AssetLimitExceeded(getCurrentMarketParameters().maxAssetCount);
}
//...
}
```
## Tools Used
Manual Review.
## Recommendations
Update `Swan.list()` function to check for the `maxAssetCount` using the saved market parameters of the buyer agent at the time of the agent deployment:
```diff
function list(
string calldata _name,
string calldata _symbol,
bytes calldata _desc,
uint256 _price,
address _buyer
) external {
BuyerAgent buyer = BuyerAgent(_buyer);
//...
+ SwanMarketParameters[] memory marketParams = swan.getMarketParameters();
- if (getCurrentMarketParameters().maxAssetCount == assetsPerBuyerRound[_buyer][round].length) {
+ if (marketParams[buyer.marketParameterIdx] == assetsPerBuyerRound[_buyer][round].length) {
revert AssetLimitExceeded(getCurrentMarketParameters().maxAssetCount);
}
//...
}
```