remargin()
/**
* @notice remargin the strategy such that margin call risk is reduced
* @dev only callable by owner
*/
function remargin() external onlyOwner {
// harvest the funds so the positions are up to date
harvest();
// ratio of the short in the short and buffer
int256 K = (((int256(MAX_BPS) - int256(buffer)) / 2) * 1e18) /
(((int256(MAX_BPS) - int256(buffer)) / 2) + int256(buffer));
// get the price of ETH
(int256 price, ) = oracle.priceTWAPLong();
// calculate amount to unwind
int256 unwindAmount = (((price * -getMarginPositions()) -
K *
getMargin()) * 1e18) / ((1e18 + K) * price);
require(unwindAmount != 0, "no changes to margin necessary");
// check if leverage is to be reduced or increased then act accordingly
if (unwindAmount > 0) {
// swap unwindAmount long to want
uint256 wantAmount = _swap(uint256(unwindAmount), long, want);
// close unwindAmount short to margin account
mcLiquidityPool.trade(
perpetualIndex,
address(this),
unwindAmount,
price + slippageTolerance,
block.timestamp,
referrer,
tradeMode
);
// deposit long swapped collateral to margin account
_depositToMarginAccount(wantAmount);
} else if (unwindAmount < 0) {
// the buffer is too high so reduce it to the correct size
// open a perpetual short position using the unwindAmount
mcLiquidityPool.trade(
perpetualIndex,
address(this),
unwindAmount,
price - slippageTolerance,
block.timestamp,
referrer,
tradeMode
);
// withdraw funds from the margin account
int256 withdrawAmount = (price * -unwindAmount) / 1e18;
mcLiquidityPool.withdraw(
perpetualIndex,
address(this),
withdrawAmount
);
// open a long position with the withdrawn funds
_swap(uint256(withdrawAmount / DECIMAL_SHIFT), want, long);
}
positions.margin = getMargin();
positions.unitAccumulativeFunding = getUnitAccumulativeFunding();
positions.perpContracts = getMarginPositions();
emit Remargined(unwindAmount);
}Last updated