Function: buy(address token, address recipient, uint256 amountOutBase, uint256 worstAmountInQuote)
This function allows buying amountOutBase
tokens, but the amount of USDC to be spent is limited by worstAmountInQuote
. After selling the BONDING_SUPPLY
amount of LaunchToken, the remaining liquidity will be transferred to the Uniswap pool, and the current function will become unavailable for this token
.
Inputs
token
Control: Full control.
Constraints: The status
active
of this token should betrue
, andlaunches
should contain thetoken
info.Impact: The address of the LaunchToken to be bought.
recipient
Control: Full control.
Constraints: No constraints.
Impact: The address of the recipient of LaunchToken.
amountOutBase
Control: Full control.
Constraints: The total sold amount of LaunchToken cannot exceed
BONDING_SUPPLY
.Impact: The desired amount of LaunchToken to be bought.
worstAmountInQuote
Control: Full control.
Constraints: No constraints.
Impact: The limited amount of USDC to be spent.
Branches and code coverage
Intended branches
amountOutBase
is less thanBONDING_SUPPLY
.amountOutBase
is greater thanBONDING_SUPPLY
but has been successfully limited byBONDING_SUPPLY
.The remaining tokens were successfully swapped using the Uniswap pool
If the swap using the Uniswap pool failed, the remaining tokens were transferred to the caller.
Negative behavior
The
token
status is not active, because it doesn't existsThe
token
status is not active, because liquidity was transferred to the Uniswap pool.worstAmountInQuote
is less thanamountInQuote
.
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.
data.bondingCurve.getAverageCostInY(token, this.baseToX(data.baseSoldFromCurve), this.baseToX(nextAmountSold))
What is controllable? N/A.
If the return value is controllable, how is it used and how can it go wrong? The returned
amountInQuote
can be less or more than expected. IfamountInQuote
is less than expected, the user can buy tokens cheaper than expected; otherwise, the resulting amount can be more expensive than expected but not more thanworstAmountInQuote
.What happens if it reverts, reenters or does other unusual control flow? It has a
nonReentrant
modifier.
SafeTransferLib.safeTransfer(token, recipient, amountOutBase)
What is controllable?
recipient
andamountOutBase
.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(this.quoteAsset), 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(this.router), 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(this.quoteAsset), address(this.router), 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.router.addLiquidity(token, address(this.quoteAsset), tokensToLock, data.quoteBoughtByCurve, 0, 0, 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. Therefore, only the portion of liquidity that matches the current rate will be added, rather than the full amount.
this._swapRemainingQuote(token, recipient, remainingQuote) -> SafeTransferLib.safeTransferFrom(address(this.quoteAsset), msg.sender, address(this), remainingQuote)
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._swapRemainingQuote(token, recipient, remainingQuote) -> SafeTransferLib.safeApprove(address(this.quoteAsset), address(this.router), remainingQuote)
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._swapRemainingQuote(token, recipient, remainingQuote) -> this.router.swapExactTokensForTokens(remainingQuote, 1, path, recipient, block.timestamp + 300)
What is controllable?
recipient
.If the return value is controllable, how is it used and how can it go wrong? Returns the output amount of LaunchToken received as a result of the swap. This amount is added to the total LaunchToken received by the recipient.
What happens if it reverts, reenters or does other unusual control flow? this function can revert if
amountOutMin
is less than the resulting output amount, but since it is called withamountOutMin
set to1
, it is unlikely to revert.
this._swapRemainingQuote(token, recipient, remainingQuote) -> SafeTransferLib.safeTransfer(address(this.quoteAsset), msg.sender, remainingQuote)
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.