Function: buy(address account, address token, address recipient, uint256 amountOutBase, uint256 maxAmountInQuote)
This function allows any caller or trusted operator to buy the specified amountOutBase amount of the LaunchToken. The maxAmountInQuote specifies the maximum amount of quote tokens that can be spent.
Inputs
accountControl: Full control.
Constraints: The caller should be the specified
accountitself or an approved operator by thisaccount.Impact: The account address on whose behalf the purchase is made.
tokenControl: Full control.
Constraints:
_launchescontains data related to thistoken.Impact: The address of the trusted LaunchToken, created using the
launchfunction.
recipientControl: Full control.
Constraints: Cannot be equal to the address of the Uniswap pool related to this LaunchToken and quote token.
Impact: The recipient of the purchased tokens.
amountOutBaseControl: Full control.
Constraints: The total amount of LaunchToken tokens bought cannot exceed the
BONDING_SUPPLYlimit.Impact: Amount of the LaunchToken to be bought.
maxAmountInQuoteControl: Full control.
Constraints: The resulting
amountInQuoteActualshould be less than or equal to themaxAmountInQuote.Impact: The maximum quote-tokens amount that can be spent.
Branches and code coverage
Intended branches
amountOutBaseActualis less thanBONDING_SUPPLY.amountOutBaseActualis greater thanBONDING_SUPPLYbut has been successfully limited byBONDING_SUPPLY.The remaining tokens are successfully swapped using the Uniswap pool.
If the swap using the Uniswap pool fails, the remaining tokens are transferred to the caller.
Negative behavior
The
tokenstatus is not active, because it does not exist.The
tokenstatus is not active, because liquidity was transferred to the Uniswap pool.The
maxAmountInQuoteis less thanamountInQuoteActual.
Function call analysis
LaunchToken(token).unlock()What is controllable?
token.If the return value is controllable, how is it used and how can it go wrong? There is no return value here.
What happens if it reverts, reenters or does other unusual control flow? This function unlocks the LaunchToken transferring.
bondingCurve.buy(token, amountOutBaseActual)What is controllable?
tokenandamountOutBaseActual.If the return value is controllable, how is it used and how can it go wrong? The returned
amountInQuotecan be less or more than expected. IfamountInQuoteis less than expected, the user can buy tokens cheaper; otherwise, the resulting amount can be more expensive than expected but not more thanmaxAmountInQuote.What happens if it reverts, reenters or does other unusual control flow? There is a
nonReentrantmodifier.
SafeTransferLib.safeTransfer(token, recipient, amountOutBaseActual)What is controllable?
recipientandamountOutBaseActual.If the return value is controllable, how is it used and how can it go wrong? There is no return value here.
What happens if it reverts, reenters or does other unusual control flow? There are no problems here.
SafeTransferLib.safeTransferFrom(address(data.quote), msg.sender, address(this), amountInQuote)What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? There is no return value here.
What happens if it reverts, reenters or does other unusual control flow? There are no problems here.
SafeTransferLib.safeApprove(token, address(uniV2Router), tokensToLock)What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? There is no return value here.
What happens if it reverts, reenters or does other unusual control flow? There are no problems here.
SafeTransferLib.safeApprove(address(data.quote), address(uniV2Router), data.quoteBoughtByCurve)What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? There is no return value here.
What happens if it reverts, reenters or does other unusual control flow? There are no problems here.
this.uniV2Router.addLiquidity(token, address(this.quote), tokensToLock, data.quoteBoughtByCurve, tokensToLock, data.quoteBoughtByCurve, address(this), block.timestamp)What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? Returned values are not used here.
What happens if it reverts, reenters or does other unusual control flow? If the pool already has liquidity, the initial price has already been determined. But since before that the
skimfunction has been called, this is not the case.
this._swapRemaining(d) -> SafeTransferLib.safeTransferFrom(address(data.quote), msg.sender, address(this), data.quoteAmount)What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? There is no return value here.
What happens if it reverts, reenters or does other unusual control flow? There are no problems here.
this._swapRemaining(d) -> SafeTransferLib.safeApprove(address(this.quote), address(this.uniV2Router), data.quoteAmount)What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? There is no return value here.
What happens if it reverts, reenters or does other unusual control flow? There are no problems here.
this._swapRemaining(d) -> this.uniV2Router.swapTokensForExactTokens(data.baseAmount, data.quoteAmount, path, data.recipient, block.timestamp + 1)What is controllable?
data.recipient.If the return value is controllable, how is it used and how can it go wrong? The returned values are not used.
What happens if it reverts, reenters or does other unusual control flow? This function can revert if
amountInMaxis less than the resulting input amount.
this._swapRemaining(d) -> SafeTransferLib.safeApprove(address(data.quote), address(uniV2Router), 0)What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? There is no return value here.
What happens if it reverts, reenters or does other unusual control flow? There are no problems here. Reset the current approve to
0.
this._swapRemaining(d) -> SafeTransferLib.safeTransfer(address(data.quote), msg.sender, data.quoteAmount)What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? There is no return value here.
What happens if it reverts, reenters or does other unusual control flow? There are no problems here.