Summary
When a plot listing is partially filled and the remaining amount is less than the minFillAmount
it should not create a new listing because it will not be able to be fulfilled
Relevant GitHub Links:
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/main/protocol/contracts/beanstalk/market/MarketplaceFacet/Listing.sol#L133-L148
Vulnerability Details
A plot listing is a plot position that have some parameters determined by the seller. One of them is the minFillAmount
which basically checks that the buyer is filling/buying a minimum amount of the plot listing. However, when someone fulfills a part of a listing, the system automatically creates an other listing with the remaining pods and the same paramters that the lister posted in the original listing. So the buyer can buy an amount that makes the remaining amount less than the minFillAmount
which will make the new plot listing not possible to be fulfilled.
function _fillListing(
PodListing calldata podListing,
address filler,
uint256 beanPayAmount
) internal {
...
delete s.sys.podListings[podListing.fieldId][podListing.index];
if (podReceiveAmount < podListing.podAmount) {
uint256 newIndex = podListing.index + podReceiveAmount + podListing.start;
s.sys.podListings[podListing.fieldId][newIndex] = _hashListing(
PodListing(
podListing.lister,
podListing.fieldId,
newIndex,
0,
podListing.podAmount - podReceiveAmount,
podListing.pricePerPod,
podListing.maxHarvestableIndex,
podListing.minFillAmount,
podListing.mode
)
);
}
...
}
Impact
Low
Tools Used
Manual review
Recommendations
When there is a partial fulfil, if the remaining amount is less than minFillAmount
do not create a new listing.
function _fillListing(
PodListing calldata podListing,
address filler,
uint256 beanPayAmount
) internal {
...
// Remove old listing and create new listing if necessary.
delete s.sys.podListings[podListing.fieldId][podListing.index];
- if (podReceiveAmount < podListing.podAmount) {
+ if (podReceiveAmount < podListing.podAmount && (podListing.podAmount - podReceiveAmount > podListing.minFillAmount)) {
uint256 newIndex = podListing.index + podReceiveAmount + podListing.start;
s.sys.podListings[podListing.fieldId][newIndex] = _hashListing(
PodListing(
podListing.lister,
podListing.fieldId,
newIndex,
0,
podListing.podAmount - podReceiveAmount,
podListing.pricePerPod,
podListing.maxHarvestableIndex,
podListing.minFillAmount,
podListing.mode
)
);
}
...
}