This then leaves the users original supplied collateral in the Aave position with no way to retrieve it, effectively locking the tokens.
function _executeUnwindOperation(address _asset, uint256 _amount, uint256 _premium, bytes calldata _params)
internal
returns (bool)
{
@>
uint256 withdrawnAmount;
{
(,, uint256 liqThreshold,,,,,,,) =
aaveDataProvider.getReserveConfigurationData(unwindParams.collateralToken);
uint256 debtTokenPrice = IStrataxOracle(strataxOracle).getPrice(_asset);
uint256 collateralTokenPrice = IStrataxOracle(strataxOracle).getPrice(unwindParams.collateralToken);
require(debtTokenPrice > 0 && collateralTokenPrice > 0, "Invalid prices");
@>
@> uint256 collateralToWithdraw = (
@> _amount * debtTokenPrice * (10 ** IERC20(unwindParams.collateralToken).decimals()) * LTV_PRECISION
@> ) / (collateralTokenPrice * (10 ** IERC20(_asset).decimals()) * liqThreshold);
@> withdrawnAmount = aavePool.withdraw(unwindParams.collateralToken, uint256(unwindParams.collateralToWithdraw), address(this));
}
}
function test_OpenAndUnwindLocksUserCollateral() public {
if (!hasApiKey && !usesSavedData) {
vm.skip(true);
}
console.log("");
console.log("============================================================");
console.log(" STRATAX OPEN AND UNWIND TEST: Locks User Collateral");
console.log("============================================================");
console.log("");
console.log("------------------------------------------------------------");
console.log(" POSITION: USDC Collateral / WETH Borrow");
console.log("------------------------------------------------------------");
uint256 collateralAmount = 1000 * 10 ** 6;
(uint256 flashLoanAmount, uint256 borrowAmount) = stratax.calculateOpenParams(
Stratax.TradeDetails({
collateralToken: address(USDC),
borrowToken: address(WETH),
desiredLeverage: 30_000,
collateralAmount: collateralAmount,
collateralTokenPrice: 0,
borrowTokenPrice: 0,
collateralTokenDec: 6,
borrowTokenDec: 18
})
);
(bytes memory openSwapData,) = get1inchSwapData(WETH, USDC, borrowAmount, address(stratax));
deal(USDC, ownerTrader, collateralAmount);
console.log(" [DEAL] USDC to ownerTrader: $", collateralAmount / 1e6);
console.log("");
console.log(" [OPEN] Parameters:");
console.log(" Collateral (USDC): $", collateralAmount / 1e6);
console.log(" Flash Loan (USDC): $", flashLoanAmount / 1e6);
console.log(" Borrow (WETH): ", borrowAmount / 1e18,".",(borrowAmount % 1e18) / 1e14);
console.log("");
console.log(" [OPEN] User Wallet Before:");
console.log(" USDC: $", IERC20(USDC).balanceOf(ownerTrader) / 1e6);
vm.startPrank(ownerTrader);
IERC20(USDC).approve(address(stratax), collateralAmount);
stratax.createLeveragedPosition(
USDC, flashLoanAmount, collateralAmount, WETH, borrowAmount, openSwapData, (flashLoanAmount * 950) / 1000
);
(uint256 totalCollateralAfterOpen, uint256 totalDebtAfterOpen,,,, uint256 healthFactorAfterOpen) =
IPool(AAVE_POOL).getUserAccountData(address(stratax));
console.log("");
console.log(" [OPEN] Aave Position After:");
console.log(" Total Collateral (USD): $", totalCollateralAfterOpen / 1e8);
console.log(" Total Debt (USD): $", totalDebtAfterOpen / 1e8);
console.log(" Health Factor: ", healthFactorAfterOpen / 1e14);
assertTrue(totalCollateralAfterOpen > 0, "Should have collateral");
assertTrue(totalDebtAfterOpen > 0, "Should have debt");
assertTrue(healthFactorAfterOpen > 1e18, "Health factor should be above 1");
console.log("");
console.log(" [UNWIND] Calculating unwind params...");
(uint256 collateralToWithdraw, uint256 debtAmount) = stratax.calculateUnwindParams(USDC, WETH);
console.log(" Collateral to Withdraw (USDC): $", collateralToWithdraw / 1e6);
console.log(" Debt to Repay (WETH): ", debtAmount / 1e18,".",(debtAmount % 1e18) / 1e14);
console.log(" [UNWIND] Fetching 1inch swap data...");
(bytes memory unwindSwapData,) = get1inchSwapData(USDC, WETH, collateralToWithdraw, address(stratax));
console.log(" [UNWIND] Executing unwind...");
stratax.unwindPosition(USDC, collateralToWithdraw, WETH, debtAmount, unwindSwapData, (debtAmount * 950) / 1000);
vm.stopPrank();
(uint256 totalCollateralAfterUnwind, uint256 totalDebtAfterUnwind,,,,) =
IPool(AAVE_POOL).getUserAccountData(address(stratax));
uint256 userUsdcAfter = IERC20(USDC).balanceOf(ownerTrader);
uint256 userWethAfter = IERC20(WETH).balanceOf(ownerTrader);
console.log("");
console.log(" [UNWIND] Aave Position After:");
console.log(" Total Collateral (USD): $", totalCollateralAfterUnwind / 1e8);
console.log(" Total Debt (USD): $", totalDebtAfterUnwind / 1e8);
console.log("");
console.log(" [UNWIND] User Wallet After:");
console.log(" USDC: ", userUsdcAfter / 1e6);
console.log(" WETH: ", userWethAfter / 1e18);
console.log("");
console.log("============================================================");
console.log(" RESULT");
console.log("============================================================");
console.log(" User deposited (USDC): $", collateralAmount / 1e6);
console.log(" User received back (USDC): $", userUsdcAfter / 1e6);
console.log(" Locked in Aave (USD): $", totalCollateralAfterUnwind / 1e8);
console.log(" Remaining Aave debt (USD): $", totalDebtAfterUnwind / 1e8);
console.log("============================================================");
console.log("");
assertTrue(totalDebtAfterUnwind == 0, "All debt should be repaid");
assertTrue(totalCollateralAfterUnwind > 0, "Collateral is still locked in Aave");
assertTrue(
userUsdcAfter == 0,
"User received no USDC back - funds permanently locked in Aave position"
);
}