Skip to content

Commit

Permalink
Merge pull request #20 from bgd-labs/fix/ltv-0-updates
Browse files Browse the repository at this point in the history
fix: do not set LTV to 0 when frozen
  • Loading branch information
rustboyar authored Jun 4, 2024
2 parents 17915df + c64c5e9 commit 08e6c78
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 69 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ bun install
- [Aave v3 technical Paper](./techpaper/Aave_V3_Technical_Paper.pdf)
- [v3 to v3.0.2 production upgrade](https://github.com/bgd-labs/proposal-3.0.2-upgrade/blob/main/README.md)
- [Aave v3.1 features](./docs/Aave-v3.1-features.md)
- [Set Ltv to 0 on Freeze Feature State diagram](./docs/freeze-ltv0-states.png)

<br>

Expand Down
Binary file added docs/freeze-ltv0-states.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 22 additions & 19 deletions src/core/contracts/protocol/pool/PoolConfigurator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -162,19 +162,23 @@ abstract contract PoolConfigurator is VersionedInitializable, IPoolConfigurator
_checkNoSuppliers(asset);
}

uint256 newLtv = ltv;

if (currentConfig.getFrozen()) {
_pendingLtv[asset] = ltv;
newLtv = 0;

emit PendingLtvChanged(asset, ltv);
} else {
currentConfig.setLtv(ltv);
}

currentConfig.setLtv(ltv);

currentConfig.setLiquidationThreshold(liquidationThreshold);
currentConfig.setLiquidationBonus(liquidationBonus);

_pool.setConfiguration(asset, currentConfig);

emit CollateralConfigurationChanged(asset, ltv, liquidationThreshold, liquidationBonus);
emit CollateralConfigurationChanged(asset, newLtv, liquidationThreshold, liquidationBonus);
}

/// @inheritdoc IPoolConfigurator
Expand Down Expand Up @@ -223,27 +227,26 @@ abstract contract PoolConfigurator is VersionedInitializable, IPoolConfigurator

currentConfig.setFrozen(freeze);

uint256 currentLtv;
uint256 pendingLtv;
uint256 ltvSet;
uint256 pendingLtvSet;

if (freeze) {
currentLtv = currentConfig.getLtv();
pendingLtvSet = currentConfig.getLtv();
_pendingLtv[asset] = pendingLtvSet;
currentConfig.setLtv(0);
} else {
pendingLtv = _pendingLtv[asset];
ltvSet = _pendingLtv[asset];
currentConfig.setLtv(ltvSet);
delete _pendingLtv[asset];
}

if (currentLtv != pendingLtv) {
_pendingLtv[asset] = currentLtv;
currentConfig.setLtv(pendingLtv);

emit PendingLtvChanged(asset, currentLtv);
emit CollateralConfigurationChanged(
asset,
pendingLtv,
currentConfig.getLiquidationThreshold(),
currentConfig.getLiquidationBonus()
);
}
emit PendingLtvChanged(asset, pendingLtvSet);
emit CollateralConfigurationChanged(
asset,
ltvSet,
currentConfig.getLiquidationThreshold(),
currentConfig.getLiquidationBonus()
);

