diff --git a/contracts/interfaces/IPool.sol b/contracts/interfaces/IPool.sol index 6351c7dba..346e34385 100644 --- a/contracts/interfaces/IPool.sol +++ b/contracts/interfaces/IPool.sol @@ -104,6 +104,13 @@ interface IPool { **/ event Swap(address indexed reserve, address indexed user, uint256 rateMode); + /** + * @notice Emitted on borrow(), repay() and liquidationCall() when using isolated assets + * @param asset The address of the underlying asset of the reserve + * @param totalDebt The total isolation mode debt for the reserve + */ + event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); + /** * @notice Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve diff --git a/contracts/protocol/libraries/logic/BorrowLogic.sol b/contracts/protocol/libraries/logic/BorrowLogic.sol index d8e7900d6..28f7b25ca 100644 --- a/contracts/protocol/libraries/logic/BorrowLogic.sol +++ b/contracts/protocol/libraries/logic/BorrowLogic.sol @@ -46,6 +46,7 @@ library BorrowLogic { event RebalanceStableBorrowRate(address indexed reserve, address indexed user); event Swap(address indexed reserve, address indexed user, uint256 rateMode); + event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); /** * @notice Implements the borrow feature. Borrowing allows users that provided collateral to draw liquidity from the @@ -124,12 +125,17 @@ library BorrowLogic { } if (isolationModeActive) { - reserves[isolationModeCollateralAddress].isolationModeTotalDebt += Helpers.castUint128( + uint256 nextIsolationModeTotalDebt = reserves[isolationModeCollateralAddress] + .isolationModeTotalDebt += Helpers.castUint128( params.amount / 10 ** (reserveCache.reserveConfiguration.getDecimals() - ReserveConfiguration.DEBT_CEILING_DECIMALS) ); + emit IsolationModeTotalDebtUpdated( + isolationModeCollateralAddress, + nextIsolationModeTotalDebt + ); } reserve.updateInterestRates( diff --git a/contracts/protocol/libraries/logic/IsolationModeLogic.sol b/contracts/protocol/libraries/logic/IsolationModeLogic.sol index 1e9b4efc8..f495b80e8 100644 --- a/contracts/protocol/libraries/logic/IsolationModeLogic.sol +++ b/contracts/protocol/libraries/logic/IsolationModeLogic.sol @@ -15,6 +15,9 @@ library IsolationModeLogic { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; using UserConfiguration for DataTypes.UserConfigurationMap; + // See `IPool` for descriptions + event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt); + /** * @notice updated the isolated debt whenever a position collateralized by an isolated asset is repaid or liquidated * @param reserves The state of all the reserves @@ -47,10 +50,14 @@ library IsolationModeLogic { // since the debt ceiling does not take into account the interest accrued, it might happen that amount repaid > debt in isolation mode if (isolationModeTotalDebt <= isolatedDebtRepaid) { reserves[isolationModeCollateralAddress].isolationModeTotalDebt = 0; + emit IsolationModeTotalDebtUpdated(isolationModeCollateralAddress, 0); } else { - reserves[isolationModeCollateralAddress].isolationModeTotalDebt = - isolationModeTotalDebt - - isolatedDebtRepaid; + uint256 nextIsolationModeTotalDebt = reserves[isolationModeCollateralAddress] + .isolationModeTotalDebt = isolationModeTotalDebt - isolatedDebtRepaid; + emit IsolationModeTotalDebtUpdated( + isolationModeCollateralAddress, + nextIsolationModeTotalDebt + ); } } } diff --git a/test-suites/isolation-mode.spec.ts b/test-suites/isolation-mode.spec.ts index 0eb335323..ef5ba2a66 100644 --- a/test-suites/isolation-mode.spec.ts +++ b/test-suites/isolation-mode.spec.ts @@ -222,7 +222,11 @@ makeSuite('Isolation mode', (testEnv: TestEnv) => { const { dai, aave, users, pool } = testEnv; const borrowAmount = utils.parseEther('10'); - await pool.connect(users[1].signer).borrow(dai.address, borrowAmount, '2', 0, users[1].address); + await expect( + pool.connect(users[1].signer).borrow(dai.address, borrowAmount, '2', 0, users[1].address) + ) + .to.emit(pool, 'IsolationModeTotalDebtUpdated') + .withArgs(aave.address, 1000); const reserveData = await pool.getReserveData(aave.address); @@ -238,8 +242,11 @@ makeSuite('Isolation mode', (testEnv: TestEnv) => { await pool.connect(users[3].signer).supply(aave.address, aaveAmount, users[3].address, 0); const borrowAmount = utils.parseEther('10'); - await pool.connect(users[3].signer).borrow(dai.address, borrowAmount, '2', 0, users[3].address); - + await expect( + pool.connect(users[3].signer).borrow(dai.address, borrowAmount, '2', 0, users[3].address) + ) + .to.emit(pool, 'IsolationModeTotalDebtUpdated') + .withArgs(aave.address, 2000); const reserveData = await pool.getReserveData(aave.address); expect(reserveData.isolationModeTotalDebt).to.be.eq('2000'); @@ -273,8 +280,11 @@ makeSuite('Isolation mode', (testEnv: TestEnv) => { await dai.connect(users[1].signer)['mint(uint256)'](mintAmount); await dai.connect(users[1].signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(users[1].signer).repay(dai.address, MAX_UINT_AMOUNT, '2', users[1].address); - + await expect( + pool.connect(users[1].signer).repay(dai.address, MAX_UINT_AMOUNT, '2', users[1].address) + ) + .to.emit(pool, 'IsolationModeTotalDebtUpdated') + .withArgs(aave.address, 0); const reserveData = await pool.getReserveData(aave.address); expect(reserveData.isolationModeTotalDebt).to.be.eq('0'); @@ -328,16 +338,20 @@ makeSuite('Isolation mode', (testEnv: TestEnv) => { const isolationModeTotalDebtBefore = (await pool.getReserveData(aave.address)) .isolationModeTotalDebt; + const expectedAmountAfter = isolationModeTotalDebtBefore.sub( + borrowAmount.div(2).div(BigNumber.from(10).pow(16)) + ); - await pool - .connect(liquidator.signer) - .liquidationCall(aave.address, dai.address, borrower.address, borrowAmount.div(2), false); + await expect( + pool + .connect(liquidator.signer) + .liquidationCall(aave.address, dai.address, borrower.address, borrowAmount.div(2), false) + ) + .to.emit(pool, 'IsolationModeTotalDebtUpdated') + .withArgs(aave.address, expectedAmountAfter); const isolationModeTotalDebtAfter = (await pool.getReserveData(aave.address)) .isolationModeTotalDebt; - const expectedAmountAfter = isolationModeTotalDebtBefore.sub( - borrowAmount.div(2).div(BigNumber.from(10).pow(16)) - ); expect(isolationModeTotalDebtAfter).to.be.eq(expectedAmountAfter); });