`BondAggregator.findMarketFor` Function Will Break In Certain Conditions
`BondAggregator.findMarketFor` function will break when the `BondBaseSDA.payoutFor` function within the for-loop reverts under certain conditions.\\nThe `BondBaseSDA.payoutFor` function will revert if the computed payout is larger than the market's max payout. Refer to Line 711 below.\\n```\\nFile: BondBaseSDA.sol\\n    function payoutFor(\\n        uint256 amount_,\\n        uint256 id_,\\n        address referrer_\\n    ) public view override returns (uint256) {\\n        // Calculate the payout for the given amount of tokens\\n        uint256 fee = amount_.mulDiv(_teller.getFee(referrer_), 1e5);\\n        uint256 payout = (amount_ - fee).mulDiv(markets[id_].scale, marketPrice(id_));\\n\\n        // Check that the payout is less than or equal to the maximum payout,\\n        // Revert if not, otherwise return the payout\\n        if (payout > markets[id_].maxPayout) {\\n            revert Auctioneer_MaxPayoutExceeded();\\n        } else {\\n            return payout;\\n        }\\n    }\\n```\\n\\nThe `BondAggregator.findMarketFor` function will call the `BondBaseSDA.payoutFor` function at Line 245. The `BondBaseSDA.payoutFor` function will revert if the final computed payout is larger than the `markets[id_].maxPayout` as mentioned earlier. This will cause the entire for-loop to "break" and the transaction to revert.\\nAssume that the user configures the `minAmountOut_` to be `0`, then the condition `minAmountOut_ <= maxPayout` Line 244 will always be true. The `amountIn_` will always be passed to the `payoutFor` function. In some markets where the computed payout is larger than the market's max payout, the `BondAggregator.findMarketFor` function will revert.\\n```\\nFile: BondAggregator.sol\\n    /// @inheritdoc IBondAggregator\\n    function findMarketFor(\\n        address payout_,\\n        address quote_,\\n        uint256 amountIn_,\\n        uint256 minAmountOut_,\\n        uint256 maxExpiry_\\n    ) external view returns (uint256) {\\n        uint256[] memory ids = marketsFor(payout_, quote_);\\n        uint256 len = ids.length;\\n        uint256[] memory payouts = new uint256[](len);\\n\\n        uint256 highestOut;\\n        uint256 id = type(uint256).max; // set to max so an empty set doesn't return 0, the first index\\n        uint48 vesting;\\n        uint256 maxPayout;\\n        IBondAuctioneer auctioneer;\\n        for (uint256 i; i < len; ++i) {\\n            auctioneer = marketsToAuctioneers[ids[i]];\\n            (, , , , vesting, maxPayout) = auctioneer.getMarketInfoForPurchase(ids[i]);\\n\\n            uint256 expiry = (vesting <= MAX_FIXED_TERM) ? block.timestamp + vesting : vesting;\\n\\n            if (expiry <= maxExpiry_) {\\n                payouts[i] = minAmountOut_ <= maxPayout\\n                    ? payoutFor(amountIn_, ids[i], address(0))\\n                    : 0;\\n\\n                if (payouts[i] > highestOut) {\\n                    highestOut = payouts[i];\\n                    id = ids[i];\\n                }\\n            }\\n        }\\n\\n        return id;\\n    }\\n```\\n
Consider using try-catch or address.call to handle the revert of the `BondBaseSDA.payoutFor` function within the for-loop gracefully. This ensures that a single revert of the `BondBaseSDA.payoutFor` function will not affect the entire for-loop within the `BondAggregator.findMarketFor` function.
The find market feature within the protocol is broken under certain conditions. As such, users would not be able to obtain the list of markets that meet their requirements. The market makers affected by this issue will lose the opportunity to sell their bond tokens.
```\\nFile: BondBaseSDA.sol\\n    function payoutFor(\\n        uint256 amount_,\\n        uint256 id_,\\n        address referrer_\\n    ) public view override returns (uint256) {\\n        // Calculate the payout for the given amount of tokens\\n        uint256 fee = amount_.mulDiv(_teller.getFee(referrer_), 1e5);\\n        uint256 payout = (amount_ - fee).mulDiv(markets[id_].scale, marketPrice(id_));\\n\\n        // Check that the payout is less than or equal to the maximum payout,\\n        // Revert if not, otherwise return the payout\\n        if (payout > markets[id_].maxPayout) {\\n            revert Auctioneer_MaxPayoutExceeded();\\n        } else {\\n            return payout;\\n        }\\n    }\\n```\\n