_pool.setConfiguration(asset, currentConfig);
emit ReserveFrozen(asset, freeze);
Expand Down
87 changes: 37 additions & 50 deletions tests/core/PoolConfigurator.pendingLTV.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,21 @@ contract PoolConfiguratorPendingLtvTests is TestnetProcedures {
function test_freezeReserve_ltvSetTo0() public {
// check current ltv
(
,
uint256 ltv,
uint256 liquidationThreshold,
uint256 liquidationBonus,
,
,
,
,
,
bool isFrozen
) = contracts.protocolDataProvider.getReserveConfigurationData(tokenList.usdx);
) = _getReserveParams();

assertTrue(ltv > 0);
assertEq(isFrozen, false);

// expect events to be emitted
vm.expectEmit(address(contracts.poolConfiguratorProxy));
emit PendingLtvChanged(tokenList.usdx, ltv);

vm.expectEmit(address(contracts.poolConfiguratorProxy));
emit CollateralConfigurationChanged(tokenList.usdx, 0, liquidationThreshold, liquidationBonus);

// freeze reserve
vm.prank(poolAdmin);
contracts.poolConfiguratorProxy.setReserveFreeze(tokenList.usdx, true);

// check ltv = 0
(, uint256 updatedltv, , , , , , , , bool updatedIsFrozen) = contracts
.protocolDataProvider
.getReserveConfigurationData(tokenList.usdx);
(uint256 updatedltv, , , bool updatedIsFrozen) = _getReserveParams();
assertEq(updatedltv, 0);
assertEq(updatedIsFrozen, true);

Expand All @@ -67,48 +52,30 @@ contract PoolConfiguratorPendingLtvTests is TestnetProcedures {
function test_unfreezeReserve_pendingSetToLtv() public {
// check ltv
(
,
uint256 originalLtv,
uint256 liquidationThreshold,
uint256 liquidationBonus,
,
,
,
,
,

) = contracts.protocolDataProvider.getReserveConfigurationData(tokenList.usdx);
) = _getReserveParams();

// freeze reserve
vm.startPrank(poolAdmin);
contracts.poolConfiguratorProxy.setReserveFreeze(tokenList.usdx, true);

// check ltv
(, uint256 ltv, , , , , , , , bool isFrozen) = contracts
.protocolDataProvider
.getReserveConfigurationData(tokenList.usdx);
(uint256 ltv, , , bool isFrozen) = _getReserveParams();

assertEq(ltv, 0);
assertEq(isFrozen, true);

// check pending ltv
uint256 pendingLtv = contracts.poolConfiguratorProxy.getPendingLtv(tokenList.usdx);

vm.expectEmit(address(contracts.poolConfiguratorProxy));
emit CollateralConfigurationChanged(
tokenList.usdx,
originalLtv,
liquidationThreshold,
liquidationBonus
);

// unfreeze reserve
contracts.poolConfiguratorProxy.setReserveFreeze(tokenList.usdx, false);

// check ltv is set back
(, uint256 updatedLtv, , , , , , , , bool updatedIsFrozen) = contracts
.protocolDataProvider
.getReserveConfigurationData(tokenList.usdx);
(uint256 updatedLtv, , , bool updatedIsFrozen) = _getReserveParams();

assertEq(updatedLtv, originalLtv);
assertEq(updatedLtv, pendingLtv);
Expand All @@ -122,6 +89,7 @@ contract PoolConfiguratorPendingLtvTests is TestnetProcedures {
vm.stopPrank();
}

// freeze reserve, set ltv, unfreeze reserve
function test_setLtv_ltvSetPendingLtvSet(uint256 originalLtv, uint256 ltvToSet) public {
uint256 liquidationThreshold = 86_00;
uint256 liquidationBonus = 10_500;
Expand Down Expand Up @@ -154,12 +122,7 @@ contract PoolConfiguratorPendingLtvTests is TestnetProcedures {
emit PendingLtvChanged(tokenList.usdx, ltvToSet);

vm.expectEmit(address(contracts.poolConfiguratorProxy));
emit CollateralConfigurationChanged(
tokenList.usdx,
ltvToSet,
liquidationThreshold,
liquidationBonus
);
emit CollateralConfigurationChanged(tokenList.usdx, 0, liquidationThreshold, liquidationBonus);

// setLtv
contracts.poolConfiguratorProxy.configureReserveAsCollateral(
Expand All @@ -170,17 +133,41 @@ contract PoolConfiguratorPendingLtvTests is TestnetProcedures {
);

// check ltv is still 0
(, uint256 ltv, , , , , , , , ) = contracts.protocolDataProvider.getReserveConfigurationData(
tokenList.usdx
);

assertEq(ltv, ltvToSet);
(uint256 ltv, , , ) = _getReserveParams();
assertEq(ltv, 0);

// check pending ltv
uint256 updatedPendingLtv = contracts.poolConfiguratorProxy.getPendingLtv(tokenList.usdx);

assertEq(updatedPendingLtv, ltvToSet);

// unfreeze reserve
contracts.poolConfiguratorProxy.setReserveFreeze(tokenList.usdx, false);

// check ltv is set
(uint256 updatedLtv, , , ) = _getReserveParams();
assertEq(updatedLtv, ltvToSet);

// check pending ltv is set to zero
uint256 finalPendingLtv = contracts.poolConfiguratorProxy.getPendingLtv(tokenList.usdx);
assertEq(finalPendingLtv, 0);

vm.stopPrank();
}

function _getReserveParams() internal returns (uint256, uint256, uint256, bool) {
(
,
uint256 ltv,
uint256 liquidationThreshold,
uint256 liquidationBonus,
,
,
,
,
,
bool isFrozen
) = contracts.protocolDataProvider.getReserveConfigurationData(tokenList.usdx);

return (ltv, liquidationThreshold, liquidationBonus, isFrozen);
}
}

0 comments on commit 08e6c78

Please sign in to comment.