Function: _rebalanceExternally(uint256 tokenId, uint128[] amounts, uint256 lpTokens, address to, byte[] data)
Allows the loan's creator to use a flash loan and also rebalance a loan’s collateral.
Inputs
tokenIdValidation: There is a check inside the
_getLoanfunction thatmsg.senderis creator of loan.Impact: A
tokenIdrefers to an existing_loan, which will be rebalancing.
amountsValidation: There is a check that
amount<=s.TOKEN_BALANCEinsideexternalSwap->sendAndCalcCollateralLPTokens->sendTokenfunction.Impact: Amount of tokens from the pool to flash loan.
lpTokensValidation: There is a check that
lpTokens<=s.LP_TOKEN_BALANCEinsideexternalSwap->sendCFMMLPTokens->sendTokenfunction.Impact: Amount of CFMM LP tokens being flash loaned.
toValidation: Cannot be zero address.
Impact: Address that will receive the collateral tokens and/or
lpTokensin flash loan.
dataValidation: No checks.
Impact: Custom user data. It is passed to the
externalCall.
Branches and code coverage (including function calls)
Intended branches
Negative behavior
Function call analysis
externalSwap(_loan, s.cfmm, amounts, lpTokens, to, data) -> sendAndCalcCollateralLPTokens(to, amounts, lastCFMMTotalSupply) -> sendToken(IERC20(tokens[i]), to, amounts[i], s.TOKEN_BALANCE[i], type(uint128).max) -> GammaSwapLibrary.safeTransfer(token, to, amount)External/Internal? External.
Argument control?
toandamount.Impact: The caller can transfer any number of tokens that is less than
s.TOKEN_BALANCE[i], but they must return the same or a larger amount after theexternalCallfunction call; it will be checked inside theupdateCollateralfunction.
externalSwap(_loan, s.cfmm, amounts, lpTokens, to, data) -> sendCFMMLPTokens(_cfmm, to, lpTokens) -> sendToken(IERC20(_cfmm), to, lpTokens, s.LP_TOKEN_BALANCE, type(uint256).max) -> GammaSwapLibrary.safeTransfer(token, to, amount)External/Internal? External.
Argument control?
toandamount.Impact: The caller can transfer any number of tokens that is less than
s.LP_TOKEN_BALANCE, but they must return the same or a larger amount after theexternalCallfunction call; it will be checked inside thecheckLPTokensfunction.
externalSwap(_loan, s.cfmm, amounts, lpTokens, to, data) -> IExternalCallee(to).externalCall(msg.sender, amounts, lpTokens, data);External/Internal? External.
Argument control?
msg.sender,amounts,lpTokens, anddata.Impact: The reentrancy is not possible because the other important external functions have
lock. If caller does not return enough amount of tokens, the transaction will be reverted.
externalSwap(_loan, s.cfmm, amounts, lpTokens, to, data) -> updateCollateral(_loan) -> GammaSwapLibrary.balanceOf(IERC20(tokens[i]), address(this)); -> address(_token).staticcall(abi.encodeWithSelector(_token.balanceOf.selector, _address))External/Internal? External.
Argument control? No.
Impact: Return the current token balance of this contract. This balance will be compared with the last
tokenBalance[i]value; if the balance was increased, the_loan.tokensHeldands.TOKEN_BALANCEwill be increased too. But if the balance was decreased, the withdrawn value will be checked that it is no more thantokensHeld[i](available collateral) and the_loan.tokensHeldands.TOKEN_BALANCEwill be increased.
externalSwap(_loan, s.cfmm, amounts, lpTokens, to, data) -> checkLPTokens(_cfmm, prevLpTokenBalance, lastCFMMInvariant, lastCFMMTotalSupply) -> GammaSwapLibrary.balanceOf(IERC20(_cfmm), address(this))External/Internal? External.
Argument control? No.
Impact: Return the current
_cfmmbalance of this contract. This new balance will be compared with the balance before theexternalCallfunction call, and if new value is less, the transaction will be reverted. Also, update thes.LP_TOKEN_BALANCEands.LP_INVARIANT.