diff --git a/.gitignore b/.gitignore
index 626ee868..e6704cbb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,7 @@ dist/
 build/
 .vscode
 .idea
-types
+/types
 
 deployed-contracts.json
 
diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol
index 1f4104dd..d445579a 100644
--- a/contracts/interfaces/ILendingPool.sol
+++ b/contracts/interfaces/ILendingPool.sol
@@ -2,10 +2,9 @@
 pragma solidity 0.6.12;
 pragma experimental ABIEncoderV2;
 
-import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
-import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
-import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol';
 import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol';
+import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
+
 
 interface ILendingPool {
   /**
@@ -355,14 +354,20 @@ interface ILendingPool {
    * @param asset The address of the underlying asset of the reserve
    * @return The configuration of the reserve
    **/
-  function getConfiguration(address asset) external view returns (ReserveConfiguration.Map memory);
+  function getConfiguration(address asset)
+    external
+    view
+    returns (DataTypes.ReserveConfigurationMap memory);
 
   /**
    * @dev Returns the configuration of the user across all the reserves
    * @param user The user address
    * @return The configuration of the user
    **/
-  function getUserConfiguration(address user) external view returns (UserConfiguration.Map memory);
+  function getUserConfiguration(address user)
+    external
+    view
+    returns (DataTypes.UserConfigurationMap memory);
 
   /**
    * @dev Returns the normalized income normalized income of the reserve
@@ -383,7 +388,7 @@ interface ILendingPool {
    * @param asset The address of the underlying asset of the reserve
    * @return The state of the reserve
    **/
-  function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);
+  function getReserveData(address asset) external view returns (DataTypes.ReserveData memory);
 
   function finalizeTransfer(
     address asset,
diff --git a/contracts/interfaces/ILendingPoolCollateralManager.sol b/contracts/interfaces/ILendingPoolCollateralManager.sol
index 39244896..785fb68b 100644
--- a/contracts/interfaces/ILendingPoolCollateralManager.sol
+++ b/contracts/interfaces/ILendingPoolCollateralManager.sol
@@ -49,5 +49,5 @@ interface ILendingPoolCollateralManager {
     address user,
     uint256 debtToCover,
     bool receiveAToken
-  ) external virtual returns (uint256, string memory);
+  ) external returns (uint256, string memory);
 }
diff --git a/contracts/misc/AaveProtocolDataProvider.sol b/contracts/misc/AaveProtocolDataProvider.sol
index 1be4f326..d9b476af 100644
--- a/contracts/misc/AaveProtocolDataProvider.sol
+++ b/contracts/misc/AaveProtocolDataProvider.sol
@@ -5,15 +5,15 @@ pragma experimental ABIEncoderV2;
 import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
 import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
 import {ILendingPool} from '../interfaces/ILendingPool.sol';
-import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol';
 import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
 import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
 import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol';
 import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableDebtToken.sol';
