Invalid baseReserve stalls buy on bonding curve
Description
The SimpleBondingCurve contract provides exchange rates between quote token and base token prior to graduation events. Graduation is when the BONDING_SUPPLY has been reached and remaining balances in the Launchpad are sent to a UniswapV2 token pool.
The _getQuoteAmount() function (used in both buy() and sell()) is as follows:
function _getQuoteAmount(uint256 baseAmount, uint256 quoteReserve, uint256 baseReserve, bool isBuy)
internal
pure
returns (uint256 quoteAmount)
{
uint256 baseReserveAfter = isBuy ? baseReserve - baseAmount : baseReserve + baseAmount;
return (quoteReserve * baseAmount) / baseReserveAfter;
}If the initial r.baseReserve == BONDING_SUPPLY, as the baseReserve reaches the BONDING_SUPPLY, the denominator will tend towards zero, ultimately reverting with division by zero.
This sets the lower bound for SimpleLaunchpad configuration of VIRTUAL_BASE to 1.
Impact
If an administrator does not understand that the VIRTUAL_BASE lower bound is 1, they may configure the bonding curve such that the Launchpad can launch tokens but will never allow graduation breaking key assumptions of early investors.
Recommendations
Add validation to the setVirtualReserves() that prevents 0 values.
Remediation
This issue has been acknowledged by Liquid Labs, Inc., and a fix was implemented in commit 7422a467↗.
Liquid Labs, Inc. provided the following response to this finding:
Virtual base can no longer be set to 0 by the owner of SimpleBondingCurve.sol