Skip to content

Commit 4aa6d43

Browse files
authored
fix: Adjust applicationo of "unitilizedLeveragePercentage" in calculation of maxBorrow (#192)
* fix: Apply unitilizedLeveragePercentage to maxBorrowCollateral only when levering up * fix: Add separate unitilizedLeveragePercentage parameter for delevering
1 parent e89098c commit 4aa6d43

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

contracts/adapters/MorphoLeverageStrategyExtension.sol

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ contract MorphoLeverageStrategyExtension is BaseExtension {
101101

102102
struct ExecutionSettings {
103103
uint256 unutilizedLeveragePercentage; // Percent of max borrow left unutilized in precise units (1% = 10e16)
104+
uint256 unutilizedLeveragePercentageDelever; // Percent of max borrow left unutilized when delevering
104105
uint256 slippageTolerance; // % in precise units to price min token receive amount from trade quantities
105106
uint256 twapCooldownPeriod; // Cooldown period required since last trade timestamp in seconds
106107
}
@@ -161,6 +162,7 @@ contract MorphoLeverageStrategyExtension is BaseExtension {
161162
);
162163
event ExecutionSettingsUpdated(
163164
uint256 _unutilizedLeveragePercentage,
165+
uint256 _unutilizedLeveragePercentageDelever,
164166
uint256 _twapCooldownPeriod,
165167
uint256 _slippageTolerance
166168
);
@@ -490,6 +492,7 @@ contract MorphoLeverageStrategyExtension is BaseExtension {
490492

491493
emit ExecutionSettingsUpdated(
492494
execution.unutilizedLeveragePercentage,
495+
execution.unutilizedLeveragePercentageDelever,
493496
execution.twapCooldownPeriod,
494497
execution.slippageTolerance
495498
);
@@ -960,6 +963,10 @@ contract MorphoLeverageStrategyExtension is BaseExtension {
960963
_execution.unutilizedLeveragePercentage <= PreciseUnitMath.preciseUnit(),
961964
"Unutilized leverage must be <100%"
962965
);
966+
require (
967+
_execution.unutilizedLeveragePercentageDelever <= PreciseUnitMath.preciseUnit(),
968+
"Unutilized leverage on delever must be <100%"
969+
);
963970
require (
964971
_execution.slippageTolerance <= PreciseUnitMath.preciseUnit(),
965972
"Slippage tolerance must be <100%"
@@ -1123,14 +1130,16 @@ contract MorphoLeverageStrategyExtension is BaseExtension {
11231130
// Note NetBorrow Limit is already denominated in borrow asset
11241131
uint256 netBorrowLimit = _actionInfo.collateralBalance
11251132
.mul(_actionInfo.collateralPrice).div(MORPHO_ORACLE_PRICE_SCALE)
1126-
.preciseMul(_actionInfo.lltv)
1127-
.preciseMul(PreciseUnitMath.preciseUnit().sub(execution.unutilizedLeveragePercentage));
1133+
.preciseMul(_actionInfo.lltv);
1134+
11281135
if (_isLever) {
11291136
return netBorrowLimit
1137+
.preciseMul(PreciseUnitMath.preciseUnit().sub(execution.unutilizedLeveragePercentage))
11301138
.sub(_actionInfo.borrowBalance)
11311139
.mul(MORPHO_ORACLE_PRICE_SCALE).div(_actionInfo.collateralPrice);
11321140
} else {
11331141
return _actionInfo.collateralBalance
1142+
.preciseMul(PreciseUnitMath.preciseUnit().sub(execution.unutilizedLeveragePercentageDelever))
11341143
.preciseMul(netBorrowLimit.sub(_actionInfo.borrowBalance))
11351144
.preciseDiv(netBorrowLimit);
11361145
}

test/integration/ethereum/morphoLeverageStrategyExtension.spec.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ if (process.env.INTEGRATIONTEST) {
385385
const rebalanceInterval = BigNumber.from(86400);
386386

387387
const unutilizedLeveragePercentage = ether(0.01);
388+
const unutilizedLeveragePercentageDelever = ZERO;
388389
const twapMaxTradeSize = ether(0.5);
389390
const twapCooldownPeriod = BigNumber.from(3000);
390391
const slippageTolerance = ether(0.01);
@@ -412,6 +413,7 @@ if (process.env.INTEGRATIONTEST) {
412413
};
413414
execution = {
414415
unutilizedLeveragePercentage: unutilizedLeveragePercentage,
416+
unutilizedLeveragePercentageDelever: unutilizedLeveragePercentageDelever,
415417
twapCooldownPeriod: twapCooldownPeriod,
416418
slippageTolerance: slippageTolerance,
417419
};
@@ -473,6 +475,7 @@ if (process.env.INTEGRATIONTEST) {
473475
};
474476
subjectExecutionSettings = {
475477
unutilizedLeveragePercentage: ether(0.01),
478+
unutilizedLeveragePercentageDelever: ZERO,
476479
twapCooldownPeriod: BigNumber.from(120),
477480
slippageTolerance: ether(0.01),
478481
};
@@ -553,6 +556,9 @@ if (process.env.INTEGRATIONTEST) {
553556
expect(execution.unutilizedLeveragePercentage).to.eq(
554557
subjectExecutionSettings.unutilizedLeveragePercentage,
555558
);
559+
expect(execution.unutilizedLeveragePercentageDelever).to.eq(
560+
subjectExecutionSettings.unutilizedLeveragePercentageDelever
561+
);
556562
expect(execution.twapCooldownPeriod).to.eq(subjectExecutionSettings.twapCooldownPeriod);
557563
expect(execution.slippageTolerance).to.eq(subjectExecutionSettings.slippageTolerance);
558564
});
@@ -650,6 +656,16 @@ if (process.env.INTEGRATIONTEST) {
650656
});
651657
});
652658

659+
describe("when unutilizedLeveragePercentageDelever is >100%", async () => {
660+
beforeEach(async () => {
661+
subjectExecutionSettings.unutilizedLeveragePercentageDelever = ether(1.1);
662+
});
663+
664+
it("should revert", async () => {
665+
await expect(subject()).to.be.revertedWith("Unutilized leverage on delever must be <100%");
666+
});
667+
});
668+
653669
describe("when slippage tolerance is >100%", async () => {
654670
beforeEach(async () => {
655671
subjectExecutionSettings.slippageTolerance = ether(1.1);
@@ -2967,7 +2983,6 @@ if (process.env.INTEGRATIONTEST) {
29672983
);
29682984

29692985
const expectedFirstPositionUnit = initialPositions[0].unit.sub(maxRedeemCollateral);
2970-
console.log("expectedFirstPositionUnit", expectedFirstPositionUnit.toString());
29712986

29722987
expect(initialPositions.length).to.eq(2);
29732988
expect(currentPositions.length).to.eq(2);
@@ -3430,6 +3445,7 @@ if (process.env.INTEGRATIONTEST) {
34303445
const oldExecution = await leverageStrategyExtension.getExecution();
34313446
const newExecution: ExecutionSettings = {
34323447
unutilizedLeveragePercentage: oldExecution.unutilizedLeveragePercentage,
3448+
unutilizedLeveragePercentageDelever: ZERO,
34333449
twapCooldownPeriod: oldExecution.twapCooldownPeriod,
34343450
slippageTolerance: ether(0.05),
34353451
};
@@ -3851,6 +3867,7 @@ if (process.env.INTEGRATIONTEST) {
38513867
const initializeSubjectVariables = () => {
38523868
subjectExecutionSettings = {
38533869
unutilizedLeveragePercentage: ether(0.05),
3870+
unutilizedLeveragePercentageDelever: ZERO,
38543871
twapCooldownPeriod: BigNumber.from(360),
38553872
slippageTolerance: ether(0.02),
38563873
};
@@ -3872,6 +3889,9 @@ if (process.env.INTEGRATIONTEST) {
38723889
expect(execution.unutilizedLeveragePercentage).to.eq(
38733890
subjectExecutionSettings.unutilizedLeveragePercentage,
38743891
);
3892+
expect(execution.unutilizedLeveragePercentageDelever).to.eq(
3893+
subjectExecutionSettings.unutilizedLeveragePercentageDelever,
3894+
);
38753895
expect(execution.twapCooldownPeriod).to.eq(subjectExecutionSettings.twapCooldownPeriod);
38763896
expect(execution.slippageTolerance).to.eq(subjectExecutionSettings.slippageTolerance);
38773897
});
@@ -3881,6 +3901,7 @@ if (process.env.INTEGRATIONTEST) {
38813901
.to.emit(leverageStrategyExtension, "ExecutionSettingsUpdated")
38823902
.withArgs(
38833903
subjectExecutionSettings.unutilizedLeveragePercentage,
3904+
subjectExecutionSettings.unutilizedLeveragePercentageDelever,
38843905
subjectExecutionSettings.twapCooldownPeriod,
38853906
subjectExecutionSettings.slippageTolerance,
38863907
);

utils/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export interface MethodologySettings {
7373

7474
export interface ExecutionSettings {
7575
unutilizedLeveragePercentage: BigNumber;
76+
unutilizedLeveragePercentageDelever: BigNumber;
7677
twapCooldownPeriod: BigNumber;
7778
slippageTolerance: BigNumber;
7879
}

0 commit comments

Comments
 (0)