+import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
 
 contract AaveProtocolDataProvider {
-  using ReserveConfiguration for ReserveConfiguration.Map;
-  using UserConfiguration for UserConfiguration.Map;
+  using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
+  using UserConfiguration for DataTypes.UserConfigurationMap;
 
   address constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2;
   address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
@@ -55,7 +55,7 @@ contract AaveProtocolDataProvider {
     address[] memory reserves = pool.getReservesList();
     TokenData[] memory aTokens = new TokenData[](reserves.length);
     for (uint256 i = 0; i < reserves.length; i++) {
-      ReserveLogic.ReserveData memory reserveData = pool.getReserveData(reserves[i]);
+      DataTypes.ReserveData memory reserveData = pool.getReserveData(reserves[i]);
       aTokens[i] = TokenData({
         symbol: IERC20Detailed(reserveData.aTokenAddress).symbol(),
         tokenAddress: reserveData.aTokenAddress
@@ -80,7 +80,7 @@ contract AaveProtocolDataProvider {
       bool isFrozen
     )
   {
-    ReserveConfiguration.Map memory configuration =
+    DataTypes.ReserveConfigurationMap memory configuration =
       ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getConfiguration(asset);
 
     (ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration
@@ -108,7 +108,7 @@ contract AaveProtocolDataProvider {
       uint40 lastUpdateTimestamp
     )
   {
-    ReserveLogic.ReserveData memory reserve =
+    DataTypes.ReserveData memory reserve =
       ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset);
 
     return (
@@ -140,10 +140,10 @@ contract AaveProtocolDataProvider {
       bool usageAsCollateralEnabled
     )
   {
-    ReserveLogic.ReserveData memory reserve =
+    DataTypes.ReserveData memory reserve =
       ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset);
 
-    UserConfiguration.Map memory userConfig =
+    DataTypes.UserConfigurationMap memory userConfig =
       ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getUserConfiguration(user);
 
     currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user);
@@ -168,7 +168,7 @@ contract AaveProtocolDataProvider {
       address variableDebtTokenAddress
     )
   {
-    ReserveLogic.ReserveData memory reserve =
+    DataTypes.ReserveData memory reserve =
       ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset);
 
     return (
diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol
index fef40724..f0e2c2d5 100644
--- a/contracts/misc/UiPoolDataProvider.sol
+++ b/contracts/misc/UiPoolDataProvider.sol
@@ -12,17 +12,17 @@ import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableD
 import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol';
 
 import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol';
-import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol';
 import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
 import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
 import {
   DefaultReserveInterestRateStrategy
 } from '../protocol/lendingpool/DefaultReserveInterestRateStrategy.sol';
+import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
 
 contract UiPoolDataProvider is IUiPoolDataProvider {
   using WadRayMath for uint256;
-  using ReserveConfiguration for ReserveConfiguration.Map;
-  using UserConfiguration for UserConfiguration.Map;
+  using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
+  using UserConfiguration for DataTypes.UserConfigurationMap;
 
   address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96;
 
@@ -57,7 +57,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
     ILendingPool lendingPool = ILendingPool(provider.getLendingPool());
     IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle());
     address[] memory reserves = lendingPool.getReservesList();
-    UserConfiguration.Map memory userConfig = lendingPool.getUserConfiguration(user);
+    DataTypes.UserConfigurationMap memory userConfig = lendingPool.getUserConfiguration(user);
 
     AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length);
     UserReserveData[] memory userReservesData =
@@ -68,7 +68,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
       reserveData.underlyingAsset = reserves[i];
 
       // reserve current state
-      ReserveLogic.ReserveData memory baseData =
+      DataTypes.ReserveData memory baseData =
         lendingPool.getReserveData(reserveData.underlyingAsset);
       reserveData.liquidityIndex = baseData.liquidityIndex;
       reserveData.variableBorrowIndex = baseData.variableBorrowIndex;
diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol
index 9acd066e..ee8261b0 100644
--- a/contracts/misc/WETHGateway.sol
+++ b/contracts/misc/WETHGateway.sol
@@ -6,16 +6,16 @@ import {IWETH} from './interfaces/IWETH.sol';
 import {IWETHGateway} from './interfaces/IWETHGateway.sol';
 import {ILendingPool} from '../interfaces/ILendingPool.sol';
 import {IAToken} from '../protocol/tokenization/interfaces/IAToken.sol';
-import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol';
 import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
 import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
 import {Helpers} from '../protocol/libraries/helpers/Helpers.sol';
 import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
 import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
+import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
 
 contract WETHGateway is IWETHGateway, Ownable {
-  using ReserveConfiguration for ReserveConfiguration.Map;
-  using UserConfiguration for UserConfiguration.Map;
+  using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
+  using UserConfiguration for DataTypes.UserConfigurationMap;
 
   IWETH internal immutable WETH;
   ILendingPool internal immutable POOL;
@@ -79,7 +79,7 @@ contract WETHGateway is IWETHGateway, Ownable {
       Helpers.getUserCurrentDebtMemory(onBehalfOf, POOL.getReserveData(address(WETH)));
 
     uint256 paybackAmount =
-      ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.STABLE
+      DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE
         ? stableDebt
         : variableDebt;
 
diff --git a/contracts/misc/WalletBalanceProvider.sol b/contracts/misc/WalletBalanceProvider.sol
index d7c2aff5..cd4a81ce 100644
--- a/contracts/misc/WalletBalanceProvider.sol
+++ b/contracts/misc/WalletBalanceProvider.sol
@@ -10,6 +10,7 @@ import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddresses
 import {ILendingPool} from '../interfaces/ILendingPool.sol';
 import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
 import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
+import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
 
 /**
  * @title WalletBalanceProvider contract
@@ -22,7 +23,7 @@ contract WalletBalanceProvider {
   using Address for address payable;
   using Address for address;
   using SafeERC20 for IERC20;
-  using ReserveConfiguration for ReserveConfiguration.Map;
+  using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
 
   address constant MOCK_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
 
@@ -92,7 +93,7 @@ contract WalletBalanceProvider {
     uint256[] memory balances = new uint256[](reservesWithEth.length);
 
     for (uint256 j = 0; j < reserves.length; j++) {
-      ReserveConfiguration.Map memory configuration = pool.getConfiguration(reservesWithEth[j]);
+      DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(reservesWithEth[j]);
 
       (bool isActive, , , ) = configuration.getFlagsMemory();
 
diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol
index 28a7d984..81a553e8 100644
--- a/contracts/misc/interfaces/IUiPoolDataProvider.sol
+++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol
@@ -3,7 +3,6 @@ pragma solidity 0.6.12;
 pragma experimental ABIEncoderV2;
 
 import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
-import {ReserveLogic} from '../../protocol/libraries/logic/ReserveLogic.sol';
 
 interface IUiPoolDataProvider {
   struct AggregatedReserveData {
diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol
index 3c4fc341..525141a6 100644
--- a/contracts/protocol/lendingpool/LendingPool.sol
+++ b/contracts/protocol/lendingpool/LendingPool.sol
@@ -24,6 +24,7 @@ import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol
 import {ILendingPool} from '../../interfaces/ILendingPool.sol';
 import {LendingPoolStorage} from './LendingPoolStorage.sol';
 import {Address} from '../../dependencies/openzeppelin/contracts/Address.sol';
+import {DataTypes} from '../libraries/types/DataTypes.sol';
 
 /**
  * @title LendingPool contract
@@ -107,7 +108,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     address onBehalfOf,
     uint16 referralCode
   ) external override whenNotPaused {
-    ReserveLogic.ReserveData storage reserve = _reserves[asset];
+    DataTypes.ReserveData storage reserve = _reserves[asset];
 
     ValidationLogic.validateDeposit(reserve, amount);
 
@@ -143,7 +144,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     uint256 amount,
     address to
   ) external override whenNotPaused {
-    ReserveLogic.ReserveData storage reserve = _reserves[asset];
+    DataTypes.ReserveData storage reserve = _reserves[asset];
 
     address aToken = reserve.aTokenAddress;
 
@@ -202,7 +203,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     uint16 referralCode,
     address onBehalfOf
   ) external override whenNotPaused {
-    ReserveLogic.ReserveData storage reserve = _reserves[asset];
+    DataTypes.ReserveData storage reserve = _reserves[asset];
 
     _executeBorrow(
       ExecuteBorrowParams(
@@ -235,11 +236,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     uint256 rateMode,
     address onBehalfOf
   ) external override whenNotPaused {
-    ReserveLogic.ReserveData storage reserve = _reserves[asset];
+    DataTypes.ReserveData storage reserve = _reserves[asset];
 
     (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(onBehalfOf, reserve);
 
-    ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode);
+    DataTypes.InterestRateMode interestRateMode = DataTypes.InterestRateMode(rateMode);
 
     ValidationLogic.validateRepay(
       reserve,
@@ -250,7 +251,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
       variableDebt
     );
 
-    uint256 paybackAmount = interestRateMode == ReserveLogic.InterestRateMode.STABLE
+    uint256 paybackAmount = interestRateMode == DataTypes.InterestRateMode.STABLE
       ? stableDebt
       : variableDebt;
 
@@ -260,7 +261,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
 
     reserve.updateState();
 
-    if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
+    if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
       IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
     } else {
       IVariableDebtToken(reserve.variableDebtTokenAddress).burn(
@@ -288,11 +289,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
    * @param rateMode The rate mode that the user wants to swap to
    **/
   function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused {
-    ReserveLogic.ReserveData storage reserve = _reserves[asset];
+    DataTypes.ReserveData storage reserve = _reserves[asset];
 
     (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
 
-    ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode);
+    DataTypes.InterestRateMode interestRateMode = DataTypes.InterestRateMode(rateMode);
 
     ValidationLogic.validateSwapRateMode(
       reserve,
@@ -304,7 +305,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
 
     reserve.updateState();
 
-    if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
+    if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
       IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt);
       IVariableDebtToken(reserve.variableDebtTokenAddress).mint(
         msg.sender,
@@ -341,7 +342,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
    * @param user The address of the user to be rebalanced
    **/
   function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused {
-    ReserveLogic.ReserveData storage reserve = _reserves[asset];
+    DataTypes.ReserveData storage reserve = _reserves[asset];
 
     IERC20 stableDebtToken = IERC20(reserve.stableDebtTokenAddress);
     IERC20 variableDebtToken = IERC20(reserve.variableDebtTokenAddress);
@@ -382,7 +383,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     override
     whenNotPaused
   {
-    ReserveLogic.ReserveData storage reserve = _reserves[asset];
+    DataTypes.ReserveData storage reserve = _reserves[asset];
 
     ValidationLogic.validateSetUseReserveAsCollateral(
       reserve,
@@ -509,7 +510,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
       vars.currentATokenAddress = aTokenAddresses[vars.i];
       vars.currentAmountPlusPremium = vars.currentAmount.add(vars.currentPremium);
 
-      if (ReserveLogic.InterestRateMode(modes[vars.i]) == ReserveLogic.InterestRateMode.NONE) {
+      if (DataTypes.InterestRateMode(modes[vars.i]) == DataTypes.InterestRateMode.NONE) {
         _reserves[vars.currentAsset].updateState();
         _reserves[vars.currentAsset].cumulateToLiquidityIndex(
           IERC20(vars.currentATokenAddress).totalSupply(),
@@ -563,7 +564,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     external
     view
     override
-    returns (ReserveLogic.ReserveData memory)
+    returns (DataTypes.ReserveData memory)
   {
     return _reserves[asset];
   }
@@ -622,7 +623,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     external
     view
     override
-    returns (ReserveConfiguration.Map memory)
+    returns (DataTypes.ReserveConfigurationMap memory)
   {
     return _reserves[asset].configuration;
   }
@@ -636,7 +637,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
     external
     view
     override
-    returns (UserConfiguration.Map memory)
+    returns (DataTypes.UserConfigurationMap memory)
   {
     return _usersConfig[user];
   }
@@ -729,13 +730,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
 
     if (from != to) {
       if (balanceFromBefore.sub(amount) == 0) {
-        UserConfiguration.Map storage fromConfig = _usersConfig[from];
+        DataTypes.UserConfigurationMap storage fromConfig = _usersConfig[from];
         fromConfig.setUsingAsCollateral(reserveId, false);
         emit ReserveUsedAsCollateralDisabled(asset, from);
       }
 
       if (balanceToBefore == 0 && amount != 0) {
-        UserConfiguration.Map storage toConfig = _usersConfig[to];
+        DataTypes.UserConfigurationMap storage toConfig = _usersConfig[to];
         toConfig.setUsingAsCollateral(reserveId, true);
         emit ReserveUsedAsCollateralEnabled(asset, to);
       }
@@ -823,8 +824,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
   }
 
   function _executeBorrow(ExecuteBorrowParams memory vars) internal {
-    ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
-    UserConfiguration.Map storage userConfig = _usersConfig[vars.onBehalfOf];
+    DataTypes.ReserveData storage reserve = _reserves[vars.asset];
+    DataTypes.UserConfigurationMap storage userConfig = _usersConfig[vars.onBehalfOf];
 
     address oracle = _addressesProvider.getPriceOracle();
 
@@ -854,7 +855,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
 
     bool isFirstBorrowing = false;
     if (
-      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
+      DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE
     ) {
       currentStableRate = reserve.currentStableBorrowRate;
 
@@ -894,7 +895,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
       vars.onBehalfOf,
       vars.amount,
       vars.interestRateMode,
-      ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
+      DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE
         ? currentStableRate
         : reserve.currentVariableBorrowRate,
       vars.referralCode
diff --git a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol
index 5e9d16ba..9606bb39 100644
--- a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol
+++ b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol
@@ -10,8 +10,6 @@ import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.
 import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
 import {ILendingPoolCollateralManager} from '../../interfaces/ILendingPoolCollateralManager.sol';
 import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
-import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
-import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
 import {Helpers} from '../libraries/helpers/Helpers.sol';
 import {WadRayMath} from '../libraries/math/WadRayMath.sol';
 import {PercentageMath} from '../libraries/math/PercentageMath.sol';
@@ -19,82 +17,76 @@ import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol
 import {Errors} from '../libraries/helpers/Errors.sol';
 import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
 import {LendingPoolStorage} from './LendingPoolStorage.sol';
+import {DataTypes} from '../libraries/types/DataTypes.sol';
 
 /**
  * @title LendingPoolCollateralManager contract
  * @author Aave
- * @notice Implements actions involving management of collateral in the protocol.
- * @notice this contract will be ran always through delegatecall
- * @dev LendingPoolCollateralManager inherits VersionedInitializable from OpenZeppelin to have the same storage layout as LendingPool
+ * @dev Implements actions involving management of collateral in the protocol, the main one being the liquidations
+ * IMPORTANT This contract will run always via DELEGATECALL, through the LendingPool, so the chain of inheritance
+ * is the same as the LendingPool, to have compatible storage layouts
  **/
-contract LendingPoolCollateralManager is ILendingPoolCollateralManager, VersionedInitializable, LendingPoolStorage {
+contract LendingPoolCollateralManager is
+  ILendingPoolCollateralManager,
+  VersionedInitializable,
+  LendingPoolStorage
+{
   using SafeERC20 for IERC20;
   using SafeMath for uint256;
   using WadRayMath for uint256;
   using PercentageMath for uint256;
 
-  // IMPORTANT The storage layout of the LendingPool is reproduced here because this contract
-  // is gonna be used through DELEGATECALL
-
   uint256 internal constant LIQUIDATION_CLOSE_FACTOR_PERCENT = 5000;
 
   struct LiquidationCallLocalVars {
     uint256 userCollateralBalance;
     uint256 userStableDebt;
     uint256 userVariableDebt;
-    uint256 maxPrincipalAmountToLiquidate;
-    uint256 actualAmountToLiquidate;
+    uint256 maxLiquidatableDebt;
+    uint256 actualDebtToLiquidate;
     uint256 liquidationRatio;
     uint256 maxAmountCollateralToLiquidate;
     uint256 userStableRate;
     uint256 maxCollateralToLiquidate;
-    uint256 principalAmountNeeded;
+    uint256 debtAmountNeeded;
     uint256 healthFactor;
     IAToken collateralAtoken;
     bool isCollateralEnabled;
-    ReserveLogic.InterestRateMode borrowRateMode;
-    address principalAToken;
+    DataTypes.InterestRateMode borrowRateMode;
     uint256 errorCode;
     string errorMsg;
   }
 
-  struct AvailableCollateralToLiquidateLocalVars {
-    uint256 userCompoundedBorrowBalance;
-    uint256 liquidationBonus;
-    uint256 collateralPrice;
-    uint256 principalCurrencyPrice;
-    uint256 maxAmountCollateralToLiquidate;
-    uint256 principalDecimals;
-    uint256 collateralDecimals;
-  }
-
   /**
-   * @dev as the contract extends the VersionedInitializable contract to match the state
-   * of the LendingPool contract, the getRevision() function is needed.
+   * @dev As thIS contract extends the VersionedInitializable contract to match the state
+   * of the LendingPool contract, the getRevision() function is needed, but the value is not
+   * important, as the initialize() function will never be called here
    */
   function getRevision() internal pure override returns (uint256) {
     return 0;
   }
 
   /**
-   * @dev users can invoke this function to liquidate an undercollateralized position.
-   * @param collateral the address of the collateral to liquidated
-   * @param principal the address of the principal reserve
-   * @param user the address of the borrower
-   * @param debtToCover the amount of principal that the liquidator wants to repay
-   * @param receiveAToken true if the liquidators wants to receive the aTokens, false if
-   * he wants to receive the underlying asset directly
+   * @dev Function to liquidate a position if its Health Factor drops below 1
+   * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
+   *   a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
+   * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
+   * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
+   * @param user The address of the borrower getting liquidated
+   * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
+   * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants
+   * to receive the underlying collateral asset directly
    **/
   function liquidationCall(
-    address collateral,
-    address principal,
+    address collateralAsset,
+    address debtAsset,
     address user,
     uint256 debtToCover,
     bool receiveAToken
   ) external override returns (uint256, string memory) {
-    ReserveLogic.ReserveData storage collateralReserve = _reserves[collateral];
-    ReserveLogic.ReserveData storage principalReserve = _reserves[principal];
-    UserConfiguration.Map storage userConfig = _usersConfig[user];
+    DataTypes.ReserveData storage collateralReserve = _reserves[collateralAsset];
+    DataTypes.ReserveData storage debtReserve = _reserves[debtAsset];
+    DataTypes.UserConfigurationMap storage userConfig = _usersConfig[user];
 
     LiquidationCallLocalVars memory vars;
 
@@ -107,15 +99,11 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
       _addressesProvider.getPriceOracle()
     );
 
-    //if the user hasn't borrowed the specific currency defined by asset, it cannot be liquidated
-    (vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(
-      user,
-      principalReserve
-    );
+    (vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(user, debtReserve);
 
     (vars.errorCode, vars.errorMsg) = ValidationLogic.validateLiquidationCall(
       collateralReserve,
-      principalReserve,
+      debtReserve,
       userConfig,
       vars.healthFactor,
       vars.userStableDebt,
@@ -130,38 +118,39 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
 
     vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user);
 
-    vars.maxPrincipalAmountToLiquidate = vars.userStableDebt.add(vars.userVariableDebt).percentMul(
+    vars.maxLiquidatableDebt = vars.userStableDebt.add(vars.userVariableDebt).percentMul(
       LIQUIDATION_CLOSE_FACTOR_PERCENT
     );
 
-    vars.actualAmountToLiquidate = debtToCover > vars.maxPrincipalAmountToLiquidate
-      ? vars.maxPrincipalAmountToLiquidate
+    vars.actualDebtToLiquidate = debtToCover > vars.maxLiquidatableDebt
+      ? vars.maxLiquidatableDebt
       : debtToCover;
 
     (
       vars.maxCollateralToLiquidate,
-      vars.principalAmountNeeded
+      vars.debtAmountNeeded
     ) = _calculateAvailableCollateralToLiquidate(
       collateralReserve,
-      principalReserve,
-      collateral,
-      principal,
-      vars.actualAmountToLiquidate,
+      debtReserve,
+      collateralAsset,
+      debtAsset,
+      vars.actualDebtToLiquidate,
       vars.userCollateralBalance
     );
 
-    //if principalAmountNeeded < vars.ActualAmountToLiquidate, there isn't enough
-    //of collateral to cover the actual amount that is being liquidated, hence we liquidate
-    //a smaller amount
+    // If debtAmountNeeded < actualDebtToLiquidate, there isn't enough
+    // collateral to cover the actual amount that is being liquidated, hence we liquidate
+    // a smaller amount
 
-    if (vars.principalAmountNeeded < vars.actualAmountToLiquidate) {
-      vars.actualAmountToLiquidate = vars.principalAmountNeeded;
+    if (vars.debtAmountNeeded < vars.actualDebtToLiquidate) {
+      vars.actualDebtToLiquidate = vars.debtAmountNeeded;
     }
 
-    //if liquidator reclaims the underlying asset, we make sure there is enough available collateral in the reserve
+    // If the liquidator reclaims the underlying asset, we make sure there is enough available liquidity in the
+    // collateral reserve
     if (!receiveAToken) {
       uint256 currentAvailableCollateral =
-        IERC20(collateral).balanceOf(address(vars.collateralAtoken));
+        IERC20(collateralAsset).balanceOf(address(vars.collateralAtoken));
       if (currentAvailableCollateral < vars.maxCollateralToLiquidate) {
         return (
           uint256(Errors.CollateralManagerErrors.NOT_ENOUGH_LIQUIDITY),
@@ -170,54 +159,48 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
       }
     }
 
-    //update the principal reserve
-    principalReserve.updateState();
+    debtReserve.updateState();
 
-    if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
-      IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
+    if (vars.userVariableDebt >= vars.actualDebtToLiquidate) {
+      IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(
         user,
-        vars.actualAmountToLiquidate,
-        principalReserve.variableBorrowIndex
+        vars.actualDebtToLiquidate,
+        debtReserve.variableBorrowIndex
       );
     } else {
-      //if the user does not have variable debt, no need to try to burn variable
-      //debt tokens
+      // If the user doesn't have variable debt, no need to try to burn variable debt tokens
       if (vars.userVariableDebt > 0) {
-        IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
+        IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(
           user,
           vars.userVariableDebt,
-          principalReserve.variableBorrowIndex
+          debtReserve.variableBorrowIndex
         );
       }
-      IStableDebtToken(principalReserve.stableDebtTokenAddress).burn(
+      IStableDebtToken(debtReserve.stableDebtTokenAddress).burn(
         user,
-        vars.actualAmountToLiquidate.sub(vars.userVariableDebt)
+        vars.actualDebtToLiquidate.sub(vars.userVariableDebt)
       );
     }
 
-    principalReserve.updateInterestRates(
-      principal,
-      principalReserve.aTokenAddress,
-      vars.actualAmountToLiquidate,
+    debtReserve.updateInterestRates(
+      debtAsset,
+      debtReserve.aTokenAddress,
+      vars.actualDebtToLiquidate,
       0
     );
 
-    //if liquidator reclaims the aToken, he receives the equivalent atoken amount
     if (receiveAToken) {
       vars.collateralAtoken.transferOnLiquidation(user, msg.sender, vars.maxCollateralToLiquidate);
     } else {
-      //otherwise receives the underlying asset
-
-      //updating collateral reserve
       collateralReserve.updateState();
       collateralReserve.updateInterestRates(
-        collateral,
+        collateralAsset,
         address(vars.collateralAtoken),
         0,
         vars.maxCollateralToLiquidate
       );
 
-      //burn the equivalent amount of atoken
+      // Burn the equivalent amount of aToken, sending the underlying to the liquidator
       vars.collateralAtoken.burn(
         user,
         msg.sender,
@@ -226,26 +209,25 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
       );
     }
 
-    //if the collateral being liquidated is equal to the user balance,
-    //we set the currency as not being used as collateral anymore
-
+    // If the collateral being liquidated is equal to the user balance,
+    // we set the currency as not being used as collateral anymore
     if (vars.maxCollateralToLiquidate == vars.userCollateralBalance) {
       userConfig.setUsingAsCollateral(collateralReserve.id, false);
-      emit ReserveUsedAsCollateralDisabled(collateral, user);
+      emit ReserveUsedAsCollateralDisabled(collateralAsset, user);
     }
 
-    //transfers the principal currency to the aToken
-    IERC20(principal).safeTransferFrom(
+    // Transfers the debt asset being repaid to the aToken, where the liquidity is kept
+    IERC20(debtAsset).safeTransferFrom(
       msg.sender,
-      principalReserve.aTokenAddress,
-      vars.actualAmountToLiquidate
+      debtReserve.aTokenAddress,
+      vars.actualDebtToLiquidate
     );
 
     emit LiquidationCall(
-      collateral,
-      principal,
+      collateralAsset,
+      debtAsset,
       user,
-      vars.actualAmountToLiquidate,
+      vars.actualDebtToLiquidate,
       vars.maxCollateralToLiquidate,
       msg.sender,
       receiveAToken
@@ -254,60 +236,74 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
     return (uint256(Errors.CollateralManagerErrors.NO_ERROR), Errors.LPCM_NO_ERRORS);
   }
 
+  struct AvailableCollateralToLiquidateLocalVars {
+    uint256 userCompoundedBorrowBalance;
+    uint256 liquidationBonus;
+    uint256 collateralPrice;
+    uint256 debtAssetPrice;
+    uint256 maxAmountCollateralToLiquidate;
+    uint256 debtAssetDecimals;
+    uint256 collateralDecimals;
+  }
+
   /**
-   * @dev calculates how much of a specific collateral can be liquidated, given
-   * a certain amount of principal currency. This function needs to be called after
-   * all the checks to validate the liquidation have been performed, otherwise it might fail.
-   * @param collateralAddress the collateral to be liquidated
-   * @param principalAddress the principal currency to be liquidated
-   * @param debtToCover the amount of principal being liquidated
-   * @param userCollateralBalance the collatera balance for the specific collateral asset of the user being liquidated
-   * @return collateralAmount the maximum amount that is possible to liquidated given all the liquidation constraints (user balance, close factor)
-   * @return principalAmountNeeded the purchase amount
+   * @dev Calculates how much of a specific collateral can be liquidated, given
+   * a certain amount of debt asset.
+   * - This function needs to be called after all the checks to validate the liquidation have been performed,
+   *   otherwise it might fail.
+   * @param collateralReserve The data of the collateral reserve
+   * @param debtReserve The data of the debt reserve
+   * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
+   * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
+   * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
+   * @param userCollateralBalance The collateral balance for the specific `collateralAsset` of the user being liquidated
+   * @return collateralAmount: The maximum amount that is possible to liquidate given all the liquidation constraints
+   *                           (user balance, close factor)
+   *         debtAmountNeeded: The amount to repay with the liquidation
    **/
   function _calculateAvailableCollateralToLiquidate(
-    ReserveLogic.ReserveData storage collateralReserve,
-    ReserveLogic.ReserveData storage principalReserve,
-    address collateralAddress,
-    address principalAddress,
+    DataTypes.ReserveData storage collateralReserve,
+    DataTypes.ReserveData storage debtReserve,
+    address collateralAsset,
+    address debtAsset,
     uint256 debtToCover,
     uint256 userCollateralBalance
   ) internal view returns (uint256, uint256) {
     uint256 collateralAmount = 0;
-    uint256 principalAmountNeeded = 0;
+    uint256 debtAmountNeeded = 0;
     IPriceOracleGetter oracle = IPriceOracleGetter(_addressesProvider.getPriceOracle());
 
     AvailableCollateralToLiquidateLocalVars memory vars;
 
-    vars.collateralPrice = oracle.getAssetPrice(collateralAddress);
-    vars.principalCurrencyPrice = oracle.getAssetPrice(principalAddress);
+    vars.collateralPrice = oracle.getAssetPrice(collateralAsset);
+    vars.debtAssetPrice = oracle.getAssetPrice(debtAsset);
 
     (, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve
       .configuration
       .getParams();
-    vars.principalDecimals = principalReserve.configuration.getDecimals();
+    vars.debtAssetDecimals = debtReserve.configuration.getDecimals();
 
-    //this is the maximum possible amount of the selected collateral that can be liquidated, given the
-    //max amount of principal currency that is available for liquidation.
+    // This is the maximum possible amount of the selected collateral that can be liquidated, given the
+    // max amount of liquidatable debt
     vars.maxAmountCollateralToLiquidate = vars
-      .principalCurrencyPrice
+      .debtAssetPrice
       .mul(debtToCover)
       .mul(10**vars.collateralDecimals)
       .percentMul(vars.liquidationBonus)
-      .div(vars.collateralPrice.mul(10**vars.principalDecimals));
+      .div(vars.collateralPrice.mul(10**vars.debtAssetDecimals));
 
     if (vars.maxAmountCollateralToLiquidate > userCollateralBalance) {
       collateralAmount = userCollateralBalance;
-      principalAmountNeeded = vars
+      debtAmountNeeded = vars
         .collateralPrice
         .mul(collateralAmount)
-        .mul(10**vars.principalDecimals)
-        .div(vars.principalCurrencyPrice.mul(10**vars.collateralDecimals))
+        .mul(10**vars.debtAssetDecimals)
+        .div(vars.debtAssetPrice.mul(10**vars.collateralDecimals))
         .percentDiv(vars.liquidationBonus);
     } else {
       collateralAmount = vars.maxAmountCollateralToLiquidate;
-      principalAmountNeeded = debtToCover;
+      debtAmountNeeded = debtToCover;
     }
-    return (collateralAmount, principalAmountNeeded);
+    return (collateralAmount, debtAmountNeeded);
   }
 }
diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol
index ad70947c..2e08d70c 100644
--- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol
+++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol
@@ -14,26 +14,26 @@ import {ITokenConfiguration} from '../tokenization/interfaces/ITokenConfiguratio
 import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
 import {Errors} from '../libraries/helpers/Errors.sol';
 import {PercentageMath} from '../libraries/math/PercentageMath.sol';
-import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
+import {DataTypes} from '../libraries/types/DataTypes.sol';
 
 /**
  * @title LendingPoolConfigurator contract
  * @author Aave
- * @notice Executes configuration methods on the LendingPoolCore contract. Allows to enable/disable reserves
- * and set different protocol parameters.
+ * @dev Implements the configuration methods for the Aave protocol
  **/
 
 contract LendingPoolConfigurator is VersionedInitializable {
   using SafeMath for uint256;
-  using ReserveConfiguration for ReserveConfiguration.Map;
+  using PercentageMath for uint256;
+  using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
 
   /**
-   * @dev emitted when a reserve is initialized.
-   * @param asset the address of the reserve
-   * @param aToken the address of the overlying aToken contract
-   * @param stableDebtToken the address of the associated stable rate debt token
-   * @param variableDebtToken the address of the associated variable rate debt token
-   * @param interestRateStrategyAddress the address of the interest rate strategy for the reserve
+   * @dev Emitted when a reserve is initialized.
+   * @param asset The address of the underlying asset of the reserve
+   * @param aToken The address of the associated aToken contract
+   * @param stableDebtToken The address of the associated stable rate debt token
+   * @param variableDebtToken The address of the associated variable rate debt token
+   * @param interestRateStrategyAddress The address of the interest rate strategy for the reserve
    **/
   event ReserveInitialized(
     address indexed asset,
@@ -44,24 +44,24 @@ contract LendingPoolConfigurator is VersionedInitializable {
   );
 
   /**
-   * @dev emitted when borrowing is enabled on a reserve
-   * @param asset the address of the reserve
-   * @param stableRateEnabled true if stable rate borrowing is enabled, false otherwise
+   * @dev Emitted when borrowing is enabled on a reserve
+   * @param asset The address of the underlying asset of the reserve
+   * @param stableRateEnabled True if stable rate borrowing is enabled, false otherwise
    **/
   event BorrowingEnabledOnReserve(address indexed asset, bool stableRateEnabled);
 
   /**
-   * @dev emitted when borrowing is disabled on a reserve
-   * @param asset the address of the reserve
+   * @dev Emitted when borrowing is disabled on a reserve
+   * @param asset The address of the underlying asset of the reserve
    **/
   event BorrowingDisabledOnReserve(address indexed asset);
 
   /**
-   * @dev emitted when a a reserve collateralization risk parameters are updated.
-   * @param asset the address of the reserve
-   * @param ltv the loan to value of the asset when used as collateral
-   * @param liquidationThreshold the threshold at which loans using this asset as collateral will be considered undercollateralized
-   * @param liquidationBonus the bonus liquidators receive to liquidate this asset
+   * @dev Emitted when the collateralization risk parameters for the specified asset are updated.
+   * @param asset The address of the underlying asset of the reserve
+   * @param ltv The loan to value of the asset when used as collateral
+   * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized
+   * @param liquidationBonus The bonus liquidators receive to liquidate this asset
    **/
   event CollateralConfigurationChanged(
     address indexed asset,
@@ -71,67 +71,67 @@ contract LendingPoolConfigurator is VersionedInitializable {
   );
 
   /**
-   * @dev emitted when stable rate borrowing is enabled on a reserve
-   * @param asset the address of the reserve
+   * @dev Emitted when stable rate borrowing is enabled on a reserve
+   * @param asset The address of the underlying asset of the reserve
    **/
   event StableRateEnabledOnReserve(address indexed asset);
 
   /**
-   * @dev emitted when stable rate borrowing is disabled on a reserve
-   * @param asset the address of the reserve
+   * @dev Emitted when stable rate borrowing is disabled on a reserve
+   * @param asset The address of the underlying asset of the reserve
    **/
   event StableRateDisabledOnReserve(address indexed asset);
 
   /**
-   * @dev emitted when a reserve is activated
-   * @param asset the address of the reserve
+   * @dev Emitted when a reserve is activated
+   * @param asset The address of the underlying asset of the reserve
    **/
   event ReserveActivated(address indexed asset);
 
   /**
-   * @dev emitted when a reserve is deactivated
-   * @param asset the address of the reserve
+   * @dev Emitted when a reserve is deactivated
+   * @param asset The address of the underlying asset of the reserve
    **/
   event ReserveDeactivated(address indexed asset);
 
   /**
-   * @dev emitted when a reserve is frozen
-   * @param asset the address of the reserve
+   * @dev Emitted when a reserve is frozen
+   * @param asset The address of the underlying asset of the reserve
    **/
   event ReserveFrozen(address indexed asset);
 
   /**
-   * @dev emitted when a reserve is unfrozen
-   * @param asset the address of the reserve
+   * @dev Emitted when a reserve is unfrozen
+   * @param asset The address of the underlying asset of the reserve
    **/
   event ReserveUnfrozen(address indexed asset);
 
   /**
-   * @dev emitted when a reserve factor is updated
-   * @param asset the address of the reserve
-   * @param factor the new reserve factor
+   * @dev Emitted when a reserve factor is updated
+   * @param asset The address of the underlying asset of the reserve
+   * @param factor The new reserve factor
    **/
   event ReserveFactorChanged(address indexed asset, uint256 factor);
 
   /**
-   * @dev emitted when the reserve decimals are updated
-   * @param asset the address of the reserve
-   * @param decimals the new decimals
+   * @dev Emitted when the reserve decimals are updated
+   * @param asset The address of the underlying asset of the reserve
+   * @param decimals The new decimals
    **/
   event ReserveDecimalsChanged(address indexed asset, uint256 decimals);
 
   /**
-   * @dev emitted when a reserve interest strategy contract is updated
-   * @param asset the address of the reserve
-   * @param strategy the new address of the interest strategy contract
+   * @dev Emitted when a reserve interest strategy contract is updated
+   * @param asset The address of the underlying asset of the reserve
+   * @param strategy The new address of the interest strategy contract
    **/
   event ReserveInterestRateStrategyChanged(address indexed asset, address strategy);
 
   /**
-   * @dev emitted when an aToken implementation is upgraded
-   * @param asset the address of the reserve
-   * @param proxy the aToken proxy address
-   * @param implementation the new aToken implementation
+   * @dev Emitted when an aToken implementation is upgraded
+   * @param asset The address of the underlying asset of the reserve
+   * @param proxy The aToken proxy address
+   * @param implementation The new aToken implementation
    **/
   event ATokenUpgraded(
     address indexed asset,
@@ -140,10 +140,10 @@ contract LendingPoolConfigurator is VersionedInitializable {
   );
 
   /**
-   * @dev emitted when the implementation of a stable debt token is upgraded
-   * @param asset the address of the reserve
-   * @param proxy the stable debt token proxy address
-   * @param implementation the new aToken implementation
+   * @dev Emitted when the implementation of a stable debt token is upgraded
+   * @param asset The address of the underlying asset of the reserve
+   * @param proxy The stable debt token proxy address
+   * @param implementation The new aToken implementation
    **/
   event StableDebtTokenUpgraded(
     address indexed asset,
@@ -152,10 +152,10 @@ contract LendingPoolConfigurator is VersionedInitializable {
   );
 
   /**
-   * @dev emitted when the implementation of a variable debt token is upgraded
-   * @param asset the address of the reserve
-   * @param proxy the variable debt token proxy address
-   * @param implementation the new aToken implementation
+   * @dev Emitted when the implementation of a variable debt token is upgraded
+   * @param asset The address of the underlying asset of the reserve
+   * @param proxy The variable debt token proxy address
+   * @param implementation The new aToken implementation
    **/
   event VariableDebtTokenUpgraded(
     address indexed asset,
@@ -166,17 +166,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
   ILendingPoolAddressesProvider internal addressesProvider;
   ILendingPool internal pool;
 
-  /**
-   * @dev only the pool admin can call functions affected by this modifier
-   **/
   modifier onlyPoolAdmin {
     require(addressesProvider.getPoolAdmin() == msg.sender, Errors.CALLER_NOT_POOL_ADMIN);
     _;
   }
 
-  /**
-   * @dev only the emergency admin can call functions affected by this modifier
-   **/
   modifier onlyEmergencyAdmin {
     require(
       addressesProvider.getEmergencyAdmin() == msg.sender,
@@ -185,7 +179,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
     _;
   }
 
-  uint256 internal constant CONFIGURATOR_REVISION = 0x3;
+  uint256 internal constant CONFIGURATOR_REVISION = 0x1;
 
   function getRevision() internal pure override returns (uint256) {
     return CONFIGURATOR_REVISION;
@@ -197,12 +191,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev initializes a reserve
-   * @param aTokenImpl  the address of the aToken contract implementation
-   * @param stableDebtTokenImpl the address of the stable debt token contract
-   * @param variableDebtTokenImpl the address of the variable debt token contract
-   * @param underlyingAssetDecimals the decimals of the reserve underlying asset
-   * @param interestRateStrategyAddress the address of the interest rate strategy contract for this reserve
+   * @dev Initializes a reserve
+   * @param aTokenImpl  The address of the aToken contract implementation
+   * @param stableDebtTokenImpl The address of the stable debt token contract
+   * @param variableDebtTokenImpl The address of the variable debt token contract
+   * @param underlyingAssetDecimals The decimals of the reserve underlying asset
+   * @param interestRateStrategyAddress The address of the interest rate strategy contract for this reserve
    **/
   function initReserve(
     address aTokenImpl,
@@ -250,7 +244,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
       interestRateStrategyAddress
     );
 
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setDecimals(underlyingAssetDecimals);
 
@@ -269,12 +263,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev updates the aToken implementation for the asset
-   * @param asset the address of the reserve to be updated
-   * @param implementation the address of the new aToken implementation
+   * @dev Updates the aToken implementation for the reserve
+   * @param asset The address of the underlying asset of the reserve to be updated
+   * @param implementation The address of the new aToken implementation
    **/
   function updateAToken(address asset, address implementation) external onlyPoolAdmin {
-    ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
+    DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
 
     _upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation);
 
@@ -282,12 +276,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev updates the stable debt token implementation for the asset
-   * @param asset the address of the reserve to be updated
-   * @param implementation the address of the new aToken implementation
+   * @dev Updates the stable debt token implementation for the reserve
+   * @param asset The address of the underlying asset of the reserve to be updated
+   * @param implementation The address of the new aToken implementation
    **/
   function updateStableDebtToken(address asset, address implementation) external onlyPoolAdmin {
-    ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
+    DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
 
     _upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation);
 
@@ -295,12 +289,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev updates the variable debt token implementation for the asset
-   * @param asset the address of the reserve to be updated
-   * @param implementation the address of the new aToken implementation
+   * @dev Updates the variable debt token implementation for the asset
+   * @param asset The address of the underlying asset of the reserve to be updated
+   * @param implementation The address of the new aToken implementation
    **/
   function updateVariableDebtToken(address asset, address implementation) external onlyPoolAdmin {
-    ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
+    DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
 
     _upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation);
 
@@ -308,15 +302,15 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev enables borrowing on a reserve
-   * @param asset the address of the reserve
-   * @param stableBorrowRateEnabled true if stable borrow rate needs to be enabled by default on this reserve
+   * @dev Enables borrowing on a reserve
+   * @param asset The address of the underlying asset of the reserve
+   * @param stableBorrowRateEnabled True if stable borrow rate needs to be enabled by default on this reserve
    **/
   function enableBorrowingOnReserve(address asset, bool stableBorrowRateEnabled)
     external
     onlyPoolAdmin
   {
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setBorrowingEnabled(true);
     currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled);
@@ -327,11 +321,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev disables borrowing on a reserve
-   * @param asset the address of the reserve
+   * @dev Disables borrowing on a reserve
+   * @param asset The address of the underlying asset of the reserve
    **/
   function disableBorrowingOnReserve(address asset) external onlyPoolAdmin {
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setBorrowingEnabled(false);
 
@@ -340,12 +334,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev configures the reserve collateralization parameters.
+   * @dev Configures the reserve collateralization parameters
    * all the values are expressed in percentages with two decimals of precision. A valid value is 10000, which means 100.00%
-   * @param asset the address of the reserve
-   * @param ltv the loan to value of the asset when used as collateral
-   * @param liquidationThreshold the threshold at which loans using this asset as collateral will be considered undercollateralized
-   * @param liquidationBonus the bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105%
+   * @param asset The address of the underlying asset of the reserve
+   * @param ltv The loan to value of the asset when used as collateral
+   * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized
+   * @param liquidationBonus The bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105%
    * means the liquidator will receive a 5% bonus
    **/
   function configureReserveAsCollateral(
@@ -354,7 +348,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
     uint256 liquidationThreshold,
     uint256 liquidationBonus
   ) external onlyPoolAdmin {
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     //validation of the parameters: the LTV can
     //only be lower or equal than the liquidation threshold
@@ -363,15 +357,16 @@ contract LendingPoolConfigurator is VersionedInitializable {
 
     if (liquidationThreshold != 0) {
       //liquidation bonus must be bigger than 100.00%, otherwise the liquidator would receive less
-      //collateral than needed to cover the debt.
-      uint256 absoluteBonus =
-        liquidationBonus.sub(PercentageMath.PERCENTAGE_FACTOR, Errors.LPC_INVALID_CONFIGURATION);
-      require(absoluteBonus > 0, Errors.LPC_INVALID_CONFIGURATION);
-
-      //we also need to require that the liq threshold is lower or equal than the liquidation bonus, to ensure that
-      //there is always enough margin for liquidators to receive the bonus.
+      //collateral than needed to cover the debt
       require(
-        liquidationThreshold.add(absoluteBonus) <= PercentageMath.PERCENTAGE_FACTOR,
+        liquidationBonus > PercentageMath.PERCENTAGE_FACTOR,
+        Errors.LPC_INVALID_CONFIGURATION
+      );
+
+      //if threshold * bonus is less than PERCENTAGE_FACTOR, it's guaranteed that at the moment
+      //a loan is taken there is enough collateral available to cover the liquidation bonus
+      require(
+        liquidationThreshold.percentMul(liquidationBonus) <= PercentageMath.PERCENTAGE_FACTOR,
         Errors.LPC_INVALID_CONFIGURATION
       );
     } else {
@@ -392,11 +387,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev enable stable rate borrowing on a reserve
-   * @param asset the address of the reserve
+   * @dev Enable stable rate borrowing on a reserve
+   * @param asset The address of the underlying asset of the reserve
    **/
   function enableReserveStableRate(address asset) external onlyPoolAdmin {
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setStableRateBorrowingEnabled(true);
 
@@ -406,11 +401,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev disable stable rate borrowing on a reserve
-   * @param asset the address of the reserve
+   * @dev Disable stable rate borrowing on a reserve
+   * @param asset The address of the underlying asset of the reserve
    **/
   function disableReserveStableRate(address asset) external onlyPoolAdmin {
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setStableRateBorrowingEnabled(false);
 
@@ -420,11 +415,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev activates a reserve
-   * @param asset the address of the reserve
+   * @dev Activates a reserve
+   * @param asset The address of the underlying asset of the reserve
    **/
   function activateReserve(address asset) external onlyPoolAdmin {
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setActive(true);
 
@@ -434,13 +429,13 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev deactivates a reserve
-   * @param asset the address of the reserve
+   * @dev Deactivates a reserve
+   * @param asset The address of the underlying asset of the reserve
    **/
   function deactivateReserve(address asset) external onlyPoolAdmin {
     _checkNoLiquidity(asset);
 
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setActive(false);
 
@@ -450,11 +445,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev freezes a reserve. A frozen reserve doesn't accept any new deposit, borrow or rate swap, but can accept repayments, liquidations, rate rebalances and redeems
-   * @param asset the address of the reserve
+   * @dev Freezes a reserve. A frozen reserve doesn't allow any new deposit, borrow or rate swap
+   *  but allows repayments, liquidations, rate rebalances and withdrawals
+   * @param asset The address of the underlying asset of the reserve
    **/
   function freezeReserve(address asset) external onlyPoolAdmin {
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setFrozen(true);
 
@@ -464,11 +460,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev unfreezes a reserve
-   * @param asset the address of the reserve
+   * @dev Unfreezes a reserve
+   * @param asset The address of the underlying asset of the reserve
    **/
   function unfreezeReserve(address asset) external onlyPoolAdmin {
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setFrozen(false);
 
@@ -478,12 +474,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev updates the reserve factor of a reserve
-   * @param asset the address of the reserve
-   * @param reserveFactor the new reserve factor of the reserve
+   * @dev Updates the reserve factor of a reserve
+   * @param asset The address of the underlying asset of the reserve
+   * @param reserveFactor The new reserve factor of the reserve
    **/
   function setReserveFactor(address asset, uint256 reserveFactor) external onlyPoolAdmin {
-    ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
 
     currentConfig.setReserveFactor(reserveFactor);
 
@@ -493,9 +489,9 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev sets the interest rate strategy of a reserve
-   * @param asset the address of the reserve
-   * @param rateStrategyAddress the new address of the interest strategy contract
+   * @dev Sets the interest rate strategy of a reserve
+   * @param asset The address of the underlying asset of the reserve
+   * @param rateStrategyAddress The new address of the interest strategy contract
    **/
   function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
     external
@@ -506,10 +502,13 @@ contract LendingPoolConfigurator is VersionedInitializable {
   }
 
   /**
-   * @dev initializes a token with a proxy and a specific implementation
-   * @param implementation the address of the implementation
-   * @param decimals the decimals of the token
+   * @dev pauses or unpauses all the actions of the protocol, including aToken transfers
+   * @param val true if protocol needs to be paused, false otherwise
    **/
+  function setPoolPause(bool val) external onlyEmergencyAdmin {
+    pool.setPause(val);
+  }
+
   function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) {
     InitializableImmutableAdminUpgradeabilityProxy proxy =
       new InitializableImmutableAdminUpgradeabilityProxy(address(this));
@@ -535,7 +534,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
     InitializableImmutableAdminUpgradeabilityProxy proxy =
       InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress));
 
-    ReserveConfiguration.Map memory configuration = pool.getConfiguration(asset);
+    DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(asset);
 
     (, , , uint256 decimals, ) = configuration.getParamsMemory();
 
@@ -550,16 +549,8 @@ contract LendingPoolConfigurator is VersionedInitializable {
     proxy.upgradeToAndCall(implementation, params);
   }
 
-  /**
-   * @dev pauses or unpauses LendingPool actions
-   * @param val the boolean value to set the current pause state of LendingPool
-   **/
-  function setPoolPause(bool val) external onlyEmergencyAdmin {
-    pool.setPause(val);
-  }
-
   function _checkNoLiquidity(address asset) internal view {
-    ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
+    DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
 
     uint256 availableLiquidity = IERC20Detailed(asset).balanceOf(reserveData.aTokenAddress);
 
diff --git a/contracts/protocol/lendingpool/LendingPoolStorage.sol b/contracts/protocol/lendingpool/LendingPoolStorage.sol
index 721a4f0a..4edff4a3 100644
--- a/contracts/protocol/lendingpool/LendingPoolStorage.sol
+++ b/contracts/protocol/lendingpool/LendingPoolStorage.sol
@@ -5,16 +5,17 @@ import {UserConfiguration} from '../libraries/configuration/UserConfiguration.so
 import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
 import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
 import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
+import {DataTypes} from '../libraries/types/DataTypes.sol';
 
 contract LendingPoolStorage {
-  using ReserveLogic for ReserveLogic.ReserveData;
-  using ReserveConfiguration for ReserveConfiguration.Map;
-  using UserConfiguration for UserConfiguration.Map;
+  using ReserveLogic for DataTypes.ReserveData;
+  using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
+  using UserConfiguration for DataTypes.UserConfigurationMap;
 
   ILendingPoolAddressesProvider internal _addressesProvider;
 
-  mapping(address => ReserveLogic.ReserveData) internal _reserves;
-  mapping(address => UserConfiguration.Map) internal _usersConfig;
+  mapping(address => DataTypes.ReserveData) internal _reserves;
+  mapping(address => DataTypes.UserConfigurationMap) internal _usersConfig;
 
   // the list of the available reserves, structured as a mapping for gas savings reasons
   mapping(uint256 => address) internal _reservesList;
diff --git a/contracts/protocol/libraries/configuration/ReserveConfiguration.sol b/contracts/protocol/libraries/configuration/ReserveConfiguration.sol
index 3f7a8bf6..39df878b 100644
--- a/contracts/protocol/libraries/configuration/ReserveConfiguration.sol
+++ b/contracts/protocol/libraries/configuration/ReserveConfiguration.sol
@@ -2,6 +2,7 @@
 pragma solidity 0.6.12;
 
 import {Errors} from '../helpers/Errors.sol';
+import {DataTypes} from '../types/DataTypes.sol';
 
 /**
  * @title ReserveConfiguration library
@@ -35,26 +36,12 @@ library ReserveConfiguration {
   uint256 constant MAX_VALID_DECIMALS = 255;
   uint256 constant MAX_VALID_RESERVE_FACTOR = 65535;
 
-  struct Map {
-    //bit 0-15: LTV
-    //bit 16-31: Liq. threshold
-    //bit 32-47: Liq. bonus
-    //bit 48-55: Decimals
-    //bit 56: Reserve is active
-    //bit 57: reserve is frozen
-    //bit 58: borrowing is enabled
-    //bit 59: stable rate borrowing enabled
-    //bit 60-63: reserved
-    //bit 64-79: reserve factor
-    uint256 data;
-  }
-
   /**
    * @dev sets the Loan to Value of the reserve
    * @param self the reserve configuration
    * @param ltv the new ltv
    **/
-  function setLtv(ReserveConfiguration.Map memory self, uint256 ltv) internal pure {
+  function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure {
     require(ltv <= MAX_VALID_LTV, Errors.RC_INVALID_LTV);
 
     self.data = (self.data & LTV_MASK) | ltv;
@@ -65,7 +52,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the loan to value
    **/
-  function getLtv(ReserveConfiguration.Map storage self) internal view returns (uint256) {
+  function getLtv(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
     return self.data & ~LTV_MASK;
   }
 
@@ -74,7 +61,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @param threshold the new liquidation threshold
    **/
-  function setLiquidationThreshold(ReserveConfiguration.Map memory self, uint256 threshold)
+  function setLiquidationThreshold(DataTypes.ReserveConfigurationMap memory self, uint256 threshold)
     internal
     pure
   {
@@ -90,7 +77,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the liquidation threshold
    **/
-  function getLiquidationThreshold(ReserveConfiguration.Map storage self)
+  function getLiquidationThreshold(DataTypes.ReserveConfigurationMap storage self)
     internal
     view
     returns (uint256)
@@ -103,7 +90,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @param bonus the new liquidation bonus
    **/
-  function setLiquidationBonus(ReserveConfiguration.Map memory self, uint256 bonus) internal pure {
+  function setLiquidationBonus(DataTypes.ReserveConfigurationMap memory self, uint256 bonus) internal pure {
     require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.RC_INVALID_LIQ_BONUS);
 
     self.data =
@@ -116,7 +103,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the liquidation bonus
    **/
-  function getLiquidationBonus(ReserveConfiguration.Map storage self)
+  function getLiquidationBonus(DataTypes.ReserveConfigurationMap storage self)
     internal
     view
     returns (uint256)
@@ -129,7 +116,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @param decimals the decimals
    **/
-  function setDecimals(ReserveConfiguration.Map memory self, uint256 decimals) internal pure {
+  function setDecimals(DataTypes.ReserveConfigurationMap memory self, uint256 decimals) internal pure {
     require(decimals <= MAX_VALID_DECIMALS, Errors.RC_INVALID_DECIMALS);
 
     self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION);
@@ -140,7 +127,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the decimals of the asset
    **/
-  function getDecimals(ReserveConfiguration.Map storage self) internal view returns (uint256) {
+  function getDecimals(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
     return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION;
   }
 
@@ -149,7 +136,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @param active the active state
    **/
-  function setActive(ReserveConfiguration.Map memory self, bool active) internal pure {
+  function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure {
     self.data =
       (self.data & ACTIVE_MASK) |
       (uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION);
@@ -160,7 +147,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the active state
    **/
-  function getActive(ReserveConfiguration.Map storage self) internal view returns (bool) {
+  function getActive(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
     return (self.data & ~ACTIVE_MASK) != 0;
   }
 
@@ -169,7 +156,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @param frozen the frozen state
    **/
-  function setFrozen(ReserveConfiguration.Map memory self, bool frozen) internal pure {
+  function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure {
     self.data =
       (self.data & FROZEN_MASK) |
       (uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION);
@@ -180,7 +167,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the frozen state
    **/
-  function getFrozen(ReserveConfiguration.Map storage self) internal view returns (bool) {
+  function getFrozen(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
     return (self.data & ~FROZEN_MASK) != 0;
   }
 
@@ -189,7 +176,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @param enabled true if the borrowing needs to be enabled, false otherwise
    **/
-  function setBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled) internal pure {
+  function setBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled) internal pure {
     self.data =
       (self.data & BORROWING_MASK) |
       (uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION);
@@ -200,7 +187,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the borrowing state
    **/
-  function getBorrowingEnabled(ReserveConfiguration.Map storage self) internal view returns (bool) {
+  function getBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
     return (self.data & ~BORROWING_MASK) != 0;
   }
 
@@ -209,7 +196,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @param enabled true if the stable rate borrowing needs to be enabled, false otherwise
    **/
-  function setStableRateBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled)
+  function setStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled)
     internal
     pure
   {
@@ -223,7 +210,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the stable rate borrowing state
    **/
-  function getStableRateBorrowingEnabled(ReserveConfiguration.Map storage self)
+  function getStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self)
     internal
     view
     returns (bool)
@@ -236,7 +223,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @param reserveFactor the reserve factor
    **/
-  function setReserveFactor(ReserveConfiguration.Map memory self, uint256 reserveFactor)
+  function setReserveFactor(DataTypes.ReserveConfigurationMap memory self, uint256 reserveFactor)
     internal
     pure
   {
@@ -252,7 +239,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the reserve factor
    **/
-  function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) {
+  function getReserveFactor(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
     return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION;
   }
 
@@ -261,7 +248,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled
    **/
-  function getFlags(ReserveConfiguration.Map storage self)
+  function getFlags(DataTypes.ReserveConfigurationMap storage self)
     internal
     view
     returns (
@@ -286,7 +273,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
    **/
-  function getParams(ReserveConfiguration.Map storage self)
+  function getParams(DataTypes.ReserveConfigurationMap storage self)
     internal
     view
     returns (
@@ -313,7 +300,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
    **/
-  function getParamsMemory(ReserveConfiguration.Map memory self)
+  function getParamsMemory(DataTypes.ReserveConfigurationMap memory self)
     internal
     pure
     returns (
@@ -338,7 +325,7 @@ library ReserveConfiguration {
    * @param self the reserve configuration
    * @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled
    **/
-  function getFlagsMemory(ReserveConfiguration.Map memory self)
+  function getFlagsMemory(DataTypes.ReserveConfigurationMap memory self)
     internal
     pure
     returns (
diff --git a/contracts/protocol/libraries/configuration/UserConfiguration.sol b/contracts/protocol/libraries/configuration/UserConfiguration.sol
index 665b019a..b4af79ad 100644
--- a/contracts/protocol/libraries/configuration/UserConfiguration.sol
+++ b/contracts/protocol/libraries/configuration/UserConfiguration.sol
@@ -2,6 +2,7 @@
 pragma solidity 0.6.12;
 
 import {Errors} from '../helpers/Errors.sol';
+import {DataTypes} from '../types/DataTypes.sol';
 
 /**
  * @title UserConfiguration library
@@ -12,10 +13,6 @@ library UserConfiguration {
   uint256 internal constant BORROWING_MASK =
     0x5555555555555555555555555555555555555555555555555555555555555555;
 
-  struct Map {
-    uint256 data;
-  }
-
   /**
    * @dev sets if the user is borrowing the reserve identified by reserveIndex
    * @param self the configuration object
@@ -23,7 +20,7 @@ library UserConfiguration {
    * @param borrowing true if the user is borrowing the reserve, false otherwise
    **/
   function setBorrowing(
-    UserConfiguration.Map storage self,
+    DataTypes.UserConfigurationMap storage self,
     uint256 reserveIndex,
     bool borrowing
   ) internal {
@@ -40,7 +37,7 @@ library UserConfiguration {
    * @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise
    **/
   function setUsingAsCollateral(
-    UserConfiguration.Map storage self,
+    DataTypes.UserConfigurationMap storage self,
     uint256 reserveIndex,
     bool _usingAsCollateral
   ) internal {
@@ -56,7 +53,7 @@ library UserConfiguration {
    * @param reserveIndex the index of the reserve in the bitmap
    * @return true if the user has been using a reserve for borrowing or as collateral, false otherwise
    **/
-  function isUsingAsCollateralOrBorrowing(UserConfiguration.Map memory self, uint256 reserveIndex)
+  function isUsingAsCollateralOrBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
     internal
     pure
     returns (bool)
@@ -71,7 +68,7 @@ library UserConfiguration {
    * @param reserveIndex the index of the reserve in the bitmap
    * @return true if the user has been using a reserve for borrowing, false otherwise
    **/
-  function isBorrowing(UserConfiguration.Map memory self, uint256 reserveIndex)
+  function isBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
     internal
     pure
     returns (bool)
@@ -86,7 +83,7 @@ library UserConfiguration {
    * @param reserveIndex the index of the reserve in the bitmap
    * @return true if the user has been using a reserve as collateral, false otherwise
    **/
-  function isUsingAsCollateral(UserConfiguration.Map memory self, uint256 reserveIndex)
+  function isUsingAsCollateral(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
     internal
     pure
     returns (bool)
@@ -100,7 +97,7 @@ library UserConfiguration {
    * @param self the configuration object
    * @return true if the user has been borrowing any reserve, false otherwise
    **/
-  function isBorrowingAny(UserConfiguration.Map memory self) internal pure returns (bool) {
+  function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
     return self.data & BORROWING_MASK != 0;
   }
 
@@ -109,7 +106,7 @@ library UserConfiguration {
    * @param self the configuration object
    * @return true if the user has been borrowing any reserve, false otherwise
    **/
-  function isEmpty(UserConfiguration.Map memory self) internal pure returns (bool) {
+  function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
     return self.data == 0;
   }
 }
diff --git a/contracts/protocol/libraries/helpers/Helpers.sol b/contracts/protocol/libraries/helpers/Helpers.sol
index b0d8731c..b21249e2 100644
--- a/contracts/protocol/libraries/helpers/Helpers.sol
+++ b/contracts/protocol/libraries/helpers/Helpers.sol
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: agpl-3.0
 pragma solidity 0.6.12;
 
-import {DebtTokenBase} from '../../tokenization/base/DebtTokenBase.sol';
-import {ReserveLogic} from '../logic/ReserveLogic.sol';
+import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
+import {DataTypes} from '../types/DataTypes.sol';
 
 /**
  * @title Helpers library
@@ -16,25 +16,25 @@ library Helpers {
    * @param reserve the reserve object
    * @return the stable and variable debt balance
    **/
-  function getUserCurrentDebt(address user, ReserveLogic.ReserveData storage reserve)
+  function getUserCurrentDebt(address user, DataTypes.ReserveData storage reserve)
     internal
     view
     returns (uint256, uint256)
   {
     return (
-      DebtTokenBase(reserve.stableDebtTokenAddress).balanceOf(user),
-      DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user)
+      IERC20(reserve.stableDebtTokenAddress).balanceOf(user),
+      IERC20(reserve.variableDebtTokenAddress).balanceOf(user)
     );
   }
 
-  function getUserCurrentDebtMemory(address user, ReserveLogic.ReserveData memory reserve)
+  function getUserCurrentDebtMemory(address user, DataTypes.ReserveData memory reserve)
     internal
     view
     returns (uint256, uint256)
   {
     return (
-      DebtTokenBase(reserve.stableDebtTokenAddress).balanceOf(user),
-      DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user)
+      IERC20(reserve.stableDebtTokenAddress).balanceOf(user),
+      IERC20(reserve.variableDebtTokenAddress).balanceOf(user)
     );
   }
 }
diff --git a/contracts/protocol/libraries/logic/GenericLogic.sol b/contracts/protocol/libraries/logic/GenericLogic.sol
index 37244dfd..e8ee263f 100644
--- a/contracts/protocol/libraries/logic/GenericLogic.sol
+++ b/contracts/protocol/libraries/logic/GenericLogic.sol
@@ -10,6 +10,7 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol';
 import {WadRayMath} from '../math/WadRayMath.sol';
 import {PercentageMath} from '../math/PercentageMath.sol';
 import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol';
+import {DataTypes} from '../types/DataTypes.sol';
 
 /**
  * @title GenericLogic library
@@ -17,12 +18,12 @@ import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol';
  * @title Implements protocol-level logic to check the status of the user across all the reserves
  */
 library GenericLogic {
-  using ReserveLogic for ReserveLogic.ReserveData;
+  using ReserveLogic for DataTypes.ReserveData;
   using SafeMath for uint256;
   using WadRayMath for uint256;
   using PercentageMath for uint256;
-  using ReserveConfiguration for ReserveConfiguration.Map;
-  using UserConfiguration for UserConfiguration.Map;
+  using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
+  using UserConfiguration for DataTypes.UserConfigurationMap;
 
   uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1 ether;
 
@@ -55,8 +56,8 @@ library GenericLogic {
     address asset,
     address user,
     uint256 amount,
-    mapping(address => ReserveLogic.ReserveData) storage reservesData,
-    UserConfiguration.Map calldata userConfig,
+    mapping(address => DataTypes.ReserveData) storage reservesData,
+    DataTypes.UserConfigurationMap calldata userConfig,
     mapping(uint256 => address) storage reserves,
     uint256 reservesCount,
     address oracle
@@ -150,8 +151,8 @@ library GenericLogic {
    **/
   function calculateUserAccountData(
     address user,
-    mapping(address => ReserveLogic.ReserveData) storage reservesData,
-    UserConfiguration.Map memory userConfig,
+    mapping(address => DataTypes.ReserveData) storage reservesData,
+    DataTypes.UserConfigurationMap memory userConfig,
     mapping(uint256 => address) storage reserves,
     uint256 reservesCount,
     address oracle
@@ -177,7 +178,7 @@ library GenericLogic {
       }
 
       vars.currentReserveAddress = reserves[vars.i];
-      ReserveLogic.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
+      DataTypes.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
 
       (vars.ltv, vars.liquidationThreshold, , vars.decimals, ) = currentReserve
         .configuration
diff --git a/contracts/protocol/libraries/logic/ReserveLogic.sol b/contracts/protocol/libraries/logic/ReserveLogic.sol
index 1e23fa0c..7a73be5b 100644
--- a/contracts/protocol/libraries/logic/ReserveLogic.sol
+++ b/contracts/protocol/libraries/logic/ReserveLogic.sol
@@ -13,6 +13,7 @@ import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterest
 import {WadRayMath} from '../math/WadRayMath.sol';
 import {PercentageMath} from '../math/PercentageMath.sol';
 import {Errors} from '../helpers/Errors.sol';
+import {DataTypes} from '../types/DataTypes.sol';
 
 /**
  * @title ReserveLogic library
@@ -43,35 +44,8 @@ library ReserveLogic {
     uint256 variableBorrowIndex
   );
 
-  using ReserveLogic for ReserveLogic.ReserveData;
-  using ReserveConfiguration for ReserveConfiguration.Map;
-
-  enum InterestRateMode {NONE, STABLE, VARIABLE}
-
-  // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
-  struct ReserveData {
-    //stores the reserve configuration
-    ReserveConfiguration.Map configuration;
-    //the liquidity index. Expressed in ray
-    uint128 liquidityIndex;
-    //variable borrow index. Expressed in ray
-    uint128 variableBorrowIndex;
-    //the current supply rate. Expressed in ray
-    uint128 currentLiquidityRate;
-    //the current variable borrow rate. Expressed in ray
-    uint128 currentVariableBorrowRate;
-    //the current stable borrow rate. Expressed in ray
-    uint128 currentStableBorrowRate;
-    uint40 lastUpdateTimestamp;
-    //tokens addresses
-    address aTokenAddress;
-    address stableDebtTokenAddress;
-    address variableDebtTokenAddress;
-    //address of the interest rate strategy
-    address interestRateStrategyAddress;
-    //the id of the reserve. Represents the position in the list of the active reserves
-    uint8 id;
-  }
+  using ReserveLogic for DataTypes.ReserveData;
+  using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
 
   /**
    * @dev returns the ongoing normalized income for the reserve.
@@ -80,7 +54,11 @@ library ReserveLogic {
    * @param reserve the reserve object
    * @return the normalized income. expressed in ray
    **/
-  function getNormalizedIncome(ReserveData storage reserve) internal view returns (uint256) {
+  function getNormalizedIncome(DataTypes.ReserveData storage reserve)
+    internal
+    view
+    returns (uint256)
+  {
     uint40 timestamp = reserve.lastUpdateTimestamp;
 
     //solium-disable-next-line
@@ -104,7 +82,11 @@ library ReserveLogic {
    * @param reserve the reserve object
    * @return the normalized variable debt. expressed in ray
    **/
-  function getNormalizedDebt(ReserveData storage reserve) internal view returns (uint256) {
+  function getNormalizedDebt(DataTypes.ReserveData storage reserve)
+    internal
+    view
+    returns (uint256)
+  {
     uint40 timestamp = reserve.lastUpdateTimestamp;
 
     //solium-disable-next-line
@@ -126,7 +108,7 @@ library ReserveLogic {
    * a formal specification.
    * @param reserve the reserve object
    **/
-  function updateState(ReserveData storage reserve) internal {
+  function updateState(DataTypes.ReserveData storage reserve) internal {
     uint256 scaledVariableDebt =
       IVariableDebtToken(reserve.variableDebtTokenAddress).scaledTotalSupply();
     uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex;
@@ -160,7 +142,7 @@ library ReserveLogic {
    * @param amount the amount to accomulate
    **/
   function cumulateToLiquidityIndex(
-    ReserveData storage reserve,
+    DataTypes.ReserveData storage reserve,
     uint256 totalLiquidity,
     uint256 amount
   ) internal {
@@ -181,7 +163,7 @@ library ReserveLogic {
    * @param interestRateStrategyAddress the address of the interest rate strategy contract
    **/
   function init(
-    ReserveData storage reserve,
+    DataTypes.ReserveData storage reserve,
     address aTokenAddress,
     address stableDebtTokenAddress,
     address variableDebtTokenAddress,
@@ -216,7 +198,7 @@ library ReserveLogic {
    * @param liquidityTaken the amount of liquidity taken from the protocol (redeem or borrow)
    **/
   function updateInterestRates(
-    ReserveData storage reserve,
+    DataTypes.ReserveData storage reserve,
     address reserveAddress,
     address aTokenAddress,
     uint256 liquidityAdded,
@@ -292,7 +274,7 @@ library ReserveLogic {
    * @param newVariableBorrowIndex the variable borrow index after the last accumulation of the interest
    **/
   function _mintToTreasury(
-    ReserveData storage reserve,
+    DataTypes.ReserveData storage reserve,
     uint256 scaledVariableDebt,
     uint256 previousVariableBorrowIndex,
     uint256 newLiquidityIndex,
@@ -352,7 +334,7 @@ library ReserveLogic {
    * @param variableBorrowIndex the last stored variable borrow index
    **/
   function _updateIndexes(
-    ReserveData storage reserve,
+    DataTypes.ReserveData storage reserve,
     uint256 scaledVariableDebt,
     uint256 liquidityIndex,
     uint256 variableBorrowIndex,
diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol
index a966aa3e..7df21875 100644
--- a/contracts/protocol/libraries/logic/ValidationLogic.sol
+++ b/contracts/protocol/libraries/logic/ValidationLogic.sol
@@ -14,6 +14,7 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol';
 import {Errors} from '../helpers/Errors.sol';
 import {Helpers} from '../helpers/Helpers.sol';
 import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
+import {DataTypes} from '../types/DataTypes.sol';
 
 /**
  * @title ReserveLogic library
@@ -21,13 +22,13 @@ import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterest
  * @notice Implements functions to validate specific action on the protocol.
  */
 library ValidationLogic {
-  using ReserveLogic for ReserveLogic.ReserveData;
+  using ReserveLogic for DataTypes.ReserveData;
   using SafeMath for uint256;
   using WadRayMath for uint256;
   using PercentageMath for uint256;
   using SafeERC20 for IERC20;
-  using ReserveConfiguration for ReserveConfiguration.Map;
-  using UserConfiguration for UserConfiguration.Map;
+  using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
+  using UserConfiguration for DataTypes.UserConfigurationMap;
 
   uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 4000;
   uint256 public constant REBALANCE_UP_USAGE_RATIO_THRESHOLD = 0.95 * 1e27; //usage ratio of 95%
@@ -37,7 +38,7 @@ library ValidationLogic {
    * @param reserve the reserve state on which the user is depositing
    * @param amount the amount to be deposited
    */
-  function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) external view {
+  function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) external view {
     (bool isActive, bool isFrozen, , ) = reserve.configuration.getFlags();
 
     require(amount != 0, Errors.VL_INVALID_AMOUNT);
@@ -60,8 +61,8 @@ library ValidationLogic {
     address reserveAddress,
     uint256 amount,
     uint256 userBalance,
-    mapping(address => ReserveLogic.ReserveData) storage reservesData,
-    UserConfiguration.Map storage userConfig,
+    mapping(address => DataTypes.ReserveData) storage reservesData,
+    DataTypes.UserConfigurationMap storage userConfig,
     mapping(uint256 => address) storage reserves,
     uint256 reservesCount,
     address oracle
@@ -100,7 +101,7 @@ library ValidationLogic {
     uint256 availableLiquidity;
     uint256 finalUserBorrowRate;
     uint256 healthFactor;
-    ReserveLogic.InterestRateMode rateMode;
+    DataTypes.InterestRateMode rateMode;
     bool healthFactorBelowThreshold;
     bool isActive;
     bool isFrozen;
@@ -125,14 +126,14 @@ library ValidationLogic {
 
   function validateBorrow(
     address asset,
-    ReserveLogic.ReserveData storage reserve,
+    DataTypes.ReserveData storage reserve,
     address userAddress,
     uint256 amount,
     uint256 amountInETH,
     uint256 interestRateMode,
     uint256 maxStableLoanPercent,
-    mapping(address => ReserveLogic.ReserveData) storage reservesData,
-    UserConfiguration.Map storage userConfig,
+    mapping(address => DataTypes.ReserveData) storage reservesData,
+    DataTypes.UserConfigurationMap storage userConfig,
     mapping(uint256 => address) storage reserves,
     uint256 reservesCount,
     address oracle
@@ -151,8 +152,8 @@ library ValidationLogic {
 
     //validate interest rate mode
     require(
-      uint256(ReserveLogic.InterestRateMode.VARIABLE) == interestRateMode ||
-        uint256(ReserveLogic.InterestRateMode.STABLE) == interestRateMode,
+      uint256(DataTypes.InterestRateMode.VARIABLE) == interestRateMode ||
+        uint256(DataTypes.InterestRateMode.STABLE) == interestRateMode,
       Errors.VL_INVALID_INTEREST_RATE_MODE_SELECTED
     );
 
@@ -197,7 +198,7 @@ library ValidationLogic {
      *    liquidity
      **/
 
-    if (vars.rateMode == ReserveLogic.InterestRateMode.STABLE) {
+    if (vars.rateMode == DataTypes.InterestRateMode.STABLE) {
       //check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve
 
       require(vars.stableRateBorrowingEnabled, Errors.VL_STABLE_BORROWING_NOT_ENABLED);
@@ -228,9 +229,9 @@ library ValidationLogic {
    * @param variableDebt the borrow balance of the user
    */
   function validateRepay(
-    ReserveLogic.ReserveData storage reserve,
+    DataTypes.ReserveData storage reserve,
     uint256 amountSent,
-    ReserveLogic.InterestRateMode rateMode,
+    DataTypes.InterestRateMode rateMode,
     address onBehalfOf,
     uint256 stableDebt,
     uint256 variableDebt
@@ -243,9 +244,9 @@ library ValidationLogic {
 
     require(
       (stableDebt > 0 &&
-        ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.STABLE) ||
+        DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE) ||
         (variableDebt > 0 &&
-          ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.VARIABLE),
+          DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.VARIABLE),
       Errors.VL_NO_DEBT_OF_SELECTED_TYPE
     );
 
@@ -264,20 +265,20 @@ library ValidationLogic {
    * @param currentRateMode the rate mode of the borrow
    */
   function validateSwapRateMode(
-    ReserveLogic.ReserveData storage reserve,
-    UserConfiguration.Map storage userConfig,
+    DataTypes.ReserveData storage reserve,
+    DataTypes.UserConfigurationMap storage userConfig,
     uint256 stableDebt,
     uint256 variableDebt,
-    ReserveLogic.InterestRateMode currentRateMode
+    DataTypes.InterestRateMode currentRateMode
   ) external view {
     (bool isActive, bool isFrozen, , bool stableRateEnabled) = reserve.configuration.getFlags();
 
     require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
     require(!isFrozen, Errors.VL_RESERVE_FROZEN);
 
-    if (currentRateMode == ReserveLogic.InterestRateMode.STABLE) {
+    if (currentRateMode == DataTypes.InterestRateMode.STABLE) {
       require(stableDebt > 0, Errors.VL_NO_STABLE_RATE_LOAN_IN_RESERVE);
-    } else if (currentRateMode == ReserveLogic.InterestRateMode.VARIABLE) {
+    } else if (currentRateMode == DataTypes.InterestRateMode.VARIABLE) {
       require(variableDebt > 0, Errors.VL_NO_VARIABLE_RATE_LOAN_IN_RESERVE);
       /**
        * user wants to swap to stable, before swapping we need to ensure that
@@ -308,7 +309,7 @@ library ValidationLogic {
    * @param aTokenAddress the address of the aToken contract
    */
   function validateRebalanceStableBorrowRate(
-    ReserveLogic.ReserveData storage reserve,
+    DataTypes.ReserveData storage reserve,
     address reserveAddress,
     IERC20 stableDebtToken,
     IERC20 variableDebtToken,
@@ -349,11 +350,11 @@ library ValidationLogic {
    * @param oracle the price oracle
    */
   function validateSetUseReserveAsCollateral(
-    ReserveLogic.ReserveData storage reserve,
+    DataTypes.ReserveData storage reserve,
     address reserveAddress,
     bool useAsCollateral,
-    mapping(address => ReserveLogic.ReserveData) storage reservesData,
-    UserConfiguration.Map storage userConfig,
+    mapping(address => DataTypes.ReserveData) storage reservesData,
+    DataTypes.UserConfigurationMap storage userConfig,
     mapping(uint256 => address) storage reserves,
     uint256 reservesCount,
     address oracle
@@ -397,9 +398,9 @@ library ValidationLogic {
    * @param userVariableDebt Total variable debt balance of the user
    **/
   function validateLiquidationCall(
-    ReserveLogic.ReserveData storage collateralReserve,
-    ReserveLogic.ReserveData storage principalReserve,
-    UserConfiguration.Map storage userConfig,
+    DataTypes.ReserveData storage collateralReserve,
+    DataTypes.ReserveData storage principalReserve,
+    DataTypes.UserConfigurationMap storage userConfig,
     uint256 userHealthFactor,
     uint256 userStableDebt,
     uint256 userVariableDebt
@@ -452,8 +453,8 @@ library ValidationLogic {
    */
   function validateTransfer(
     address from,
-    mapping(address => ReserveLogic.ReserveData) storage reservesData,
-    UserConfiguration.Map storage userConfig,
+    mapping(address => DataTypes.ReserveData) storage reservesData,
+    DataTypes.UserConfigurationMap storage userConfig,
     mapping(uint256 => address) storage reserves,
     uint256 reservesCount,
     address oracle
diff --git a/contracts/protocol/libraries/types/DataTypes.sol b/contracts/protocol/libraries/types/DataTypes.sol
new file mode 100644
index 00000000..a19e5efc
--- /dev/null
+++ b/contracts/protocol/libraries/types/DataTypes.sol
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: agpl-3.0
+pragma solidity 0.6.12;
+
+library DataTypes {
+  // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
+  struct ReserveData {
+    //stores the reserve configuration
+    ReserveConfigurationMap configuration;
+    //the liquidity index. Expressed in ray
+    uint128 liquidityIndex;
+    //variable borrow index. Expressed in ray
+    uint128 variableBorrowIndex;
+    //the current supply rate. Expressed in ray
+    uint128 currentLiquidityRate;
+    //the current variable borrow rate. Expressed in ray
+    uint128 currentVariableBorrowRate;
+    //the current stable borrow rate. Expressed in ray
+    uint128 currentStableBorrowRate;
+    uint40 lastUpdateTimestamp;
+    //tokens addresses
+    address aTokenAddress;
+    address stableDebtTokenAddress;
+    address variableDebtTokenAddress;
+    //address of the interest rate strategy
+    address interestRateStrategyAddress;
+    //the id of the reserve. Represents the position in the list of the active reserves
+    uint8 id;
+  }
+
+  struct ReserveConfigurationMap {
+    //bit 0-15: LTV
+    //bit 16-31: Liq. threshold
+    //bit 32-47: Liq. bonus
+    //bit 48-55: Decimals
+    //bit 56: Reserve is active
+    //bit 57: reserve is frozen
+    //bit 58: borrowing is enabled
+    //bit 59: stable rate borrowing enabled
+    //bit 60-63: reserved
+    //bit 64-79: reserve factor
+    uint256 data;
+  }
+
+  struct UserConfigurationMap {
+    uint256 data;
+  }
+
+  enum InterestRateMode {NONE, STABLE, VARIABLE}
+}
diff --git a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol
index cb699e39..57752c58 100644
--- a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol
+++ b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol
@@ -1,16 +1,12 @@
 pragma solidity 0.6.12;
 pragma experimental ABIEncoderV2;
 
-import {
-ReserveConfiguration
-} from '../../contracts/protocol/libraries/configuration/ReserveConfiguration.sol';
-import {UserConfiguration} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol';
-import {ReserveLogic} from '../../contracts/protocol/libraries/logic/ReserveLogic.sol';
 import {ILendingPool} from '../../contracts/interfaces/ILendingPool.sol';
 import {LendingPool} from '../../contracts/protocol/lendingpool/LendingPool.sol';
 import {
 ILendingPoolAddressesProvider
 } from '../../contracts/interfaces/ILendingPoolAddressesProvider.sol';
+import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
 
 /*
 Certora: Harness that delegates calls to the original LendingPool.
@@ -77,24 +73,24 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
     originalPool.liquidationCall(collateral, asset, user, debtToCover, receiveAToken);
   }
 
-  function getReservesList() external override view returns (address[] memory) {
+  function getReservesList() external view override returns (address[] memory) {
     return originalPool.getReservesList();
   }
 
   function getReserveData(address asset)
     external
-    override
     view
-    returns (ReserveLogic.ReserveData memory)
+    override
+    returns (DataTypes.ReserveData memory)
   {
     return originalPool.getReserveData(asset);
   }
 
   function getUserConfiguration(address user)
     external
-    override
     view
-    returns (UserConfiguration.Map memory)
+    override
+    returns (DataTypes.UserConfigurationMap memory)
   {
     return originalPool.getUserConfiguration(user);
   }
@@ -144,16 +140,16 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
 
   function getConfiguration(address asset)
     external
-    override
     view
-    returns (ReserveConfiguration.Map memory)
+    override
+    returns (DataTypes.ReserveConfigurationMap memory)
   {
     return originalPool.getConfiguration(asset);
   }
 
   mapping(uint256 => uint256) private reserveNormalizedIncome;
 
-  function getReserveNormalizedIncome(address asset) external override view returns (uint256) {
+  function getReserveNormalizedIncome(address asset) external view override returns (uint256) {
     require(reserveNormalizedIncome[block.timestamp] == 1e27);
     return reserveNormalizedIncome[block.timestamp];
   }
@@ -162,8 +158,8 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
 
   function getReserveNormalizedVariableDebt(address asset)
     external
-    override
     view
+    override
     returns (uint256)
   {
     require(reserveNormalizedVariableDebt[block.timestamp] == 1e27);
@@ -174,7 +170,7 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
     originalPool.setPause(val);
   }
 
-  function paused() external override view returns (bool) {
+  function paused() external view override returns (bool) {
     return originalPool.paused();
   }
 
@@ -201,7 +197,7 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
     originalPool.finalizeTransfer(asset, from, to, amount, balanceFromAfter, balanceToBefore);
   }
 
-  function getAddressesProvider() external override view returns (ILendingPoolAddressesProvider) {
+  function getAddressesProvider() external view override returns (ILendingPoolAddressesProvider) {
     return originalPool.getAddressesProvider();
   }
 }
diff --git a/specs/harness/UserConfigurationHarness.sol b/specs/harness/UserConfigurationHarness.sol
index 1ebd6e34..00a8da90 100644
--- a/specs/harness/UserConfigurationHarness.sol
+++ b/specs/harness/UserConfigurationHarness.sol
@@ -7,7 +7,7 @@ import {UserConfiguration} from '../../contracts/protocol/libraries/configuratio
 A wrapper contract for calling functions from the library UserConfiguration.
 */
 contract UserConfigurationHarness {
-  UserConfiguration.Map internal usersConfig;
+  DataTypes.UserConfigurationMap internal usersConfig;
 
   function setBorrowing(
     address user,