Skip to content

Commit 4469cf9

Browse files
authored
fix(FlashMintLeveragedExtended): Avoid undercollateralization revertion. (#172)
Send 1 wei of aToken to set token to try to avoid undercollateralization revertion
1 parent 212d252 commit 4469cf9

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

contracts/exchangeIssuance/FlashMintLeveraged.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ contract FlashMintLeveraged is ReentrancyGuard, IFlashLoanRecipient{
474474
DecodedParams memory _decodedParams
475475
)
476476
internal
477+
virtual
477478
{
478479
// Deposit collateral token obtained from flashloan to get the respective aToken position required for issuance
479480
_depositCollateralToken(_collateralToken, _collateralTokenAmountNet);
@@ -504,6 +505,7 @@ contract FlashMintLeveraged is ReentrancyGuard, IFlashLoanRecipient{
504505
DecodedParams memory _decodedParams
505506
)
506507
internal
508+
virtual
507509
{
508510
// Redeem set using debt tokens obtained from flashloan
509511
_redeemSet(

contracts/exchangeIssuance/FlashMintLeveragedExtended.sol

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,5 +701,83 @@ contract FlashMintLeveragedExtended is FlashMintLeveraged, Ownable {
701701
IWETH(addresses.weth).withdraw(ethObtained);
702702
msg.sender.transfer(ethObtained);
703703
}
704+
705+
/**
706+
* @dev Same as in FlashMintLeveraged but with added transfer of 1 wei of atoken to the set token to avoid "undercollateralized" revertion
707+
*/
708+
function _performIssuance(
709+
address _collateralToken,
710+
uint256 _collateralTokenAmountNet,
711+
uint256 _premium,
712+
DecodedParams memory _decodedParams
713+
)
714+
internal
715+
override
716+
{
717+
// Deposit collateral token obtained from flashloan to get the respective aToken position required for issuance
718+
_depositCollateralToken(_collateralToken, _collateralTokenAmountNet);
719+
720+
// Avoid "undercollateralized" revertion due to rounding error here: https://github.com/IndexCoop/index-protocol/blob/1a587d93d273d9004d03f1235c395f6f7cd147dc/contracts/protocol/lib/IssuanceValidationUtils.sol#L63
721+
IERC20(_decodedParams.leveragedTokenData.collateralAToken).safeTransfer(address(_decodedParams.setToken), 1);
722+
723+
// Issue set using the aToken returned by deposit step
724+
_issueSet(_decodedParams.setToken, _decodedParams.setAmount, _decodedParams.originalSender);
725+
// Obtain necessary collateral tokens to repay flashloan
726+
uint amountInputTokenSpent = _obtainCollateralTokens(
727+
_collateralToken,
728+
_collateralTokenAmountNet + _premium,
729+
_decodedParams
730+
);
731+
require(amountInputTokenSpent <= _decodedParams.limitAmount, "IIA");
732+
}
733+
734+
/**
735+
* @dev Same as in FlashMintLeveraged but with added transfer of 1 wei of atoken to the set token to avoid "undercollateralized" revertion
736+
*/
737+
function _performRedemption(
738+
address _debtToken,
739+
uint256 _debtTokenAmountNet,
740+
uint256 _premium,
741+
DecodedParams memory _decodedParams
742+
)
743+
internal
744+
override
745+
{
746+
// Avoid "undercollateralized" revertion due to rounding error here: https://github.com/IndexCoop/index-protocol/blob/1a587d93d273d9004d03f1235c395f6f7cd147dc/contracts/protocol/lib/IssuanceValidationUtils.sol#L6
747+
IERC20(_decodedParams.leveragedTokenData.collateralAToken).safeTransfer(address(_decodedParams.setToken), 1);
748+
749+
// Redeem set using debt tokens obtained from flashloan
750+
_redeemSet(
751+
_decodedParams.setToken,
752+
_decodedParams.setAmount,
753+
_decodedParams.originalSender
754+
);
755+
// Withdraw underlying collateral token from the aToken position returned by redeem step
756+
_withdrawCollateralToken(
757+
_decodedParams.leveragedTokenData.collateralToken,
758+
_decodedParams.leveragedTokenData.collateralAmount - ROUNDING_ERROR_MARGIN
759+
);
760+
// Obtain debt tokens required to repay flashloan by swapping the underlying collateral tokens obtained in withdraw step
761+
uint256 collateralTokenSpent = _swapCollateralForDebtToken(
762+
_debtTokenAmountNet + _premium,
763+
_debtToken,
764+
_decodedParams.leveragedTokenData.collateralAmount,
765+
_decodedParams.leveragedTokenData.collateralToken,
766+
_decodedParams.collateralAndDebtSwapData
767+
);
768+
// Liquidate remaining collateral tokens for the payment token specified by user
769+
uint256 amountOutputToken = _liquidateCollateralTokens(
770+
collateralTokenSpent,
771+
_decodedParams.setToken,
772+
_decodedParams.setAmount,
773+
_decodedParams.originalSender,
774+
_decodedParams.paymentToken,
775+
_decodedParams.limitAmount,
776+
_decodedParams.leveragedTokenData.collateralToken,
777+
_decodedParams.leveragedTokenData.collateralAmount - 2*ROUNDING_ERROR_MARGIN,
778+
_decodedParams.paymentTokenSwapData
779+
);
780+
require(amountOutputToken >= _decodedParams.limitAmount, "IOA");
781+
}
704782
}
705783

0 commit comments

Comments
 (0)