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
tokenId
Validation: There is a check inside the
_getLoan
function thatmsg.sender
is creator of loan.Impact: A
tokenId
refers to an existing_loan
, which will be rebalancing.
amounts
Validation: There is a check that
amount
<=s.TOKEN_BALANCE
insideexternalSwap->sendAndCalcCollateralLPTokens->sendToken
function.Impact: Amount of tokens from the pool to flash loan.
lpTokens
Validation: There is a check that
lpTokens
<=s.LP_TOKEN_BALANCE
insideexternalSwap->sendCFMMLPTokens->sendToken
function.Impact: Amount of CFMM LP tokens being flash loaned.
to
Validation: Cannot be zero address.
Impact: Address that will receive the collateral tokens and/or
lpTokens
in flash loan.
data
Validation: 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?
to
andamount
.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 theexternalCall
function call; it will be checked inside theupdateCollateral
function.
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?
to
andamount
.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 theexternalCall
function call; it will be checked inside thecheckLPTokens
function.
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.tokensHeld
ands.TOKEN_BALANCE
will 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.tokensHeld
ands.TOKEN_BALANCE
will 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
_cfmm
balance of this contract. This new balance will be compared with the balance before theexternalCall
function call, and if new value is less, the transaction will be reverted. Also, update thes.LP_TOKEN_BALANCE
ands.LP_INVARIANT
.