diff --git a/src/PositionsManager.sol b/src/PositionsManager.sol index 42b76216..90140b1f 100644 --- a/src/PositionsManager.sol +++ b/src/PositionsManager.sol @@ -59,7 +59,7 @@ contract PositionsManager is IPositionsManager, PositionsManagerInternal { Types.SupplyRepayVars memory vars = _executeSupply(underlying, amount, from, onBehalf, maxIterations, indexes); - _pool.repayToPool(underlying, market.variableDebtToken, vars.toRepay); + _pool.repayToPool(underlying, market.variableDebtToken, vars.toRepay, indexes.borrow.poolIndex); _pool.supplyToPool(underlying, vars.toSupply, indexes.supply.poolIndex); return amount; @@ -143,7 +143,7 @@ contract PositionsManager is IPositionsManager, PositionsManagerInternal { Types.SupplyRepayVars memory vars = _executeRepay(underlying, amount, repayer, onBehalf, _defaultIterations.repay, indexes); - _pool.repayToPool(underlying, market.variableDebtToken, vars.toRepay); + _pool.repayToPool(underlying, market.variableDebtToken, vars.toRepay, indexes.borrow.poolIndex); _pool.supplyToPool(underlying, vars.toSupply, indexes.supply.poolIndex); return amount; @@ -259,7 +259,12 @@ contract PositionsManager is IPositionsManager, PositionsManagerInternal { underlyingCollateral, vars.seized, borrower, liquidator, collateralIndexes.supply.poolIndex ); - _pool.repayToPool(underlyingBorrowed, _market[underlyingBorrowed].variableDebtToken, repayVars.toRepay); + _pool.repayToPool( + underlyingBorrowed, + _market[underlyingBorrowed].variableDebtToken, + repayVars.toRepay, + borrowIndexes.borrow.poolIndex + ); _pool.supplyToPool(underlyingBorrowed, repayVars.toSupply, borrowIndexes.supply.poolIndex); _pool.withdrawFromPool(underlyingCollateral, _market[underlyingCollateral].aToken, vars.seized); diff --git a/src/libraries/PoolLib.sol b/src/libraries/PoolLib.sol index a6ec870e..f1c999e1 100644 --- a/src/libraries/PoolLib.sol +++ b/src/libraries/PoolLib.sol @@ -21,7 +21,7 @@ library PoolLib { /// @dev The pool supply `index` must be passed as a parameter to skip the supply on pool /// if it were to revert due to the amount being too small. function supplyToPool(IPool pool, address underlying, uint256 amount, uint256 index) internal { - if (amount.rayDiv(index) == 0) return; + if (amount.rayDivDown(index) == 0) return; pool.supply(underlying, amount, address(this), Constants.NO_REFERRAL_CODE); } @@ -35,8 +35,13 @@ library PoolLib { /// @notice Repays `amount` of `underlying` to `pool`. /// @dev If the debt has been fully repaid already, the function will return early. - function repayToPool(IPool pool, address underlying, address variableDebtToken, uint256 amount) internal { - if (amount == 0 || IVariableDebtToken(variableDebtToken).scaledBalanceOf(address(this)) == 0) return; + function repayToPool(IPool pool, address underlying, address variableDebtToken, uint256 amount, uint256 index) + internal + { + uint256 scaledBalance = IVariableDebtToken(variableDebtToken).scaledBalanceOf(address(this)); + uint256 paybackAmount = amount < scaledBalance ? amount : scaledBalance; + + if (paybackAmount.rayDivDown(index) == 0) return; pool.repay(underlying, amount, Constants.VARIABLE_INTEREST_MODE, address(this)); // Reverts if debt is 0. } diff --git a/test/integration/TestIntegrationPoolLib.sol b/test/integration/TestIntegrationPoolLib.sol index 616e670e..06a3966a 100644 --- a/test/integration/TestIntegrationPoolLib.sol +++ b/test/integration/TestIntegrationPoolLib.sol @@ -80,7 +80,7 @@ contract TestIntegrationPoolLibRepay is TestIntegrationPoolLib { uint256 balanceBefore = ERC20(dai).balanceOf(address(this)); uint256 vBalanceBefore = ERC20(vDai).balanceOf(address(this)); - pool.repayToPool(dai, vDai, amount / 4); + pool.repayToPool(dai, vDai, amount / 4, 1e27); assertEq(ERC20(dai).balanceOf(address(this)) + amount / 4, balanceBefore, "balance"); assertApproxEqAbs(ERC20(vDai).balanceOf(address(this)) + amount / 4, vBalanceBefore, 2, "vBalance");