Merge branch 'fix/73' into 'master'

Resolve "PVE001, PVE002, PVE004, PVE006, PVE009"

Closes #73

See merge request aave-tech/protocol-v2!82
This commit is contained in:
The-3D 2020-10-26 08:42:24 +00:00
commit 5275d281d1
15 changed files with 79 additions and 3121 deletions

View File

@ -54,6 +54,8 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP
* @param provider the pool address to be registered
**/
function registerAddressesProvider(address provider, uint256 id) external override onlyOwner {
require(id != 0, Errors.INVALID_ADDRESSES_PROVIDER_ID);
_addressesProviders[provider] = id;
_addToAddressesProvidersList(provider);
emit AddressesProviderRegistered(provider);

View File

@ -162,7 +162,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
_stableRateSlope1.rayMul(utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE))
);
vars.currentVariableBorrowRate = _baseVariableBorrowRate.add(
utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE).rayMul(_variableRateSlope1)
utilizationRate.rayMul(_variableRateSlope1).rayDiv(OPTIMAL_UTILIZATION_RATE)
);
}

View File

@ -267,7 +267,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
? stableDebt
: variableDebt;
if (amount != type(uint256).max && amount < paybackAmount) {
if (amount < paybackAmount) {
paybackAmount = amount;
}

View File

@ -10,6 +10,7 @@ import {
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {ITokenConfiguration} from '../tokenization/interfaces/ITokenConfiguration.sol';
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
import {Errors} from '../libraries/helpers/Errors.sol';
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
@ -200,7 +201,6 @@ contract LendingPoolConfigurator is VersionedInitializable {
/**
* @dev initializes a reserve
* @param asset the address of the reserve to be initialized
* @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
@ -208,13 +208,35 @@ contract LendingPoolConfigurator is VersionedInitializable {
* @param interestRateStrategyAddress the address of the interest rate strategy contract for this reserve
**/
function initReserve(
address asset,
address aTokenImpl,
address stableDebtTokenImpl,
address variableDebtTokenImpl,
uint8 underlyingAssetDecimals,
address interestRateStrategyAddress
) public onlyAaveAdmin {
address asset = ITokenConfiguration(aTokenImpl).UNDERLYING_ASSET_ADDRESS();
require(
address(pool) == ITokenConfiguration(aTokenImpl).POOL(),
Errors.INVALID_ATOKEN_POOL_ADDRESS
);
require(
address(pool) == ITokenConfiguration(stableDebtTokenImpl).POOL(),
Errors.INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS
);
require(
address(pool) == ITokenConfiguration(variableDebtTokenImpl).POOL(),
Errors.INVALID_VARIABLE_DEBT_TOKEN_POOL_ADDRESS
);
require(
asset == ITokenConfiguration(stableDebtTokenImpl).UNDERLYING_ASSET_ADDRESS(),
Errors.INVALID_STABLE_DEBT_TOKEN_UNDERLYING_ADDRESS
);
require(
asset == ITokenConfiguration(variableDebtTokenImpl).UNDERLYING_ASSET_ADDRESS(),
Errors.INVALID_VARIABLE_DEBT_TOKEN_UNDERLYING_ADDRESS
);
address aTokenProxyAddress = _initTokenWithProxy(aTokenImpl, underlyingAssetDecimals);
address stableDebtTokenProxyAddress = _initTokenWithProxy(

View File

@ -50,8 +50,8 @@ library Errors {
string public constant CALLER_MUST_BE_LENDING_POOL = '28'; // 'The caller of this function must be a lending pool'
string public constant CANNOT_GIVE_ALLOWANCE_TO_HIMSELF = '30'; // 'User cannot give allowance to himself'
string public constant TRANSFER_AMOUNT_NOT_GT_0 = '31'; // 'Transferred amount needs to be greater than zero'
string public constant INVALID_MINT_AMOUNT = '53'; //invalid amount to mint
string public constant INVALID_BURN_AMOUNT = '54'; //invalid amount to burn
string public constant INVALID_MINT_AMOUNT = '61'; //invalid amount to mint
string public constant INVALID_BURN_AMOUNT = '62'; //invalid amount to burn
// require error messages - ReserveLogic
string public constant RESERVE_ALREADY_INITIALIZED = '34'; // 'Reserve has already been initialized'
@ -64,9 +64,15 @@ library Errors {
//require error messages - LendingPoolConfiguration
string public constant CALLER_NOT_AAVE_ADMIN = '35'; // 'The caller must be the aave admin'
string public constant RESERVE_LIQUIDITY_NOT_0 = '36'; // 'The liquidity of the reserve needs to be 0'
string public constant INVALID_ATOKEN_POOL_ADDRESS = '63'; // the lending pool in the aToken implementation is not configured correctly
string public constant INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS = '64'; // the lending pool in the stable debt token implementation is not configured correctly
string public constant INVALID_VARIABLE_DEBT_TOKEN_POOL_ADDRESS = '65'; // the lending pool in the variable debt token implementation is not configured correctly
string public constant INVALID_STABLE_DEBT_TOKEN_UNDERLYING_ADDRESS = '66'; // the underlying asset in the stable debt token implementation is not configured correctly
string public constant INVALID_VARIABLE_DEBT_TOKEN_UNDERLYING_ADDRESS = '67'; // the underlying asset in the variable debt token implementation is not configured correctly
//require error messages - LendingPoolAddressesProviderRegistry
string public constant PROVIDER_NOT_REGISTERED = '37'; // 'Provider is not registered'
string public constant INVALID_ADDRESSES_PROVIDER_ID = '68'; // the addresses provider id needs to be greater than 0
//return error messages - LendingPoolCollateralManager
string public constant HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '38'; // 'Health factor is not below the threshold'

View File

@ -359,7 +359,9 @@ library ReserveLogic {
vars.amountToMint = vars.totalDebtAccrued.percentMul(vars.reserveFactor);
IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, newLiquidityIndex);
if (vars.amountToMint != 0) {
IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, newLiquidityIndex);
}
}
/**

View File

@ -58,13 +58,9 @@ library WadRayMath {
return 0;
}
uint256 result = a * b;
uint256 result = a * b + halfWAD;
require(result / a == b, Errors.MULTIPLICATION_OVERFLOW);
result += halfWAD;
require(result >= halfWAD, Errors.ADDITION_OVERFLOW);
require(result >= halfWAD && (result - halfWAD) / a == b, Errors.MULTIPLICATION_OVERFLOW);
return result / WAD;
}
@ -80,13 +76,9 @@ library WadRayMath {
uint256 halfB = b / 2;
uint256 result = a * WAD;
uint256 result = a * WAD + halfB;
require(result / WAD == a, Errors.MULTIPLICATION_OVERFLOW);
result += halfB;
require(result >= halfB, Errors.ADDITION_OVERFLOW);
require(result >= halfB && (result - halfB) / WAD == a, Errors.MULTIPLICATION_OVERFLOW);
return result / b;
}
@ -102,13 +94,9 @@ library WadRayMath {
return 0;
}
uint256 result = a * b;
uint256 result = a * b + halfRAY;
require(result / a == b, Errors.MULTIPLICATION_OVERFLOW);
result += halfRAY;
require(result >= halfRAY, Errors.ADDITION_OVERFLOW);
require(result >= halfRAY && (result - halfRAY) / a == b, Errors.MULTIPLICATION_OVERFLOW);
return result / RAY;
}
@ -124,13 +112,9 @@ library WadRayMath {
uint256 halfB = b / 2;
uint256 result = a * RAY;
uint256 result = a * RAY + halfB;
require(result / RAY == a, Errors.MULTIPLICATION_OVERFLOW);
result += halfB;
require(result >= halfB, Errors.ADDITION_OVERFLOW);
require(result >= halfB && (result - halfB) / RAY == a, Errors.MULTIPLICATION_OVERFLOW);
return result / b;
}

View File

@ -2,7 +2,7 @@
pragma solidity ^0.6.8;
import {IncentivizedERC20} from './IncentivizedERC20.sol';
import {LendingPool} from '../lendingpool/LendingPool.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
import {Errors} from '../libraries/helpers/Errors.sol';
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
@ -32,7 +32,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
uint256 public constant ATOKEN_REVISION = 0x1;
address public immutable UNDERLYING_ASSET_ADDRESS;
address public immutable RESERVE_TREASURY_ADDRESS;
LendingPool public immutable POOL;
ILendingPool public immutable POOL;
/// @dev owner => next valid nonce to submit with permit()
mapping(address => uint256) public _nonces;
@ -45,7 +45,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
}
constructor(
LendingPool pool,
ILendingPool pool,
address underlyingAssetAddress,
address reserveTreasuryAddress,
string memory tokenName,

View File

@ -43,7 +43,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
return 0;
}
return scaledBalance.rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET));
return scaledBalance.rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET_ADDRESS));
}
/**
@ -102,7 +102,8 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
* @return the total supply
**/
function totalSupply() public virtual override view returns (uint256) {
return super.totalSupply().rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET));
return
super.totalSupply().rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET_ADDRESS));
}
/**

View File

@ -15,8 +15,8 @@ import {Errors} from '../../libraries/helpers/Errors.sol';
*/
abstract contract DebtTokenBase is IncentivizedERC20, VersionedInitializable {
address internal immutable UNDERLYING_ASSET;
ILendingPool internal immutable POOL;
address public immutable UNDERLYING_ASSET_ADDRESS;
ILendingPool public immutable POOL;
mapping(address => uint256) internal _usersData;
/**
@ -39,7 +39,7 @@ abstract contract DebtTokenBase is IncentivizedERC20, VersionedInitializable {
address incentivesController
) public IncentivizedERC20(name, symbol, 18, incentivesController) {
POOL = ILendingPool(pool);
UNDERLYING_ASSET = underlyingAssetAddress;
UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress;
}
/**
@ -58,10 +58,6 @@ abstract contract DebtTokenBase is IncentivizedERC20, VersionedInitializable {
_setDecimals(decimals);
}
function underlyingAssetAddress() public view returns (address) {
return UNDERLYING_ASSET;
}
/**
* @dev Being non transferrable, the debt token does not implement any of the
* standard ERC20 functions for transfer and allowance.

View File

@ -0,0 +1,13 @@
pragma solidity ^0.6;
/**
* @title ITokenConfiguration
* @author Aave
* @dev common interface between aTokens and debt tokens to fetch the
* token configuration
**/
interface ITokenConfiguration {
function UNDERLYING_ASSET_ADDRESS() external view returns (address);
function POOL() external view returns (address);
}

View File

@ -857,7 +857,6 @@ export const initReserves = async (
console.log('init reserve currency ', assetSymbol);
await lendingPoolConfigurator.initReserve(
tokenAddress,
aToken.address,
stableDebtToken.address,
variableDebtToken.address,

View File

@ -106,6 +106,7 @@ export enum ProtocolErrors {
//require error messages - LendingPoolAddressesProviderRegistry
PROVIDER_NOT_REGISTERED = '37', // 'Provider is not registered'
INVALID_ADDRESSES_PROVIDER_ID = '68',
//return error messages - LendingPoolCollateralManager
HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '38', // 'Health factor is not below the threshold'

3077
test.log

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,15 @@ makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => {
);
});
it('tries to register an addresses provider with id 0', async () => {
const {users, registry} = testEnv;
const {INVALID_ADDRESSES_PROVIDER_ID} = ProtocolErrors;
await expect(registry.registerAddressesProvider(users[2].address, '0')).to.be.revertedWith(
INVALID_ADDRESSES_PROVIDER_ID
);
});
it('Registers a new mock addresses provider', async () => {
const {users, registry} = testEnv;