Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,55 @@ contract VaultExternalLiquidationStrategy is CPMMExternalLiquidationStrategy, Va
override(BaseRepayStrategy,VaultBaseLiquidationStrategy) returns(uint256 lpTokenPrincipal, uint256 remainingLiquidity) {
return super.payLoanLiquidity(liquidity, loanLiquidity, _loan);
}

/// @dev See {IExternalLiquidationStrategy-_liquidateExternally}.
function _liquidateExternally(uint256 tokenId, uint128[] calldata amounts, uint256 lpTokens, address to, bytes calldata data) external override lock beforeLiquidation virtual
returns(uint256, uint128[] memory) {
// Check can liquidate loan and get loan with updated loan liquidity and collateral
// No need to check if msg.sender has permission
LibStorage.Loan storage _loan = _getExistingLoan(tokenId);

(LiquidatableLoan memory _liqLoan,) = getLiquidatableLoan(_loan, tokenId);

uint256 liquiditySwapped;
(liquiditySwapped,) = externalSwap(_loan, s.cfmm, amounts, lpTokens, to, data); // of the CFMM LP Tokens that we pulled out, more have to come back

for(uint256 i = 0; i < _liqLoan.tokensHeld.length;) {
if(_liqLoan.tokensHeld[i] > _loan.tokensHeld[i]) revert CollateralShortfall();
unchecked {
++i;
}
}

uint256 loanLiquidity = _liqLoan.loanLiquidity;
if(liquiditySwapped > loanLiquidity && _loan.refType != 3) {
uint256 swapFee = calcExternalSwapFee(liquiditySwapped, loanLiquidity) / 2;
uint256 borrowedInvariant = s.BORROWED_INVARIANT + swapFee;
s.LP_TOKEN_BORROWED_PLUS_INTEREST = convertInvariantToLPRoundUp(borrowedInvariant, s.lastCFMMTotalSupply, s.lastCFMMInvariant);
s.BORROWED_INVARIANT = uint128(borrowedInvariant);
loanLiquidity += swapFee;
_loan.liquidity = uint128(loanLiquidity);
_liqLoan.payableInternalLiquidity += swapFee;
_liqLoan.loanLiquidity = loanLiquidity;
}

_liqLoan.writeDownAmt = payLiquidatableLoan(_liqLoan, 0, true);

uint128[] memory refund;
(refund, _liqLoan.tokensHeld) = refundLiquidator(_liqLoan.payableInternalLiquidityPlusFee, _liqLoan.internalCollateral, _liqLoan.tokensHeld);

_loan.tokensHeld = _liqLoan.tokensHeld; // Clear loan collateral

onLoanUpdate(_loan, tokenId);

emit ExternalSwap(tokenId, amounts, lpTokens, uint128(liquiditySwapped), TX_TYPE.EXTERNAL_LIQUIDATION);

emit Liquidation(tokenId, uint128(_liqLoan.collateral), uint128(loanLiquidity - _liqLoan.writeDownAmt), uint128(_liqLoan.writeDownAmt), uint128(_liqLoan.internalFee), TX_TYPE.EXTERNAL_LIQUIDATION);

emit LoanUpdated(tokenId, _liqLoan.tokensHeld, 0, 0, 0, 0, TX_TYPE.EXTERNAL_LIQUIDATION);

emit PoolUpdated(s.LP_TOKEN_BALANCE, s.LP_TOKEN_BORROWED, s.LAST_BLOCK_NUMBER, s.accFeeIndex, s.LP_TOKEN_BORROWED_PLUS_INTEREST, s.LP_INVARIANT, s.BORROWED_INVARIANT, s.CFMM_RESERVES, TX_TYPE.EXTERNAL_LIQUIDATION);

return(loanLiquidity, refund);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,40 @@ contract VaultExternalRebalanceStrategy is VaultBaseLongStrategy, ExternalRebala

return lpTokens;
}

/// @dev See {IExternalLongStrategy-_rebalanceExternally}.
function _rebalanceExternally(uint256 tokenId, uint128[] calldata amounts, uint256 lpTokens, address to, bytes calldata data) external override lock virtual returns(uint256 loanLiquidity, uint128[] memory tokensHeld) {
// Get loan for tokenId, revert if not loan creator
LibStorage.Loan storage _loan = _getLoan(tokenId);

// Update liquidity debt to include accrued interest since last update
loanLiquidity = updateLoan(_loan);

address _cfmm = s.cfmm;

uint256 liquiditySwapped;
// Calculate amounts to swap from deltas and available loan collateral
(liquiditySwapped, tokensHeld) = externalSwap(_loan, _cfmm, amounts, lpTokens, to, data);
_loan.tokensHeld = tokensHeld;

if(liquiditySwapped > loanLiquidity && _loan.refType != 3) {
uint256 fee = calcExternalSwapFee(liquiditySwapped, loanLiquidity);
uint256 borrowedInvariant = s.BORROWED_INVARIANT + fee;
s.LP_TOKEN_BORROWED_PLUS_INTEREST = convertInvariantToLP(borrowedInvariant, s.lastCFMMTotalSupply, s.lastCFMMInvariant);
s.BORROWED_INVARIANT = uint128(borrowedInvariant);
loanLiquidity = loanLiquidity + fee;
_loan.liquidity = uint128(loanLiquidity);
}

// Check that loan is not undercollateralized after external swap
uint256 collateral = calcInvariant(_cfmm, tokensHeld) + onLoanUpdate(_loan, tokenId);
checkMargin(collateral, loanLiquidity);

emit ExternalSwap(tokenId, amounts, lpTokens, uint128(liquiditySwapped), TX_TYPE.EXTERNAL_REBALANCE);

emit LoanUpdated(tokenId, tokensHeld, uint128(loanLiquidity), _loan.initLiquidity, _loan.lpTokens, _loan.rateIndex, TX_TYPE.EXTERNAL_REBALANCE);

emit PoolUpdated(s.LP_TOKEN_BALANCE, s.LP_TOKEN_BORROWED, s.LAST_BLOCK_NUMBER, s.accFeeIndex,
s.LP_TOKEN_BORROWED_PLUS_INTEREST, s.LP_INVARIANT, s.BORROWED_INVARIANT, s.CFMM_RESERVES, TX_TYPE.EXTERNAL_REBALANCE);
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gammaswap/v1-implementations",
"version": "1.2.17",
"version": "1.2.18",
"description": "Pool and strategies implementation contracts for GammaSwap V1 protocol",
"homepage": "https://gammaswap.com",
"scripts": {
Expand Down