Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add method to exit collateral position after disengaging #191

Merged
merged 1 commit into from
Nov 11, 2024
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
22 changes: 22 additions & 0 deletions contracts/adapters/MorphoLeverageStrategyExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ contract MorphoLeverageStrategyExtension is BaseExtension {
event ExchangeRemoved(
string _exchangeName
);
event CollateralWithdrawn();

/* ============ Modifiers ============ */

Expand Down Expand Up @@ -457,6 +458,16 @@ contract MorphoLeverageStrategyExtension is BaseExtension {
);
}

/**
* OPERATOR ONLY: Withdraw all collateral from morpho
*
* Note: Can only be executed after fully deleveraging / disengaging the strategy. Will revert otherwise.
*/
function exitCollateralPosition() external onlyOperator {
_exitCollateralPosition();
emit CollateralWithdrawn();
}

/**
* OPERATOR ONLY: Set methodology settings and check new settings are valid. Note: Need to pass in existing parameters if only changing a few settings. Must not be
* in a rebalance.
Expand Down Expand Up @@ -770,6 +781,17 @@ contract MorphoLeverageStrategyExtension is BaseExtension {
invokeManager(address(strategy.leverageModule), enterPositionCallData);
}

function _exitCollateralPosition()
internal
{
bytes memory exitPositionCallData = abi.encodeWithSignature(
"exitCollateralPosition(address)",
address(strategy.setToken)
);

invokeManager(address(strategy.leverageModule), exitPositionCallData);
}

/**
* Calculate notional rebalance quantity, whether to chunk rebalance based on max trade size and max borrow and invoke lever on MorphoLeverageModule
*
Expand Down
38 changes: 26 additions & 12 deletions external/abi/set/MorphoLeverageModule.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ if (process.env.INTEGRATIONTEST) {
const [, borrowShares, collateral] = await morpho.position(marketId, setToken.address);
const collateralTokenBalance = await wsteth.balanceOf(setToken.address);
const collateralTotalBalance = collateralTokenBalance.add(collateral);
const [, , totalBorrowAssets, totalBorrowShares, , ] = await morpho.market(marketId);
const [, , totalBorrowAssets, totalBorrowShares, ,] = await morpho.market(marketId);
const borrowAssets = sharesToAssetsUp(borrowShares, totalBorrowAssets, totalBorrowShares);
return { collateralTotalBalance, borrowAssets };
}
Expand Down Expand Up @@ -3606,6 +3606,22 @@ if (process.env.INTEGRATIONTEST) {
expect(BigNumber.from(newSecondPosition.unit)).to.gt(ZERO);
expect(newSecondPosition.module).to.eq(ADDRESS_ZERO);
});

it("can run exitCollateralPosition afterwards", async () => {
await subject();

const [, , collateralBefore] = await morpho.position(marketId, setToken.address);
await leverageStrategyExtension.exitCollateralPosition();
const [, , collateralAfter] = await morpho.position(marketId, setToken.address);
expect(await wsteth.balanceOf(setToken.address)).to.eq(collateralBefore);
expect(collateralAfter).to.eq(ZERO);
});

it("can't run exitCollateralPosition without disengaging", async () => {
await expect(leverageStrategyExtension.exitCollateralPosition()).to.be.revertedWith(
"Borrow balance must be 0",
);
});
},
);
});
Expand Down
Loading