From 7b4812c956a0ba68f3bedf02c47255be441c478b Mon Sep 17 00:00:00 2001 From: pol <> Date: Wed, 2 Sep 2020 15:48:38 +0200 Subject: [PATCH] Moved error messages to error lib --- contracts/lendingpool/LendingPool.sol | 9 +--- contracts/libraries/helpers/Errors.sol | 48 +++++++++++++++++++ contracts/libraries/logic/ValidationLogic.sol | 23 +-------- contracts/tokenization/AToken.sol | 24 +++++----- helpers/types.ts | 43 ++++++++++++++++- test/atoken-modifiers.spec.ts | 10 ++-- 6 files changed, 108 insertions(+), 49 deletions(-) create mode 100644 contracts/libraries/helpers/Errors.sol diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index be4b4d18..1bf63fce 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -11,6 +11,7 @@ import { import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; import {IAToken} from '../tokenization/interfaces/IAToken.sol'; import {Helpers} from '../libraries/helpers/Helpers.sol'; +import {Errors} from '../libraries/helpers/Errors.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; import {GenericLogic} from '../libraries/logic/GenericLogic.sol'; @@ -44,14 +45,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool { uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25; uint256 public constant FLASHLOAN_FEE_TOTAL = 9; - //require error messages - string private constant NOT_ENOUGH_STABLE_BORROW_BALANCE = '1'; // 'User does not have any stable rate loan for this reserve' - string private constant INTERESTRATE_REBALANCE_CONDITIONS_NOT_MET = '2'; // 'Interest rate rebalance conditions were not met' - string private constant LIQUIDATION_CALL_FAILED = '3'; // 'Liquidation call failed' - string private constant NOT_ENOUGH_LIQUIDITY_TO_BORROW = '4'; // 'There is not enough liquidity available to borrow' - string private constant REQUESTED_AMOUNT_TO_SMALL = '5'; // 'The requested amount is too small for a FlashLoan.' - string private constant INCONSISTENT_PROTOCOL_ACTUAL_BALANCE = '6'; // 'The actual balance of the protocol is inconsistent' - ILendingPoolAddressesProvider internal _addressesProvider; mapping(address => ReserveLogic.ReserveData) internal _reserves; diff --git a/contracts/libraries/helpers/Errors.sol b/contracts/libraries/helpers/Errors.sol new file mode 100644 index 00000000..9821add4 --- /dev/null +++ b/contracts/libraries/helpers/Errors.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity ^0.6.8; + +/** + * @title Errors library + * @author Aave + * @notice Implements error messages. + */ +library Errors { + // require error messages - ValidationLogic + string private constant AMOUNT_NOT_GREATER_THAN_0 = '1'; // 'Amount must be greater than 0' + string private constant NO_ACTIVE_RESERVE = '2'; // 'Action requires an active reserve' + string private constant NO_UNFREEZED_RESERVE = '3'; // 'Action requires an unfreezed reserve' + string private constant CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = '4'; // 'The current liquidity is not enough' + string private constant NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5'; // 'User cannot withdraw more than the available balance' + string private constant TRANSFER_NOT_ALLOWED = '6'; // 'Transfer cannot be allowed.' + string private constant BORROWING_NOT_ENABLED = '7'; // 'Borrowing is not enabled' + string private constant INVALID_INTERESTRATE_MODE_SELECTED = '8'; // 'Invalid interest rate mode selected' + string private constant COLLATERAL_BALANCE_IS_0 = '9'; // 'The collateral balance is 0' + string private constant HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '10'; // 'Health factor is lesser than the liquidation threshold' + string private constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '11'; // 'There is not enough collateral to cover a new borrow' + string private constant STABLE_BORROWING_NOT_ENABLED = '12'; // stable borrowing not enabled + string private constant CALLATERAL_SAME_AS_BORROWING_CURRENCY = '13'; // collateral is (mostly) the same currency that is being borrowed + string private constant AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '14'; // 'The requested amount is greater than the max loan size in stable rate mode + string private constant NO_DEBT_OF_SELECTED_TYPE = '15'; // 'for repayment of stable debt, the user needs to have stable debt, otherwise, he needs to have variable debt' + string private constant NO_EPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '16'; // 'To repay on behalf of an user an explicit amount to repay is needed' + string private constant NO_STABLE_RATE_LOAN_IN_RESERVE = '17'; // 'User does not have a stable rate loan in progress on this reserve' + string private constant NO_VARIABLE_RATE_LOAN_IN_RESERVE = '18'; // 'User does not have a variable rate loan in progress on this reserve' + string private constant UNDERLYING_BALANCE_NOT_GREATER_THAN_0 = '19'; // 'The underlying balance needs to be greater than 0' + string private constant DEPOSIT_ALREADY_IN_USE = '20'; // 'User deposit is already being used as collateral' + + // require error messages - LendingPool + string private constant NOT_ENOUGH_STABLE_BORROW_BALANCE = '21'; // 'User does not have any stable rate loan for this reserve' + string private constant INTERESTRATE_REBALANCE_CONDITIONS_NOT_MET = '22'; // 'Interest rate rebalance conditions were not met' + string private constant LIQUIDATION_CALL_FAILED = '23'; // 'Liquidation call failed' + string private constant NOT_ENOUGH_LIQUIDITY_TO_BORROW = '24'; // 'There is not enough liquidity available to borrow' + string private constant REQUESTED_AMOUNT_TO_SMALL = '25'; // 'The requested amount is too small for a FlashLoan.' + string private constant INCONSISTENT_PROTOCOL_ACTUAL_BALANCE = '26'; // 'The actual balance of the protocol is inconsistent' + + // require error messages - aToken + string private constant CALLER_MUST_BE_LENDING_POOL = '27'; // 'The caller of this function must be a lending pool' + string private constant TRANSFER_CANNOT_BE_ALLOWED = '28'; // 'Transfer cannot be allowed.' + string private constant NOT_ALLOWED_TO_REDIRECT_INTEREST = '29'; // 'Caller is not allowed to redirect the interest of the user' + string private constant CANNOT_GIVE_ALLOWANCE_TO_HIMSELF = '30'; // 'User cannot give allowance to himself' + string private constant TRANSFER_AMOUNT_NOT_GT_0 = '31'; // 'Transferred amount needs to be greater than zero' + string private constant INTEREST_ALREADY_REDIRECTED = '32'; // 'Interest is already redirected to the user' + string private constant NO_VALID_BALANCE_FOR_REDIRECT_INT_STREAM = '33'; // 'Interest stream can only be redirected if there is a valid balance' +} diff --git a/contracts/libraries/logic/ValidationLogic.sol b/contracts/libraries/logic/ValidationLogic.sol index c262144d..c21a8831 100644 --- a/contracts/libraries/logic/ValidationLogic.sol +++ b/contracts/libraries/logic/ValidationLogic.sol @@ -12,6 +12,7 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../configuration/UserConfiguration.sol'; import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; +import {Errors} from '../libraries/helpers/Errors.sol'; /** * @title ReserveLogic library @@ -27,28 +28,6 @@ library ValidationLogic { using ReserveConfiguration for ReserveConfiguration.Map; using UserConfiguration for UserConfiguration.Map; - //require error messages - string private constant AMOUNT_NOT_GREATER_THAN_0 = '1'; // 'Amount must be greater than 0' - string private constant NO_ACTIVE_RESERVE = '2'; // 'Action requires an active reserve' - string private constant NO_UNFREEZED_RESERVE = '3'; // 'Action requires an unfreezed reserve' - string private constant CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = '4'; // 'The current liquidity is not enough' - string private constant NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5'; // 'User cannot withdraw more than the available balance' - string private constant TRANSFER_NOT_ALLOWED = '6'; // 'Transfer cannot be allowed.' - string private constant BORROWING_NOT_ENABLED = '7'; // 'Borrowing is not enabled' - string private constant INVALID_INTERESTRATE_MODE_SELECTED = '8'; // 'Invalid interest rate mode selected' - string private constant COLLATERAL_BALANCE_IS_0 = '9'; // 'The collateral balance is 0' - string private constant HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '10'; // 'Health factor is lesser than the liquidation threshold' - string private constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '11'; // 'There is not enough collateral to cover a new borrow' - string private constant STABLE_BORROWING_NOT_ENABLED = '12'; // stable borrowing not enabled - string private constant CALLATERAL_SAME_AS_BORROWING_CURRENCY = '13'; // collateral is (mostly) the same currency that is being borrowed - string private constant AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '14'; // 'The requested amount is greater than the max loan size in stable rate mode - string private constant NO_DEBT_OF_SELECTED_TYPE = '15'; // 'for repayment of stable debt, the user needs to have stable debt, otherwise, he needs to have variable debt' - string private constant NO_EPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '16'; // 'To repay on behalf of an user an explicit amount to repay is needed' - string private constant NO_STABLE_RATE_LOAN_IN_RESERVE = '17'; // 'User does not have a stable rate loan in progress on this reserve' - string private constant NO_VARIABLE_RATE_LOAN_IN_RESERVE = '18'; // 'User does not have a variable rate loan in progress on this reserve' - string private constant UNDERLYING_BALANCE_NOT_GREATER_THAN_0 = '19'; // 'The underlying balance needs to be greater than 0' - string private constant DEPOSIT_ALREADY_IN_USE = '20'; // 'User deposit is already being used as collateral' - /** * @dev validates a deposit. * @param reserve the reserve state on which the user is depositing diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol index 0deb6dc2..dc871640 100644 --- a/contracts/tokenization/AToken.sol +++ b/contracts/tokenization/AToken.sol @@ -4,6 +4,7 @@ pragma solidity ^0.6.8; import {ERC20} from './ERC20.sol'; import {LendingPool} from '../lendingpool/LendingPool.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; +import {Errors} from '../libraries/helpers/Errors'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import { VersionedInitializable @@ -34,12 +35,12 @@ contract AToken is VersionedInitializable, ERC20, IAToken { uint256 public constant ATOKEN_REVISION = 0x1; modifier onlyLendingPool { - require(msg.sender == address(_pool), 'The caller of this function must be a lending pool'); + require(msg.sender == address(_pool), CALLER_MUST_BE_LENDING_POOL); _; } modifier whenTransferAllowed(address from, uint256 amount) { - require(isTransferAllowed(from, amount), 'Transfer cannot be allowed.'); + require(isTransferAllowed(from, amount), TRANSFER_CANNOT_BE_ALLOWED); _; } @@ -100,7 +101,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken { function redirectInterestStreamOf(address from, address to) external override { require( msg.sender == _interestRedirectionAllowances[from], - 'Caller is not allowed to redirect the interest of the user' + CALLER_NOT_ALLOWED_TO_REDIRECT_INTEREST ); _redirectInterestStream(from, to); } @@ -112,7 +113,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken { * the allowance. **/ function allowInterestRedirectionTo(address to) external override { - require(to != msg.sender, 'User cannot give allowance to himself'); + require(to != msg.sender, CANNOT_GIVE_ALLOWANCE_TO_HIMSELF); _interestRedirectionAllowances[msg.sender] = to; emit InterestRedirectionAllowanceChanged(msg.sender, to); } @@ -434,15 +435,12 @@ contract AToken is VersionedInitializable, ERC20, IAToken { address to, uint256 value ) internal { - require(value > 0, 'Transferred amount needs to be greater than zero'); + require(value > 0, TRANSFER_AMOUNT_NOT_GT_0); //cumulate the balance of the sender - ( - , - uint256 fromBalance, - uint256 fromBalanceIncrease, - uint256 fromIndex - ) = _cumulateBalance(from); + (, uint256 fromBalance, uint256 fromBalanceIncrease, uint256 fromIndex) = _cumulateBalance( + from + ); //cumulate the balance of the receiver (, , uint256 toBalanceIncrease, uint256 toIndex) = _cumulateBalance(to); @@ -486,7 +484,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken { function _redirectInterestStream(address from, address to) internal { address currentRedirectionAddress = _interestRedirectionAddresses[from]; - require(to != currentRedirectionAddress, 'Interest is already redirected to the user'); + require(to != currentRedirectionAddress, INTEREST_ALREADY_REDIRECTED); //accumulates the accrued interest to the principal ( @@ -496,7 +494,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken { uint256 fromIndex ) = _cumulateBalance(from); - require(fromBalance > 0, 'Interest stream can only be redirected if there is a valid balance'); + require(fromBalance > 0, NO_VALID_BALANCE_FOR_REDIRECT_INT_STREAM); //if the user is already redirecting the interest to someone, before changing //the redirection address we substract the redirected balance of the previous diff --git a/helpers/types.ts b/helpers/types.ts index 106e5376..c008816d 100644 --- a/helpers/types.ts +++ b/helpers/types.ts @@ -44,9 +44,50 @@ export enum eContractid { } export enum ProtocolErrors { + // require error messages - ValidationLogic + AMOUNT_NOT_GREATER_THAN_0 = '1', // 'Amount must be greater than 0' + NO_ACTIVE_RESERVE = '2', // 'Action requires an active reserve' + NO_UNFREEZED_RESERVE = '3', // 'Action requires an unfreezed reserve' + CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = '4', // 'The current liquidity is not enough' + NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5', // 'User cannot withdraw more than the available balance' + TRANSFER_NOT_ALLOWED = '6', // 'Transfer cannot be allowed.' + BORROWING_NOT_ENABLED = '7', // 'Borrowing is not enabled' + INVALID_INTERESTRATE_MODE_SELECTED = '8', // 'Invalid interest rate mode selected' + COLLATERAL_BALANCE_IS_0 = '9', // 'The collateral balance is 0' + HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '10', // 'Health factor is lesser than the liquidation threshold' + COLLATERAL_CANNOT_COVER_NEW_BORROW = '11', // 'There is not enough collateral to cover a new borrow' + STABLE_BORROWING_NOT_ENABLED = '12', // stable borrowing not enabled + CALLATERAL_SAME_AS_BORROWING_CURRENCY = '13', // collateral is (mostly) the same currency that is being borrowed + AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '14', // 'The requested amount is greater than the max loan size in stable rate mode + NO_DEBT_OF_SELECTED_TYPE = '15', // 'for repayment of stable debt, the user needs to have stable debt, otherwise, he needs to have variable debt' + NO_EPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '16', // 'To repay on behalf of an user an explicit amount to repay is needed' + NO_STABLE_RATE_LOAN_IN_RESERVE = '17', // 'User does not have a stable rate loan in progress on this reserve' + NO_VARIABLE_RATE_LOAN_IN_RESERVE = '18', // 'User does not have a variable rate loan in progress on this reserve' + UNDERLYING_BALANCE_NOT_GREATER_THAN_0 = '19', // 'The underlying balance needs to be greater than 0' + DEPOSIT_ALREADY_IN_USE = '20', // 'User deposit is already being used as collateral' + + // require error messages - LendingPool + NOT_ENOUGH_STABLE_BORROW_BALANCE = '21', // 'User does not have any stable rate loan for this reserve' + INTERESTRATE_REBALANCE_CONDITIONS_NOT_MET = '22', // 'Interest rate rebalance conditions were not met' + LIQUIDATION_CALL_FAILED = '23', // 'Liquidation call failed' + NOT_ENOUGH_LIQUIDITY_TO_BORROW = '24', // 'There is not enough liquidity available to borrow' + REQUESTED_AMOUNT_TO_SMALL = '25', // 'The requested amount is too small for a FlashLoan.' + INCONSISTENT_PROTOCOL_ACTUAL_BALANCE = '26', // 'The actual balance of the protocol is inconsistent' + + // require error messages - aToken + CALLER_MUST_BE_LENDING_POOL = '27', // 'The caller of this function must be a lending pool' + TRANSFER_CANNOT_BE_ALLOWED = '28', // 'Transfer cannot be allowed.' + NOT_ALLOWED_TO_REDIRECT_INTEREST = '29', // 'Caller is not allowed to redirect the interest of the user' + CANNOT_GIVE_ALLOWANCE_TO_HIMSELF = '30', // 'User cannot give allowance to himself' + TRANSFER_AMOUNT_NOT_GT_0 = '31', // 'Transferred amount needs to be greater than zero' + INTEREST_ALREADY_REDIRECTED = '32', // 'Interest is already redirected to the user' + NO_VALID_BALANCE_FOR_REDIRECT_INT_STREAM = '33', // 'Interest stream can only be redirected if there is a valid balance' +} + +export enum OLD_ProtocolErrors { INVALID_CONFIGURATOR_CALLER_MSG = 'The caller must be a lending pool configurator contract', INVALID_POOL_CALLER_MSG = 'The caller must be a lending pool contract', - INVALID_POOL_CALLER_MSG_1 = 'The caller of this function must be a lending pool', + // INVALID_POOL_CALLER_MSG_1 = 'The caller of this function must be a lending pool', => CALLER_MUST_BE_LENDING_POOL INVALID_POOL_MANAGER_CALLER_MSG = 'The caller must be a lending pool manager', INVALID_FROM_BALANCE_AFTER_TRANSFER = 'Invalid from balance after transfer', INVALID_TO_BALANCE_AFTER_TRANSFER = 'Invalid from balance after transfer', diff --git a/test/atoken-modifiers.spec.ts b/test/atoken-modifiers.spec.ts index 97115c0c..406d910a 100644 --- a/test/atoken-modifiers.spec.ts +++ b/test/atoken-modifiers.spec.ts @@ -3,17 +3,17 @@ import {makeSuite, TestEnv} from './helpers/make-suite'; import {ProtocolErrors} from '../helpers/types'; makeSuite('AToken: Modifiers', (testEnv: TestEnv) => { - const {INVALID_POOL_CALLER_MSG_1} = ProtocolErrors; + const {CALLER_MUST_BE_LENDING_POOL} = ProtocolErrors; it('Tries to invoke mint not being the LendingPool', async () => { const {deployer, aDai} = testEnv; - await expect(aDai.mint(deployer.address, '1')).to.be.revertedWith(INVALID_POOL_CALLER_MSG_1); + await expect(aDai.mint(deployer.address, '1')).to.be.revertedWith(CALLER_MUST_BE_LENDING_POOL); }); it('Tries to invoke burn not being the LendingPool', async () => { const {deployer, aDai} = testEnv; await expect(aDai.burn(deployer.address, deployer.address, '1')).to.be.revertedWith( - INVALID_POOL_CALLER_MSG_1 + CALLER_MUST_BE_LENDING_POOL ); }); @@ -21,13 +21,13 @@ makeSuite('AToken: Modifiers', (testEnv: TestEnv) => { const {deployer, users, aDai} = testEnv; await expect( aDai.transferOnLiquidation(deployer.address, users[0].address, '1') - ).to.be.revertedWith(INVALID_POOL_CALLER_MSG_1); + ).to.be.revertedWith(CALLER_MUST_BE_LENDING_POOL); }); it('Tries to invoke transferUnderlyingTo not being the LendingPool', async () => { const {deployer, users, aDai} = testEnv; await expect(aDai.transferUnderlyingTo(deployer.address, '1')).to.be.revertedWith( - INVALID_POOL_CALLER_MSG_1 + CALLER_MUST_BE_LENDING_POOL ); }); });