mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Initial commit
This commit is contained in:
parent
abc0d3edb6
commit
a784e42b78
a.out
contracts
deployed-contracts.jsonhelpers
test
types
ATokenFactory.tsAaveProtocolTestHelpersFactory.tsDebtTokenBase.d.tsDebtTokenBaseFactory.tsGenericLogicFactory.tsIStableDebtToken.d.tsIStableDebtTokenFactory.tsIVariableDebtToken.d.tsIVariableDebtTokenFactory.tsLendingPool.d.tsLendingPoolConfigurator.d.tsLendingPoolConfiguratorFactory.tsLendingPoolFactory.tsLendingPoolLiquidationManagerFactory.tsMintableErc20Factory.tsMockBatFactory.tsMockBusdFactory.tsMockDaiFactory.tsMockFlashLoanReceiverFactory.tsMockKncFactory.tsMockKyberProxyFactory.tsMockLendFactory.tsMockLinkFactory.tsMockManaFactory.tsMockMkrFactory.tsMockOneSplitFactory.tsMockRepFactory.tsMockSnxFactory.tsMockSusdFactory.tsMockTusdFactory.tsMockUniDaiEthFactory.tsMockUniLendEthFactory.tsMockUniLinkEthFactory.tsMockUniMkrEthFactory.tsMockUniSethEthFactory.tsMockUniUsdcEthFactory.tsMockUsdFactory.tsMockUsdcFactory.tsMockUsdtFactory.tsMockWbtcFactory.tsMockZrxFactory.tsReserveLogicFactory.tsStableDebtToken.d.tsStableDebtTokenFactory.tsVariableDebtToken.d.tsVariableDebtTokenFactory.tsWalletBalanceProviderFactory.ts
|
@ -1,15 +0,0 @@
|
|||
pragma solidity ^0.6.8;
|
||||
|
||||
// "SPDX-License-Identifier: AGPL-3.0-only"
|
||||
|
||||
contract Example {
|
||||
uint256 public _n;
|
||||
|
||||
constructor() public {
|
||||
_n = 5;
|
||||
}
|
||||
|
||||
function test() external view returns(uint256 n) {
|
||||
n = _n;
|
||||
}
|
||||
}
|
|
@ -16,6 +16,8 @@ import "../libraries/UserLogic.sol";
|
|||
import "../libraries/GenericLogic.sol";
|
||||
import "../libraries/ValidationLogic.sol";
|
||||
import "../libraries/UniversalERC20.sol";
|
||||
import "../tokenization/interfaces/IStableDebtToken.sol";
|
||||
import "../tokenization/interfaces/IVariableDebtToken.sol";
|
||||
|
||||
import "../interfaces/IFeeProvider.sol";
|
||||
import "../flashloan/interfaces/IFlashLoanReceiver.sol";
|
||||
|
@ -89,8 +91,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
* @param _amount the amount to be deposited
|
||||
* @param _borrowRateMode the rate mode, can be either 1-stable or 2-variable
|
||||
* @param _borrowRate the rate at which the user has borrowed
|
||||
* @param _originationFee the origination fee to be paid by the user
|
||||
* @param _borrowBalanceIncrease the balance increase since the last borrow, 0 if it's the first time borrowing
|
||||
* @param _referral the referral number of the action
|
||||
* @param _timestamp the timestamp of the action
|
||||
**/
|
||||
|
@ -100,8 +100,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
uint256 _amount,
|
||||
uint256 _borrowRateMode,
|
||||
uint256 _borrowRate,
|
||||
uint256 _originationFee,
|
||||
uint256 _borrowBalanceIncrease,
|
||||
uint16 indexed _referral,
|
||||
uint256 _timestamp
|
||||
);
|
||||
|
@ -111,18 +109,14 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
* @param _reserve the address of the reserve
|
||||
* @param _user the address of the user for which the repay has been executed
|
||||
* @param _repayer the address of the user that has performed the repay action
|
||||
* @param _amountMinusFees the amount repaid minus fees
|
||||
* @param _fees the fees repaid
|
||||
* @param _borrowBalanceIncrease the balance increase since the last action
|
||||
* @param _amount the amount repaid
|
||||
* @param _timestamp the timestamp of the action
|
||||
**/
|
||||
event Repay(
|
||||
address indexed _reserve,
|
||||
address indexed _user,
|
||||
address indexed _repayer,
|
||||
uint256 _amountMinusFees,
|
||||
uint256 _fees,
|
||||
uint256 _borrowBalanceIncrease,
|
||||
uint256 _amount,
|
||||
uint256 _timestamp
|
||||
);
|
||||
|
||||
|
@ -132,7 +126,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
* @param _user the address of the user executing the swap
|
||||
* @param _newRateMode the new interest rate mode
|
||||
* @param _newRate the new borrow rate
|
||||
* @param _borrowBalanceIncrease the balance increase since the last action
|
||||
* @param _timestamp the timestamp of the action
|
||||
**/
|
||||
event Swap(
|
||||
|
@ -140,7 +133,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
address indexed _user,
|
||||
uint256 _newRateMode,
|
||||
uint256 _newRate,
|
||||
uint256 _borrowBalanceIncrease,
|
||||
uint256 _timestamp
|
||||
);
|
||||
|
||||
|
@ -377,26 +369,16 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
(uint256 principalBorrowBalance, , uint256 borrowBalanceIncrease) = user.getBorrowBalances(
|
||||
reserve
|
||||
);
|
||||
//borrow passed
|
||||
reserve.updateCumulativeIndexes();
|
||||
|
||||
//all conditions passed - borrow is accepted
|
||||
reserve.updateStateOnBorrow(
|
||||
user,
|
||||
principalBorrowBalance,
|
||||
borrowBalanceIncrease,
|
||||
_amount,
|
||||
CoreLibrary.InterestRateMode(_interestRateMode)
|
||||
);
|
||||
|
||||
user.updateStateOnBorrow(
|
||||
reserve,
|
||||
_amount,
|
||||
borrowBalanceIncrease,
|
||||
borrowFee,
|
||||
CoreLibrary.InterestRateMode(_interestRateMode)
|
||||
);
|
||||
if(CoreLibrary.InterestRateMode(_interestRateMode) == CoreLibrary.InterestRateMode.STABLE) {
|
||||
IStableDebtToken(reserve.stableDebtTokenAddress).mint(msg.sender, _amount, reserve.currentStableBorrowRate);
|
||||
}
|
||||
else {
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, _amount);
|
||||
}
|
||||
uint256 userStableRate = reserve.currentStableBorrowRate;
|
||||
|
||||
reserve.updateInterestRatesAndTimestamp(_reserve, 0, _amount);
|
||||
|
||||
|
@ -409,10 +391,8 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
_amount,
|
||||
_interestRateMode,
|
||||
CoreLibrary.InterestRateMode(_interestRateMode) == CoreLibrary.InterestRateMode.STABLE
|
||||
? user.stableBorrowRate
|
||||
? userStableRate
|
||||
: reserve.currentVariableBorrowRate,
|
||||
borrowFee,
|
||||
borrowBalanceIncrease,
|
||||
_referralCode,
|
||||
//solium-disable-next-line
|
||||
block.timestamp
|
||||
|
@ -429,8 +409,8 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
**/
|
||||
|
||||
struct RepayLocalVars {
|
||||
uint256 principalBorrowBalance;
|
||||
uint256 compoundedBorrowBalance;
|
||||
uint256 stableBorrowBalance;
|
||||
uint256 variableBorrowBalance;
|
||||
uint256 borrowBalanceIncrease;
|
||||
uint256 paybackAmount;
|
||||
uint256 paybackAmountMinusFees;
|
||||
|
@ -438,7 +418,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
uint256 originationFee;
|
||||
}
|
||||
|
||||
function repay(address _reserve, uint256 _amount, address payable _onBehalfOf)
|
||||
function repay(address _reserve, uint256 _amount, uint256 _rateMode, address payable _onBehalfOf)
|
||||
external
|
||||
payable
|
||||
nonReentrant
|
||||
|
@ -448,94 +428,45 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
CoreLibrary.UserReserveData storage user = usersReserveData[_onBehalfOf][_reserve];
|
||||
|
||||
(
|
||||
vars.principalBorrowBalance,
|
||||
vars.compoundedBorrowBalance,
|
||||
vars.borrowBalanceIncrease
|
||||
) = user.getBorrowBalances(reserve);
|
||||
vars.stableBorrowBalance,
|
||||
vars.variableBorrowBalance
|
||||
) = UserLogic.getUserBorrowBalances(_onBehalfOf, reserve);
|
||||
|
||||
vars.originationFee = user.originationFee;
|
||||
CoreLibrary.InterestRateMode rateMode = CoreLibrary.InterestRateMode(_rateMode);
|
||||
|
||||
//default to max amount
|
||||
vars.paybackAmount = vars.compoundedBorrowBalance.add(vars.originationFee);
|
||||
vars.paybackAmount = rateMode == CoreLibrary.InterestRateMode.STABLE ? vars.stableBorrowBalance : vars.variableBorrowBalance;
|
||||
|
||||
if (_amount != UINT_MAX_VALUE && _amount < vars.paybackAmount) {
|
||||
vars.paybackAmount = _amount;
|
||||
}
|
||||
|
||||
|
||||
ValidationLogic.validateRepay(
|
||||
reserve,
|
||||
_reserve,
|
||||
_amount,
|
||||
rateMode,
|
||||
_onBehalfOf,
|
||||
vars.compoundedBorrowBalance,
|
||||
vars.stableBorrowBalance,
|
||||
vars.variableBorrowBalance,
|
||||
vars.paybackAmount,
|
||||
msg.value
|
||||
);
|
||||
|
||||
//if the amount is smaller than the origination fee, just transfer the amount to the fee destination address
|
||||
if (vars.paybackAmount <= vars.originationFee) {
|
||||
reserve.updateStateOnRepay(user, _reserve, 0, vars.borrowBalanceIncrease);
|
||||
reserve.updateCumulativeIndexes();
|
||||
|
||||
user.updateStateOnRepay(
|
||||
reserve,
|
||||
0,
|
||||
vars.paybackAmount,
|
||||
vars.borrowBalanceIncrease,
|
||||
false
|
||||
);
|
||||
|
||||
reserve.updateInterestRatesAndTimestamp(_reserve, 0, 0);
|
||||
|
||||
IERC20(_reserve).universalTransferFrom(
|
||||
msg.sender,
|
||||
addressesProvider.getTokenDistributor(),
|
||||
vars.paybackAmount,
|
||||
true
|
||||
);
|
||||
|
||||
emit Repay(
|
||||
_reserve,
|
||||
_onBehalfOf,
|
||||
msg.sender,
|
||||
0,
|
||||
vars.paybackAmount,
|
||||
vars.borrowBalanceIncrease,
|
||||
//solium-disable-next-line
|
||||
block.timestamp
|
||||
);
|
||||
return;
|
||||
//burns an equivalent amount of debt tokens
|
||||
if(rateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
IStableDebtToken(reserve.stableDebtTokenAddress).burn(_onBehalfOf, vars.paybackAmount);
|
||||
}
|
||||
else {
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).burn(_onBehalfOf, vars.paybackAmount);
|
||||
}
|
||||
|
||||
vars.paybackAmountMinusFees = vars.paybackAmount.sub(vars.originationFee);
|
||||
reserve.updateInterestRatesAndTimestamp(_reserve, vars.paybackAmount, 0);
|
||||
|
||||
reserve.updateStateOnRepay(
|
||||
user,
|
||||
_reserve,
|
||||
vars.paybackAmountMinusFees,
|
||||
vars.borrowBalanceIncrease
|
||||
);
|
||||
|
||||
user.updateStateOnRepay(
|
||||
reserve,
|
||||
vars.paybackAmountMinusFees,
|
||||
vars.originationFee,
|
||||
vars.borrowBalanceIncrease,
|
||||
vars.compoundedBorrowBalance == vars.paybackAmountMinusFees
|
||||
);
|
||||
|
||||
reserve.updateInterestRatesAndTimestamp(_reserve, vars.paybackAmountMinusFees, 0);
|
||||
|
||||
//if the user didn't repay the origination fee, transfer the fee to the fee collection address
|
||||
if (vars.originationFee > 0) {
|
||||
IERC20(_reserve).universalTransferFrom(
|
||||
msg.sender,
|
||||
addressesProvider.getTokenDistributor(),
|
||||
vars.originationFee,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
IERC20(_reserve).universalTransferFromSenderToThis(vars.paybackAmountMinusFees, false);
|
||||
IERC20(_reserve).universalTransferFromSenderToThis(vars.paybackAmount, false);
|
||||
|
||||
if (IERC20(_reserve).isETH()) {
|
||||
//send excess ETH back to the caller if needed
|
||||
|
@ -550,9 +481,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
_reserve,
|
||||
_onBehalfOf,
|
||||
msg.sender,
|
||||
vars.paybackAmountMinusFees,
|
||||
vars.originationFee,
|
||||
vars.borrowBalanceIncrease,
|
||||
vars.paybackAmount,
|
||||
//solium-disable-next-line
|
||||
block.timestamp
|
||||
);
|
||||
|
@ -566,11 +495,12 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
CoreLibrary.ReserveData storage reserve = reserves[_reserve];
|
||||
CoreLibrary.UserReserveData storage user = usersReserveData[msg.sender][_reserve];
|
||||
|
||||
(uint256 principalBorrowBalance, uint256 compoundedBorrowBalance, uint256 borrowBalanceIncrease) = user
|
||||
.getBorrowBalances(reserve);
|
||||
|
||||
CoreLibrary.InterestRateMode currentRateMode = user.getCurrentBorrowRateMode();
|
||||
(uint256 principalBorrowBalance, uint256 compoundedBorrowBalance) = UserLogic.
|
||||
getUserBorrowBalances(msg.sender,reserve);
|
||||
|
||||
|
||||
/*
|
||||
CoreLibrary.InterestRateMode currentRateMode = user.getCurrentBorrowRateMode();
|
||||
ValidationLogic.validateSwapRateMode(
|
||||
reserve,
|
||||
user,
|
||||
|
@ -578,18 +508,12 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
currentRateMode
|
||||
);
|
||||
|
||||
reserve.updateStateOnSwapRate(
|
||||
user,
|
||||
_reserve,
|
||||
principalBorrowBalance,
|
||||
compoundedBorrowBalance,
|
||||
currentRateMode
|
||||
);
|
||||
|
||||
user.updateStateOnSwapRate(reserve, borrowBalanceIncrease, currentRateMode);
|
||||
/**
|
||||
TODO: Burn old tokens and mint new ones
|
||||
**/
|
||||
|
||||
reserve.updateInterestRatesAndTimestamp(_reserve, 0, 0);
|
||||
|
||||
/*
|
||||
CoreLibrary.InterestRateMode newRateMode = user.getCurrentBorrowRateMode();
|
||||
emit Swap(
|
||||
_reserve,
|
||||
|
@ -598,10 +522,10 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
newRateMode == CoreLibrary.InterestRateMode.STABLE
|
||||
? user.stableBorrowRate
|
||||
: reserve.currentVariableBorrowRate,
|
||||
borrowBalanceIncrease,
|
||||
//solium-disable-next-line
|
||||
block.timestamp
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -615,6 +539,9 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
CoreLibrary.ReserveData storage reserve = reserves[_reserve];
|
||||
CoreLibrary.UserReserveData storage user = usersReserveData[_user][_reserve];
|
||||
|
||||
|
||||
//TODO: Burn tokens at old rate, mint new ones at new rate
|
||||
/*
|
||||
(, uint256 compoundedBalance, uint256 borrowBalanceIncrease) = user.getBorrowBalances(
|
||||
reserve
|
||||
);
|
||||
|
@ -667,7 +594,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
return;
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
revert("Interest rate rebalance conditions were not met");
|
||||
}
|
||||
|
||||
|
@ -869,12 +796,12 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
CoreLibrary.ReserveData memory reserve = reserves[_reserve];
|
||||
return (
|
||||
IERC20(_reserve).universalBalanceOf(address(this)),
|
||||
reserve.totalBorrowsStable,
|
||||
reserve.totalBorrowsVariable,
|
||||
IERC20(reserve.stableDebtTokenAddress).totalSupply(),
|
||||
IERC20(reserve.variableDebtTokenAddress).totalSupply(),
|
||||
reserve.currentLiquidityRate,
|
||||
reserve.currentVariableBorrowRate,
|
||||
reserve.currentStableBorrowRate,
|
||||
reserve.currentAverageStableBorrowRate,
|
||||
IStableDebtToken(reserve.stableDebtTokenAddress).getAverageStableRate(),
|
||||
reserve.lastLiquidityCumulativeIndex,
|
||||
reserve.lastVariableBorrowCumulativeIndex,
|
||||
reserve.lastUpdateTimestamp
|
||||
|
@ -925,37 +852,25 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
view
|
||||
returns (
|
||||
uint256 currentATokenBalance,
|
||||
uint256 currentBorrowBalance,
|
||||
uint256 principalBorrowBalance,
|
||||
uint256 borrowRateMode,
|
||||
uint256 borrowRate,
|
||||
uint256 currentStableBorrowBalance,
|
||||
uint256 currentVariableBorrowBalance,
|
||||
uint256 principalStableBorrowBalance,
|
||||
uint256 principalVariableBorrowBalance,
|
||||
uint256 stableBorrowRate,
|
||||
uint256 liquidityRate,
|
||||
uint256 originationFee,
|
||||
uint256 variableBorrowIndex,
|
||||
uint256 lastUpdateTimestamp,
|
||||
bool usageAsCollateralEnabled
|
||||
)
|
||||
{
|
||||
CoreLibrary.ReserveData storage reserve = reserves[_reserve];
|
||||
CoreLibrary.UserReserveData storage user = usersReserveData[_user][_reserve];
|
||||
|
||||
currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(_user);
|
||||
CoreLibrary.InterestRateMode mode = user.getCurrentBorrowRateMode();
|
||||
(principalBorrowBalance, currentBorrowBalance, ) = user.getBorrowBalances(reserve);
|
||||
|
||||
//default is 0, if mode == CoreLibrary.InterestRateMode.NONE
|
||||
if (mode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
borrowRate = user.stableBorrowRate;
|
||||
} else if (mode == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
borrowRate = reserve.currentVariableBorrowRate;
|
||||
}
|
||||
|
||||
borrowRateMode = uint256(mode);
|
||||
(currentStableBorrowBalance, currentVariableBorrowBalance) = UserLogic.getUserBorrowBalances(_user,reserve);
|
||||
(principalStableBorrowBalance, principalVariableBorrowBalance) = UserLogic.getUserPrincipalBorrowBalances(_user,reserve);
|
||||
liquidityRate = reserve.currentLiquidityRate;
|
||||
originationFee = user.originationFee;
|
||||
variableBorrowIndex = user.lastVariableBorrowCumulativeIndex;
|
||||
lastUpdateTimestamp = user.lastUpdateTimestamp;
|
||||
usageAsCollateralEnabled = user.useAsCollateral;
|
||||
stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(_user);
|
||||
usageAsCollateralEnabled = usersReserveData[_user][_reserve].useAsCollateral;
|
||||
variableBorrowIndex = IVariableDebtToken(reserve.variableDebtTokenAddress).getUserIndex(_user);
|
||||
}
|
||||
|
||||
function getReserves() external view returns (address[] memory) {
|
||||
|
@ -978,10 +893,12 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
function initReserve(
|
||||
address _reserve,
|
||||
address _aTokenAddress,
|
||||
address _stableDebtAddress,
|
||||
address _variableDebtAddress,
|
||||
uint256 _decimals,
|
||||
address _interestRateStrategyAddress
|
||||
) external onlyLendingPoolConfigurator {
|
||||
reserves[_reserve].init(_aTokenAddress, _decimals, _interestRateStrategyAddress);
|
||||
reserves[_reserve].init(_aTokenAddress, _stableDebtAddress, _variableDebtAddress, _decimals, _interestRateStrategyAddress);
|
||||
addReserveToListInternal(_reserve);
|
||||
|
||||
}
|
||||
|
@ -1161,6 +1078,11 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
return reserves[_reserve].getNormalizedIncome();
|
||||
}
|
||||
|
||||
function getReserveNormalizedVariableDebt(address _reserve) external view returns (uint256) {
|
||||
return reserves[_reserve].getNormalizedDebt();
|
||||
}
|
||||
|
||||
|
||||
function balanceDecreaseAllowed(address _reserve, address _user, uint256 _amount)
|
||||
external
|
||||
view
|
||||
|
|
|
@ -30,13 +30,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
address _interestRateStrategyAddress
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve is removed.
|
||||
* @param _reserve the address of the reserve
|
||||
**/
|
||||
event ReserveRemoved(address indexed _reserve);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @dev emitted when borrowing is enabled on a reserve
|
||||
* @param _reserve the address of the reserve
|
||||
* @param _stableRateEnabled true if stable rate borrowing is enabled, false otherwise
|
||||
|
@ -171,17 +165,22 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
function initReserve(
|
||||
address _reserve,
|
||||
uint8 _underlyingAssetDecimals,
|
||||
address _interestRateStrategyAddress
|
||||
address _interestRateStrategyAddress,
|
||||
address _stableDebtTokenAddress,
|
||||
address _variableDebtTokenAddress
|
||||
) external onlyLendingPoolManager {
|
||||
IERC20Detailed asset = IERC20Detailed(_reserve);
|
||||
string memory aTokenName = string(
|
||||
abi.encodePacked('Aave Interest bearing ', IERC20Detailed(_reserve).name())
|
||||
);
|
||||
string memory aTokenSymbol = string(abi.encodePacked('a', IERC20Detailed(_reserve).symbol()));
|
||||
|
||||
string memory aTokenName = string(abi.encodePacked('Aave Interest bearing ', asset.name()));
|
||||
string memory aTokenSymbol = string(abi.encodePacked('a', asset.symbol()));
|
||||
|
||||
initReserveWithData(
|
||||
_reserve,
|
||||
aTokenName,
|
||||
aTokenSymbol,
|
||||
_stableDebtTokenAddress,
|
||||
_variableDebtTokenAddress,
|
||||
_underlyingAssetDecimals,
|
||||
_interestRateStrategyAddress
|
||||
);
|
||||
|
@ -199,11 +198,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
address _reserve,
|
||||
string memory _aTokenName,
|
||||
string memory _aTokenSymbol,
|
||||
address _stableDebtTokenAddress,
|
||||
address _variableDebtTokenAddress,
|
||||
uint8 _underlyingAssetDecimals,
|
||||
address _interestRateStrategyAddress
|
||||
) public onlyLendingPoolManager {
|
||||
LendingPool pool = LendingPool(payable(poolAddressesProvider.getLendingPool()));
|
||||
|
||||
AToken aTokenInstance = new AToken(
|
||||
poolAddressesProvider,
|
||||
_reserve,
|
||||
|
@ -211,9 +210,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
_aTokenName,
|
||||
_aTokenSymbol
|
||||
);
|
||||
pool.initReserve(
|
||||
|
||||
LendingPool(payable(poolAddressesProvider.getLendingPool())).initReserve(
|
||||
_reserve,
|
||||
address(aTokenInstance),
|
||||
_stableDebtTokenAddress,
|
||||
_variableDebtTokenAddress,
|
||||
_underlyingAssetDecimals,
|
||||
_interestRateStrategyAddress
|
||||
);
|
||||
|
|
|
@ -184,8 +184,7 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
|
|||
}
|
||||
|
||||
//if the user hasn't borrowed the specific currency defined by _reserve, it cannot be liquidated
|
||||
(, vars.userCompoundedBorrowBalance, vars.borrowBalanceIncrease) = userPrincipal
|
||||
.getBorrowBalances(principalReserve);
|
||||
(,vars.userCompoundedBorrowBalance) = UserLogic.getUserBorrowBalances(_user, principalReserve);
|
||||
|
||||
if (vars.userCompoundedBorrowBalance == 0) {
|
||||
return (
|
||||
|
@ -216,23 +215,7 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
|
|||
vars.userCollateralBalance
|
||||
);
|
||||
|
||||
vars.originationFee = userPrincipal.originationFee;
|
||||
|
||||
//if there is a fee to liquidate, calculate the maximum amount of fee that can be liquidated
|
||||
if (vars.originationFee > 0) {
|
||||
(
|
||||
vars.liquidatedCollateralForFee,
|
||||
vars.feeLiquidated
|
||||
) = calculateAvailableCollateralToLiquidate(
|
||||
collateralReserve,
|
||||
principalReserve,
|
||||
_collateral,
|
||||
_reserve,
|
||||
vars.originationFee,
|
||||
vars.userCollateralBalance.sub(vars.maxCollateralToLiquidate)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//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
|
||||
|
@ -252,16 +235,9 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
|
|||
}
|
||||
}
|
||||
|
||||
principalReserve.updateStateOnLiquidationAsPrincipal(
|
||||
userPrincipal,
|
||||
_reserve,
|
||||
vars.actualAmountToLiquidate,
|
||||
vars.borrowBalanceIncrease
|
||||
);
|
||||
collateralReserve.updateStateOnLiquidationAsCollateral(
|
||||
_collateral,
|
||||
vars.maxCollateralToLiquidate,
|
||||
vars.liquidatedCollateralForFee,
|
||||
_receiveAToken
|
||||
);
|
||||
|
||||
|
|
|
@ -1,440 +1,253 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import "@openzeppelin/contracts/math/SafeMath.sol";
|
||||
import "./WadRayMath.sol";
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import './WadRayMath.sol';
|
||||
import './MathUtils.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
|
||||
/**
|
||||
* @title CoreLibrary library
|
||||
* @author Aave
|
||||
* @notice Defines the data structures of the reserves and the user data
|
||||
**/
|
||||
* @title CoreLibrary library
|
||||
* @author Aave
|
||||
* @notice Defines the data structures of the reserves and the user data
|
||||
**/
|
||||
library CoreLibrary {
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
|
||||
enum InterestRateMode {NONE, STABLE, VARIABLE}
|
||||
enum InterestRateMode {NONE, STABLE, VARIABLE}
|
||||
|
||||
uint256 internal constant SECONDS_PER_YEAR = 365 days;
|
||||
|
||||
struct UserReserveData {
|
||||
//principal amount borrowed by the user.
|
||||
uint256 principalBorrowBalance;
|
||||
//cumulated variable borrow index for the user. Expressed in ray
|
||||
uint256 lastVariableBorrowCumulativeIndex;
|
||||
//origination fee cumulated by the user
|
||||
uint256 originationFee;
|
||||
// stable borrow rate at which the user has borrowed. Expressed in ray
|
||||
uint256 stableBorrowRate;
|
||||
uint40 lastUpdateTimestamp;
|
||||
//defines if a specific deposit should or not be used as a collateral in borrows
|
||||
bool useAsCollateral;
|
||||
}
|
||||
|
||||
struct ReserveData {
|
||||
/**
|
||||
* @dev refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
|
||||
**/
|
||||
//the liquidity index. Expressed in ray
|
||||
uint256 lastLiquidityCumulativeIndex;
|
||||
//the current supply rate. Expressed in ray
|
||||
uint256 currentLiquidityRate;
|
||||
//the total borrows of the reserve at a stable rate. Expressed in the currency decimals
|
||||
uint256 totalBorrowsStable;
|
||||
//the total borrows of the reserve at a variable rate. Expressed in the currency decimals
|
||||
uint256 totalBorrowsVariable;
|
||||
//the current variable borrow rate. Expressed in ray
|
||||
uint256 currentVariableBorrowRate;
|
||||
//the current stable borrow rate. Expressed in ray
|
||||
uint256 currentStableBorrowRate;
|
||||
//the current average stable borrow rate (weighted average of all the different stable rate loans). Expressed in ray
|
||||
uint256 currentAverageStableBorrowRate;
|
||||
//variable borrow index. Expressed in ray
|
||||
uint256 lastVariableBorrowCumulativeIndex;
|
||||
//the ltv of the reserve. Expressed in percentage (0-100)
|
||||
uint256 baseLTVasCollateral;
|
||||
//the liquidation threshold of the reserve. Expressed in percentage (0-100)
|
||||
uint256 liquidationThreshold;
|
||||
//the liquidation bonus of the reserve. Expressed in percentage
|
||||
uint256 liquidationBonus;
|
||||
//the decimals of the reserve asset
|
||||
uint256 decimals;
|
||||
/**
|
||||
* @dev address of the aToken representing the asset
|
||||
**/
|
||||
address aTokenAddress;
|
||||
/**
|
||||
* @dev address of the interest rate strategy contract
|
||||
**/
|
||||
address interestRateStrategyAddress;
|
||||
uint40 lastUpdateTimestamp;
|
||||
// borrowingEnabled = true means users can borrow from this reserve
|
||||
bool borrowingEnabled;
|
||||
// usageAsCollateralEnabled = true means users can use this reserve as collateral
|
||||
bool usageAsCollateralEnabled;
|
||||
// isStableBorrowRateEnabled = true means users can borrow at a stable rate
|
||||
bool isStableBorrowRateEnabled;
|
||||
// isActive = true means the reserve has been activated and properly configured
|
||||
bool isActive;
|
||||
// isFreezed = true means the reserve only allows repays and redeems, but not deposits, new borrowings or rate swap
|
||||
bool isFreezed;
|
||||
}
|
||||
struct UserReserveData {
|
||||
//defines if a specific deposit should or not be used as a collateral in borrows
|
||||
bool useAsCollateral;
|
||||
}
|
||||
|
||||
struct ReserveData {
|
||||
/**
|
||||
* @dev returns the ongoing normalized income for the reserve.
|
||||
* a value of 1e27 means there is no income. As time passes, the income is accrued.
|
||||
* A value of 2*1e27 means that the income of the reserve is double the initial amount.
|
||||
* @param _reserve the reserve object
|
||||
* @return the normalized income. expressed in ray
|
||||
**/
|
||||
function getNormalizedIncome(CoreLibrary.ReserveData storage _reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
uint256 cumulated = calculateLinearInterest(
|
||||
_reserve
|
||||
.currentLiquidityRate,
|
||||
_reserve
|
||||
.lastUpdateTimestamp
|
||||
)
|
||||
.rayMul(_reserve.lastLiquidityCumulativeIndex);
|
||||
|
||||
return cumulated;
|
||||
|
||||
}
|
||||
|
||||
* @dev refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
|
||||
**/
|
||||
//the liquidity index. Expressed in ray
|
||||
uint256 lastLiquidityCumulativeIndex;
|
||||
//the current supply rate. Expressed in ray
|
||||
uint256 currentLiquidityRate;
|
||||
//the current variable borrow rate. Expressed in ray
|
||||
uint256 currentVariableBorrowRate;
|
||||
//the current stable borrow rate. Expressed in ray
|
||||
uint256 currentStableBorrowRate;
|
||||
//variable borrow index. Expressed in ray
|
||||
uint256 lastVariableBorrowCumulativeIndex;
|
||||
//the ltv of the reserve. Expressed in percentage (0-100)
|
||||
uint256 baseLTVasCollateral;
|
||||
//the liquidation threshold of the reserve. Expressed in percentage (0-100)
|
||||
uint256 liquidationThreshold;
|
||||
//the liquidation bonus of the reserve. Expressed in percentage
|
||||
uint256 liquidationBonus;
|
||||
//the decimals of the reserve asset
|
||||
uint256 decimals;
|
||||
/**
|
||||
* @dev Updates the liquidity cumulative index Ci and variable borrow cumulative index Bvc. Refer to the whitepaper for
|
||||
* a formal specification.
|
||||
* @param _self the reserve object
|
||||
**/
|
||||
function updateCumulativeIndexes(ReserveData storage _self) internal {
|
||||
uint256 totalBorrows = getTotalBorrows(_self);
|
||||
|
||||
if (totalBorrows > 0) {
|
||||
//only cumulating if there is any income being produced
|
||||
uint256 cumulatedLiquidityInterest = calculateLinearInterest(
|
||||
_self.currentLiquidityRate,
|
||||
_self.lastUpdateTimestamp
|
||||
);
|
||||
|
||||
_self.lastLiquidityCumulativeIndex = cumulatedLiquidityInterest.rayMul(
|
||||
_self.lastLiquidityCumulativeIndex
|
||||
);
|
||||
|
||||
uint256 cumulatedVariableBorrowInterest = calculateCompoundedInterest(
|
||||
_self.currentVariableBorrowRate,
|
||||
_self.lastUpdateTimestamp
|
||||
);
|
||||
_self.lastVariableBorrowCumulativeIndex = cumulatedVariableBorrowInterest.rayMul(
|
||||
_self.lastVariableBorrowCumulativeIndex
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
* @dev address of the aToken representing the asset
|
||||
**/
|
||||
address aTokenAddress;
|
||||
address stableDebtTokenAddress;
|
||||
address variableDebtTokenAddress;
|
||||
/**
|
||||
* @dev accumulates a predefined amount of asset to the reserve as a fixed, one time income. Used for example to accumulate
|
||||
* the flashloan fee to the reserve, and spread it through the depositors.
|
||||
* @param _self the reserve object
|
||||
* @param _totalLiquidity the total liquidity available in the reserve
|
||||
* @param _amount the amount to accomulate
|
||||
**/
|
||||
function cumulateToLiquidityIndex(
|
||||
ReserveData storage _self,
|
||||
uint256 _totalLiquidity,
|
||||
uint256 _amount
|
||||
) internal {
|
||||
uint256 amountToLiquidityRatio = _amount.wadToRay().rayDiv(_totalLiquidity.wadToRay());
|
||||
* @dev address of the interest rate strategy contract
|
||||
**/
|
||||
address interestRateStrategyAddress;
|
||||
uint40 lastUpdateTimestamp;
|
||||
// borrowingEnabled = true means users can borrow from this reserve
|
||||
bool borrowingEnabled;
|
||||
// usageAsCollateralEnabled = true means users can use this reserve as collateral
|
||||
bool usageAsCollateralEnabled;
|
||||
// isStableBorrowRateEnabled = true means users can borrow at a stable rate
|
||||
bool isStableBorrowRateEnabled;
|
||||
// isActive = true means the reserve has been activated and properly configured
|
||||
bool isActive;
|
||||
// isFreezed = true means the reserve only allows repays and redeems, but not deposits, new borrowings or rate swap
|
||||
bool isFreezed;
|
||||
}
|
||||
|
||||
uint256 cumulatedLiquidity = amountToLiquidityRatio.add(WadRayMath.ray());
|
||||
/**
|
||||
* @dev returns the ongoing normalized income for the reserve.
|
||||
* a value of 1e27 means there is no income. As time passes, the income is accrued.
|
||||
* A value of 2*1e27 means that the income of the reserve is double the initial amount.
|
||||
* @param _reserve the reserve object
|
||||
* @return the normalized income. expressed in ray
|
||||
**/
|
||||
function getNormalizedIncome(CoreLibrary.ReserveData storage _reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
uint256 cumulated = MathUtils
|
||||
.calculateLinearInterest(_reserve.currentLiquidityRate, _reserve.lastUpdateTimestamp)
|
||||
.rayMul(_reserve.lastLiquidityCumulativeIndex);
|
||||
|
||||
_self.lastLiquidityCumulativeIndex = cumulatedLiquidity.rayMul(
|
||||
_self.lastLiquidityCumulativeIndex
|
||||
);
|
||||
return cumulated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the ongoing normalized variable debt for the reserve.
|
||||
* a value of 1e27 means there is no debt. As time passes, the income is accrued.
|
||||
* A value of 2*1e27 means that the debt of the reserve is double the initial amount.
|
||||
* @param _reserve the reserve object
|
||||
* @return the normalized variable debt. expressed in ray
|
||||
**/
|
||||
function getNormalizedDebt(CoreLibrary.ReserveData storage _reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
uint256 cumulated = MathUtils
|
||||
.calculateCompoundedInterest(_reserve.currentVariableBorrowRate, _reserve.lastUpdateTimestamp)
|
||||
.rayMul(_reserve.lastVariableBorrowCumulativeIndex);
|
||||
|
||||
return cumulated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the liquidity cumulative index Ci and variable borrow cumulative index Bvc. Refer to the whitepaper for
|
||||
* a formal specification.
|
||||
* @param _self the reserve object
|
||||
**/
|
||||
function updateCumulativeIndexes(ReserveData storage _self) internal {
|
||||
uint256 totalBorrows = getTotalBorrows(_self);
|
||||
|
||||
if (totalBorrows > 0) {
|
||||
//only cumulating if there is any income being produced
|
||||
uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest(
|
||||
_self.currentLiquidityRate,
|
||||
_self.lastUpdateTimestamp
|
||||
);
|
||||
|
||||
_self.lastLiquidityCumulativeIndex = cumulatedLiquidityInterest.rayMul(
|
||||
_self.lastLiquidityCumulativeIndex
|
||||
);
|
||||
|
||||
uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest(
|
||||
_self.currentVariableBorrowRate,
|
||||
_self.lastUpdateTimestamp
|
||||
);
|
||||
_self.lastVariableBorrowCumulativeIndex = cumulatedVariableBorrowInterest.rayMul(
|
||||
_self.lastVariableBorrowCumulativeIndex
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev accumulates a predefined amount of asset to the reserve as a fixed, one time income. Used for example to accumulate
|
||||
* the flashloan fee to the reserve, and spread it through the depositors.
|
||||
* @param _self the reserve object
|
||||
* @param _totalLiquidity the total liquidity available in the reserve
|
||||
* @param _amount the amount to accomulate
|
||||
**/
|
||||
function cumulateToLiquidityIndex(
|
||||
ReserveData storage _self,
|
||||
uint256 _totalLiquidity,
|
||||
uint256 _amount
|
||||
) internal {
|
||||
uint256 amountToLiquidityRatio = _amount.wadToRay().rayDiv(_totalLiquidity.wadToRay());
|
||||
|
||||
uint256 cumulatedLiquidity = amountToLiquidityRatio.add(WadRayMath.ray());
|
||||
|
||||
_self.lastLiquidityCumulativeIndex = cumulatedLiquidity.rayMul(
|
||||
_self.lastLiquidityCumulativeIndex
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev initializes a reserve
|
||||
* @param _self the reserve object
|
||||
* @param _aTokenAddress the address of the overlying atoken contract
|
||||
* @param _decimals the number of decimals of the underlying asset
|
||||
* @param _interestRateStrategyAddress the address of the interest rate strategy contract
|
||||
**/
|
||||
function init(
|
||||
ReserveData storage _self,
|
||||
address _aTokenAddress,
|
||||
address _stableDebtAddress,
|
||||
address _variableDebtAddress,
|
||||
uint256 _decimals,
|
||||
address _interestRateStrategyAddress
|
||||
) external {
|
||||
require(_self.aTokenAddress == address(0), 'Reserve has already been initialized');
|
||||
|
||||
if (_self.lastLiquidityCumulativeIndex == 0) {
|
||||
//if the reserve has not been initialized yet
|
||||
_self.lastLiquidityCumulativeIndex = WadRayMath.ray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev initializes a reserve
|
||||
* @param _self the reserve object
|
||||
* @param _aTokenAddress the address of the overlying atoken contract
|
||||
* @param _decimals the number of decimals of the underlying asset
|
||||
* @param _interestRateStrategyAddress the address of the interest rate strategy contract
|
||||
**/
|
||||
function init(
|
||||
ReserveData storage _self,
|
||||
address _aTokenAddress,
|
||||
uint256 _decimals,
|
||||
address _interestRateStrategyAddress
|
||||
) external {
|
||||
require(_self.aTokenAddress == address(0), "Reserve has already been initialized");
|
||||
|
||||
if (_self.lastLiquidityCumulativeIndex == 0) {
|
||||
//if the reserve has not been initialized yet
|
||||
_self.lastLiquidityCumulativeIndex = WadRayMath.ray();
|
||||
}
|
||||
|
||||
if (_self.lastVariableBorrowCumulativeIndex == 0) {
|
||||
_self.lastVariableBorrowCumulativeIndex = WadRayMath.ray();
|
||||
}
|
||||
|
||||
_self.aTokenAddress = _aTokenAddress;
|
||||
_self.decimals = _decimals;
|
||||
|
||||
_self.interestRateStrategyAddress = _interestRateStrategyAddress;
|
||||
_self.isActive = true;
|
||||
_self.isFreezed = false;
|
||||
|
||||
if (_self.lastVariableBorrowCumulativeIndex == 0) {
|
||||
_self.lastVariableBorrowCumulativeIndex = WadRayMath.ray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev enables borrowing on a reserve
|
||||
* @param _self the reserve object
|
||||
* @param _stableBorrowRateEnabled true if the stable borrow rate must be enabled by default, false otherwise
|
||||
**/
|
||||
function enableBorrowing(ReserveData storage _self, bool _stableBorrowRateEnabled) external {
|
||||
require(_self.borrowingEnabled == false, "Reserve is already enabled");
|
||||
_self.aTokenAddress = _aTokenAddress;
|
||||
_self.stableDebtTokenAddress = _stableDebtAddress;
|
||||
_self.variableDebtTokenAddress = _variableDebtAddress;
|
||||
_self.decimals = _decimals;
|
||||
|
||||
_self.borrowingEnabled = true;
|
||||
_self.isStableBorrowRateEnabled = _stableBorrowRateEnabled;
|
||||
_self.interestRateStrategyAddress = _interestRateStrategyAddress;
|
||||
_self.isActive = true;
|
||||
_self.isFreezed = false;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @dev enables borrowing on a reserve
|
||||
* @param _self the reserve object
|
||||
* @param _stableBorrowRateEnabled true if the stable borrow rate must be enabled by default, false otherwise
|
||||
**/
|
||||
function enableBorrowing(ReserveData storage _self, bool _stableBorrowRateEnabled) external {
|
||||
require(_self.borrowingEnabled == false, 'Reserve is already enabled');
|
||||
|
||||
/**
|
||||
* @dev disables borrowing on a reserve
|
||||
* @param _self the reserve object
|
||||
**/
|
||||
function disableBorrowing(ReserveData storage _self) external {
|
||||
_self.borrowingEnabled = false;
|
||||
}
|
||||
_self.borrowingEnabled = true;
|
||||
_self.isStableBorrowRateEnabled = _stableBorrowRateEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev enables a reserve to be used as collateral
|
||||
* @param _self the reserve object
|
||||
* @param _baseLTVasCollateral 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
|
||||
**/
|
||||
function enableAsCollateral(
|
||||
ReserveData storage _self,
|
||||
uint256 _baseLTVasCollateral,
|
||||
uint256 _liquidationThreshold,
|
||||
uint256 _liquidationBonus
|
||||
) external {
|
||||
require(
|
||||
_self.usageAsCollateralEnabled == false,
|
||||
"Reserve is already enabled as collateral"
|
||||
);
|
||||
/**
|
||||
* @dev disables borrowing on a reserve
|
||||
* @param _self the reserve object
|
||||
**/
|
||||
function disableBorrowing(ReserveData storage _self) external {
|
||||
_self.borrowingEnabled = false;
|
||||
}
|
||||
|
||||
_self.usageAsCollateralEnabled = true;
|
||||
_self.baseLTVasCollateral = _baseLTVasCollateral;
|
||||
_self.liquidationThreshold = _liquidationThreshold;
|
||||
_self.liquidationBonus = _liquidationBonus;
|
||||
/**
|
||||
* @dev enables a reserve to be used as collateral
|
||||
* @param _self the reserve object
|
||||
* @param _baseLTVasCollateral 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
|
||||
**/
|
||||
function enableAsCollateral(
|
||||
ReserveData storage _self,
|
||||
uint256 _baseLTVasCollateral,
|
||||
uint256 _liquidationThreshold,
|
||||
uint256 _liquidationBonus
|
||||
) external {
|
||||
require(_self.usageAsCollateralEnabled == false, 'Reserve is already enabled as collateral');
|
||||
|
||||
if (_self.lastLiquidityCumulativeIndex == 0)
|
||||
_self.lastLiquidityCumulativeIndex = WadRayMath.ray();
|
||||
_self.usageAsCollateralEnabled = true;
|
||||
_self.baseLTVasCollateral = _baseLTVasCollateral;
|
||||
_self.liquidationThreshold = _liquidationThreshold;
|
||||
_self.liquidationBonus = _liquidationBonus;
|
||||
|
||||
}
|
||||
if (_self.lastLiquidityCumulativeIndex == 0)
|
||||
_self.lastLiquidityCumulativeIndex = WadRayMath.ray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev disables a reserve as collateral
|
||||
* @param _self the reserve object
|
||||
**/
|
||||
function disableAsCollateral(ReserveData storage _self) external {
|
||||
_self.usageAsCollateralEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @dev calculates the compounded borrow balance of a user
|
||||
* @param _self the userReserve object
|
||||
* @param _reserve the reserve object
|
||||
* @return the user compounded borrow balance
|
||||
**/
|
||||
function getCompoundedBorrowBalance(
|
||||
CoreLibrary.UserReserveData storage _self,
|
||||
CoreLibrary.ReserveData storage _reserve
|
||||
) internal view returns (uint256) {
|
||||
if (_self.principalBorrowBalance == 0) return 0;
|
||||
|
||||
uint256 principalBorrowBalanceRay = _self.principalBorrowBalance.wadToRay();
|
||||
uint256 compoundedBalance = 0;
|
||||
uint256 cumulatedInterest = 0;
|
||||
|
||||
if (_self.stableBorrowRate > 0) {
|
||||
cumulatedInterest = calculateCompoundedInterest(
|
||||
_self.stableBorrowRate,
|
||||
_self.lastUpdateTimestamp
|
||||
);
|
||||
} else {
|
||||
//variable interest
|
||||
cumulatedInterest = calculateCompoundedInterest(
|
||||
_reserve
|
||||
.currentVariableBorrowRate,
|
||||
_reserve
|
||||
.lastUpdateTimestamp
|
||||
)
|
||||
.rayMul(_reserve.lastVariableBorrowCumulativeIndex)
|
||||
.rayDiv(_self.lastVariableBorrowCumulativeIndex);
|
||||
}
|
||||
|
||||
compoundedBalance = principalBorrowBalanceRay.rayMul(cumulatedInterest).rayToWad();
|
||||
|
||||
if (compoundedBalance == _self.principalBorrowBalance) {
|
||||
//solium-disable-next-line
|
||||
if (_self.lastUpdateTimestamp != block.timestamp) {
|
||||
//no interest cumulation because of the rounding - we add 1 wei
|
||||
//as symbolic cumulated interest to avoid interest free loans.
|
||||
|
||||
return _self.principalBorrowBalance.add(1 wei);
|
||||
}
|
||||
}
|
||||
|
||||
return compoundedBalance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev increases the total borrows at a stable rate on a specific reserve and updates the
|
||||
* average stable rate consequently
|
||||
* @param _reserve the reserve object
|
||||
* @param _amount the amount to add to the total borrows stable
|
||||
* @param _rate the rate at which the amount has been borrowed
|
||||
**/
|
||||
function increaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
ReserveData storage _reserve,
|
||||
uint256 _amount,
|
||||
uint256 _rate
|
||||
) internal {
|
||||
uint256 previousTotalBorrowStable = _reserve.totalBorrowsStable;
|
||||
//updating reserve borrows stable
|
||||
_reserve.totalBorrowsStable = _reserve.totalBorrowsStable.add(_amount);
|
||||
|
||||
//update the average stable rate
|
||||
//weighted average of all the borrows
|
||||
uint256 weightedLastBorrow = _amount.wadToRay().rayMul(_rate);
|
||||
uint256 weightedPreviousTotalBorrows = previousTotalBorrowStable.wadToRay().rayMul(
|
||||
_reserve.currentAverageStableBorrowRate
|
||||
);
|
||||
|
||||
_reserve.currentAverageStableBorrowRate = weightedLastBorrow
|
||||
.add(weightedPreviousTotalBorrows)
|
||||
.rayDiv(_reserve.totalBorrowsStable.wadToRay());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev decreases the total borrows at a stable rate on a specific reserve and updates the
|
||||
* average stable rate consequently
|
||||
* @param _reserve the reserve object
|
||||
* @param _amount the amount to substract to the total borrows stable
|
||||
* @param _rate the rate at which the amount has been repaid
|
||||
**/
|
||||
function decreaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
ReserveData storage _reserve,
|
||||
uint256 _amount,
|
||||
uint256 _rate
|
||||
) internal {
|
||||
require(_reserve.totalBorrowsStable >= _amount, "Invalid amount to decrease");
|
||||
|
||||
uint256 previousTotalBorrowStable = _reserve.totalBorrowsStable;
|
||||
|
||||
//updating reserve borrows stable
|
||||
_reserve.totalBorrowsStable = _reserve.totalBorrowsStable.sub(_amount);
|
||||
|
||||
if (_reserve.totalBorrowsStable == 0) {
|
||||
_reserve.currentAverageStableBorrowRate = 0; //no income if there are no stable rate borrows
|
||||
return;
|
||||
}
|
||||
|
||||
//update the average stable rate
|
||||
//weighted average of all the borrows
|
||||
uint256 weightedLastBorrow = _amount.wadToRay().rayMul(_rate);
|
||||
uint256 weightedPreviousTotalBorrows = previousTotalBorrowStable.wadToRay().rayMul(
|
||||
_reserve.currentAverageStableBorrowRate
|
||||
);
|
||||
|
||||
require(
|
||||
weightedPreviousTotalBorrows >= weightedLastBorrow,
|
||||
"The amounts to subtract don't match"
|
||||
);
|
||||
|
||||
_reserve.currentAverageStableBorrowRate = weightedPreviousTotalBorrows
|
||||
.sub(weightedLastBorrow)
|
||||
.rayDiv(_reserve.totalBorrowsStable.wadToRay());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev increases the total borrows at a variable rate
|
||||
* @param _reserve the reserve object
|
||||
* @param _amount the amount to add to the total borrows variable
|
||||
**/
|
||||
function increaseTotalBorrowsVariable(ReserveData storage _reserve, uint256 _amount) internal {
|
||||
_reserve.totalBorrowsVariable = _reserve.totalBorrowsVariable.add(_amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev decreases the total borrows at a variable rate
|
||||
* @param _reserve the reserve object
|
||||
* @param _amount the amount to substract to the total borrows variable
|
||||
**/
|
||||
function decreaseTotalBorrowsVariable(ReserveData storage _reserve, uint256 _amount) internal {
|
||||
require(
|
||||
_reserve.totalBorrowsVariable >= _amount,
|
||||
"The amount that is being subtracted from the variable total borrows is incorrect"
|
||||
);
|
||||
_reserve.totalBorrowsVariable = _reserve.totalBorrowsVariable.sub(_amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev function to calculate the interest using a linear interest rate formula
|
||||
* @param _rate the interest rate, in ray
|
||||
* @param _lastUpdateTimestamp the timestamp of the last update of the interest
|
||||
* @return the interest rate linearly accumulated during the timeDelta, in ray
|
||||
**/
|
||||
|
||||
function calculateLinearInterest(uint256 _rate, uint40 _lastUpdateTimestamp)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
//solium-disable-next-line
|
||||
uint256 timeDifference = block.timestamp.sub(uint256(_lastUpdateTimestamp));
|
||||
|
||||
uint256 timeDelta = timeDifference.wadToRay().rayDiv(SECONDS_PER_YEAR.wadToRay());
|
||||
|
||||
return _rate.rayMul(timeDelta).add(WadRayMath.ray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev function to calculate the interest using a compounded interest rate formula
|
||||
* @param _rate the interest rate, in ray
|
||||
* @param _lastUpdateTimestamp the timestamp of the last update of the interest
|
||||
* @return the interest rate compounded during the timeDelta, in ray
|
||||
**/
|
||||
function calculateCompoundedInterest(uint256 _rate, uint40 _lastUpdateTimestamp)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
//solium-disable-next-line
|
||||
uint256 timeDifference = block.timestamp.sub(uint256(_lastUpdateTimestamp));
|
||||
|
||||
uint256 ratePerSecond = _rate.div(SECONDS_PER_YEAR);
|
||||
|
||||
return ratePerSecond.add(WadRayMath.ray()).rayPow(timeDifference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the total borrows on the reserve
|
||||
* @param _reserve the reserve object
|
||||
* @return the total borrows (stable + variable)
|
||||
**/
|
||||
function getTotalBorrows(CoreLibrary.ReserveData storage _reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _reserve.totalBorrowsStable.add(_reserve.totalBorrowsVariable);
|
||||
}
|
||||
/**
|
||||
* @dev disables a reserve as collateral
|
||||
* @param _self the reserve object
|
||||
**/
|
||||
function disableAsCollateral(ReserveData storage _self) external {
|
||||
_self.usageAsCollateralEnabled = false;
|
||||
}
|
||||
|
||||
function getTotalBorrows(ReserveData storage _self) internal view returns(uint256) {
|
||||
return
|
||||
IERC20(_self.stableDebtTokenAddress).totalSupply().add(
|
||||
IERC20(_self.variableDebtTokenAddress).totalSupply()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,8 +156,8 @@ library GenericLogic {
|
|||
.currentReserveAddress];
|
||||
|
||||
vars.compoundedLiquidityBalance = IERC20(currentReserve.aTokenAddress).balanceOf(_user);
|
||||
(, vars.compoundedBorrowBalance, ) = _usersReserveData[_user][_reserves[vars.i]]
|
||||
.getBorrowBalances(currentReserve);
|
||||
vars.compoundedBorrowBalance = IERC20(currentReserve.stableDebtTokenAddress).balanceOf(_user);
|
||||
vars.compoundedBorrowBalance = vars.compoundedBorrowBalance.add(IERC20(currentReserve.variableDebtTokenAddress).balanceOf(_user));
|
||||
|
||||
if (vars.compoundedLiquidityBalance == 0 && vars.compoundedBorrowBalance == 0) {
|
||||
continue;
|
||||
|
|
54
contracts/libraries/MathUtils.sol
Normal file
54
contracts/libraries/MathUtils.sol
Normal file
|
@ -0,0 +1,54 @@
|
|||
|
||||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import "@openzeppelin/contracts/math/SafeMath.sol";
|
||||
import "./WadRayMath.sol";
|
||||
|
||||
library MathUtils {
|
||||
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
|
||||
uint256 internal constant SECONDS_PER_YEAR = 365 days;
|
||||
|
||||
/**
|
||||
* @dev function to calculate the interest using a linear interest rate formula
|
||||
* @param _rate the interest rate, in ray
|
||||
* @param _lastUpdateTimestamp the timestamp of the last update of the interest
|
||||
* @return the interest rate linearly accumulated during the timeDelta, in ray
|
||||
**/
|
||||
|
||||
function calculateLinearInterest(uint256 _rate, uint40 _lastUpdateTimestamp)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
//solium-disable-next-line
|
||||
uint256 timeDifference = block.timestamp.sub(uint256(_lastUpdateTimestamp));
|
||||
|
||||
uint256 timeDelta = timeDifference.wadToRay().rayDiv(SECONDS_PER_YEAR.wadToRay());
|
||||
|
||||
return _rate.rayMul(timeDelta).add(WadRayMath.ray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev function to calculate the interest using a compounded interest rate formula
|
||||
* @param _rate the interest rate, in ray
|
||||
* @param _lastUpdateTimestamp the timestamp of the last update of the interest
|
||||
* @return the interest rate compounded during the timeDelta, in ray
|
||||
**/
|
||||
function calculateCompoundedInterest(uint256 _rate, uint40 _lastUpdateTimestamp)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
//solium-disable-next-line
|
||||
uint256 timeDifference = block.timestamp.sub(uint256(_lastUpdateTimestamp));
|
||||
|
||||
uint256 ratePerSecond = _rate.div(SECONDS_PER_YEAR);
|
||||
|
||||
return ratePerSecond.add(WadRayMath.ray()).rayPow(timeDifference);
|
||||
}
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@ import {CoreLibrary} from "./CoreLibrary.sol";
|
|||
import {UserLogic} from "./UserLogic.sol";
|
||||
import {IPriceOracleGetter} from "../interfaces/IPriceOracleGetter.sol";
|
||||
import {UniversalERC20} from "./UniversalERC20.sol";
|
||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
|
||||
import "../configuration/LendingPoolAddressesProvider.sol";
|
||||
import "../interfaces/ILendingRateOracle.sol";
|
||||
|
@ -75,96 +76,17 @@ library ReserveLogic {
|
|||
updateInterestRatesAndTimestamp(_reserve, _reserveAddress, _income, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev updates the state of the core as a consequence of a repay action.
|
||||
* @param _reserve the address of the reserve on which the user is repaying
|
||||
* @param _user the address of the borrower
|
||||
* @param _paybackAmount the amount being paid back
|
||||
* @param _balanceIncrease the accrued interest on the borrowed amount
|
||||
**/
|
||||
function updateStateOnRepay(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
address _reserveAddress,
|
||||
uint256 _paybackAmount,
|
||||
uint256 _balanceIncrease
|
||||
) external {
|
||||
CoreLibrary.InterestRateMode borrowRateMode = _user.getCurrentBorrowRateMode();
|
||||
|
||||
//update the indexes
|
||||
_reserve.updateCumulativeIndexes();
|
||||
|
||||
//compound the cumulated interest to the borrow balance and then subtracting the payback amount
|
||||
if (borrowRateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
_reserve.increaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
_balanceIncrease,
|
||||
_user.stableBorrowRate
|
||||
);
|
||||
_reserve.decreaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
_paybackAmount,
|
||||
_user.stableBorrowRate
|
||||
);
|
||||
} else {
|
||||
_reserve.increaseTotalBorrowsVariable(_balanceIncrease);
|
||||
_reserve.decreaseTotalBorrowsVariable(_paybackAmount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the state of the core as a consequence of a swap rate action.
|
||||
* @param _reserve the address of the reserve on which the user is repaying
|
||||
* @param _user the address of the borrower
|
||||
* @param _principalBorrowBalance the amount borrowed by the user
|
||||
* @param _compoundedBorrowBalance the amount borrowed plus accrued interest
|
||||
* @param _currentRateMode the current interest rate mode for the user
|
||||
**/
|
||||
function updateStateOnSwapRate(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
address _reserveAddress,
|
||||
uint256 _principalBorrowBalance,
|
||||
uint256 _compoundedBorrowBalance,
|
||||
CoreLibrary.InterestRateMode _currentRateMode
|
||||
) external {
|
||||
//compounding reserve indexes
|
||||
_reserve.updateCumulativeIndexes();
|
||||
|
||||
if (_currentRateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
uint256 userCurrentStableRate = _user.stableBorrowRate;
|
||||
|
||||
//swap to variable
|
||||
_reserve.decreaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
_principalBorrowBalance,
|
||||
userCurrentStableRate
|
||||
); //decreasing stable from old principal balance
|
||||
_reserve.increaseTotalBorrowsVariable(_compoundedBorrowBalance); //increase variable borrows
|
||||
} else if (_currentRateMode == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
//swap to stable
|
||||
uint256 currentStableRate = _reserve.currentStableBorrowRate;
|
||||
_reserve.decreaseTotalBorrowsVariable(_principalBorrowBalance);
|
||||
_reserve.increaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
_compoundedBorrowBalance,
|
||||
currentStableRate
|
||||
);
|
||||
|
||||
} else {
|
||||
revert("Invalid rate mode received");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev updates the state of the core as a consequence of a liquidation action.
|
||||
* @param _collateralReserve the collateral reserve that is being liquidated
|
||||
* @param _collateralToLiquidate the amount of collateral being liquidated
|
||||
* @param _liquidatedCollateralForFee the amount of collateral equivalent to the origination fee + bonus
|
||||
* @param _liquidatorReceivesAToken true if the liquidator will receive aTokens, false otherwise
|
||||
**/
|
||||
function updateStateOnLiquidationAsCollateral(
|
||||
CoreLibrary.ReserveData storage _collateralReserve,
|
||||
address _collateralReserveAddress,
|
||||
uint256 _collateralToLiquidate,
|
||||
uint256 _liquidatedCollateralForFee,
|
||||
bool _liquidatorReceivesAToken
|
||||
) external {
|
||||
_collateralReserve.updateCumulativeIndexes();
|
||||
|
@ -174,82 +96,12 @@ library ReserveLogic {
|
|||
_collateralReserve,
|
||||
_collateralReserveAddress,
|
||||
0,
|
||||
_collateralToLiquidate.add(_liquidatedCollateralForFee)
|
||||
_collateralToLiquidate
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the state of the core as a consequence of a stable rate rebalance
|
||||
* @param _reserve the address of the principal reserve where the user borrowed
|
||||
* @param _user the address of the borrower
|
||||
* @param _balanceIncrease the accrued interest on the borrowed amount
|
||||
* @return the new stable rate for the user
|
||||
**/
|
||||
function updateStateOnRebalance(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
address _reserveAddress,
|
||||
uint256 _balanceIncrease
|
||||
) internal returns (uint256) {
|
||||
_reserve.updateCumulativeIndexes();
|
||||
|
||||
_reserve.increaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
_balanceIncrease,
|
||||
_user.stableBorrowRate
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the state of the principal reserve as a consequence of a liquidation action.
|
||||
* @param _reserve the reserve data
|
||||
* @param _user the address of the borrower
|
||||
* @param _reserveAddress the address of the reserve
|
||||
* @param _amountToLiquidate the amount being repaid by the liquidator
|
||||
* @param _balanceIncrease the accrued interest on the borrowed amount
|
||||
**/
|
||||
function updateStateOnLiquidationAsPrincipal(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
address _reserveAddress,
|
||||
uint256 _amountToLiquidate,
|
||||
uint256 _balanceIncrease
|
||||
) external {
|
||||
//update principal reserve data
|
||||
_reserve.updateCumulativeIndexes();
|
||||
|
||||
CoreLibrary.InterestRateMode borrowRateMode = _user.getCurrentBorrowRateMode();
|
||||
|
||||
if (borrowRateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
//increase the total borrows by the compounded interest
|
||||
_reserve.increaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
_balanceIncrease,
|
||||
_user.stableBorrowRate
|
||||
);
|
||||
|
||||
//decrease by the actual amount to liquidate
|
||||
_reserve.decreaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
_amountToLiquidate,
|
||||
_user.stableBorrowRate
|
||||
);
|
||||
|
||||
} else {
|
||||
//increase the total borrows by the compounded interest
|
||||
_reserve.increaseTotalBorrowsVariable(_balanceIncrease);
|
||||
|
||||
//decrease by the actual amount to liquidate
|
||||
_reserve.decreaseTotalBorrowsVariable(_amountToLiquidate);
|
||||
}
|
||||
updateInterestRatesAndTimestamp(
|
||||
_reserve,
|
||||
_reserveAddress,
|
||||
_amountToLiquidate.add(_balanceIncrease),
|
||||
0
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev gets the total liquidity in the reserve. The total liquidity is the balance of the core contract + total borrows
|
||||
* @param _reserve the reserve address
|
||||
|
@ -266,48 +118,6 @@ library ReserveLogic {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the state of the user as a consequence of a stable rate rebalance
|
||||
* @param _reserve the address of the principal reserve where the user borrowed
|
||||
* @param _user the address of the borrower
|
||||
* @param _balanceIncrease the accrued interest on the borrowed amount
|
||||
* @param _amountBorrowed the accrued interest on the borrowed amount
|
||||
**/
|
||||
function updateStateOnBorrow(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
uint256 _principalBalance,
|
||||
uint256 _balanceIncrease,
|
||||
uint256 _amountBorrowed,
|
||||
CoreLibrary.InterestRateMode _newBorrowRateMode
|
||||
) public {
|
||||
|
||||
_reserve.updateCumulativeIndexes();
|
||||
|
||||
CoreLibrary.InterestRateMode previousRateMode = _user.getCurrentBorrowRateMode();
|
||||
|
||||
if (previousRateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
_reserve.decreaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
_principalBalance,
|
||||
_user.stableBorrowRate
|
||||
);
|
||||
} else if (previousRateMode == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
_reserve.decreaseTotalBorrowsVariable(_principalBalance);
|
||||
}
|
||||
|
||||
uint256 newPrincipalAmount = _principalBalance.add(_balanceIncrease).add(_amountBorrowed);
|
||||
if (_newBorrowRateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
_reserve.increaseTotalBorrowsStableAndUpdateAverageRate(
|
||||
newPrincipalAmount,
|
||||
_reserve.currentStableBorrowRate
|
||||
);
|
||||
} else if (_newBorrowRateMode == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
_reserve.increaseTotalBorrowsVariable(newPrincipalAmount);
|
||||
} else {
|
||||
revert("Invalid new borrow rate mode");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the reserve current stable borrow rate Rf, the current variable borrow rate Rv and the current liquidity rate Rl.
|
||||
* Also updates the lastUpdateTimestamp value. Please refer to the whitepaper for further information.
|
||||
|
@ -321,7 +131,7 @@ library ReserveLogic {
|
|||
uint256 _liquidityAdded,
|
||||
uint256 _liquidityTaken
|
||||
) internal {
|
||||
uint256 currentAvgStableRate = _reserve.currentAverageStableBorrowRate;
|
||||
uint256 currentAvgStableRate = IStableDebtToken(_reserve.stableDebtTokenAddress).getAverageStableRate();
|
||||
|
||||
uint256 balance = IERC20(_reserveAddress).universalBalanceOf(address(this));
|
||||
|
||||
|
@ -337,8 +147,8 @@ library ReserveLogic {
|
|||
.calculateInterestRates(
|
||||
_reserveAddress,
|
||||
balance.add(_liquidityAdded).sub(_liquidityTaken),
|
||||
_reserve.totalBorrowsStable,
|
||||
_reserve.totalBorrowsVariable,
|
||||
IERC20(_reserve.stableDebtTokenAddress).totalSupply(),
|
||||
IERC20(_reserve.variableDebtTokenAddress).totalSupply(),
|
||||
currentAvgStableRate
|
||||
);
|
||||
|
||||
|
|
|
@ -1,273 +1,65 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {CoreLibrary} from "./CoreLibrary.sol";
|
||||
import {IPriceOracleGetter} from "../interfaces/IPriceOracleGetter.sol";
|
||||
import {IFeeProvider} from "../interfaces/IFeeProvider.sol";
|
||||
import {CoreLibrary} from './CoreLibrary.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
|
||||
|
||||
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
|
||||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import "../tokenization/base/DebtTokenBase.sol";
|
||||
|
||||
/**
|
||||
* @title UserLogic library
|
||||
* @author Aave
|
||||
* @notice Implements user specific logic.
|
||||
*/
|
||||
* @title UserLogic library
|
||||
* @author Aave
|
||||
* @notice Implements user specific logic.
|
||||
*/
|
||||
library UserLogic {
|
||||
using CoreLibrary for CoreLibrary.UserReserveData;
|
||||
using CoreLibrary for CoreLibrary.ReserveData;
|
||||
using SafeMath for uint256;
|
||||
using CoreLibrary for CoreLibrary.UserReserveData;
|
||||
using CoreLibrary for CoreLibrary.ReserveData;
|
||||
using SafeMath for uint256;
|
||||
|
||||
/**
|
||||
* @dev checks if a user is allowed to borrow at a stable rate
|
||||
* @param _reserve the reserve address
|
||||
* @param _user the user
|
||||
* @param _amount the amount the the user wants to borrow
|
||||
* @return true if the user is allowed to borrow at a stable rate, false otherwise
|
||||
**/
|
||||
/**
|
||||
* @dev checks if a user is allowed to borrow at a stable rate
|
||||
* @param _reserve the reserve address
|
||||
* @param _user the user
|
||||
* @param _amount the amount the the user wants to borrow
|
||||
* @return true if the user is allowed to borrow at a stable rate, false otherwise
|
||||
**/
|
||||
|
||||
function isAllowedToBorrowAtStable(
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
address _userAddress,
|
||||
uint256 _amount
|
||||
) external view returns (bool) {
|
||||
if (!_reserve.isStableBorrowRateEnabled) return false;
|
||||
function isAllowedToBorrowAtStable(
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
address _userAddress,
|
||||
uint256 _amount
|
||||
) external view returns (bool) {
|
||||
if (!_reserve.isStableBorrowRateEnabled) return false;
|
||||
|
||||
return
|
||||
!_user.useAsCollateral ||
|
||||
!_reserve.usageAsCollateralEnabled ||
|
||||
_amount > IERC20(_reserve.aTokenAddress).balanceOf(_userAddress);
|
||||
}
|
||||
return
|
||||
!_user.useAsCollateral ||
|
||||
!_reserve.usageAsCollateralEnabled ||
|
||||
_amount > IERC20(_reserve.aTokenAddress).balanceOf(_userAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev users with no loans in progress have NONE as borrow rate mode
|
||||
* @param _user the address of the user for which the information is needed
|
||||
* @return the borrow rate mode for the user,
|
||||
**/
|
||||
function getUserBorrowBalances(address _user,CoreLibrary.ReserveData storage _reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
IERC20(_reserve.stableDebtTokenAddress).balanceOf(_user),
|
||||
IERC20(_reserve.variableDebtTokenAddress).balanceOf(_user)
|
||||
);
|
||||
}
|
||||
|
||||
function getCurrentBorrowRateMode(CoreLibrary.UserReserveData storage _user)
|
||||
internal
|
||||
view
|
||||
returns (CoreLibrary.InterestRateMode)
|
||||
{
|
||||
if (_user.principalBorrowBalance == 0) {
|
||||
return CoreLibrary.InterestRateMode.NONE;
|
||||
}
|
||||
|
||||
return
|
||||
_user.stableBorrowRate > 0
|
||||
? CoreLibrary.InterestRateMode.STABLE
|
||||
: CoreLibrary.InterestRateMode.VARIABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev gets the current borrow rate of the user
|
||||
* @param _reserve the address of the reserve for which the information is needed
|
||||
* @param _user the address of the user for which the information is needed
|
||||
* @return the borrow rate for the user,
|
||||
**/
|
||||
function getCurrentBorrowRate(
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
CoreLibrary.ReserveData storage _reserve
|
||||
) public view returns (uint256) {
|
||||
CoreLibrary.InterestRateMode rateMode = getCurrentBorrowRateMode(_user);
|
||||
|
||||
if (rateMode == CoreLibrary.InterestRateMode.NONE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return
|
||||
rateMode == CoreLibrary.InterestRateMode.STABLE
|
||||
? _user.stableBorrowRate
|
||||
: _reserve.currentVariableBorrowRate;
|
||||
}
|
||||
/**
|
||||
* @dev calculates and returns the borrow balances of the user
|
||||
* @param _reserve the address of the reserve
|
||||
* @param _user the address of the user
|
||||
* @return the principal borrow balance, the compounded balance and the balance increase since the last borrow/repay/swap/rebalance
|
||||
**/
|
||||
function getBorrowBalances(
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
CoreLibrary.ReserveData storage _reserve
|
||||
) public view returns (uint256, uint256, uint256) {
|
||||
if (_user.principalBorrowBalance == 0) {
|
||||
return (0, 0, 0);
|
||||
}
|
||||
|
||||
uint256 principal = _user.principalBorrowBalance;
|
||||
uint256 compoundedBalance = CoreLibrary.getCompoundedBorrowBalance(_user, _reserve);
|
||||
return (principal, compoundedBalance, compoundedBalance.sub(principal));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the state of a user as a consequence of a borrow action.
|
||||
* @param _reserve the address of the reserve on which the user is borrowing
|
||||
* @param _user the address of the borrower
|
||||
* @param _amountBorrowed the amount borrowed
|
||||
* @param _balanceIncrease the accrued interest of the user on the previous borrowed amount
|
||||
* @param _rateMode the borrow rate mode (stable, variable)
|
||||
**/
|
||||
|
||||
function updateStateOnBorrow(
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
uint256 _amountBorrowed,
|
||||
uint256 _balanceIncrease,
|
||||
uint256 _fee,
|
||||
CoreLibrary.InterestRateMode _rateMode
|
||||
) external {
|
||||
if (_rateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
//stable
|
||||
//reset the user variable index, and update the stable rate
|
||||
_user.stableBorrowRate = _reserve.currentStableBorrowRate;
|
||||
_user.lastVariableBorrowCumulativeIndex = 0;
|
||||
} else if (_rateMode == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
//variable
|
||||
//reset the user stable rate, and store the new borrow index
|
||||
_user.stableBorrowRate = 0;
|
||||
_user.lastVariableBorrowCumulativeIndex = _reserve.lastVariableBorrowCumulativeIndex;
|
||||
} else {
|
||||
revert("Invalid borrow rate mode");
|
||||
}
|
||||
//increase the principal borrows and the origination fee
|
||||
_user.principalBorrowBalance = _user.principalBorrowBalance.add(_amountBorrowed).add(
|
||||
_balanceIncrease
|
||||
);
|
||||
_user.originationFee = _user.originationFee.add(_fee);
|
||||
|
||||
//solium-disable-next-line
|
||||
_user.lastUpdateTimestamp = uint40(block.timestamp);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the state of the user as a consequence of a repay action.
|
||||
* @param _reserve the address of the reserve on which the user is repaying
|
||||
* @param _user the address of the borrower
|
||||
* @param _paybackAmountMinusFees the amount being paid back minus fees
|
||||
* @param _originationFeeRepaid the fee on the amount that is being repaid
|
||||
* @param _balanceIncrease the accrued interest on the borrowed amount
|
||||
* @param _repaidWholeLoan true if the user is repaying the whole loan
|
||||
**/
|
||||
function updateStateOnRepay(
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
uint256 _paybackAmountMinusFees,
|
||||
uint256 _originationFeeRepaid,
|
||||
uint256 _balanceIncrease,
|
||||
bool _repaidWholeLoan
|
||||
) external {
|
||||
//update the user principal borrow balance, adding the cumulated interest and then subtracting the payback amount
|
||||
_user.principalBorrowBalance = _user.principalBorrowBalance.add(_balanceIncrease).sub(
|
||||
_paybackAmountMinusFees
|
||||
);
|
||||
|
||||
//if the balance decrease is equal to the previous principal (user is repaying the whole loan)
|
||||
//and the rate mode is stable, we reset the interest rate mode of the user
|
||||
if (_repaidWholeLoan) {
|
||||
_user.stableBorrowRate = 0;
|
||||
_user.lastVariableBorrowCumulativeIndex = 0;
|
||||
//solium-disable-next-line
|
||||
_user.lastUpdateTimestamp = 0;
|
||||
} else {
|
||||
if (getCurrentBorrowRateMode(_user) == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
_user.lastVariableBorrowCumulativeIndex = _reserve
|
||||
.lastVariableBorrowCumulativeIndex;
|
||||
}
|
||||
//solium-disable-next-line
|
||||
_user.lastUpdateTimestamp = uint40(block.timestamp);
|
||||
|
||||
}
|
||||
|
||||
_user.originationFee = _user.originationFee.sub(_originationFeeRepaid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the state of the user as a consequence of a swap rate action.
|
||||
* @param _reserve the address of the reserve on which the user is performing the swap
|
||||
* @param _user the address of the borrower
|
||||
* @param _balanceIncrease the accrued interest on the borrowed amount
|
||||
* @param _currentRateMode the current rate mode of the user
|
||||
**/
|
||||
|
||||
function updateStateOnSwapRate(
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
uint256 _balanceIncrease,
|
||||
CoreLibrary.InterestRateMode _currentRateMode
|
||||
) external returns (CoreLibrary.InterestRateMode) {
|
||||
CoreLibrary.InterestRateMode newMode = CoreLibrary.InterestRateMode.NONE;
|
||||
|
||||
if (_currentRateMode == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
//switch to stable
|
||||
newMode = CoreLibrary.InterestRateMode.STABLE;
|
||||
_user.stableBorrowRate = _reserve.currentStableBorrowRate;
|
||||
_user.lastVariableBorrowCumulativeIndex = 0;
|
||||
} else if (_currentRateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
newMode = CoreLibrary.InterestRateMode.VARIABLE;
|
||||
_user.stableBorrowRate = 0;
|
||||
_user.lastVariableBorrowCumulativeIndex = _reserve.lastVariableBorrowCumulativeIndex;
|
||||
} else {
|
||||
revert("Invalid interest rate mode received");
|
||||
}
|
||||
//compounding cumulated interest
|
||||
_user.principalBorrowBalance = _user.principalBorrowBalance.add(_balanceIncrease);
|
||||
//solium-disable-next-line
|
||||
_user.lastUpdateTimestamp = uint40(block.timestamp);
|
||||
|
||||
return newMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the state of the user being liquidated as a consequence of a liquidation action.
|
||||
* @param _reserve the address of the principal reserve that is being repaid
|
||||
* @param _user the address of the borrower
|
||||
* @param _amountToLiquidate the amount being repaid by the liquidator
|
||||
* @param _feeLiquidated the amount of origination fee being liquidated
|
||||
* @param _balanceIncrease the accrued interest on the borrowed amount
|
||||
**/
|
||||
function updateStateOnLiquidation(
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
uint256 _amountToLiquidate,
|
||||
uint256 _feeLiquidated,
|
||||
uint256 _balanceIncrease
|
||||
) external {
|
||||
//first increase by the compounded interest, then decrease by the liquidated amount
|
||||
_user.principalBorrowBalance = _user.principalBorrowBalance.add(_balanceIncrease).sub(
|
||||
_amountToLiquidate
|
||||
);
|
||||
|
||||
if (getCurrentBorrowRateMode(_user) == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
_user.lastVariableBorrowCumulativeIndex = _reserve.lastVariableBorrowCumulativeIndex;
|
||||
}
|
||||
|
||||
if (_feeLiquidated > 0) {
|
||||
_user.originationFee = _user.originationFee.sub(_feeLiquidated);
|
||||
}
|
||||
|
||||
//solium-disable-next-line
|
||||
_user.lastUpdateTimestamp = uint40(block.timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the state of the user as a consequence of a stable rate rebalance
|
||||
* @param _reserve the address of the principal reserve where the user borrowed
|
||||
* @param _user the address of the borrower
|
||||
* @param _balanceIncrease the accrued interest on the borrowed amount
|
||||
**/
|
||||
|
||||
function updateUserStateOnRebalanceInternal(
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
uint256 _balanceIncrease
|
||||
) external {
|
||||
_user.principalBorrowBalance = _user.principalBorrowBalance.add(_balanceIncrease);
|
||||
_user.stableBorrowRate = _reserve.currentStableBorrowRate;
|
||||
|
||||
//solium-disable-next-line
|
||||
_user.lastUpdateTimestamp = uint40(block.timestamp);
|
||||
}
|
||||
function getUserPrincipalBorrowBalances(address _user,CoreLibrary.ReserveData storage _reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
DebtTokenBase(_reserve.stableDebtTokenAddress).principalBalanceOf(_user),
|
||||
DebtTokenBase(_reserve.variableDebtTokenAddress).principalBalanceOf(_user)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,310 +1,317 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
|
||||
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
|
||||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import {CoreLibrary} from './CoreLibrary.sol';
|
||||
import {ReserveLogic} from './ReserveLogic.sol';
|
||||
import {UserLogic} from './UserLogic.sol';
|
||||
import {GenericLogic} from './GenericLogic.sol';
|
||||
import {WadRayMath} from './WadRayMath.sol';
|
||||
import {UniversalERC20} from './UniversalERC20.sol';
|
||||
|
||||
import {CoreLibrary} from "./CoreLibrary.sol";
|
||||
import {ReserveLogic} from "./ReserveLogic.sol";
|
||||
import {UserLogic} from "./UserLogic.sol";
|
||||
import {GenericLogic} from "./GenericLogic.sol";
|
||||
import {WadRayMath} from "./WadRayMath.sol";
|
||||
import {UniversalERC20} from "./UniversalERC20.sol";
|
||||
|
||||
import {IPriceOracleGetter} from "../interfaces/IPriceOracleGetter.sol";
|
||||
import {IFeeProvider} from "../interfaces/IFeeProvider.sol";
|
||||
import "@nomiclabs/buidler/console.sol";
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveLogic library
|
||||
* @author Aave
|
||||
* @notice Implements functions to validate specific action on the protocol.
|
||||
*/
|
||||
* @title ReserveLogic library
|
||||
* @author Aave
|
||||
* @notice Implements functions to validate specific action on the protocol.
|
||||
*/
|
||||
library ValidationLogic {
|
||||
using ReserveLogic for CoreLibrary.ReserveData;
|
||||
using UserLogic for CoreLibrary.UserReserveData;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using UniversalERC20 for IERC20;
|
||||
using ReserveLogic for CoreLibrary.ReserveData;
|
||||
using UserLogic for CoreLibrary.UserReserveData;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using UniversalERC20 for IERC20;
|
||||
|
||||
/**
|
||||
* @dev validates a deposit.
|
||||
* @param _reserve the reserve state on which the user is depositing
|
||||
* @param _amount the amount to be deposited
|
||||
*/
|
||||
function validateDeposit(CoreLibrary.ReserveData storage _reserve, uint256 _amount)
|
||||
external
|
||||
view
|
||||
{
|
||||
internalValidateReserveStateAndAmount(_reserve, _amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev validates a redeem.
|
||||
* @param _reserve the reserve state from which the user is redeeming
|
||||
* @param _reserveAddress the address of the reserve
|
||||
* @param _amount the amount to be redeemed
|
||||
*/
|
||||
function validateRedeem(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
address _reserveAddress,
|
||||
uint256 _amount
|
||||
) external view {
|
||||
internalValidateReserveStateAndAmount(_reserve, _amount);
|
||||
|
||||
require(msg.sender == _reserve.aTokenAddress, '31');
|
||||
|
||||
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).universalBalanceOf(address(this));
|
||||
require(currentAvailableLiquidity >= _amount, '4');
|
||||
}
|
||||
|
||||
struct ValidateBorrowLocalVars {
|
||||
uint256 principalBorrowBalance;
|
||||
uint256 currentLtv;
|
||||
uint256 currentLiquidationThreshold;
|
||||
uint256 requestedBorrowAmountETH;
|
||||
uint256 amountOfCollateralNeededETH;
|
||||
uint256 userCollateralBalanceETH;
|
||||
uint256 userBorrowBalanceETH;
|
||||
uint256 userTotalFeesETH;
|
||||
uint256 borrowBalanceIncrease;
|
||||
uint256 currentReserveStableRate;
|
||||
uint256 availableLiquidity;
|
||||
uint256 finalUserBorrowRate;
|
||||
uint256 healthFactor;
|
||||
CoreLibrary.InterestRateMode rateMode;
|
||||
bool healthFactorBelowThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev validates a borrow.
|
||||
* @param _reserve the reserve state from which the user is borrowing
|
||||
* @param _user the state of the user for the specific reserve
|
||||
* @param _reserveAddress the address of the reserve
|
||||
* @param _amount the amount to be borrowed
|
||||
* @param _amountInETH the amount to be borrowed, in ETH
|
||||
* @param _interestRateMode the interest rate mode at which the user is borrowing
|
||||
* @param _borrowFee the fee
|
||||
* @param _maxStableLoanPercent the max amount of the liquidity that can be borrowed at stable rate, in percentage
|
||||
* @param _reservesData the state of all the reserves
|
||||
* @param _usersData the state of all the users for all the reserves
|
||||
* @param _reserves the addresses of all the active reserves
|
||||
* @param _oracle the price oracle
|
||||
*/
|
||||
|
||||
function validateBorrow(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
address _reserveAddress,
|
||||
uint256 _amount,
|
||||
uint256 _amountInETH,
|
||||
uint256 _interestRateMode,
|
||||
uint256 _borrowFee,
|
||||
uint256 _maxStableLoanPercent,
|
||||
mapping(address => CoreLibrary.ReserveData) storage _reservesData,
|
||||
mapping(address => mapping(address => CoreLibrary.UserReserveData)) storage _usersData,
|
||||
address[] calldata _reserves,
|
||||
address _oracle
|
||||
) external view {
|
||||
ValidateBorrowLocalVars memory vars;
|
||||
|
||||
internalValidateReserveStateAndAmount(_reserve, _amount);
|
||||
|
||||
require(_reserve.borrowingEnabled, '5');
|
||||
|
||||
//validate interest rate mode
|
||||
require(
|
||||
uint256(CoreLibrary.InterestRateMode.VARIABLE) == _interestRateMode ||
|
||||
uint256(CoreLibrary.InterestRateMode.STABLE) == _interestRateMode,
|
||||
'Invalid interest rate mode selected'
|
||||
);
|
||||
|
||||
//check that the amount is available in the reserve
|
||||
vars.availableLiquidity = IERC20(_reserveAddress).universalBalanceOf(address(this));
|
||||
|
||||
require(vars.availableLiquidity >= _amount, '7');
|
||||
|
||||
(
|
||||
vars.userCollateralBalanceETH,
|
||||
vars.userBorrowBalanceETH,
|
||||
vars.userTotalFeesETH,
|
||||
vars.currentLtv,
|
||||
vars.currentLiquidationThreshold,
|
||||
vars.healthFactor
|
||||
) = GenericLogic.calculateUserAccountData(
|
||||
msg.sender,
|
||||
_reservesData,
|
||||
_usersData,
|
||||
_reserves,
|
||||
_oracle
|
||||
);
|
||||
|
||||
require(vars.userCollateralBalanceETH > 0, 'The collateral balance is 0');
|
||||
|
||||
require(vars.healthFactor > GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD, '8');
|
||||
|
||||
require(_borrowFee > 0, 'The amount to borrow is too small');
|
||||
|
||||
//add the current already borrowed amount to the amount requested to calculate the total collateral needed.
|
||||
vars.amountOfCollateralNeededETH = vars
|
||||
.userBorrowBalanceETH
|
||||
.add(vars.userTotalFeesETH)
|
||||
.add(_amountInETH)
|
||||
.mul(100)
|
||||
.div(vars.currentLtv); //LTV is calculated in percentage
|
||||
|
||||
require(
|
||||
vars.amountOfCollateralNeededETH <= vars.userCollateralBalanceETH,
|
||||
'There is not enough collateral to cover a new borrow'
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev validates a deposit.
|
||||
* @param _reserve the reserve state on which the user is depositing
|
||||
* @param _amount the amount to be deposited
|
||||
*/
|
||||
function validateDeposit(CoreLibrary.ReserveData storage _reserve, uint256 _amount)
|
||||
external
|
||||
view
|
||||
{
|
||||
internalValidateReserveStateAndAmount(_reserve, _amount);
|
||||
* Following conditions need to be met if the user is borrowing at a stable rate:
|
||||
* 1. Reserve must be enabled for stable rate borrowing
|
||||
* 2. Users cannot borrow from the reserve if their collateral is (mostly) the same currency
|
||||
* they are borrowing, to prevent abuses.
|
||||
* 3. Users will be able to borrow only a relatively small, configurable amount of the total
|
||||
* liquidity
|
||||
**/
|
||||
|
||||
if (vars.rateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
//check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve
|
||||
|
||||
require(_reserve.isStableBorrowRateEnabled, '11');
|
||||
|
||||
require(
|
||||
!_user.useAsCollateral ||
|
||||
!_reserve.usageAsCollateralEnabled ||
|
||||
_amount > IERC20(_reserve.aTokenAddress).balanceOf(msg.sender),
|
||||
'12'
|
||||
);
|
||||
|
||||
//calculate the max available loan size in stable rate mode as a percentage of the
|
||||
//available liquidity
|
||||
uint256 maxLoanSizeStable = vars.availableLiquidity.mul(_maxStableLoanPercent).div(100);
|
||||
|
||||
require(_amount <= maxLoanSizeStable, '13');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev validates a redeem.
|
||||
* @param _reserve the reserve state from which the user is redeeming
|
||||
* @param _reserveAddress the address of the reserve
|
||||
* @param _amount the amount to be redeemed
|
||||
*/
|
||||
function validateRedeem(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
address _reserveAddress,
|
||||
uint256 _amount
|
||||
) external view {
|
||||
internalValidateReserveStateAndAmount(_reserve, _amount);
|
||||
/**
|
||||
* @dev validates a repay.
|
||||
* @param _reserve the reserve state from which the user is repaying
|
||||
* @param _reserveAddress the address of the reserve
|
||||
* @param _amountSent the amount sent for the repayment. Can be an actual value or uint(-1)
|
||||
* @param _onBehalfOf the address of the user msg.sender is repaying for
|
||||
* @param _stableBorrowBalance the borrow balance of the user
|
||||
* @param _variableBorrowBalance the borrow balance of the user
|
||||
* @param _actualPaybackAmount the actual amount being repaid
|
||||
* @param _msgValue the value passed to the repay() function
|
||||
*/
|
||||
function validateRepay(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
address _reserveAddress,
|
||||
uint256 _amountSent,
|
||||
CoreLibrary.InterestRateMode _rateMode,
|
||||
address _onBehalfOf,
|
||||
uint256 _stableBorrowBalance,
|
||||
uint256 _variableBorrowBalance,
|
||||
uint256 _actualPaybackAmount,
|
||||
uint256 _msgValue
|
||||
) external view {
|
||||
require(_reserve.isActive, 'Action requires an active reserve');
|
||||
|
||||
require(msg.sender == _reserve.aTokenAddress, "31");
|
||||
require(_amountSent > 0, 'Amount must be greater than 0');
|
||||
|
||||
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).universalBalanceOf(
|
||||
address(this)
|
||||
);
|
||||
require(currentAvailableLiquidity >= _amount, "4");
|
||||
require(
|
||||
(_stableBorrowBalance > 0 &&
|
||||
CoreLibrary.InterestRateMode(_rateMode) == CoreLibrary.InterestRateMode.STABLE) ||
|
||||
(_variableBorrowBalance > 0 &&
|
||||
CoreLibrary.InterestRateMode(_rateMode) == CoreLibrary.InterestRateMode.VARIABLE),
|
||||
'16'
|
||||
);
|
||||
|
||||
require(
|
||||
_amountSent != uint256(-1) || msg.sender == _onBehalfOf,
|
||||
'To repay on behalf of an user an explicit amount to repay is needed'
|
||||
);
|
||||
|
||||
require(
|
||||
!IERC20(_reserveAddress).isETH() || _msgValue >= _actualPaybackAmount,
|
||||
'Invalid msg.value sent for the repayment'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev validates a swap of borrow rate mode.
|
||||
* @param _reserve the reserve state on which the user is swapping the rate
|
||||
* @param _user the user state for the reserve on which user is swapping the rate
|
||||
* @param _borrowBalance the borrow balance of the user
|
||||
* @param _currentRateMode the rate mode of the borrow
|
||||
*/
|
||||
function validateSwapRateMode(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
uint256 _borrowBalance,
|
||||
CoreLibrary.InterestRateMode _currentRateMode
|
||||
) external view {
|
||||
require(_reserve.isActive, 'Action requires an active reserve');
|
||||
require(!_reserve.isFreezed, 'Action requires an unfreezed reserve');
|
||||
require(_borrowBalance > 0, 'User does not have a borrow in progress on this reserve');
|
||||
|
||||
if (_currentRateMode == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
/**
|
||||
* user wants to swap to stable, before swapping we need to ensure that
|
||||
* 1. stable borrow rate is enabled on the reserve
|
||||
* 2. user is not trying to abuse the reserve by depositing
|
||||
* more collateral than he is borrowing, artificially lowering
|
||||
* the interest rate, borrowing at variable, and switching to stable
|
||||
**/
|
||||
require(_reserve.isStableBorrowRateEnabled, '11');
|
||||
|
||||
require(
|
||||
!_user.useAsCollateral ||
|
||||
!_reserve.usageAsCollateralEnabled ||
|
||||
_borrowBalance > IERC20(_reserve.aTokenAddress).balanceOf(msg.sender),
|
||||
'12'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev validates the choice of a user of setting (or not) an asset as collateral
|
||||
* @param _reserve the state of the reserve that the user is enabling or disabling as collateral
|
||||
* @param _reserveAddress the address of the reserve
|
||||
* @param _reservesData the data of all the reserves
|
||||
* @param _usersData the data of all the users
|
||||
*/
|
||||
function validateSetUseReserveAsCollateral(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
address _reserveAddress,
|
||||
mapping(address => CoreLibrary.ReserveData) storage _reservesData,
|
||||
mapping(address => mapping(address => CoreLibrary.UserReserveData)) storage _usersData,
|
||||
address[] calldata _reserves,
|
||||
address _oracle
|
||||
) external view {
|
||||
uint256 underlyingBalance = IERC20(_reserve.aTokenAddress).balanceOf(msg.sender);
|
||||
|
||||
struct ValidateBorrowLocalVars {
|
||||
uint256 principalBorrowBalance;
|
||||
uint256 currentLtv;
|
||||
uint256 currentLiquidationThreshold;
|
||||
uint256 requestedBorrowAmountETH;
|
||||
uint256 amountOfCollateralNeededETH;
|
||||
uint256 userCollateralBalanceETH;
|
||||
uint256 userBorrowBalanceETH;
|
||||
uint256 userTotalFeesETH;
|
||||
uint256 borrowBalanceIncrease;
|
||||
uint256 currentReserveStableRate;
|
||||
uint256 availableLiquidity;
|
||||
uint256 finalUserBorrowRate;
|
||||
uint256 healthFactor;
|
||||
CoreLibrary.InterestRateMode rateMode;
|
||||
bool healthFactorBelowThreshold;
|
||||
}
|
||||
require(underlyingBalance > 0, '22');
|
||||
|
||||
/**
|
||||
* @dev validates a borrow.
|
||||
* @param _reserve the reserve state from which the user is borrowing
|
||||
* @param _user the state of the user for the specific reserve
|
||||
* @param _reserveAddress the address of the reserve
|
||||
* @param _amount the amount to be borrowed
|
||||
* @param _amountInETH the amount to be borrowed, in ETH
|
||||
* @param _interestRateMode the interest rate mode at which the user is borrowing
|
||||
* @param _borrowFee the fee
|
||||
* @param _maxStableLoanPercent the max amount of the liquidity that can be borrowed at stable rate, in percentage
|
||||
* @param _reservesData the state of all the reserves
|
||||
* @param _usersData the state of all the users for all the reserves
|
||||
* @param _reserves the addresses of all the active reserves
|
||||
* @param _oracle the price oracle
|
||||
*/
|
||||
require(
|
||||
GenericLogic.balanceDecreaseAllowed(
|
||||
_reserveAddress,
|
||||
msg.sender,
|
||||
underlyingBalance,
|
||||
_reservesData,
|
||||
_usersData,
|
||||
_reserves,
|
||||
_oracle
|
||||
),
|
||||
'User deposit is already being used as collateral'
|
||||
);
|
||||
}
|
||||
|
||||
function validateBorrow(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
address _reserveAddress,
|
||||
uint256 _amount,
|
||||
uint256 _amountInETH,
|
||||
uint256 _interestRateMode,
|
||||
uint256 _borrowFee,
|
||||
uint256 _maxStableLoanPercent,
|
||||
mapping(address => CoreLibrary.ReserveData) storage _reservesData,
|
||||
mapping(address => mapping(address => CoreLibrary.UserReserveData)) storage _usersData,
|
||||
address[] calldata _reserves,
|
||||
address _oracle
|
||||
) external view {
|
||||
|
||||
ValidateBorrowLocalVars memory vars;
|
||||
|
||||
internalValidateReserveStateAndAmount(_reserve, _amount);
|
||||
|
||||
require(_reserve.borrowingEnabled, "5");
|
||||
|
||||
//validate interest rate mode
|
||||
require(
|
||||
uint256(CoreLibrary.InterestRateMode.VARIABLE) == _interestRateMode ||
|
||||
uint256(CoreLibrary.InterestRateMode.STABLE) == _interestRateMode,
|
||||
"Invalid interest rate mode selected"
|
||||
);
|
||||
|
||||
//check that the amount is available in the reserve
|
||||
vars.availableLiquidity = IERC20(_reserveAddress).universalBalanceOf(address(this));
|
||||
|
||||
require(vars.availableLiquidity >= _amount, "7");
|
||||
|
||||
(
|
||||
vars.userCollateralBalanceETH,
|
||||
vars.userBorrowBalanceETH,
|
||||
vars.userTotalFeesETH,
|
||||
vars.currentLtv,
|
||||
vars.currentLiquidationThreshold,
|
||||
vars.healthFactor
|
||||
) = GenericLogic.calculateUserAccountData(
|
||||
msg.sender,
|
||||
_reservesData,
|
||||
_usersData,
|
||||
_reserves,
|
||||
_oracle
|
||||
);
|
||||
|
||||
require(vars.userCollateralBalanceETH > 0, "The collateral balance is 0");
|
||||
|
||||
require(vars.healthFactor > GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD, "8");
|
||||
|
||||
require(_borrowFee > 0, "The amount to borrow is too small");
|
||||
|
||||
//add the current already borrowed amount to the amount requested to calculate the total collateral needed.
|
||||
vars.amountOfCollateralNeededETH = vars
|
||||
.userBorrowBalanceETH
|
||||
.add(vars.userTotalFeesETH)
|
||||
.add(_amountInETH)
|
||||
.mul(100)
|
||||
.div(vars.currentLtv); //LTV is calculated in percentage
|
||||
|
||||
require(vars.amountOfCollateralNeededETH <= vars.userCollateralBalanceETH, "There is not enough collateral to cover a new borrow");
|
||||
|
||||
/**
|
||||
* Following conditions need to be met if the user is borrowing at a stable rate:
|
||||
* 1. Reserve must be enabled for stable rate borrowing
|
||||
* 2. Users cannot borrow from the reserve if their collateral is (mostly) the same currency
|
||||
* they are borrowing, to prevent abuses.
|
||||
* 3. Users will be able to borrow only a relatively small, configurable amount of the total
|
||||
* liquidity
|
||||
**/
|
||||
|
||||
if (vars.rateMode == CoreLibrary.InterestRateMode.STABLE) {
|
||||
//check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve
|
||||
|
||||
require(_reserve.isStableBorrowRateEnabled, "11");
|
||||
|
||||
require(
|
||||
!_user.useAsCollateral ||
|
||||
!_reserve.usageAsCollateralEnabled ||
|
||||
_amount > IERC20(_reserve.aTokenAddress).balanceOf(msg.sender),
|
||||
"12"
|
||||
);
|
||||
|
||||
//calculate the max available loan size in stable rate mode as a percentage of the
|
||||
//available liquidity
|
||||
uint256 maxLoanSizeStable = vars.availableLiquidity.mul(_maxStableLoanPercent).div(100);
|
||||
|
||||
require(_amount <= maxLoanSizeStable, "13");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev validates a repay.
|
||||
* @param _reserve the reserve state from which the user is repaying
|
||||
* @param _reserveAddress the address of the reserve
|
||||
* @param _amountSent the amount sent for the repayment. Can be an actual value or uint(-1)
|
||||
* @param _onBehalfOf the address of the user msg.sender is repaying for
|
||||
* @param _borrowBalance the borrow balance of the user
|
||||
* @param _actualPaybackAmount the actual amount being repaid
|
||||
* @param _msgValue the value passed to the repay() function
|
||||
*/
|
||||
function validateRepay(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
address _reserveAddress,
|
||||
uint256 _amountSent,
|
||||
address _onBehalfOf,
|
||||
uint256 _borrowBalance,
|
||||
uint256 _actualPaybackAmount,
|
||||
uint256 _msgValue
|
||||
) external view {
|
||||
require(_reserve.isActive, "Action requires an active reserve");
|
||||
|
||||
require(_amountSent > 0, "Amount must be greater than 0");
|
||||
|
||||
require(_borrowBalance > 0, "16");
|
||||
|
||||
require(_amountSent != uint256(-1) || msg.sender == _onBehalfOf, "To repay on behalf of an user an explicit amount to repay is needed");
|
||||
|
||||
require(!IERC20(_reserveAddress).isETH() || _msgValue >= _actualPaybackAmount, "Invalid msg.value sent for the repayment");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev validates a swap of borrow rate mode.
|
||||
* @param _reserve the reserve state on which the user is swapping the rate
|
||||
* @param _user the user state for the reserve on which user is swapping the rate
|
||||
* @param _borrowBalance the borrow balance of the user
|
||||
* @param _currentRateMode the rate mode of the borrow
|
||||
*/
|
||||
function validateSwapRateMode(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
CoreLibrary.UserReserveData storage _user,
|
||||
uint256 _borrowBalance,
|
||||
CoreLibrary.InterestRateMode _currentRateMode
|
||||
) external view {
|
||||
require(_reserve.isActive, "Action requires an active reserve");
|
||||
require(!_reserve.isFreezed, "Action requires an unfreezed reserve");
|
||||
require(_borrowBalance > 0, "User does not have a borrow in progress on this reserve");
|
||||
|
||||
if (_currentRateMode == CoreLibrary.InterestRateMode.VARIABLE) {
|
||||
/**
|
||||
* user wants to swap to stable, before swapping we need to ensure that
|
||||
* 1. stable borrow rate is enabled on the reserve
|
||||
* 2. user is not trying to abuse the reserve by depositing
|
||||
* more collateral than he is borrowing, artificially lowering
|
||||
* the interest rate, borrowing at variable, and switching to stable
|
||||
**/
|
||||
require(_reserve.isStableBorrowRateEnabled, "11");
|
||||
|
||||
require(
|
||||
!_user.useAsCollateral ||
|
||||
!_reserve.usageAsCollateralEnabled ||
|
||||
_borrowBalance > IERC20(_reserve.aTokenAddress).balanceOf(msg.sender),
|
||||
"12"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev validates the choice of a user of setting (or not) an asset as collateral
|
||||
* @param _reserve the state of the reserve that the user is enabling or disabling as collateral
|
||||
* @param _reserveAddress the address of the reserve
|
||||
* @param _reservesData the data of all the reserves
|
||||
* @param _usersData the data of all the users
|
||||
*/
|
||||
function validateSetUseReserveAsCollateral(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
address _reserveAddress,
|
||||
mapping(address => CoreLibrary.ReserveData) storage _reservesData,
|
||||
mapping(address => mapping(address => CoreLibrary.UserReserveData)) storage _usersData,
|
||||
address[] calldata _reserves,
|
||||
address _oracle
|
||||
) external view {
|
||||
|
||||
uint256 underlyingBalance = IERC20(_reserve.aTokenAddress).balanceOf(msg.sender);
|
||||
|
||||
require(underlyingBalance > 0, "22");
|
||||
|
||||
require(
|
||||
GenericLogic.balanceDecreaseAllowed(
|
||||
_reserveAddress,
|
||||
msg.sender,
|
||||
underlyingBalance,
|
||||
_reservesData,
|
||||
_usersData,
|
||||
_reserves,
|
||||
_oracle
|
||||
),
|
||||
"User deposit is already being used as collateral"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev validates that the reserve is active and the amount is greater than 0
|
||||
* @param _reserve the state of the reserve being validated
|
||||
* @param _amount the amount being validated
|
||||
*/
|
||||
function internalValidateReserveStateAndAmount(CoreLibrary.ReserveData storage _reserve, uint256 _amount)
|
||||
internal
|
||||
view
|
||||
{
|
||||
require(_reserve.isActive, "Action requires an active reserve");
|
||||
require(!_reserve.isFreezed, "Action requires an unfreezed reserve");
|
||||
require(_amount > 0, "Amount must be greater than 0");
|
||||
|
||||
}
|
||||
/**
|
||||
* @dev validates that the reserve is active and the amount is greater than 0
|
||||
* @param _reserve the state of the reserve being validated
|
||||
* @param _amount the amount being validated
|
||||
*/
|
||||
function internalValidateReserveStateAndAmount(
|
||||
CoreLibrary.ReserveData storage _reserve,
|
||||
uint256 _amount
|
||||
) internal view {
|
||||
require(_reserve.isActive, 'Action requires an active reserve');
|
||||
require(!_reserve.isFreezed, 'Action requires an unfreezed reserve');
|
||||
require(_amount > 0, 'Amount must be greater than 0');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import "../../tokenization/ERC20.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
|
||||
/**
|
||||
* @title ERC20Mintable
|
||||
|
|
177
contracts/tokenization/StableDebtToken.sol
Normal file
177
contracts/tokenization/StableDebtToken.sol
Normal file
|
@ -0,0 +1,177 @@
|
|||
pragma solidity ^0.6.0;
|
||||
|
||||
import '@openzeppelin/contracts/GSN/Context.sol';
|
||||
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import '@openzeppelin/contracts/utils/Address.sol';
|
||||
import {DebtTokenBase} from './base/DebtTokenBase.sol';
|
||||
import {MathUtils} from '../libraries/MathUtils.sol';
|
||||
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
||||
import {IStableDebtToken} from './interfaces/IStableDebtToken.sol';
|
||||
|
||||
contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using Address for address;
|
||||
|
||||
struct UserData {
|
||||
uint256 currentRate;
|
||||
uint40 lastUpdateTimestamp;
|
||||
}
|
||||
|
||||
uint256 private avgStableRate;
|
||||
|
||||
mapping(address => UserData) usersData;
|
||||
|
||||
event mintDebt(
|
||||
address _user,
|
||||
uint256 _amount,
|
||||
uint256 _previousBalance,
|
||||
uint256 _currentBalance,
|
||||
uint256 _balanceIncrease,
|
||||
uint256 _newRate
|
||||
);
|
||||
event burnDebt(
|
||||
address _user,
|
||||
uint256 _amount,
|
||||
uint256 _previousBalance,
|
||||
uint256 _currentBalance,
|
||||
uint256 _balanceIncrease
|
||||
);
|
||||
|
||||
function getAverageStableRate() external virtual override view returns (uint256) {
|
||||
return avgStableRate;
|
||||
}
|
||||
|
||||
function getUserStableRate(address _user) external virtual override view returns (uint256) {
|
||||
return usersData[_user].currentRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-balanceOf}.
|
||||
*/
|
||||
function balanceOf(address account) public virtual override view returns (uint256) {
|
||||
if(balances[account] == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
UserData storage userData = usersData[account];
|
||||
|
||||
uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest(
|
||||
userData.currentRate,
|
||||
userData.lastUpdateTimestamp
|
||||
);
|
||||
return balances[account].wadToRay().rayMul(cumulatedInterest).rayToWad();
|
||||
}
|
||||
|
||||
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
|
||||
* the total supply.
|
||||
*
|
||||
* Emits a {Transfer} event with `from` set to the zero address.
|
||||
*
|
||||
* Requirements
|
||||
*
|
||||
* - `to` cannot be the zero address.
|
||||
*/
|
||||
function mint(
|
||||
address account,
|
||||
uint256 amount,
|
||||
uint256 rate
|
||||
) public override onlyLendingPool {
|
||||
(
|
||||
uint256 previousBalance,
|
||||
uint256 currentBalance,
|
||||
uint256 balanceIncrease
|
||||
) = internalCumulateBalance(account);
|
||||
|
||||
uint256 newSupply = totalSupply.add(amount);
|
||||
|
||||
uint256 amountInRay = amount.wadToRay();
|
||||
|
||||
usersData[account].currentRate = usersData[account]
|
||||
.currentRate
|
||||
.rayMul(currentBalance.wadToRay())
|
||||
.add(amountInRay.wadMul(rate))
|
||||
.rayDiv(currentBalance.add(amount).wadToRay());
|
||||
usersData[account].lastUpdateTimestamp = uint40(block.timestamp);
|
||||
|
||||
avgStableRate = avgStableRate
|
||||
.rayMul(totalSupply.wadToRay())
|
||||
.add(rate.rayMul(amountInRay))
|
||||
.rayDiv(newSupply.wadToRay());
|
||||
|
||||
internalMint(account, amount);
|
||||
|
||||
emit mintDebt(
|
||||
account,
|
||||
amount,
|
||||
previousBalance,
|
||||
currentBalance,
|
||||
balanceIncrease,
|
||||
usersData[account].currentRate
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Destroys `amount` tokens from `account`, reducing the
|
||||
* total supply.
|
||||
*
|
||||
* Emits a {Transfer} event with `to` set to the zero address.
|
||||
*
|
||||
* Requirements
|
||||
*
|
||||
* - `account` cannot be the zero address.
|
||||
* - `account` must have at least `amount` tokens.
|
||||
*/
|
||||
function burn(address _account, uint256 _amount) public override onlyLendingPool {
|
||||
(
|
||||
uint256 previousBalance,
|
||||
uint256 currentBalance,
|
||||
uint256 balanceIncrease
|
||||
) = internalCumulateBalance(_account);
|
||||
|
||||
uint256 newSupply = totalSupply.sub(_amount);
|
||||
|
||||
uint256 amountInRay = _amount.wadToRay();
|
||||
|
||||
if (newSupply == 0) {
|
||||
avgStableRate = 0;
|
||||
} else {
|
||||
avgStableRate = avgStableRate
|
||||
.rayMul(totalSupply.wadToRay())
|
||||
.sub(usersData[_account].currentRate.rayMul(amountInRay))
|
||||
.rayDiv(newSupply.wadToRay());
|
||||
}
|
||||
|
||||
internalBurn(_account, _amount);
|
||||
|
||||
emit burnDebt(_account, _amount, previousBalance, currentBalance, balanceIncrease);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev accumulates the accrued interest of the user to the principal balance
|
||||
* @param _user the address of the user for which the interest is being accumulated
|
||||
* @return the previous principal balance, the new principal balance, the balance increase
|
||||
**/
|
||||
function internalCumulateBalance(address _user)
|
||||
internal
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
uint256
|
||||
)
|
||||
{
|
||||
uint256 previousPrincipalBalance = balances[_user];
|
||||
|
||||
//calculate the accrued interest since the last accumulation
|
||||
uint256 balanceIncrease = balanceOf(_user).sub(previousPrincipalBalance);
|
||||
//mints an amount of tokens equivalent to the amount accumulated
|
||||
internalMint(_user, balanceIncrease);
|
||||
|
||||
return (
|
||||
previousPrincipalBalance,
|
||||
previousPrincipalBalance.add(balanceIncrease),
|
||||
balanceIncrease
|
||||
);
|
||||
}
|
||||
}
|
135
contracts/tokenization/VariableDebtToken.sol
Normal file
135
contracts/tokenization/VariableDebtToken.sol
Normal file
|
@ -0,0 +1,135 @@
|
|||
pragma solidity ^0.6.0;
|
||||
|
||||
import '@openzeppelin/contracts/GSN/Context.sol';
|
||||
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import '@openzeppelin/contracts/utils/Address.sol';
|
||||
import {DebtTokenBase} from './base/DebtTokenBase.sol';
|
||||
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
import {IVariableDebtToken} from './interfaces/IVariableDebtToken.sol';
|
||||
|
||||
|
||||
contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using Address for address;
|
||||
|
||||
mapping(address => uint256) private userIndexes;
|
||||
|
||||
event mintDebt(
|
||||
address _user,
|
||||
uint256 _amount,
|
||||
uint256 _previousBalance,
|
||||
uint256 _currentBalance,
|
||||
uint256 _balanceIncrease,
|
||||
uint256 _index
|
||||
);
|
||||
event burnDebt(
|
||||
address _user,
|
||||
uint256 _amount,
|
||||
uint256 _previousBalance,
|
||||
uint256 _currentBalance,
|
||||
uint256 _balanceIncrease,
|
||||
uint256 _index
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-balanceOf}.
|
||||
*/
|
||||
function balanceOf(address account) public virtual override view returns (uint256) {
|
||||
|
||||
if (balances[account] == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return
|
||||
balances[account]
|
||||
.wadToRay()
|
||||
.rayMul(pool.getReserveNormalizedVariableDebt(underlyingAssetAddress))
|
||||
.rayToWad();
|
||||
}
|
||||
|
||||
function getUserIndex(address _user) public virtual override view returns(uint256) {
|
||||
return userIndexes[_user];
|
||||
}
|
||||
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
|
||||
* the total supply.
|
||||
*
|
||||
* Emits a {Transfer} event with `from` set to the zero address.
|
||||
*
|
||||
* Requirements
|
||||
*
|
||||
* - `to` cannot be the zero address.
|
||||
*/
|
||||
function mint(address account, uint256 amount) public override onlyLendingPool {
|
||||
|
||||
(
|
||||
uint256 previousBalance,
|
||||
uint256 currentBalance,
|
||||
uint256 balanceIncrease,
|
||||
uint256 index
|
||||
) = internalCumulateBalance(account);
|
||||
|
||||
internalMint(account, amount);
|
||||
|
||||
emit mintDebt(account, amount, previousBalance, currentBalance, balanceIncrease, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Destroys `amount` tokens from `account`, reducing the
|
||||
* total supply.
|
||||
*
|
||||
* Emits a {Transfer} event with `to` set to the zero address.
|
||||
*
|
||||
* Requirements
|
||||
*
|
||||
* - `account` cannot be the zero address.
|
||||
* - `account` must have at least `amount` tokens.
|
||||
*/
|
||||
function burn(address account, uint256 amount) public override onlyLendingPool {
|
||||
(
|
||||
uint256 previousBalance,
|
||||
uint256 currentBalance,
|
||||
uint256 balanceIncrease,
|
||||
uint256 index
|
||||
) = internalCumulateBalance(account);
|
||||
|
||||
internalBurn(account, amount);
|
||||
|
||||
emit burnDebt(account, amount, previousBalance, currentBalance, balanceIncrease, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev accumulates the accrued interest of the user to the principal balance
|
||||
* @param _user the address of the user for which the interest is being accumulated
|
||||
* @return the previous principal balance, the new principal balance, the balance increase
|
||||
* and the new user index
|
||||
**/
|
||||
function internalCumulateBalance(address _user)
|
||||
internal
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
uint256,
|
||||
uint256
|
||||
)
|
||||
{
|
||||
uint256 previousPrincipalBalance = balances[_user];
|
||||
|
||||
//calculate the accrued interest since the last accumulation
|
||||
uint256 balanceIncrease = balanceOf(_user).sub(previousPrincipalBalance);
|
||||
//mints an amount of tokens equivalent to the amount accumulated
|
||||
internalMint(_user, balanceIncrease);
|
||||
//updates the user index
|
||||
uint256 index = userIndexes[_user] = pool.getReserveNormalizedVariableDebt(
|
||||
underlyingAssetAddress
|
||||
);
|
||||
return (
|
||||
previousPrincipalBalance,
|
||||
previousPrincipalBalance.add(balanceIncrease),
|
||||
balanceIncrease,
|
||||
index
|
||||
);
|
||||
}
|
||||
}
|
164
contracts/tokenization/base/DebtTokenBase.sol
Normal file
164
contracts/tokenization/base/DebtTokenBase.sol
Normal file
|
@ -0,0 +1,164 @@
|
|||
pragma solidity ^0.6.0;
|
||||
|
||||
import '@openzeppelin/contracts/GSN/Context.sol';
|
||||
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import '@openzeppelin/contracts/utils/Address.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {LendingPool} from '../../lendingpool/LendingPool.sol';
|
||||
|
||||
|
||||
abstract contract DebtTokenBase is IERC20 {
|
||||
using SafeMath for uint256;
|
||||
using Address for address;
|
||||
|
||||
uint256 public override totalSupply;
|
||||
|
||||
string public name;
|
||||
string public symbol;
|
||||
uint8 public decimals;
|
||||
address public underlyingAssetAddress;
|
||||
|
||||
LendingPool internal pool;
|
||||
mapping(address => uint256) internal balances;
|
||||
|
||||
|
||||
|
||||
modifier onlyLendingPool {
|
||||
require(
|
||||
msg.sender == address(pool),
|
||||
"The caller of this function must be a lending pool"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
|
||||
* a default value of 18.
|
||||
*
|
||||
* To select a different value for {decimals}, use {_setupDecimals}.
|
||||
*
|
||||
* All three of these values are immutable: they can only be set once during
|
||||
* construction.
|
||||
*/
|
||||
function init(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
uint8 _decimals,
|
||||
address _underlying,
|
||||
ILendingPoolAddressesProvider _addressesProvider
|
||||
) public {
|
||||
name = _name;
|
||||
symbol = _symbol;
|
||||
decimals = _decimals;
|
||||
underlyingAssetAddress = _underlying;
|
||||
pool = LendingPool(payable(_addressesProvider.getLendingPool()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-balanceOf}.
|
||||
*/
|
||||
function balanceOf(address account) public virtual override view returns (uint256);
|
||||
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-balanceOf}.
|
||||
*/
|
||||
function principalBalanceOf(address account) public view returns (uint256) {
|
||||
return balances[account];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-transfer}.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `recipient` cannot be the zero address.
|
||||
* - the caller must have a balance of at least `amount`.
|
||||
*/
|
||||
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
|
||||
revert('TRANSFER_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-allowance}.
|
||||
*/
|
||||
function allowance(address owner, address spender)
|
||||
public
|
||||
virtual
|
||||
override
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
revert('ALLOWANCE_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-approve}.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `spender` cannot be the zero address.
|
||||
*/
|
||||
function approve(address spender, uint256 amount) public virtual override returns (bool) {
|
||||
revert('APPROVAL_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
function transferFrom(
|
||||
address sender,
|
||||
address recipient,
|
||||
uint256 amount
|
||||
) public virtual override returns (bool) {
|
||||
revert('TRANSFER_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Atomically increases the allowance granted to `spender` by the caller.
|
||||
*
|
||||
* This is an alternative to {approve} that can be used as a mitigation for
|
||||
* problems described in {IERC20-approve}.
|
||||
*
|
||||
* Emits an {Approval} event indicating the updated allowance.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `spender` cannot be the zero address.
|
||||
*/
|
||||
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
|
||||
revert('ALLOWANCE_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Atomically decreases the allowance granted to `spender` by the caller.
|
||||
*
|
||||
* This is an alternative to {approve} that can be used as a mitigation for
|
||||
* problems described in {IERC20-approve}.
|
||||
*
|
||||
* Emits an {Approval} event indicating the updated allowance.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `spender` cannot be the zero address.
|
||||
* - `spender` must have allowance for the caller of at least
|
||||
* `subtractedValue`.
|
||||
*/
|
||||
function decreaseAllowance(address spender, uint256 subtractedValue)
|
||||
public
|
||||
virtual
|
||||
returns (bool)
|
||||
{
|
||||
revert('ALLOWANCE_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
function internalMint(address account, uint256 amount) internal {
|
||||
totalSupply = totalSupply.add(amount);
|
||||
balances[account] = balances[account].add(amount);
|
||||
}
|
||||
|
||||
function internalBurn(address account, uint256 amount) internal {
|
||||
totalSupply = totalSupply.sub(amount);
|
||||
balances[account] = balances[account].sub(amount);
|
||||
}
|
||||
}
|
17
contracts/tokenization/interfaces/IStableDebtToken.sol
Normal file
17
contracts/tokenization/interfaces/IStableDebtToken.sol
Normal file
|
@ -0,0 +1,17 @@
|
|||
pragma solidity ^0.6.0;
|
||||
|
||||
|
||||
interface IStableDebtToken {
|
||||
|
||||
function mint(
|
||||
address account,
|
||||
uint256 amount,
|
||||
uint256 rate
|
||||
) external virtual;
|
||||
|
||||
function burn(address _account, uint256 _amount) external virtual;
|
||||
|
||||
function getAverageStableRate() external virtual view returns(uint256);
|
||||
|
||||
function getUserStableRate(address _user) external virtual view returns(uint256);
|
||||
}
|
11
contracts/tokenization/interfaces/IVariableDebtToken.sol
Normal file
11
contracts/tokenization/interfaces/IVariableDebtToken.sol
Normal file
|
@ -0,0 +1,11 @@
|
|||
pragma solidity ^0.6.0;
|
||||
|
||||
|
||||
interface IVariableDebtToken {
|
||||
|
||||
function mint(address account, uint256 amount) external virtual;
|
||||
|
||||
function burn(address _account, uint256 _amount) external virtual;
|
||||
|
||||
function getUserIndex(address _account) external virtual view returns(uint256);
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x9cbEE5c0A6178F61dcD57C3b21180C8602aBdAc1",
|
||||
"address": "0x749258D38b0473d96FEcc14cC5e7DCE12d7Bd6f6",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -15,7 +15,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xdE00B3eb5e9F867eE45F9B9E5aF0d102Fe6A093f",
|
||||
"address": "0xA29C2A7e59aa49C71aF084695337E3AA5e820758",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -25,7 +25,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x1b52F7d75DA9b64daF2D8ad2E7eaf75205c99d3B",
|
||||
"address": "0x4a2a69879B8fD38371e804eD0415c7A187A6aD13",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -34,7 +34,7 @@
|
|||
"address": "0x852e3718A320aD93Ad8692E8D663d247e4c1b400"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x704e04A46B436335f2024c54373F64863F879532"
|
||||
"address": "0x6DCCc1c1A3b5eD8c3Ef8DA857ed06d806B6Db68A"
|
||||
}
|
||||
},
|
||||
"LendingPoolParametersProvider": {
|
||||
|
@ -52,7 +52,7 @@
|
|||
"address": "0x2C4603396dE2F08642354A3A102760827FfFe113"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x1899Fe21bB5135E792F34fe89F3F47246c92D724"
|
||||
"address": "0xf8EcabD263c539005407C99346E145d046AeC2E7"
|
||||
}
|
||||
},
|
||||
"LendingPoolDataProvider": {
|
||||
|
@ -65,7 +65,7 @@
|
|||
"address": "0xA10958a24032283FbE2D23cedf264d6eC9411CBA"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x4ec19E17FC0A28Dda89a5a96C8f65dfbAE922CA6"
|
||||
"address": "0x2d2F372ba90F87Ac45e93eFEa29c20cDD696e764"
|
||||
}
|
||||
},
|
||||
"PriceOracle": {
|
||||
|
@ -74,7 +74,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x3c3AB51fF33032159e82E1FDEe6503dEd082F1d9",
|
||||
"address": "0x8a854d2cf4f20b72B02e8c0F5781E3C11519d320",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -84,7 +84,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x5B51d8344769d18fB85DF29EDbaB8E94dbA38455",
|
||||
"address": "0xfC6d9227413D021f7a50EF3AAdF9545aA4ebb439",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -94,7 +94,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xd8f831Ef919D3f38694f2797CD44D7Cc7d595A67",
|
||||
"address": "0xdc006C4186148C29B57f52A8ad7694542ad4E675",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -104,17 +104,17 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xc52Df73f1BBe582061C65a2bd36A1d685f0a2BE5",
|
||||
"address": "0x107Aa2cc3FE981E78140424C3d4DD55aF00Ab24C",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
"DefaultReserveInterestRateStrategy": {
|
||||
"buidlerevm": {
|
||||
"address": "0xFf130817Aa9863B3D809A2A11617c05646245d80",
|
||||
"address": "0xC8Df507578fEfb60aA626ABFDDB20B48ee439ad1",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x62ebEd87c709e29EaE50521059e8AF78D893d7D5",
|
||||
"address": "0x77183A4B7c0375bA9A5090Ae68c32A5C567d77c6",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -126,57 +126,57 @@
|
|||
},
|
||||
"MockOneSplit": {
|
||||
"buidlerevm": {
|
||||
"address": "0xe5a5a5b78F165C875EE2264a8743570176eA39d9",
|
||||
"address": "0x4b2c297ba5be42610994974b9543D56B864CA011",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x2A7BE996B8801ED21f2f45148791D402811A2106",
|
||||
"address": "0x5B51d8344769d18fB85DF29EDbaB8E94dbA38455",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
"OneSplitAdapter": {
|
||||
"buidlerevm": {
|
||||
"address": "0x828C9C41Fae6113C1DEA9056Dcd9C85A19002d52",
|
||||
"address": "0x24E420B42971372F060a93129846761F354Bc50B",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xcDfbcd115A4074d3311e6935Cb996b2C62F6F4F9",
|
||||
"address": "0xd8f831Ef919D3f38694f2797CD44D7Cc7d595A67",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
"TokenDistributor": {
|
||||
"buidlerevm": {
|
||||
"address": "0x7d40dD74d3aE1a7e4A7dd08eaE899e85940563cd"
|
||||
"address": "0xb840b4fe440b5E26e1840cd2D6320FAda1C0ca5d"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x8ba99a6fe4101539A3b403603d8C297E8074c4b8"
|
||||
"address": "0xc52Df73f1BBe582061C65a2bd36A1d685f0a2BE5"
|
||||
}
|
||||
},
|
||||
"InitializableAdminUpgradeabilityProxy": {
|
||||
"buidlerevm": {
|
||||
"address": "0x7d40dD74d3aE1a7e4A7dd08eaE899e85940563cd",
|
||||
"address": "0xb840b4fe440b5E26e1840cd2D6320FAda1C0ca5d",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x8ba99a6fe4101539A3b403603d8C297E8074c4b8",
|
||||
"address": "0xc52Df73f1BBe582061C65a2bd36A1d685f0a2BE5",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
"MockFlashLoanReceiver": {
|
||||
"buidlerevm": {
|
||||
"address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6"
|
||||
"address": "0x5c98c9202b73d27A618662d34A6805c34AB041B8"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xe3353ddEc0cf8aA6761a3C21D896D04ebd59bDe2"
|
||||
"address": "0x09157249a5937Bd78fea52CE189887Bd55c13050"
|
||||
}
|
||||
},
|
||||
"WalletBalanceProvider": {
|
||||
"buidlerevm": {
|
||||
"address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d",
|
||||
"address": "0x435250F99d9ec2D7956773c6768392caD183765e",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xa7B8e0F888D416d7e08bD12029c6ec8b8Ed18373",
|
||||
"address": "0x2848E572a05Ed122E538E8d611AB1bb76DF7E98d",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -186,7 +186,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x16b610FCD65E552FAC8c8FC6AC9104E1E00a7B86",
|
||||
"address": "0x79B51482dA73373D7828Ed728F8fC8d3994c4141",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -196,7 +196,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x4A9559FEF44B25F1A7157e047cD09683fe45c599",
|
||||
"address": "0x8eF6CAbcAE15FB78b436e67B26FFE80Ba7ef8424",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -206,7 +206,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x02F36856D11c723A78c91758b6e24b244Cdd05b0",
|
||||
"address": "0xd0FD468D3ff12932f997a8298fe267BE55a9cCC6",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -216,7 +216,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xe94Cb57AD747445c13C08A931F3f1421C540eB5F",
|
||||
"address": "0xA106BFbDB5C925A04358bE49db41aDd308a1458f",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -226,7 +226,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xE2ba935c1b3e833aFD45dA9CBCBDd2e90875ba30",
|
||||
"address": "0x9c91aEaD98b1354C7B0EAfb8ff539d0796c79894",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -236,7 +236,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x377eC146Bd9299cd8f5f35dc22DCdE3623E37ECB",
|
||||
"address": "0x48FAde2E719B770E1783d03466dAEe98b5183538",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -246,7 +246,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x303CEAFd0aF91A63576FF7dEFc01E66ca2D19E3a",
|
||||
"address": "0x145b7B6368Df63e7F3497b0A948B30fC1A4d5E55",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -256,7 +256,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x168ef56fCb0382f4808497C9570434684657A9D3",
|
||||
"address": "0x1Dbf1BB6407f30661756b236D809930762BEa337",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -266,7 +266,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x5366cD335B002b009304Dc74a21EC97e94510177",
|
||||
"address": "0x142bFA0788F794d3D0aE1EC36373ee034aABC11f",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -276,7 +276,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x8821b8e3000629f2c43BB99A092f6687366592F0",
|
||||
"address": "0xC052EC931CdA4aC288BD60c1F8D3E29412976837",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -286,7 +286,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x71FF58Af627447C233Febdb9390CFB6c52fAA3a7",
|
||||
"address": "0x3894795f9e148D52731Bc35A9B21583F20E6e4A2",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -296,7 +296,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x3E447b144e446558c2467d95FcF17Eaee9d704Bf",
|
||||
"address": "0xe01B716332D22c496812c2c2BaAF6d20f299C069",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -306,7 +306,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x6452dDB1f891be0426b6B519E461a777aeAe2E9d",
|
||||
"address": "0x02e85B5D2BB248d76eb5be13826793AA841f01D1",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -316,7 +316,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x6174769FBbC16D956a7bf70c3Ae7283341CAe3B6",
|
||||
"address": "0xAAeA2C44686fBEE1e9972723D50f12977345A7aa",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -326,7 +326,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x9e498c2dF52Efdd649140417E405B9DeedcfEbE1",
|
||||
"address": "0xF657a556c7fE4F6C46fAEd02E876f70FA413318f",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -336,7 +336,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x09d5c8d8EB9dF4A9779778d4B2c66943F1A0f923",
|
||||
"address": "0xaA9e95d9131774A1Fb02122111CF860a40A83B2f",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -346,7 +346,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x184E5376484c2728e7A2cb4E7f2c1975f4a177dA",
|
||||
"address": "0x9Ec40e5F15c197F46350AA248910E8cDAc3fa5c9",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -356,7 +356,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x23Fa899d0b780f2f439354DcdC325ff738d1234d",
|
||||
"address": "0x477F33Ca315d5C9D64Dd23F2D5696d5F629b15c6",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -366,7 +366,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x398A7a447E4D9007Fa1A5F82F2D07F0B369bD26f",
|
||||
"address": "0x8ae47ca16f5017d5E2369c71540C1DF582719a30",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -376,7 +376,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xc9ffDd024B01AcE9B8ee692b85797593ddd25eBb",
|
||||
"address": "0xe0c40bFb910c24368bBcd2dE9Dc3af45684F96d5",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -386,7 +386,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xE95b5DF6c8c8b8AE04bb8ccA9802E5faf8E2a380",
|
||||
"address": "0xc2517909aE3cFacC0283EB8FB917EAe273a3aE9e",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -396,7 +396,7 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x8A054E7463937F7bf914B2a0C6C1a9D7348f32d9",
|
||||
"address": "0xAd49512dFBaD6fc13D67d3935283c0606812E962",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
|
@ -406,16 +406,36 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x9cbEE5c0A6178F61dcD57C3b21180C8602aBdAc1",
|
||||
"address": "0x749258D38b0473d96FEcc14cC5e7DCE12d7Bd6f6",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
"AaveProtocolTestHelpers": {
|
||||
"buidlerevm": {
|
||||
"address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E"
|
||||
"address": "0xBE7fFcC01164C890e59D298FD755FcBE6B7941a9"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x7dF045e4721203EBEDD3436b15391f32A375Cbc4"
|
||||
"address": "0xF85d6001ADaD5376ef63143bdf1f11D9b163ac4f"
|
||||
}
|
||||
},
|
||||
"StableDebtToken": {
|
||||
"buidlerevm": {
|
||||
"address": "0xD325d114a728C2114Bd33Ad47152f790f2a29c5c",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x209bb253C2f894D3Cc53b9dC23d308Eb8593613A",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
"VariableDebtToken": {
|
||||
"buidlerevm": {
|
||||
"address": "0x910b6a78b413e47401f20aA2350d264b55ae0189",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x8744c818024B89571C9eB9e798a55fd7bad3Dc43",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,6 +35,8 @@ import {AaveProtocolTestHelpers} from "../types/AaveProtocolTestHelpers";
|
|||
import {MOCK_ETH_ADDRESS} from "./constants";
|
||||
import BigNumber from "bignumber.js";
|
||||
import {Ierc20Detailed} from "../types/Ierc20Detailed";
|
||||
import { StableDebtToken } from "../types/StableDebtToken";
|
||||
import { VariableDebtToken } from "../types/VariableDebtToken";
|
||||
|
||||
export const registerContractInJsonDb = async (
|
||||
contractId: string,
|
||||
|
@ -315,7 +317,7 @@ export const deployDefaultReserveInterestRateStrategy = async ([
|
|||
string,
|
||||
string,
|
||||
string
|
||||
]) =>
|
||||
]) =>
|
||||
await deployContract<DefaultReserveInterestRateStrategy>(
|
||||
eContractid.DefaultReserveInterestRateStrategy,
|
||||
[
|
||||
|
@ -328,6 +330,68 @@ export const deployDefaultReserveInterestRateStrategy = async ([
|
|||
]
|
||||
);
|
||||
|
||||
export const deployStableDebtToken = async ([
|
||||
name,
|
||||
symbol,
|
||||
decimals,
|
||||
underlyingAsset,
|
||||
addressesProvider
|
||||
]: [
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress
|
||||
]) =>{
|
||||
|
||||
const token = await deployContract<StableDebtToken>(
|
||||
eContractid.StableDebtToken, []
|
||||
);
|
||||
|
||||
await token.init(
|
||||
name,
|
||||
symbol,
|
||||
decimals,
|
||||
underlyingAsset,
|
||||
addressesProvider
|
||||
);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
export const deployVariableDebtToken = async ([
|
||||
name,
|
||||
symbol,
|
||||
decimals,
|
||||
underlyingAsset,
|
||||
addressesProvider
|
||||
]: [
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
tEthereumAddress,
|
||||
tEthereumAddress
|
||||
]) => {
|
||||
|
||||
const token = await deployContract<VariableDebtToken>(
|
||||
eContractid.VariableDebtToken,
|
||||
[]
|
||||
);
|
||||
|
||||
|
||||
await token.init(
|
||||
name,
|
||||
symbol,
|
||||
decimals,
|
||||
underlyingAsset,
|
||||
addressesProvider
|
||||
);
|
||||
|
||||
return token;
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const getLendingPoolAddressesProvider = async (
|
||||
address?: tEthereumAddress
|
||||
) => {
|
||||
|
|
|
@ -41,7 +41,10 @@ export const timeLatest = async () => {
|
|||
export const advanceBlock = async (timestamp: number) =>
|
||||
await BRE.ethers.provider.send("evm_mine", [timestamp]);
|
||||
|
||||
export const increaseTime = async (secondsToIncrease: number) =>
|
||||
export const increaseTime = async (secondsToIncrease: number) =>{
|
||||
|
||||
|
||||
await BRE.ethers.provider.send("evm_increaseTime", [secondsToIncrease]);
|
||||
|
||||
await BRE.ethers.provider.send("evm_mine",[]);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ export enum eContractid {
|
|||
AToken = "AToken",
|
||||
AaveProtocolTestHelpers = "AaveProtocolTestHelpers",
|
||||
IERC20Detailed = "IERC20Detailed",
|
||||
StableDebtToken = "StableDebtToken",
|
||||
VariableDebtToken = "VariableDebtToken"
|
||||
}
|
||||
|
||||
export enum ProtocolErrors {
|
||||
|
|
|
@ -26,6 +26,8 @@ import {
|
|||
deployAaveProtocolTestHelpers,
|
||||
getEthersSigners,
|
||||
registerContractInJsonDb,
|
||||
deployStableDebtToken,
|
||||
deployVariableDebtToken,
|
||||
} from "../helpers/contracts-helpers";
|
||||
import {LendingPoolAddressesProvider} from "../types/LendingPoolAddressesProvider";
|
||||
import {Wallet, ContractTransaction, ethers, Signer} from "ethers";
|
||||
|
@ -251,6 +253,26 @@ const initReserves = async (
|
|||
stableRateSlope2,
|
||||
]
|
||||
);
|
||||
|
||||
const stableDebtToken = await deployStableDebtToken([
|
||||
`Aave stable debt bearing ${assetSymbol}`,
|
||||
`stableDebt${assetSymbol}`,
|
||||
reserveDecimals,
|
||||
tokenAddress,
|
||||
lendingPoolAddressesProvider.address
|
||||
]
|
||||
)
|
||||
|
||||
const variableDebtToken = await deployVariableDebtToken([
|
||||
`Aave stable debt bearing ${assetSymbol}`,
|
||||
`stableDebt${assetSymbol}`,
|
||||
reserveDecimals,
|
||||
tokenAddress,
|
||||
lendingPoolAddressesProvider.address
|
||||
]
|
||||
)
|
||||
|
||||
console.log(`Debt tokens for ${assetSymbol}: stable ${stableDebtToken.address} variable ${variableDebtToken.address}`)
|
||||
|
||||
if (process.env.POOL === AavePools.secondary) {
|
||||
if (assetSymbol.search("UNI") === -1) {
|
||||
|
@ -264,6 +286,8 @@ const initReserves = async (
|
|||
tokenAddress,
|
||||
`Aave Interest bearing ${assetSymbol}`,
|
||||
`a${assetSymbol}`,
|
||||
stableDebtToken.address,
|
||||
variableDebtToken.address,
|
||||
reserveDecimals,
|
||||
rateStrategyContract.address
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import BigNumber from "bignumber.js";
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import {
|
||||
calcExpectedReserveDataAfterDeposit,
|
||||
|
@ -15,33 +15,25 @@ import {
|
|||
calcExpectedReserveDataAfterStableRateRebalance,
|
||||
calcExpectedUserDataAfterStableRateRebalance,
|
||||
calcExpectedUsersDataAfterRedirectInterest,
|
||||
} from "./utils/calculations";
|
||||
import {
|
||||
getReserveAddressFromSymbol,
|
||||
getReserveData,
|
||||
getUserData,
|
||||
} from "./utils/helpers";
|
||||
} from './utils/calculations';
|
||||
import {getReserveAddressFromSymbol, getReserveData, getUserData} from './utils/helpers';
|
||||
|
||||
import {
|
||||
getMintableErc20,
|
||||
convertToCurrencyDecimals,
|
||||
getAToken,
|
||||
} from "../../helpers/contracts-helpers";
|
||||
import {
|
||||
MOCK_ETH_ADDRESS,
|
||||
ONE_YEAR,
|
||||
MAX_UINT_AMOUNT,
|
||||
} from "../../helpers/constants";
|
||||
import {TestEnv, SignerWithAddress} from "./make-suite";
|
||||
import {BRE, increaseTime, timeLatest} from "../../helpers/misc-utils";
|
||||
} from '../../helpers/contracts-helpers';
|
||||
import {MOCK_ETH_ADDRESS, ONE_YEAR, MAX_UINT_AMOUNT} from '../../helpers/constants';
|
||||
import {TestEnv, SignerWithAddress} from './make-suite';
|
||||
import {BRE, increaseTime, timeLatest} from '../../helpers/misc-utils';
|
||||
|
||||
import chai from "chai";
|
||||
import {ReserveData, UserReserveData} from "./utils/interfaces";
|
||||
import {waitForTx} from "../__setup.spec";
|
||||
import {ContractReceipt} from "ethers/contract";
|
||||
import {ethers} from "ethers";
|
||||
import {AToken} from "../../types/AToken";
|
||||
import {tEthereumAddress} from "../../helpers/types";
|
||||
import chai from 'chai';
|
||||
import {ReserveData, UserReserveData} from './utils/interfaces';
|
||||
import {waitForTx} from '../__setup.spec';
|
||||
import {ContractReceipt} from 'ethers/contract';
|
||||
import {ethers} from 'ethers';
|
||||
import {AToken} from '../../types/AToken';
|
||||
import {tEthereumAddress, RateMode} from '../../helpers/types';
|
||||
|
||||
const {expect} = chai;
|
||||
|
||||
|
@ -54,36 +46,28 @@ const almostEqualOrEqual = function (
|
|||
|
||||
keys.forEach((key) => {
|
||||
if (
|
||||
key === "lastUpdateTimestamp" ||
|
||||
key === "marketStableRate" ||
|
||||
key === "symbol" ||
|
||||
key === "aTokenAddress" ||
|
||||
key === "initialATokenExchangeRate" ||
|
||||
key === "decimals"
|
||||
key === 'lastUpdateTimestamp' ||
|
||||
key === 'marketStableRate' ||
|
||||
key === 'symbol' ||
|
||||
key === 'aTokenAddress' ||
|
||||
key === 'initialATokenExchangeRate' ||
|
||||
key === 'decimals'
|
||||
) {
|
||||
// skipping consistency check on accessory data
|
||||
return;
|
||||
}
|
||||
|
||||
this.assert(
|
||||
actual[key] != undefined,
|
||||
`Property ${key} is undefined in the actual data`
|
||||
);
|
||||
expect(
|
||||
expected[key] != undefined,
|
||||
`Property ${key} is undefined in the expected data`
|
||||
);
|
||||
this.assert(actual[key] != undefined, `Property ${key} is undefined in the actual data`);
|
||||
expect(expected[key] != undefined, `Property ${key} is undefined in the expected data`);
|
||||
|
||||
if (actual[key] instanceof BigNumber) {
|
||||
const actualValue = (<BigNumber>actual[key]).decimalPlaces(
|
||||
0,
|
||||
BigNumber.ROUND_DOWN
|
||||
);
|
||||
const expectedValue = (<BigNumber>expected[key]).decimalPlaces(
|
||||
0,
|
||||
BigNumber.ROUND_DOWN
|
||||
);
|
||||
if(!expected[key]){
|
||||
console.log("Key ", key, " value ", expected[key], actual[key]);
|
||||
|
||||
}
|
||||
const actualValue = (<BigNumber>actual[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
|
||||
const expectedValue = (<BigNumber>expected[key]).decimalPlaces(0, BigNumber.ROUND_DOWN);
|
||||
|
||||
this.assert(
|
||||
actualValue.eq(expectedValue) ||
|
||||
actualValue.plus(1).eq(expectedValue) ||
|
||||
|
@ -98,6 +82,7 @@ const almostEqualOrEqual = function (
|
|||
actualValue.toFixed(0)
|
||||
);
|
||||
} else {
|
||||
console.log("Key ", key, " value ", expected[key], actual[key]);
|
||||
this.assert(
|
||||
actual[key] !== null &&
|
||||
expected[key] !== null &&
|
||||
|
@ -112,9 +97,7 @@ const almostEqualOrEqual = function (
|
|||
};
|
||||
|
||||
chai.use(function (chai: any, utils: any) {
|
||||
chai.Assertion.overwriteMethod("almostEqualOrEqual", function (
|
||||
original: any
|
||||
) {
|
||||
chai.Assertion.overwriteMethod('almostEqualOrEqual', function (original: any) {
|
||||
return function (this: any, expected: ReserveData | UserReserveData) {
|
||||
const actual = (expected as ReserveData)
|
||||
? <ReserveData>this._obj
|
||||
|
@ -131,43 +114,31 @@ interface ActionsConfig {
|
|||
|
||||
export const configuration: ActionsConfig = <ActionsConfig>{};
|
||||
|
||||
export const mint = async (
|
||||
reserveSymbol: string,
|
||||
amount: string,
|
||||
user: SignerWithAddress
|
||||
) => {
|
||||
export const mint = async (reserveSymbol: string, amount: string, user: SignerWithAddress) => {
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
if (MOCK_ETH_ADDRESS.toLowerCase() === reserve.toLowerCase()) {
|
||||
throw "Cannot mint ethereum. Mint action is most likely not needed in this story";
|
||||
throw 'Cannot mint ethereum. Mint action is most likely not needed in this story';
|
||||
}
|
||||
|
||||
const token = await getMintableErc20(reserve);
|
||||
|
||||
await waitForTx(
|
||||
await token
|
||||
.connect(user.signer)
|
||||
.mint(await convertToCurrencyDecimals(reserve, amount))
|
||||
await token.connect(user.signer).mint(await convertToCurrencyDecimals(reserve, amount))
|
||||
);
|
||||
};
|
||||
|
||||
export const approve = async (
|
||||
reserveSymbol: string,
|
||||
user: SignerWithAddress,
|
||||
testEnv: TestEnv
|
||||
) => {
|
||||
export const approve = async (reserveSymbol: string, user: SignerWithAddress, testEnv: TestEnv) => {
|
||||
const {pool} = testEnv;
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
if (MOCK_ETH_ADDRESS.toLowerCase() === reserve.toLowerCase()) {
|
||||
throw "Cannot mint ethereum. Mint action is most likely not needed in this story";
|
||||
throw 'Cannot mint ethereum. Mint action is most likely not needed in this story';
|
||||
}
|
||||
|
||||
const token = await getMintableErc20(reserve);
|
||||
|
||||
await token
|
||||
.connect(user.signer)
|
||||
.approve(pool.address, "100000000000000000000000000000");
|
||||
await token.connect(user.signer).approve(pool.address, '100000000000000000000000000000');
|
||||
};
|
||||
|
||||
export const deposit = async (
|
||||
|
@ -187,10 +158,11 @@ export const deposit = async (
|
|||
|
||||
const txOptions: any = {};
|
||||
|
||||
const {
|
||||
reserveData: reserveDataBefore,
|
||||
userData: userDataBefore,
|
||||
} = await getContractsData(reserve, user.address, testEnv);
|
||||
const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
|
||||
reserve,
|
||||
user.address,
|
||||
testEnv
|
||||
);
|
||||
|
||||
if (MOCK_ETH_ADDRESS === reserve) {
|
||||
if (sendValue) {
|
||||
|
@ -200,11 +172,9 @@ export const deposit = async (
|
|||
txOptions.value = amountToDeposit;
|
||||
}
|
||||
}
|
||||
if (expectedResult === "success") {
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
await await pool
|
||||
.connect(user.signer)
|
||||
.deposit(reserve, amountToDeposit, "0", txOptions)
|
||||
await await pool.connect(user.signer).deposit(reserve, amountToDeposit, '0', txOptions)
|
||||
);
|
||||
|
||||
const {
|
||||
|
@ -242,11 +212,9 @@ export const deposit = async (
|
|||
// new BigNumber(_amount).isEqualTo(new BigNumber(amountToDeposit))
|
||||
// );
|
||||
// });
|
||||
} else if (expectedResult === "revert") {
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(
|
||||
pool
|
||||
.connect(user.signer)
|
||||
.deposit(reserve, amountToDeposit, "0", txOptions),
|
||||
pool.connect(user.signer).deposit(reserve, amountToDeposit, '0', txOptions),
|
||||
revertMessage
|
||||
).to.be.reverted;
|
||||
}
|
||||
|
@ -260,25 +228,22 @@ export const redeem = async (
|
|||
testEnv: TestEnv,
|
||||
revertMessage?: string
|
||||
) => {
|
||||
|
||||
const {
|
||||
aTokenInstance,
|
||||
reserve,
|
||||
userData: userDataBefore,
|
||||
reserveData: reserveDataBefore,
|
||||
} = await getDataBeforeAction(reserveSymbol, user.address, testEnv);
|
||||
|
||||
let amountToRedeem = "0";
|
||||
|
||||
if (amount !== "-1") {
|
||||
amountToRedeem = (
|
||||
await convertToCurrencyDecimals(reserve, amount)
|
||||
).toString();
|
||||
let amountToRedeem = '0';
|
||||
|
||||
if (amount !== '-1') {
|
||||
amountToRedeem = (await convertToCurrencyDecimals(reserve, amount)).toString();
|
||||
} else {
|
||||
amountToRedeem = MAX_UINT_AMOUNT;
|
||||
}
|
||||
|
||||
if (expectedResult === "success") {
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
await aTokenInstance.connect(user.signer).redeem(amountToRedeem)
|
||||
);
|
||||
|
@ -321,11 +286,9 @@ export const redeem = async (
|
|||
// _from === user && new BigNumber(_value).isEqualTo(actualAmountRedeemed)
|
||||
// );
|
||||
// });
|
||||
} else if (expectedResult === "revert") {
|
||||
await expect(
|
||||
aTokenInstance.connect(user.signer).redeem(amountToRedeem),
|
||||
revertMessage
|
||||
).to.be.reverted;
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(aTokenInstance.connect(user.signer).redeem(amountToRedeem), revertMessage).to.be
|
||||
.reverted;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -343,40 +306,37 @@ export const borrow = async (
|
|||
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
const {
|
||||
reserveData: reserveDataBefore,
|
||||
userData: userDataBefore,
|
||||
} = await getContractsData(reserve, user.address, testEnv);
|
||||
const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
|
||||
reserve,
|
||||
user.address,
|
||||
testEnv
|
||||
);
|
||||
|
||||
const amountToBorrow = await convertToCurrencyDecimals(reserve, amount);
|
||||
|
||||
if (expectedResult === "success") {
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
await pool
|
||||
.connect(user.signer)
|
||||
.borrow(reserve, amountToBorrow, interestRateMode, "0")
|
||||
await pool.connect(user.signer).borrow(reserve, amountToBorrow, interestRateMode, '0')
|
||||
);
|
||||
|
||||
const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
|
||||
|
||||
if (timeTravel) {
|
||||
const secondsToTravel = new BigNumber(timeTravel)
|
||||
.multipliedBy(ONE_YEAR)
|
||||
.div(365)
|
||||
.toNumber();
|
||||
const secondsToTravel = new BigNumber(timeTravel).multipliedBy(ONE_YEAR).div(365).toNumber();
|
||||
|
||||
await increaseTime(secondsToTravel);
|
||||
// await advanceBlock(new Date().getTime());
|
||||
// TODO
|
||||
// await time.increase(secondsToTravel);
|
||||
|
||||
}
|
||||
|
||||
|
||||
const {
|
||||
reserveData: reserveDataAfter,
|
||||
userData: userDataAfter,
|
||||
timestamp,
|
||||
} = await getContractsData(reserve, user.address, testEnv);
|
||||
|
||||
console.log(txTimestamp, timestamp);
|
||||
|
||||
const expectedReserveData = calcExpectedReserveDataAfterBorrow(
|
||||
amountToBorrow.toString(),
|
||||
interestRateMode,
|
||||
|
@ -419,11 +379,9 @@ export const borrow = async (
|
|||
// )
|
||||
// );
|
||||
// });
|
||||
} else if (expectedResult === "revert") {
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(
|
||||
pool
|
||||
.connect(user.signer)
|
||||
.borrow(reserve, amountToBorrow, interestRateMode, "0"),
|
||||
pool.connect(user.signer).borrow(reserve, amountToBorrow, interestRateMode, '0'),
|
||||
revertMessage
|
||||
).to.be.reverted;
|
||||
}
|
||||
|
@ -432,6 +390,7 @@ export const borrow = async (
|
|||
export const repay = async (
|
||||
reserveSymbol: string,
|
||||
amount: string,
|
||||
rateMode: string,
|
||||
user: SignerWithAddress,
|
||||
onBehalfOf: SignerWithAddress,
|
||||
sendValue: string,
|
||||
|
@ -442,35 +401,38 @@ export const repay = async (
|
|||
const {pool} = testEnv;
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
const {
|
||||
reserveData: reserveDataBefore,
|
||||
userData: userDataBefore,
|
||||
} = await getContractsData(reserve, onBehalfOf.address, testEnv);
|
||||
const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
|
||||
reserve,
|
||||
onBehalfOf.address,
|
||||
testEnv
|
||||
);
|
||||
|
||||
let amountToRepay = "0";
|
||||
let amountToRepay = '0';
|
||||
|
||||
if (amount !== "-1") {
|
||||
amountToRepay = (
|
||||
await convertToCurrencyDecimals(reserve, amount)
|
||||
).toString();
|
||||
if (amount !== '-1') {
|
||||
amountToRepay = (await convertToCurrencyDecimals(reserve, amount)).toString();
|
||||
} else {
|
||||
amountToRepay = ethers.utils.bigNumberify(MAX_UINT_AMOUNT).toString();
|
||||
}
|
||||
amountToRepay = "0x" + new BigNumber(amountToRepay).toString(16);
|
||||
amountToRepay = '0x' + new BigNumber(amountToRepay).toString(16);
|
||||
|
||||
const txOptions: any = {};
|
||||
|
||||
if (MOCK_ETH_ADDRESS === reserve) {
|
||||
if (sendValue) {
|
||||
if (sendValue !== "-1") {
|
||||
const valueToSend =
|
||||
rateMode == RateMode.Stable
|
||||
? userDataBefore.currentStableBorrowBalance
|
||||
: userDataBefore.currentVariableBorrowBalance;
|
||||
|
||||
if (sendValue !== '-1') {
|
||||
const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
|
||||
txOptions.value =
|
||||
"0x" + new BigNumber(valueToSend.toString()).toString(16);
|
||||
txOptions.value = '0x' + new BigNumber(valueToSend.toString()).toString(16);
|
||||
} else {
|
||||
txOptions.value =
|
||||
"0x" +
|
||||
userDataBefore.currentBorrowBalance
|
||||
.plus((await convertToCurrencyDecimals(reserve, "0.1")).toString())
|
||||
'0x' +
|
||||
valueToSend
|
||||
.plus((await convertToCurrencyDecimals(reserve, '0.1')).toString())
|
||||
.toString(16); //add 0.1 ETH to the repayment amount to cover for accrued interest during tx execution
|
||||
}
|
||||
} else {
|
||||
|
@ -478,11 +440,11 @@ export const repay = async (
|
|||
}
|
||||
}
|
||||
|
||||
if (expectedResult === "success") {
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
await pool
|
||||
.connect(user.signer)
|
||||
.repay(reserve, amountToRepay, onBehalfOf.address, txOptions)
|
||||
.repay(reserve, amountToRepay, rateMode, onBehalfOf.address, txOptions)
|
||||
);
|
||||
|
||||
const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
|
||||
|
@ -495,6 +457,7 @@ export const repay = async (
|
|||
|
||||
const expectedReserveData = calcExpectedReserveDataAfterRepay(
|
||||
amountToRepay,
|
||||
<RateMode>(rateMode),
|
||||
reserveDataBefore,
|
||||
userDataBefore,
|
||||
txTimestamp,
|
||||
|
@ -503,6 +466,7 @@ export const repay = async (
|
|||
|
||||
const expectedUserData = calcExpectedUserDataAfterRepay(
|
||||
amountToRepay,
|
||||
<RateMode>(rateMode),
|
||||
reserveDataBefore,
|
||||
expectedReserveData,
|
||||
userDataBefore,
|
||||
|
@ -525,11 +489,9 @@ export const repay = async (
|
|||
// _repayer.toLowerCase() === user.toLowerCase()
|
||||
// );
|
||||
// });
|
||||
} else if (expectedResult === "revert") {
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(
|
||||
pool
|
||||
.connect(user.signer)
|
||||
.repay(reserve, amountToRepay, onBehalfOf.address, txOptions),
|
||||
pool.connect(user.signer).repay(reserve, amountToRepay, onBehalfOf.address, txOptions),
|
||||
revertMessage
|
||||
).to.be.reverted;
|
||||
}
|
||||
|
@ -547,30 +509,25 @@ export const setUseAsCollateral = async (
|
|||
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
const {
|
||||
reserveData: reserveDataBefore,
|
||||
userData: userDataBefore,
|
||||
} = await getContractsData(reserve, user.address, testEnv);
|
||||
const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
|
||||
reserve,
|
||||
user.address,
|
||||
testEnv
|
||||
);
|
||||
|
||||
const useAsCollateralBool = useAsCollateral.toLowerCase() === "true";
|
||||
const useAsCollateralBool = useAsCollateral.toLowerCase() === 'true';
|
||||
|
||||
if (expectedResult === "success") {
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
await pool
|
||||
.connect(user.signer)
|
||||
.setUserUseReserveAsCollateral(reserve, useAsCollateralBool)
|
||||
await pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool)
|
||||
);
|
||||
|
||||
const {txCost} = await getTxCostAndTimestamp(txResult);
|
||||
|
||||
const {userData: userDataAfter} = await getContractsData(
|
||||
reserve,
|
||||
user.address,
|
||||
testEnv
|
||||
);
|
||||
const {userData: userDataAfter} = await getContractsData(reserve, user.address, testEnv);
|
||||
|
||||
const expectedUserData = calcExpectedUserDataAfterSetUseAsCollateral(
|
||||
useAsCollateral.toLocaleLowerCase() === "true",
|
||||
useAsCollateral.toLocaleLowerCase() === 'true',
|
||||
reserveDataBefore,
|
||||
userDataBefore,
|
||||
txCost
|
||||
|
@ -588,11 +545,9 @@ export const setUseAsCollateral = async (
|
|||
// return _reserve === reserve && _user === user;
|
||||
// });
|
||||
// }
|
||||
} else if (expectedResult === "revert") {
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(
|
||||
pool
|
||||
.connect(user.signer)
|
||||
.setUserUseReserveAsCollateral(reserve, useAsCollateralBool),
|
||||
pool.connect(user.signer).setUserUseReserveAsCollateral(reserve, useAsCollateralBool),
|
||||
revertMessage
|
||||
).to.be.reverted;
|
||||
}
|
||||
|
@ -609,22 +564,22 @@ export const swapBorrowRateMode = async (
|
|||
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
const {
|
||||
reserveData: reserveDataBefore,
|
||||
userData: userDataBefore,
|
||||
} = await getContractsData(reserve, user.address, testEnv);
|
||||
const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
|
||||
reserve,
|
||||
user.address,
|
||||
testEnv
|
||||
);
|
||||
|
||||
if (expectedResult === "success") {
|
||||
const txResult = await waitForTx(
|
||||
await pool.connect(user.signer).swapBorrowRateMode(reserve)
|
||||
);
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(await pool.connect(user.signer).swapBorrowRateMode(reserve));
|
||||
|
||||
const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
|
||||
|
||||
const {
|
||||
reserveData: reserveDataAfter,
|
||||
userData: userDataAfter,
|
||||
} = await getContractsData(reserve, user.address, testEnv);
|
||||
const {reserveData: reserveDataAfter, userData: userDataAfter} = await getContractsData(
|
||||
reserve,
|
||||
user.address,
|
||||
testEnv
|
||||
);
|
||||
|
||||
const expectedReserveData = calcExpectedReserveDataAfterSwapRateMode(
|
||||
reserveDataBefore,
|
||||
|
@ -652,11 +607,9 @@ export const swapBorrowRateMode = async (
|
|||
// new BigNumber(_newRate).eq(expectedUserData.borrowRate)
|
||||
// );
|
||||
// });
|
||||
} else if (expectedResult === "revert") {
|
||||
await expect(
|
||||
pool.connect(user.signer).swapBorrowRateMode(reserve),
|
||||
revertMessage
|
||||
).to.be.reverted;
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(pool.connect(user.signer).swapBorrowRateMode(reserve), revertMessage).to.be
|
||||
.reverted;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -672,24 +625,24 @@ export const rebalanceStableBorrowRate = async (
|
|||
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
const {
|
||||
reserveData: reserveDataBefore,
|
||||
userData: userDataBefore,
|
||||
} = await getContractsData(reserve, target.address, testEnv);
|
||||
const {reserveData: reserveDataBefore, userData: userDataBefore} = await getContractsData(
|
||||
reserve,
|
||||
target.address,
|
||||
testEnv
|
||||
);
|
||||
|
||||
if (expectedResult === "success") {
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
await pool
|
||||
.connect(user.signer)
|
||||
.rebalanceStableBorrowRate(reserve, target.address)
|
||||
await pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address)
|
||||
);
|
||||
|
||||
const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
|
||||
|
||||
const {
|
||||
reserveData: reserveDataAfter,
|
||||
userData: userDataAfter,
|
||||
} = await getContractsData(reserve, target.address, testEnv);
|
||||
const {reserveData: reserveDataAfter, userData: userDataAfter} = await getContractsData(
|
||||
reserve,
|
||||
target.address,
|
||||
testEnv
|
||||
);
|
||||
|
||||
const expectedReserveData = calcExpectedReserveDataAfterStableRateRebalance(
|
||||
reserveDataBefore,
|
||||
|
@ -716,11 +669,9 @@ export const rebalanceStableBorrowRate = async (
|
|||
// new BigNumber(_newStableRate).eq(expectedUserData.borrowRate)
|
||||
// );
|
||||
// });
|
||||
} else if (expectedResult === "revert") {
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(
|
||||
pool
|
||||
.connect(user.signer)
|
||||
.rebalanceStableBorrowRate(reserve, target.address),
|
||||
pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address),
|
||||
revertMessage
|
||||
).to.be.reverted;
|
||||
}
|
||||
|
@ -743,29 +694,18 @@ export const redirectInterestStream = async (
|
|||
|
||||
const {userData: toDataBefore} = await getContractsData(reserve, to, testEnv);
|
||||
|
||||
if (expectedResult === "success") {
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
await aTokenInstance.connect(user.signer).redirectInterestStream(to)
|
||||
);
|
||||
|
||||
const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
|
||||
|
||||
const {userData: fromDataAfter} = await getContractsData(
|
||||
reserve,
|
||||
user.address,
|
||||
testEnv
|
||||
);
|
||||
const {userData: fromDataAfter} = await getContractsData(reserve, user.address, testEnv);
|
||||
|
||||
const {userData: toDataAfter} = await getContractsData(
|
||||
reserve,
|
||||
to,
|
||||
testEnv
|
||||
);
|
||||
const {userData: toDataAfter} = await getContractsData(reserve, to, testEnv);
|
||||
|
||||
const [
|
||||
expectedFromData,
|
||||
expectedToData,
|
||||
] = calcExpectedUsersDataAfterRedirectInterest(
|
||||
const [expectedFromData, expectedToData] = calcExpectedUsersDataAfterRedirectInterest(
|
||||
reserveDataBefore,
|
||||
fromDataBefore,
|
||||
toDataBefore,
|
||||
|
@ -784,11 +724,9 @@ export const redirectInterestStream = async (
|
|||
// return _from === user
|
||||
// && _to === (to === user ? NIL_ADDRESS : to);
|
||||
// });
|
||||
} else if (expectedResult === "revert") {
|
||||
await expect(
|
||||
aTokenInstance.connect(user.signer).redirectInterestStream(to),
|
||||
revertMessage
|
||||
).to.be.reverted;
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(aTokenInstance.connect(user.signer).redirectInterestStream(to), revertMessage).to
|
||||
.be.reverted;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -808,37 +746,20 @@ export const redirectInterestStreamOf = async (
|
|||
reserveData: reserveDataBefore,
|
||||
} = await getDataBeforeAction(reserveSymbol, from, testEnv);
|
||||
|
||||
const {userData: toDataBefore} = await getContractsData(
|
||||
reserve,
|
||||
user.address,
|
||||
testEnv
|
||||
);
|
||||
const {userData: toDataBefore} = await getContractsData(reserve, user.address, testEnv);
|
||||
|
||||
if (expectedResult === "success") {
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
await aTokenInstance
|
||||
.connect(user.signer)
|
||||
.redirectInterestStreamOf(from, to)
|
||||
await aTokenInstance.connect(user.signer).redirectInterestStreamOf(from, to)
|
||||
);
|
||||
|
||||
const {txCost, txTimestamp} = await getTxCostAndTimestamp(txResult);
|
||||
|
||||
const {userData: fromDataAfter} = await getContractsData(
|
||||
reserve,
|
||||
from,
|
||||
testEnv
|
||||
);
|
||||
const {userData: fromDataAfter} = await getContractsData(reserve, from, testEnv);
|
||||
|
||||
const {userData: toDataAfter} = await getContractsData(
|
||||
reserve,
|
||||
to,
|
||||
testEnv
|
||||
);
|
||||
const {userData: toDataAfter} = await getContractsData(reserve, to, testEnv);
|
||||
|
||||
const [
|
||||
expectedFromData,
|
||||
exptectedToData,
|
||||
] = calcExpectedUsersDataAfterRedirectInterest(
|
||||
const [expectedFromData, exptectedToData] = calcExpectedUsersDataAfterRedirectInterest(
|
||||
reserveDataBefore,
|
||||
fromDataBefore,
|
||||
toDataBefore,
|
||||
|
@ -863,7 +784,7 @@ export const redirectInterestStreamOf = async (
|
|||
// );
|
||||
// }
|
||||
// );
|
||||
} else if (expectedResult === "revert") {
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(
|
||||
aTokenInstance.connect(user.signer).redirectInterestStreamOf(from, to),
|
||||
revertMessage
|
||||
|
@ -879,13 +800,9 @@ export const allowInterestRedirectionTo = async (
|
|||
testEnv: TestEnv,
|
||||
revertMessage?: string
|
||||
) => {
|
||||
const {aTokenInstance} = await getDataBeforeAction(
|
||||
reserveSymbol,
|
||||
user.address,
|
||||
testEnv
|
||||
);
|
||||
const {aTokenInstance} = await getDataBeforeAction(reserveSymbol, user.address, testEnv);
|
||||
|
||||
if (expectedResult === "success") {
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
await aTokenInstance.connect(user.signer).allowInterestRedirectionTo(to)
|
||||
);
|
||||
|
@ -901,11 +818,9 @@ export const allowInterestRedirectionTo = async (
|
|||
// );
|
||||
// }
|
||||
// );
|
||||
} else if (expectedResult === "revert") {
|
||||
await expect(
|
||||
aTokenInstance.connect(user.signer).allowInterestRedirectionTo(to),
|
||||
revertMessage
|
||||
).to.be.reverted;
|
||||
} else if (expectedResult === 'revert') {
|
||||
await expect(aTokenInstance.connect(user.signer).allowInterestRedirectionTo(to), revertMessage)
|
||||
.to.be.reverted;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -931,14 +846,9 @@ const getDataBeforeAction = async (
|
|||
user: tEthereumAddress,
|
||||
testEnv: TestEnv
|
||||
): Promise<ActionData> => {
|
||||
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
const {reserveData, userData} = await getContractsData(
|
||||
reserve,
|
||||
user,
|
||||
testEnv
|
||||
);
|
||||
const {reserveData, userData} = await getContractsData(reserve, user, testEnv);
|
||||
const aTokenInstance = await getAToken(reserveData.aTokenAddress);
|
||||
return {
|
||||
reserve,
|
||||
|
@ -950,11 +860,9 @@ const getDataBeforeAction = async (
|
|||
|
||||
const getTxCostAndTimestamp = async (tx: ContractReceipt) => {
|
||||
if (!tx.blockNumber || !tx.transactionHash || !tx.cumulativeGasUsed) {
|
||||
throw new Error("No tx blocknumber");
|
||||
throw new Error('No tx blocknumber');
|
||||
}
|
||||
const txTimestamp = new BigNumber(
|
||||
(await BRE.ethers.provider.getBlock(tx.blockNumber)).timestamp
|
||||
);
|
||||
const txTimestamp = new BigNumber((await BRE.ethers.provider.getBlock(tx.blockNumber)).timestamp);
|
||||
|
||||
const txInfo = await BRE.ethers.provider.getTransaction(tx.transactionHash);
|
||||
const txCost = new BigNumber(tx.cumulativeGasUsed.toString()).multipliedBy(
|
||||
|
@ -964,11 +872,7 @@ const getTxCostAndTimestamp = async (tx: ContractReceipt) => {
|
|||
return {txCost, txTimestamp};
|
||||
};
|
||||
|
||||
const getContractsData = async (
|
||||
reserve: string,
|
||||
user: string,
|
||||
testEnv: TestEnv
|
||||
) => {
|
||||
const getContractsData = async (reserve: string, user: string, testEnv: TestEnv) => {
|
||||
const {pool} = testEnv;
|
||||
const reserveData = await getReserveData(pool, reserve);
|
||||
const userData = await getUserData(pool, reserve, user);
|
||||
|
|
|
@ -146,12 +146,24 @@ const executeAction = async (
|
|||
|
||||
case "repay":
|
||||
{
|
||||
const {amount, sendValue} = action.args;
|
||||
const {amount, borrowRateMode, sendValue} = action.args;
|
||||
let {onBehalfOf: onBehalfOfIndex} = action.args;
|
||||
|
||||
if (!amount || amount === "") {
|
||||
throw `Invalid amount to repay into the ${reserve} reserve`;
|
||||
}
|
||||
let rateMode: string = RateMode.None;
|
||||
|
||||
if (borrowRateMode === "none") {
|
||||
rateMode = RateMode.None;
|
||||
} else if (borrowRateMode === "stable") {
|
||||
rateMode = RateMode.Stable;
|
||||
} else if (borrowRateMode === "variable") {
|
||||
rateMode = RateMode.Variable;
|
||||
} else {
|
||||
//random value, to test improper selection of the parameter
|
||||
rateMode = "4";
|
||||
}
|
||||
|
||||
let userToRepayOnBehalf: SignerWithAddress;
|
||||
if (!onBehalfOfIndex || onBehalfOfIndex === "") {
|
||||
|
@ -166,6 +178,7 @@ const executeAction = async (
|
|||
await repay(
|
||||
reserve,
|
||||
amount,
|
||||
rateMode,
|
||||
user,
|
||||
userToRepayOnBehalf,
|
||||
sendValue,
|
||||
|
|
|
@ -287,7 +287,8 @@
|
|||
"amount": "0",
|
||||
"user": "1",
|
||||
"onBehalfOf": "1",
|
||||
"sendValue": "0"
|
||||
"borrowRateMode": "variable",
|
||||
"sendValue": "0"
|
||||
},
|
||||
"expected": "revert",
|
||||
"revertMessage": "Amount must be greater than 0"
|
||||
|
@ -303,6 +304,7 @@
|
|||
"reserve": "ETH",
|
||||
"amount": "-1",
|
||||
"user": "1",
|
||||
"borrowRateMode": "variable",
|
||||
"onBehalfOf": "1",
|
||||
"sendValue": "0"
|
||||
},
|
||||
|
@ -320,6 +322,7 @@
|
|||
"reserve": "ETH",
|
||||
"amount": "-1",
|
||||
"user": "2",
|
||||
"borrowRateMode": "variable",
|
||||
"onBehalfOf": "1",
|
||||
"sendValue": "-1"
|
||||
},
|
||||
|
@ -337,6 +340,7 @@
|
|||
"reserve": "ETH",
|
||||
"amount": "0.2",
|
||||
"user": "3",
|
||||
"borrowRateMode": "variable",
|
||||
"onBehalfOf": "1",
|
||||
"sendValue": "0.2"
|
||||
},
|
||||
|
@ -352,6 +356,7 @@
|
|||
"args": {
|
||||
"reserve": "ETH",
|
||||
"amount": "-1",
|
||||
"borrowRateMode": "variable",
|
||||
"user": "1",
|
||||
"onBehalfOf": "1",
|
||||
"sendValue": "-1"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,8 +29,6 @@ export const getReserveData = async (
|
|||
symbol = await token.symbol();
|
||||
decimals = new BigNumber(await token.decimals());
|
||||
}
|
||||
|
||||
|
||||
|
||||
const totalLiquidity = new BigNumber(data.availableLiquidity).plus(data.totalBorrowsStable).plus(data.totalBorrowsVariable);
|
||||
|
||||
|
@ -62,7 +60,7 @@ export const getUserData = async (
|
|||
reserve: string,
|
||||
user: string
|
||||
): Promise<UserReserveData> => {
|
||||
const [data, aTokenData] = await Promise.all([
|
||||
const [userData, aTokenData] = await Promise.all([
|
||||
pool.getUserReserveData(reserve, user),
|
||||
getATokenUserData(reserve, user, pool),
|
||||
]);
|
||||
|
@ -86,8 +84,6 @@ export const getUserData = async (
|
|||
walletBalance = new BigNumber((await token.balanceOf(user)).toString());
|
||||
}
|
||||
|
||||
const userData: any = data;
|
||||
|
||||
return {
|
||||
principalATokenBalance: new BigNumber(principalATokenBalance),
|
||||
interestRedirectionAddress,
|
||||
|
@ -96,15 +92,14 @@ export const getUserData = async (
|
|||
),
|
||||
redirectedBalance: new BigNumber(redirectedBalance),
|
||||
currentATokenUserIndex: new BigNumber(userIndex),
|
||||
currentATokenBalance: new BigNumber(userData.currentATokenBalance),
|
||||
currentBorrowBalance: new BigNumber(userData.currentBorrowBalance),
|
||||
principalBorrowBalance: new BigNumber(userData.principalBorrowBalance),
|
||||
borrowRateMode: userData.borrowRateMode.toString(),
|
||||
borrowRate: new BigNumber(userData.borrowRate),
|
||||
liquidityRate: new BigNumber(userData.liquidityRate),
|
||||
originationFee: new BigNumber(userData.originationFee),
|
||||
variableBorrowIndex: new BigNumber(userData.variableBorrowIndex),
|
||||
lastUpdateTimestamp: new BigNumber(userData.lastUpdateTimestamp),
|
||||
currentATokenBalance: new BigNumber(userData.currentATokenBalance.toString()),
|
||||
currentStableBorrowBalance: new BigNumber(userData.currentStableBorrowBalance.toString()),
|
||||
currentVariableBorrowBalance: new BigNumber(userData.currentVariableBorrowBalance.toString()),
|
||||
principalStableBorrowBalance: new BigNumber(userData.principalStableBorrowBalance.toString()),
|
||||
principalVariableBorrowBalance: new BigNumber(userData.principalVariableBorrowBalance.toString()),
|
||||
variableBorrowIndex: new BigNumber(userData.variableBorrowIndex.toString()),
|
||||
stableBorrowRate: new BigNumber(userData.stableBorrowRate.toString()),
|
||||
liquidityRate: new BigNumber(userData.liquidityRate.toString()),
|
||||
usageAsCollateralEnabled: userData.usageAsCollateralEnabled,
|
||||
walletBalance,
|
||||
};
|
||||
|
|
|
@ -7,16 +7,15 @@ export interface UserReserveData {
|
|||
interestRedirectionAddress: string
|
||||
redirectionAddressRedirectedBalance: BigNumber
|
||||
redirectedBalance: BigNumber
|
||||
principalBorrowBalance: BigNumber
|
||||
borrowRateMode: string
|
||||
borrowRate: BigNumber
|
||||
liquidityRate: BigNumber
|
||||
originationFee: BigNumber
|
||||
currentStableBorrowBalance: BigNumber
|
||||
currentVariableBorrowBalance: BigNumber
|
||||
principalStableBorrowBalance: BigNumber
|
||||
principalVariableBorrowBalance: BigNumber
|
||||
variableBorrowIndex: BigNumber
|
||||
lastUpdateTimestamp: BigNumber
|
||||
liquidityRate: BigNumber
|
||||
stableBorrowRate: BigNumber
|
||||
usageAsCollateralEnabled: Boolean
|
||||
walletBalance: BigNumber
|
||||
currentBorrowBalance: BigNumber
|
||||
[key: string]: BigNumber | string | Boolean
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@ BigNumber.config({DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN});
|
|||
const scenarioFolder = "./test/helpers/scenarios/";
|
||||
|
||||
fs.readdirSync(scenarioFolder).forEach((file) => {
|
||||
/* if (![
|
||||
if (![
|
||||
"borrow-repay-variable.json",
|
||||
].includes(file)
|
||||
)
|
||||
return;
|
||||
*/
|
||||
|
||||
const scenario = require(`./helpers/scenarios/${file}`);
|
||||
|
||||
makeSuite(scenario.title, async (testEnv) => {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
278
types/DebtTokenBase.d.ts
vendored
Normal file
278
types/DebtTokenBase.d.ts
vendored
Normal file
|
@ -0,0 +1,278 @@
|
|||
/* Generated by ts-generator ver. 0.0.8 */
|
||||
/* tslint:disable */
|
||||
|
||||
import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
|
||||
import { Listener, Provider } from "ethers/providers";
|
||||
import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
|
||||
import {
|
||||
TransactionOverrides,
|
||||
TypedEventDescription,
|
||||
TypedFunctionDescription
|
||||
} from ".";
|
||||
|
||||
interface DebtTokenBaseInterface extends Interface {
|
||||
functions: {
|
||||
allowance: TypedFunctionDescription<{
|
||||
encode([owner, spender]: [string, string]): string;
|
||||
}>;
|
||||
|
||||
approve: TypedFunctionDescription<{
|
||||
encode([spender, amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
balanceOf: TypedFunctionDescription<{
|
||||
encode([account]: [string]): string;
|
||||
}>;
|
||||
|
||||
decimals: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
decreaseAllowance: TypedFunctionDescription<{
|
||||
encode([spender, subtractedValue]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
increaseAllowance: TypedFunctionDescription<{
|
||||
encode([spender, addedValue]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
init: TypedFunctionDescription<{
|
||||
encode([_name, _symbol, _decimals, _underlying, _addressesProvider]: [
|
||||
string,
|
||||
string,
|
||||
BigNumberish,
|
||||
string,
|
||||
string
|
||||
]): string;
|
||||
}>;
|
||||
|
||||
name: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
principalBalanceOf: TypedFunctionDescription<{
|
||||
encode([account]: [string]): string;
|
||||
}>;
|
||||
|
||||
symbol: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
totalSupply: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
transfer: TypedFunctionDescription<{
|
||||
encode([recipient, amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
transferFrom: TypedFunctionDescription<{
|
||||
encode([sender, recipient, amount]: [
|
||||
string,
|
||||
string,
|
||||
BigNumberish
|
||||
]): string;
|
||||
}>;
|
||||
|
||||
underlyingAssetAddress: TypedFunctionDescription<{
|
||||
encode([]: []): string;
|
||||
}>;
|
||||
};
|
||||
|
||||
events: {
|
||||
Approval: TypedEventDescription<{
|
||||
encodeTopics([owner, spender, value]: [
|
||||
string | null,
|
||||
string | null,
|
||||
null
|
||||
]): string[];
|
||||
}>;
|
||||
|
||||
Transfer: TypedEventDescription<{
|
||||
encodeTopics([from, to, value]: [
|
||||
string | null,
|
||||
string | null,
|
||||
null
|
||||
]): string[];
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
export class DebtTokenBase extends Contract {
|
||||
connect(signerOrProvider: Signer | Provider | string): DebtTokenBase;
|
||||
attach(addressOrName: string): DebtTokenBase;
|
||||
deployed(): Promise<DebtTokenBase>;
|
||||
|
||||
on(event: EventFilter | string, listener: Listener): DebtTokenBase;
|
||||
once(event: EventFilter | string, listener: Listener): DebtTokenBase;
|
||||
addListener(
|
||||
eventName: EventFilter | string,
|
||||
listener: Listener
|
||||
): DebtTokenBase;
|
||||
removeAllListeners(eventName: EventFilter | string): DebtTokenBase;
|
||||
removeListener(eventName: any, listener: Listener): DebtTokenBase;
|
||||
|
||||
interface: DebtTokenBaseInterface;
|
||||
|
||||
functions: {
|
||||
allowance(owner: string, spender: string): Promise<BigNumber>;
|
||||
|
||||
approve(
|
||||
spender: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
balanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
decimals(): Promise<number>;
|
||||
|
||||
decreaseAllowance(
|
||||
spender: string,
|
||||
subtractedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
increaseAllowance(
|
||||
spender: string,
|
||||
addedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
init(
|
||||
_name: string,
|
||||
_symbol: string,
|
||||
_decimals: BigNumberish,
|
||||
_underlying: string,
|
||||
_addressesProvider: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
name(): Promise<string>;
|
||||
|
||||
principalBalanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
symbol(): Promise<string>;
|
||||
|
||||
totalSupply(): Promise<BigNumber>;
|
||||
|
||||
transfer(
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
transferFrom(
|
||||
sender: string,
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
underlyingAssetAddress(): Promise<string>;
|
||||
};
|
||||
|
||||
allowance(owner: string, spender: string): Promise<BigNumber>;
|
||||
|
||||
approve(
|
||||
spender: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
balanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
decimals(): Promise<number>;
|
||||
|
||||
decreaseAllowance(
|
||||
spender: string,
|
||||
subtractedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
increaseAllowance(
|
||||
spender: string,
|
||||
addedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
init(
|
||||
_name: string,
|
||||
_symbol: string,
|
||||
_decimals: BigNumberish,
|
||||
_underlying: string,
|
||||
_addressesProvider: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
name(): Promise<string>;
|
||||
|
||||
principalBalanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
symbol(): Promise<string>;
|
||||
|
||||
totalSupply(): Promise<BigNumber>;
|
||||
|
||||
transfer(
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
transferFrom(
|
||||
sender: string,
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
underlyingAssetAddress(): Promise<string>;
|
||||
|
||||
filters: {
|
||||
Approval(
|
||||
owner: string | null,
|
||||
spender: string | null,
|
||||
value: null
|
||||
): EventFilter;
|
||||
|
||||
Transfer(from: string | null, to: string | null, value: null): EventFilter;
|
||||
};
|
||||
|
||||
estimate: {
|
||||
allowance(owner: string, spender: string): Promise<BigNumber>;
|
||||
|
||||
approve(spender: string, amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
balanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
decimals(): Promise<BigNumber>;
|
||||
|
||||
decreaseAllowance(
|
||||
spender: string,
|
||||
subtractedValue: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
increaseAllowance(
|
||||
spender: string,
|
||||
addedValue: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
init(
|
||||
_name: string,
|
||||
_symbol: string,
|
||||
_decimals: BigNumberish,
|
||||
_underlying: string,
|
||||
_addressesProvider: string
|
||||
): Promise<BigNumber>;
|
||||
|
||||
name(): Promise<BigNumber>;
|
||||
|
||||
principalBalanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
symbol(): Promise<BigNumber>;
|
||||
|
||||
totalSupply(): Promise<BigNumber>;
|
||||
|
||||
transfer(recipient: string, amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
transferFrom(
|
||||
sender: string,
|
||||
recipient: string,
|
||||
amount: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
underlyingAssetAddress(): Promise<BigNumber>;
|
||||
};
|
||||
}
|
354
types/DebtTokenBaseFactory.ts
Normal file
354
types/DebtTokenBaseFactory.ts
Normal file
|
@ -0,0 +1,354 @@
|
|||
/* Generated by ts-generator ver. 0.0.8 */
|
||||
/* tslint:disable */
|
||||
|
||||
import { Contract, Signer } from "ethers";
|
||||
import { Provider } from "ethers/providers";
|
||||
|
||||
import { DebtTokenBase } from "./DebtTokenBase";
|
||||
|
||||
export class DebtTokenBaseFactory {
|
||||
static connect(
|
||||
address: string,
|
||||
signerOrProvider: Signer | Provider
|
||||
): DebtTokenBase {
|
||||
return new Contract(address, _abi, signerOrProvider) as DebtTokenBase;
|
||||
}
|
||||
}
|
||||
|
||||
const _abi = [
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
name: "owner",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
name: "spender",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
name: "value",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "Approval",
|
||||
type: "event"
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
name: "from",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
name: "to",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
name: "value",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "Transfer",
|
||||
type: "event"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "owner",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "address",
|
||||
name: "spender",
|
||||
type: "address"
|
||||
}
|
||||
],
|
||||
name: "allowance",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "spender",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "amount",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "approve",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "bool",
|
||||
name: "",
|
||||
type: "bool"
|
||||
}
|
||||
],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "account",
|
||||
type: "address"
|
||||
}
|
||||
],
|
||||
name: "balanceOf",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "decimals",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint8",
|
||||
name: "",
|
||||
type: "uint8"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "spender",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "subtractedValue",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "decreaseAllowance",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "bool",
|
||||
name: "",
|
||||
type: "bool"
|
||||
}
|
||||
],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "spender",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "addedValue",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "increaseAllowance",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "bool",
|
||||
name: "",
|
||||
type: "bool"
|
||||
}
|
||||
],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "string",
|
||||
name: "_name",
|
||||
type: "string"
|
||||
},
|
||||
{
|
||||
internalType: "string",
|
||||
name: "_symbol",
|
||||
type: "string"
|
||||
},
|
||||
{
|
||||
internalType: "uint8",
|
||||
name: "_decimals",
|
||||
type: "uint8"
|
||||
},
|
||||
{
|
||||
internalType: "address",
|
||||
name: "_underlying",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "contract ILendingPoolAddressesProvider",
|
||||
name: "_addressesProvider",
|
||||
type: "address"
|
||||
}
|
||||
],
|
||||
name: "init",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "name",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "string",
|
||||
name: "",
|
||||
type: "string"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "account",
|
||||
type: "address"
|
||||
}
|
||||
],
|
||||
name: "principalBalanceOf",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "symbol",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "string",
|
||||
name: "",
|
||||
type: "string"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "totalSupply",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "recipient",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "amount",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "transfer",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "bool",
|
||||
name: "",
|
||||
type: "bool"
|
||||
}
|
||||
],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "sender",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "address",
|
||||
name: "recipient",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "amount",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "transferFrom",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "bool",
|
||||
name: "",
|
||||
type: "bool"
|
||||
}
|
||||
],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "underlyingAssetAddress",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "",
|
||||
type: "address"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
}
|
||||
];
|
File diff suppressed because one or more lines are too long
104
types/IStableDebtToken.d.ts
vendored
Normal file
104
types/IStableDebtToken.d.ts
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* Generated by ts-generator ver. 0.0.8 */
|
||||
/* tslint:disable */
|
||||
|
||||
import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
|
||||
import { Listener, Provider } from "ethers/providers";
|
||||
import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
|
||||
import {
|
||||
TransactionOverrides,
|
||||
TypedEventDescription,
|
||||
TypedFunctionDescription
|
||||
} from ".";
|
||||
|
||||
interface IStableDebtTokenInterface extends Interface {
|
||||
functions: {
|
||||
burn: TypedFunctionDescription<{
|
||||
encode([_account, _amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
getAverageStableRate: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
getUserStableRate: TypedFunctionDescription<{
|
||||
encode([_user]: [string]): string;
|
||||
}>;
|
||||
|
||||
mint: TypedFunctionDescription<{
|
||||
encode([account, amount, rate]: [
|
||||
string,
|
||||
BigNumberish,
|
||||
BigNumberish
|
||||
]): string;
|
||||
}>;
|
||||
};
|
||||
|
||||
events: {};
|
||||
}
|
||||
|
||||
export class IStableDebtToken extends Contract {
|
||||
connect(signerOrProvider: Signer | Provider | string): IStableDebtToken;
|
||||
attach(addressOrName: string): IStableDebtToken;
|
||||
deployed(): Promise<IStableDebtToken>;
|
||||
|
||||
on(event: EventFilter | string, listener: Listener): IStableDebtToken;
|
||||
once(event: EventFilter | string, listener: Listener): IStableDebtToken;
|
||||
addListener(
|
||||
eventName: EventFilter | string,
|
||||
listener: Listener
|
||||
): IStableDebtToken;
|
||||
removeAllListeners(eventName: EventFilter | string): IStableDebtToken;
|
||||
removeListener(eventName: any, listener: Listener): IStableDebtToken;
|
||||
|
||||
interface: IStableDebtTokenInterface;
|
||||
|
||||
functions: {
|
||||
burn(
|
||||
_account: string,
|
||||
_amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
getAverageStableRate(): Promise<BigNumber>;
|
||||
|
||||
getUserStableRate(_user: string): Promise<BigNumber>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
rate: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
};
|
||||
|
||||
burn(
|
||||
_account: string,
|
||||
_amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
getAverageStableRate(): Promise<BigNumber>;
|
||||
|
||||
getUserStableRate(_user: string): Promise<BigNumber>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
rate: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
filters: {};
|
||||
|
||||
estimate: {
|
||||
burn(_account: string, _amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
getAverageStableRate(): Promise<BigNumber>;
|
||||
|
||||
getUserStableRate(_user: string): Promise<BigNumber>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
rate: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
};
|
||||
}
|
92
types/IStableDebtTokenFactory.ts
Normal file
92
types/IStableDebtTokenFactory.ts
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* Generated by ts-generator ver. 0.0.8 */
|
||||
/* tslint:disable */
|
||||
|
||||
import { Contract, Signer } from "ethers";
|
||||
import { Provider } from "ethers/providers";
|
||||
|
||||
import { IStableDebtToken } from "./IStableDebtToken";
|
||||
|
||||
export class IStableDebtTokenFactory {
|
||||
static connect(
|
||||
address: string,
|
||||
signerOrProvider: Signer | Provider
|
||||
): IStableDebtToken {
|
||||
return new Contract(address, _abi, signerOrProvider) as IStableDebtToken;
|
||||
}
|
||||
}
|
||||
|
||||
const _abi = [
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "_account",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "_amount",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "burn",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "getAverageStableRate",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "_user",
|
||||
type: "address"
|
||||
}
|
||||
],
|
||||
name: "getUserStableRate",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "account",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "amount",
|
||||
type: "uint256"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "rate",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "mint",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
}
|
||||
];
|
76
types/IVariableDebtToken.d.ts
vendored
Normal file
76
types/IVariableDebtToken.d.ts
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* Generated by ts-generator ver. 0.0.8 */
|
||||
/* tslint:disable */
|
||||
|
||||
import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
|
||||
import { Listener, Provider } from "ethers/providers";
|
||||
import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
|
||||
import {
|
||||
TransactionOverrides,
|
||||
TypedEventDescription,
|
||||
TypedFunctionDescription
|
||||
} from ".";
|
||||
|
||||
interface IVariableDebtTokenInterface extends Interface {
|
||||
functions: {
|
||||
burn: TypedFunctionDescription<{
|
||||
encode([_account, _amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
mint: TypedFunctionDescription<{
|
||||
encode([account, amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
};
|
||||
|
||||
events: {};
|
||||
}
|
||||
|
||||
export class IVariableDebtToken extends Contract {
|
||||
connect(signerOrProvider: Signer | Provider | string): IVariableDebtToken;
|
||||
attach(addressOrName: string): IVariableDebtToken;
|
||||
deployed(): Promise<IVariableDebtToken>;
|
||||
|
||||
on(event: EventFilter | string, listener: Listener): IVariableDebtToken;
|
||||
once(event: EventFilter | string, listener: Listener): IVariableDebtToken;
|
||||
addListener(
|
||||
eventName: EventFilter | string,
|
||||
listener: Listener
|
||||
): IVariableDebtToken;
|
||||
removeAllListeners(eventName: EventFilter | string): IVariableDebtToken;
|
||||
removeListener(eventName: any, listener: Listener): IVariableDebtToken;
|
||||
|
||||
interface: IVariableDebtTokenInterface;
|
||||
|
||||
functions: {
|
||||
burn(
|
||||
_account: string,
|
||||
_amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
};
|
||||
|
||||
burn(
|
||||
_account: string,
|
||||
_amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
filters: {};
|
||||
|
||||
estimate: {
|
||||
burn(_account: string, _amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
mint(account: string, amount: BigNumberish): Promise<BigNumber>;
|
||||
};
|
||||
}
|
55
types/IVariableDebtTokenFactory.ts
Normal file
55
types/IVariableDebtTokenFactory.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* Generated by ts-generator ver. 0.0.8 */
|
||||
/* tslint:disable */
|
||||
|
||||
import { Contract, Signer } from "ethers";
|
||||
import { Provider } from "ethers/providers";
|
||||
|
||||
import { IVariableDebtToken } from "./IVariableDebtToken";
|
||||
|
||||
export class IVariableDebtTokenFactory {
|
||||
static connect(
|
||||
address: string,
|
||||
signerOrProvider: Signer | Provider
|
||||
): IVariableDebtToken {
|
||||
return new Contract(address, _abi, signerOrProvider) as IVariableDebtToken;
|
||||
}
|
||||
}
|
||||
|
||||
const _abi = [
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "_account",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "_amount",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "burn",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "account",
|
||||
type: "address"
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "amount",
|
||||
type: "uint256"
|
||||
}
|
||||
],
|
||||
name: "mint",
|
||||
outputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "function"
|
||||
}
|
||||
];
|
92
types/LendingPool.d.ts
vendored
92
types/LendingPool.d.ts
vendored
|
@ -77,6 +77,10 @@ interface LendingPoolInterface extends Interface {
|
|||
encode([_reserve]: [string]): string;
|
||||
}>;
|
||||
|
||||
getReserveNormalizedVariableDebt: TypedFunctionDescription<{
|
||||
encode([_reserve]: [string]): string;
|
||||
}>;
|
||||
|
||||
getReserves: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
getUserAccountData: TypedFunctionDescription<{
|
||||
|
@ -91,9 +95,11 @@ interface LendingPoolInterface extends Interface {
|
|||
encode([
|
||||
_reserve,
|
||||
_aTokenAddress,
|
||||
_stableDebtAddress,
|
||||
_variableDebtAddress,
|
||||
_decimals,
|
||||
_interestRateStrategyAddress
|
||||
]: [string, string, BigNumberish, string]): string;
|
||||
]: [string, string, string, string, BigNumberish, string]): string;
|
||||
}>;
|
||||
|
||||
initialize: TypedFunctionDescription<{
|
||||
|
@ -124,9 +130,10 @@ interface LendingPoolInterface extends Interface {
|
|||
}>;
|
||||
|
||||
repay: TypedFunctionDescription<{
|
||||
encode([_reserve, _amount, _onBehalfOf]: [
|
||||
encode([_reserve, _amount, _rateMode, _onBehalfOf]: [
|
||||
string,
|
||||
BigNumberish,
|
||||
BigNumberish,
|
||||
string
|
||||
]): string;
|
||||
}>;
|
||||
|
@ -192,8 +199,6 @@ interface LendingPoolInterface extends Interface {
|
|||
_amount,
|
||||
_borrowRateMode,
|
||||
_borrowRate,
|
||||
_originationFee,
|
||||
_borrowBalanceIncrease,
|
||||
_referral,
|
||||
_timestamp
|
||||
]: [
|
||||
|
@ -202,8 +207,6 @@ interface LendingPoolInterface extends Interface {
|
|||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
BigNumberish | null,
|
||||
null
|
||||
]): string[];
|
||||
|
@ -292,21 +295,11 @@ interface LendingPoolInterface extends Interface {
|
|||
}>;
|
||||
|
||||
Repay: TypedEventDescription<{
|
||||
encodeTopics([
|
||||
_reserve,
|
||||
_user,
|
||||
_repayer,
|
||||
_amountMinusFees,
|
||||
_fees,
|
||||
_borrowBalanceIncrease,
|
||||
_timestamp
|
||||
]: [
|
||||
encodeTopics([_reserve, _user, _repayer, _amount, _timestamp]: [
|
||||
string | null,
|
||||
string | null,
|
||||
string | null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]): string[];
|
||||
}>;
|
||||
|
@ -320,14 +313,13 @@ interface LendingPoolInterface extends Interface {
|
|||
}>;
|
||||
|
||||
Swap: TypedEventDescription<{
|
||||
encodeTopics([
|
||||
_reserve,
|
||||
_user,
|
||||
_newRateMode,
|
||||
_newRate,
|
||||
_borrowBalanceIncrease,
|
||||
_timestamp
|
||||
]: [string | null, string | null, null, null, null, null]): string[];
|
||||
encodeTopics([_reserve, _user, _newRateMode, _newRate, _timestamp]: [
|
||||
string | null,
|
||||
string | null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]): string[];
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
@ -446,6 +438,8 @@ export class LendingPool extends Contract {
|
|||
|
||||
getReserveNormalizedIncome(_reserve: string): Promise<BigNumber>;
|
||||
|
||||
getReserveNormalizedVariableDebt(_reserve: string): Promise<BigNumber>;
|
||||
|
||||
getReserves(): Promise<string[]>;
|
||||
|
||||
getUserAccountData(
|
||||
|
@ -472,14 +466,13 @@ export class LendingPool extends Contract {
|
|||
_user: string
|
||||
): Promise<{
|
||||
currentATokenBalance: BigNumber;
|
||||
currentBorrowBalance: BigNumber;
|
||||
principalBorrowBalance: BigNumber;
|
||||
borrowRateMode: BigNumber;
|
||||
borrowRate: BigNumber;
|
||||
currentStableBorrowBalance: BigNumber;
|
||||
currentVariableBorrowBalance: BigNumber;
|
||||
principalStableBorrowBalance: BigNumber;
|
||||
principalVariableBorrowBalance: BigNumber;
|
||||
stableBorrowRate: BigNumber;
|
||||
liquidityRate: BigNumber;
|
||||
originationFee: BigNumber;
|
||||
variableBorrowIndex: BigNumber;
|
||||
lastUpdateTimestamp: BigNumber;
|
||||
usageAsCollateralEnabled: boolean;
|
||||
0: BigNumber;
|
||||
1: BigNumber;
|
||||
|
@ -489,13 +482,14 @@ export class LendingPool extends Contract {
|
|||
5: BigNumber;
|
||||
6: BigNumber;
|
||||
7: BigNumber;
|
||||
8: BigNumber;
|
||||
9: boolean;
|
||||
8: boolean;
|
||||
}>;
|
||||
|
||||
initReserve(
|
||||
_reserve: string,
|
||||
_aTokenAddress: string,
|
||||
_stableDebtAddress: string,
|
||||
_variableDebtAddress: string,
|
||||
_decimals: BigNumberish,
|
||||
_interestRateStrategyAddress: string,
|
||||
overrides?: TransactionOverrides
|
||||
|
@ -532,6 +526,7 @@ export class LendingPool extends Contract {
|
|||
repay(
|
||||
_reserve: string,
|
||||
_amount: BigNumberish,
|
||||
_rateMode: BigNumberish,
|
||||
_onBehalfOf: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
@ -705,6 +700,8 @@ export class LendingPool extends Contract {
|
|||
|
||||
getReserveNormalizedIncome(_reserve: string): Promise<BigNumber>;
|
||||
|
||||
getReserveNormalizedVariableDebt(_reserve: string): Promise<BigNumber>;
|
||||
|
||||
getReserves(): Promise<string[]>;
|
||||
|
||||
getUserAccountData(
|
||||
|
@ -731,14 +728,13 @@ export class LendingPool extends Contract {
|
|||
_user: string
|
||||
): Promise<{
|
||||
currentATokenBalance: BigNumber;
|
||||
currentBorrowBalance: BigNumber;
|
||||
principalBorrowBalance: BigNumber;
|
||||
borrowRateMode: BigNumber;
|
||||
borrowRate: BigNumber;
|
||||
currentStableBorrowBalance: BigNumber;
|
||||
currentVariableBorrowBalance: BigNumber;
|
||||
principalStableBorrowBalance: BigNumber;
|
||||
principalVariableBorrowBalance: BigNumber;
|
||||
stableBorrowRate: BigNumber;
|
||||
liquidityRate: BigNumber;
|
||||
originationFee: BigNumber;
|
||||
variableBorrowIndex: BigNumber;
|
||||
lastUpdateTimestamp: BigNumber;
|
||||
usageAsCollateralEnabled: boolean;
|
||||
0: BigNumber;
|
||||
1: BigNumber;
|
||||
|
@ -748,13 +744,14 @@ export class LendingPool extends Contract {
|
|||
5: BigNumber;
|
||||
6: BigNumber;
|
||||
7: BigNumber;
|
||||
8: BigNumber;
|
||||
9: boolean;
|
||||
8: boolean;
|
||||
}>;
|
||||
|
||||
initReserve(
|
||||
_reserve: string,
|
||||
_aTokenAddress: string,
|
||||
_stableDebtAddress: string,
|
||||
_variableDebtAddress: string,
|
||||
_decimals: BigNumberish,
|
||||
_interestRateStrategyAddress: string,
|
||||
overrides?: TransactionOverrides
|
||||
|
@ -791,6 +788,7 @@ export class LendingPool extends Contract {
|
|||
repay(
|
||||
_reserve: string,
|
||||
_amount: BigNumberish,
|
||||
_rateMode: BigNumberish,
|
||||
_onBehalfOf: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
@ -870,8 +868,6 @@ export class LendingPool extends Contract {
|
|||
_amount: null,
|
||||
_borrowRateMode: null,
|
||||
_borrowRate: null,
|
||||
_originationFee: null,
|
||||
_borrowBalanceIncrease: null,
|
||||
_referral: BigNumberish | null,
|
||||
_timestamp: null
|
||||
): EventFilter;
|
||||
|
@ -933,9 +929,7 @@ export class LendingPool extends Contract {
|
|||
_reserve: string | null,
|
||||
_user: string | null,
|
||||
_repayer: string | null,
|
||||
_amountMinusFees: null,
|
||||
_fees: null,
|
||||
_borrowBalanceIncrease: null,
|
||||
_amount: null,
|
||||
_timestamp: null
|
||||
): EventFilter;
|
||||
|
||||
|
@ -954,7 +948,6 @@ export class LendingPool extends Contract {
|
|||
_user: string | null,
|
||||
_newRateMode: null,
|
||||
_newRate: null,
|
||||
_borrowBalanceIncrease: null,
|
||||
_timestamp: null
|
||||
): EventFilter;
|
||||
};
|
||||
|
@ -1007,6 +1000,8 @@ export class LendingPool extends Contract {
|
|||
|
||||
getReserveNormalizedIncome(_reserve: string): Promise<BigNumber>;
|
||||
|
||||
getReserveNormalizedVariableDebt(_reserve: string): Promise<BigNumber>;
|
||||
|
||||
getReserves(): Promise<BigNumber>;
|
||||
|
||||
getUserAccountData(_user: string): Promise<BigNumber>;
|
||||
|
@ -1016,6 +1011,8 @@ export class LendingPool extends Contract {
|
|||
initReserve(
|
||||
_reserve: string,
|
||||
_aTokenAddress: string,
|
||||
_stableDebtAddress: string,
|
||||
_variableDebtAddress: string,
|
||||
_decimals: BigNumberish,
|
||||
_interestRateStrategyAddress: string
|
||||
): Promise<BigNumber>;
|
||||
|
@ -1045,6 +1042,7 @@ export class LendingPool extends Contract {
|
|||
repay(
|
||||
_reserve: string,
|
||||
_amount: BigNumberish,
|
||||
_rateMode: BigNumberish,
|
||||
_onBehalfOf: string
|
||||
): Promise<BigNumber>;
|
||||
|
||||
|
|
46
types/LendingPoolConfigurator.d.ts
vendored
46
types/LendingPoolConfigurator.d.ts
vendored
|
@ -30,7 +30,7 @@ interface LendingPoolConfiguratorInterface extends Interface {
|
|||
encode([_reserve]: [string]): string;
|
||||
}>;
|
||||
|
||||
disableReserveStableBorrowRate: TypedFunctionDescription<{
|
||||
disableReserveStableRate: TypedFunctionDescription<{
|
||||
encode([_reserve]: [string]): string;
|
||||
}>;
|
||||
|
||||
|
@ -59,8 +59,10 @@ interface LendingPoolConfiguratorInterface extends Interface {
|
|||
encode([
|
||||
_reserve,
|
||||
_underlyingAssetDecimals,
|
||||
_interestRateStrategyAddress
|
||||
]: [string, BigNumberish, string]): string;
|
||||
_interestRateStrategyAddress,
|
||||
_stableDebtTokenAddress,
|
||||
_variableDebtTokenAddress
|
||||
]: [string, BigNumberish, string, string, string]): string;
|
||||
}>;
|
||||
|
||||
initReserveWithData: TypedFunctionDescription<{
|
||||
|
@ -68,9 +70,19 @@ interface LendingPoolConfiguratorInterface extends Interface {
|
|||
_reserve,
|
||||
_aTokenName,
|
||||
_aTokenSymbol,
|
||||
_stableDebtTokenAddress,
|
||||
_variableDebtTokenAddress,
|
||||
_underlyingAssetDecimals,
|
||||
_interestRateStrategyAddress
|
||||
]: [string, string, string, BigNumberish, string]): string;
|
||||
]: [
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
BigNumberish,
|
||||
string
|
||||
]): string;
|
||||
}>;
|
||||
|
||||
initialize: TypedFunctionDescription<{
|
||||
|
@ -166,10 +178,6 @@ interface LendingPoolConfiguratorInterface extends Interface {
|
|||
encodeTopics([_reserve, _threshold]: [null, null]): string[];
|
||||
}>;
|
||||
|
||||
ReserveRemoved: TypedEventDescription<{
|
||||
encodeTopics([_reserve]: [string | null]): string[];
|
||||
}>;
|
||||
|
||||
ReserveUnfreezed: TypedEventDescription<{
|
||||
encodeTopics([_reserve]: [string | null]): string[];
|
||||
}>;
|
||||
|
@ -228,7 +236,7 @@ export class LendingPoolConfigurator extends Contract {
|
|||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
disableReserveStableBorrowRate(
|
||||
disableReserveStableRate(
|
||||
_reserve: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
@ -261,6 +269,8 @@ export class LendingPoolConfigurator extends Contract {
|
|||
_reserve: string,
|
||||
_underlyingAssetDecimals: BigNumberish,
|
||||
_interestRateStrategyAddress: string,
|
||||
_stableDebtTokenAddress: string,
|
||||
_variableDebtTokenAddress: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
|
@ -268,6 +278,8 @@ export class LendingPoolConfigurator extends Contract {
|
|||
_reserve: string,
|
||||
_aTokenName: string,
|
||||
_aTokenSymbol: string,
|
||||
_stableDebtTokenAddress: string,
|
||||
_variableDebtTokenAddress: string,
|
||||
_underlyingAssetDecimals: BigNumberish,
|
||||
_interestRateStrategyAddress: string,
|
||||
overrides?: TransactionOverrides
|
||||
|
@ -338,7 +350,7 @@ export class LendingPoolConfigurator extends Contract {
|
|||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
disableReserveStableBorrowRate(
|
||||
disableReserveStableRate(
|
||||
_reserve: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
@ -371,6 +383,8 @@ export class LendingPoolConfigurator extends Contract {
|
|||
_reserve: string,
|
||||
_underlyingAssetDecimals: BigNumberish,
|
||||
_interestRateStrategyAddress: string,
|
||||
_stableDebtTokenAddress: string,
|
||||
_variableDebtTokenAddress: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
|
@ -378,6 +392,8 @@ export class LendingPoolConfigurator extends Contract {
|
|||
_reserve: string,
|
||||
_aTokenName: string,
|
||||
_aTokenSymbol: string,
|
||||
_stableDebtTokenAddress: string,
|
||||
_variableDebtTokenAddress: string,
|
||||
_underlyingAssetDecimals: BigNumberish,
|
||||
_interestRateStrategyAddress: string,
|
||||
overrides?: TransactionOverrides
|
||||
|
@ -470,8 +486,6 @@ export class LendingPoolConfigurator extends Contract {
|
|||
_threshold: null
|
||||
): EventFilter;
|
||||
|
||||
ReserveRemoved(_reserve: string | null): EventFilter;
|
||||
|
||||
ReserveUnfreezed(_reserve: string | null): EventFilter;
|
||||
|
||||
StableRateDisabledOnReserve(_reserve: string | null): EventFilter;
|
||||
|
@ -490,7 +504,7 @@ export class LendingPoolConfigurator extends Contract {
|
|||
|
||||
disableReserveAsCollateral(_reserve: string): Promise<BigNumber>;
|
||||
|
||||
disableReserveStableBorrowRate(_reserve: string): Promise<BigNumber>;
|
||||
disableReserveStableRate(_reserve: string): Promise<BigNumber>;
|
||||
|
||||
enableBorrowingOnReserve(
|
||||
_reserve: string,
|
||||
|
@ -511,13 +525,17 @@ export class LendingPoolConfigurator extends Contract {
|
|||
initReserve(
|
||||
_reserve: string,
|
||||
_underlyingAssetDecimals: BigNumberish,
|
||||
_interestRateStrategyAddress: string
|
||||
_interestRateStrategyAddress: string,
|
||||
_stableDebtTokenAddress: string,
|
||||
_variableDebtTokenAddress: string
|
||||
): Promise<BigNumber>;
|
||||
|
||||
initReserveWithData(
|
||||
_reserve: string,
|
||||
_aTokenName: string,
|
||||
_aTokenSymbol: string,
|
||||
_stableDebtTokenAddress: string,
|
||||
_variableDebtTokenAddress: string,
|
||||
_underlyingAssetDecimals: BigNumberish,
|
||||
_interestRateStrategyAddress: string
|
||||
): Promise<BigNumber>;
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -166,4 +166,4 @@ const _abi = [
|
|||
];
|
||||
|
||||
const _bytecode =
|
||||
"0x60806040526000805460ff60a01b1916905534801561001d57600080fd5b5060405161097d38038061097d8339818101604052602081101561004057600080fd5b5051600080546001600160a01b039092166001600160a01b031990921691909117905561090b806100726000396000f3fe6080604052600436106100385760003560e01c8063388f70f114610044578063c72c4d1014610072578063ee872558146100a35761003f565b3661003f57005b600080fd5b34801561005057600080fd5b506100706004803603602081101561006757600080fd5b50351515610172565b005b34801561007e57600080fd5b50610087610190565b604080516001600160a01b039092168252519081900360200190f35b3480156100af57600080fd5b50610070600480360360808110156100c657600080fd5b6001600160a01b0382351691602081013591604082013591908101906080810160608201356401000000008111156100fd57600080fd5b82018360208201111561010f57600080fd5b8035906020019184600183028401116401000000008311171561013157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061019f945050505050565b60008054911515600160a01b0260ff60a01b19909216919091179055565b6000546001600160a01b031681565b836101aa308261035c565b8411156101fe576040805162461bcd60e51b815260206004820181905260248201527f496e76616c69642062616c616e636520666f722074686520636f6e7472616374604482015290519081900360640190fd5b600054600160a01b900460ff161561025f57604080516001600160a01b03871681526020810186905280820185905290517f816f6a6bc084e1996be1a831afa1af30763d0501b6b43b9e1922a11f347366d79181900360600190a150610356565b61026761041b565b6001600160a01b0316856001600160a01b0316146102f257806001600160a01b031663a0712d68846040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156102c557600080fd5b505af11580156102d9573d6000803e3d6000fd5b505050506040513d60208110156102ef57600080fd5b50505b61030b85610306868663ffffffff61043316565b610494565b604080516001600160a01b03871681526020810186905280820185905290517f7d94e9d0c906b8d7b2b52a581b9e9ba728aa6f8cd8532bd87243d193f47401be9181900360600190a1505b50505050565b600061036661041b565b6001600160a01b0316826001600160a01b0316141561039057506001600160a01b03821631610415565b816001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156103e657600080fd5b505afa1580156103fa573d6000803e3d6000fd5b505050506040513d602081101561041057600080fd5b505190505b92915050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b60008282018381101561048d576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60008060009054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156104e357600080fd5b505afa1580156104f7573d6000803e3d6000fd5b505050506040513d602081101561050d57600080fd5b5051905061051c818484610521565b505050565b61052961041b565b6001600160a01b0316826001600160a01b03161415610598576040516001600160a01b038416908290600081818185875af1925050503d806000811461058b576040519150601f19603f3d011682016040523d82523d6000602084013e610590565b606091505b50505061051c565b61051c6001600160a01b038316848363ffffffff6105b216565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261051c9084906060610654826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166106b09092919063ffffffff16565b80519091501561051c5780806020019051602081101561067357600080fd5b505161051c5760405162461bcd60e51b815260040180806020018281038252602a8152602001806108ac602a913960400191505060405180910390fd5b60606106bf84846000856106c7565b949350505050565b60606106d285610872565b610723576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106107625780518252601f199092019160209182019101610743565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146107c4576040519150601f19603f3d011682016040523d82523d6000602084013e6107c9565b606091505b509150915081156107dd5791506106bf9050565b8051156107ed5780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561083757818101518382015260200161081f565b50505050905090810190601f1680156108645780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906106bf57505015159291505056fe5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220a299983b72bd4ca32d420156e97674b8e9505e79a24f73825976473a30f93d2764736f6c63430006080033";
|
||||
"0x60806040526000805460ff60a01b1916905534801561001d57600080fd5b5060405161097d38038061097d8339818101604052602081101561004057600080fd5b5051600080546001600160a01b039092166001600160a01b031990921691909117905561090b806100726000396000f3fe6080604052600436106100385760003560e01c8063388f70f114610044578063c72c4d1014610072578063ee872558146100a35761003f565b3661003f57005b600080fd5b34801561005057600080fd5b506100706004803603602081101561006757600080fd5b50351515610172565b005b34801561007e57600080fd5b50610087610190565b604080516001600160a01b039092168252519081900360200190f35b3480156100af57600080fd5b50610070600480360360808110156100c657600080fd5b6001600160a01b0382351691602081013591604082013591908101906080810160608201356401000000008111156100fd57600080fd5b82018360208201111561010f57600080fd5b8035906020019184600183028401116401000000008311171561013157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061019f945050505050565b60008054911515600160a01b0260ff60a01b19909216919091179055565b6000546001600160a01b031681565b836101aa308261035c565b8411156101fe576040805162461bcd60e51b815260206004820181905260248201527f496e76616c69642062616c616e636520666f722074686520636f6e7472616374604482015290519081900360640190fd5b600054600160a01b900460ff161561025f57604080516001600160a01b03871681526020810186905280820185905290517f816f6a6bc084e1996be1a831afa1af30763d0501b6b43b9e1922a11f347366d79181900360600190a150610356565b61026761041b565b6001600160a01b0316856001600160a01b0316146102f257806001600160a01b031663a0712d68846040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156102c557600080fd5b505af11580156102d9573d6000803e3d6000fd5b505050506040513d60208110156102ef57600080fd5b50505b61030b85610306868663ffffffff61043316565b610494565b604080516001600160a01b03871681526020810186905280820185905290517f7d94e9d0c906b8d7b2b52a581b9e9ba728aa6f8cd8532bd87243d193f47401be9181900360600190a1505b50505050565b600061036661041b565b6001600160a01b0316826001600160a01b0316141561039057506001600160a01b03821631610415565b816001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156103e657600080fd5b505afa1580156103fa573d6000803e3d6000fd5b505050506040513d602081101561041057600080fd5b505190505b92915050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b60008282018381101561048d576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60008060009054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156104e357600080fd5b505afa1580156104f7573d6000803e3d6000fd5b505050506040513d602081101561050d57600080fd5b5051905061051c818484610521565b505050565b61052961041b565b6001600160a01b0316826001600160a01b03161415610598576040516001600160a01b038416908290600081818185875af1925050503d806000811461058b576040519150601f19603f3d011682016040523d82523d6000602084013e610590565b606091505b50505061051c565b61051c6001600160a01b038316848363ffffffff6105b216565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261051c9084906060610654826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166106b09092919063ffffffff16565b80519091501561051c5780806020019051602081101561067357600080fd5b505161051c5760405162461bcd60e51b815260040180806020018281038252602a8152602001806108ac602a913960400191505060405180910390fd5b60606106bf84846000856106c7565b949350505050565b60606106d285610872565b610723576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106107625780518252601f199092019160209182019101610743565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146107c4576040519150601f19603f3d011682016040523d82523d6000602084013e6107c9565b606091505b509150915081156107dd5791506106bf9050565b8051156107ed5780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561083757818101518382015260200161081f565b50505050905090810190601f1680156108645780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906106bf57505015159291505056fe5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122023de80bbbbbbaf12affd9536d6b8b029e9c0edc1d14c31a634e817ffe3d033db64736f6c63430006080033";
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -121,4 +121,4 @@ const _abi = [
|
|||
];
|
||||
|
||||
const _bytecode =
|
||||
"0x608060405234801561001057600080fd5b506040516106b53803806106b58339818101604052602081101561003357600080fd5b5051600080546001600160a01b039092166001600160a01b0319909216919091179055610650806100656000396000f3fe6080604052600436106100295760003560e01c806329589f611461002e5780634f1b86eb146100ec575b600080fd5b6100da600480360361010081101561004557600080fd5b6001600160a01b0382358116926020810135926040820135831692606083013581169260808101359260a08201359260c0830135169190810190610100810160e082013564010000000081111561009b57600080fd5b8201836020820111156100ad57600080fd5b803590602001918460018302840111640100000000831117156100cf57600080fd5b50909250905061011d565b60408051918252519081900360200190f35b3480156100f857600080fd5b50610101610266565b604080516001600160a01b039092168252519081900360200190f35b600080546040805163140e25ad60e31b8152670de0b6b3a7640000600482015290516001600160a01b039092169163a0712d689160248082019260209290919082900301818787803b15801561017257600080fd5b505af1158015610186573d6000803e3d6000fd5b505050506040513d602081101561019c57600080fd5b50516101ef576040805162461bcd60e51b815260206004820181905260248201527f54524144455f574954485f48494e542e205265766572746564206d696e742829604482015290519081900360640190fd5b6101f7610275565b6001600160a01b03168a6001600160a01b03161461022a5761022a6001600160a01b038b1633308c63ffffffff61028d16565b60005461024f906001600160a01b031633670de0b6b3a764000063ffffffff6102ed16565b50670de0b6b3a76400009998505050505050505050565b6000546001600160a01b031681565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526102e7908590610344565b50505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261033f908490610344565b505050565b6060610399826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166103f59092919063ffffffff16565b80519091501561033f578080602001905160208110156103b857600080fd5b505161033f5760405162461bcd60e51b815260040180806020018281038252602a8152602001806105f1602a913960400191505060405180910390fd5b6060610404848460008561040c565b949350505050565b6060610417856105b7565b610468576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106104a75780518252601f199092019160209182019101610488565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114610509576040519150601f19603f3d011682016040523d82523d6000602084013e61050e565b606091505b509150915081156105225791506104049050565b8051156105325780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561057c578181015183820152602001610564565b50505050905090810190601f1680156105a95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061040457505015159291505056fe5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122066073a4fdabfdc9fdc75e5c06b763b6d46c77b60344a68746725799a4b1b9b7264736f6c63430006080033";
|
||||
"0x608060405234801561001057600080fd5b506040516106b53803806106b58339818101604052602081101561003357600080fd5b5051600080546001600160a01b039092166001600160a01b0319909216919091179055610650806100656000396000f3fe6080604052600436106100295760003560e01c806329589f611461002e5780634f1b86eb146100ec575b600080fd5b6100da600480360361010081101561004557600080fd5b6001600160a01b0382358116926020810135926040820135831692606083013581169260808101359260a08201359260c0830135169190810190610100810160e082013564010000000081111561009b57600080fd5b8201836020820111156100ad57600080fd5b803590602001918460018302840111640100000000831117156100cf57600080fd5b50909250905061011d565b60408051918252519081900360200190f35b3480156100f857600080fd5b50610101610266565b604080516001600160a01b039092168252519081900360200190f35b600080546040805163140e25ad60e31b8152670de0b6b3a7640000600482015290516001600160a01b039092169163a0712d689160248082019260209290919082900301818787803b15801561017257600080fd5b505af1158015610186573d6000803e3d6000fd5b505050506040513d602081101561019c57600080fd5b50516101ef576040805162461bcd60e51b815260206004820181905260248201527f54524144455f574954485f48494e542e205265766572746564206d696e742829604482015290519081900360640190fd5b6101f7610275565b6001600160a01b03168a6001600160a01b03161461022a5761022a6001600160a01b038b1633308c63ffffffff61028d16565b60005461024f906001600160a01b031633670de0b6b3a764000063ffffffff6102ed16565b50670de0b6b3a76400009998505050505050505050565b6000546001600160a01b031681565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee90565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526102e7908590610344565b50505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261033f908490610344565b505050565b6060610399826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166103f59092919063ffffffff16565b80519091501561033f578080602001905160208110156103b857600080fd5b505161033f5760405162461bcd60e51b815260040180806020018281038252602a8152602001806105f1602a913960400191505060405180910390fd5b6060610404848460008561040c565b949350505050565b6060610417856105b7565b610468576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106104a75780518252601f199092019160209182019101610488565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114610509576040519150601f19603f3d011682016040523d82523d6000602084013e61050e565b606091505b509150915081156105225791506104049050565b8051156105325780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561057c578181015183820152602001610564565b50505050905090810190601f1680156105a95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061040457505015159291505056fe5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122099f447de7dc340bb9fad6029140c928c6fde2d7c3b3f7bb83714a93e38cb1f2f64736f6c63430006080033";
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
380
types/StableDebtToken.d.ts
vendored
Normal file
380
types/StableDebtToken.d.ts
vendored
Normal file
|
@ -0,0 +1,380 @@
|
|||
/* Generated by ts-generator ver. 0.0.8 */
|
||||
/* tslint:disable */
|
||||
|
||||
import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
|
||||
import { Listener, Provider } from "ethers/providers";
|
||||
import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
|
||||
import {
|
||||
TransactionOverrides,
|
||||
TypedEventDescription,
|
||||
TypedFunctionDescription
|
||||
} from ".";
|
||||
|
||||
interface StableDebtTokenInterface extends Interface {
|
||||
functions: {
|
||||
allowance: TypedFunctionDescription<{
|
||||
encode([owner, spender]: [string, string]): string;
|
||||
}>;
|
||||
|
||||
approve: TypedFunctionDescription<{
|
||||
encode([spender, amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
balanceOf: TypedFunctionDescription<{
|
||||
encode([account]: [string]): string;
|
||||
}>;
|
||||
|
||||
burn: TypedFunctionDescription<{
|
||||
encode([_account, _amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
decimals: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
decreaseAllowance: TypedFunctionDescription<{
|
||||
encode([spender, subtractedValue]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
getAverageStableRate: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
getUserStableRate: TypedFunctionDescription<{
|
||||
encode([_user]: [string]): string;
|
||||
}>;
|
||||
|
||||
increaseAllowance: TypedFunctionDescription<{
|
||||
encode([spender, addedValue]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
init: TypedFunctionDescription<{
|
||||
encode([_name, _symbol, _decimals, _underlying, _addressesProvider]: [
|
||||
string,
|
||||
string,
|
||||
BigNumberish,
|
||||
string,
|
||||
string
|
||||
]): string;
|
||||
}>;
|
||||
|
||||
mint: TypedFunctionDescription<{
|
||||
encode([account, amount, rate]: [
|
||||
string,
|
||||
BigNumberish,
|
||||
BigNumberish
|
||||
]): string;
|
||||
}>;
|
||||
|
||||
name: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
principalBalanceOf: TypedFunctionDescription<{
|
||||
encode([account]: [string]): string;
|
||||
}>;
|
||||
|
||||
symbol: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
totalSupply: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
transfer: TypedFunctionDescription<{
|
||||
encode([recipient, amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
transferFrom: TypedFunctionDescription<{
|
||||
encode([sender, recipient, amount]: [
|
||||
string,
|
||||
string,
|
||||
BigNumberish
|
||||
]): string;
|
||||
}>;
|
||||
|
||||
underlyingAssetAddress: TypedFunctionDescription<{
|
||||
encode([]: []): string;
|
||||
}>;
|
||||
};
|
||||
|
||||
events: {
|
||||
Approval: TypedEventDescription<{
|
||||
encodeTopics([owner, spender, value]: [
|
||||
string | null,
|
||||
string | null,
|
||||
null
|
||||
]): string[];
|
||||
}>;
|
||||
|
||||
Transfer: TypedEventDescription<{
|
||||
encodeTopics([from, to, value]: [
|
||||
string | null,
|
||||
string | null,
|
||||
null
|
||||
]): string[];
|
||||
}>;
|
||||
|
||||
burnDebt: TypedEventDescription<{
|
||||
encodeTopics([
|
||||
_user,
|
||||
_amount,
|
||||
_previousBalance,
|
||||
_currentBalance,
|
||||
_balanceIncrease
|
||||
]: [null, null, null, null, null]): string[];
|
||||
}>;
|
||||
|
||||
mintDebt: TypedEventDescription<{
|
||||
encodeTopics([
|
||||
_user,
|
||||
_amount,
|
||||
_previousBalance,
|
||||
_currentBalance,
|
||||
_balanceIncrease,
|
||||
_newRate
|
||||
]: [null, null, null, null, null, null]): string[];
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
export class StableDebtToken extends Contract {
|
||||
connect(signerOrProvider: Signer | Provider | string): StableDebtToken;
|
||||
attach(addressOrName: string): StableDebtToken;
|
||||
deployed(): Promise<StableDebtToken>;
|
||||
|
||||
on(event: EventFilter | string, listener: Listener): StableDebtToken;
|
||||
once(event: EventFilter | string, listener: Listener): StableDebtToken;
|
||||
addListener(
|
||||
eventName: EventFilter | string,
|
||||
listener: Listener
|
||||
): StableDebtToken;
|
||||
removeAllListeners(eventName: EventFilter | string): StableDebtToken;
|
||||
removeListener(eventName: any, listener: Listener): StableDebtToken;
|
||||
|
||||
interface: StableDebtTokenInterface;
|
||||
|
||||
functions: {
|
||||
allowance(owner: string, spender: string): Promise<BigNumber>;
|
||||
|
||||
approve(
|
||||
spender: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
balanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
burn(
|
||||
_account: string,
|
||||
_amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
decimals(): Promise<number>;
|
||||
|
||||
decreaseAllowance(
|
||||
spender: string,
|
||||
subtractedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
getAverageStableRate(): Promise<BigNumber>;
|
||||
|
||||
getUserStableRate(_user: string): Promise<BigNumber>;
|
||||
|
||||
increaseAllowance(
|
||||
spender: string,
|
||||
addedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
init(
|
||||
_name: string,
|
||||
_symbol: string,
|
||||
_decimals: BigNumberish,
|
||||
_underlying: string,
|
||||
_addressesProvider: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
rate: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
name(): Promise<string>;
|
||||
|
||||
principalBalanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
symbol(): Promise<string>;
|
||||
|
||||
totalSupply(): Promise<BigNumber>;
|
||||
|
||||
transfer(
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
transferFrom(
|
||||
sender: string,
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
underlyingAssetAddress(): Promise<string>;
|
||||
};
|
||||
|
||||
allowance(owner: string, spender: string): Promise<BigNumber>;
|
||||
|
||||
approve(
|
||||
spender: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
balanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
burn(
|
||||
_account: string,
|
||||
_amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
decimals(): Promise<number>;
|
||||
|
||||
decreaseAllowance(
|
||||
spender: string,
|
||||
subtractedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
getAverageStableRate(): Promise<BigNumber>;
|
||||
|
||||
getUserStableRate(_user: string): Promise<BigNumber>;
|
||||
|
||||
increaseAllowance(
|
||||
spender: string,
|
||||
addedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
init(
|
||||
_name: string,
|
||||
_symbol: string,
|
||||
_decimals: BigNumberish,
|
||||
_underlying: string,
|
||||
_addressesProvider: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
rate: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
name(): Promise<string>;
|
||||
|
||||
principalBalanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
symbol(): Promise<string>;
|
||||
|
||||
totalSupply(): Promise<BigNumber>;
|
||||
|
||||
transfer(
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
transferFrom(
|
||||
sender: string,
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
underlyingAssetAddress(): Promise<string>;
|
||||
|
||||
filters: {
|
||||
Approval(
|
||||
owner: string | null,
|
||||
spender: string | null,
|
||||
value: null
|
||||
): EventFilter;
|
||||
|
||||
Transfer(from: string | null, to: string | null, value: null): EventFilter;
|
||||
|
||||
burnDebt(
|
||||
_user: null,
|
||||
_amount: null,
|
||||
_previousBalance: null,
|
||||
_currentBalance: null,
|
||||
_balanceIncrease: null
|
||||
): EventFilter;
|
||||
|
||||
mintDebt(
|
||||
_user: null,
|
||||
_amount: null,
|
||||
_previousBalance: null,
|
||||
_currentBalance: null,
|
||||
_balanceIncrease: null,
|
||||
_newRate: null
|
||||
): EventFilter;
|
||||
};
|
||||
|
||||
estimate: {
|
||||
allowance(owner: string, spender: string): Promise<BigNumber>;
|
||||
|
||||
approve(spender: string, amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
balanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
burn(_account: string, _amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
decimals(): Promise<BigNumber>;
|
||||
|
||||
decreaseAllowance(
|
||||
spender: string,
|
||||
subtractedValue: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
getAverageStableRate(): Promise<BigNumber>;
|
||||
|
||||
getUserStableRate(_user: string): Promise<BigNumber>;
|
||||
|
||||
increaseAllowance(
|
||||
spender: string,
|
||||
addedValue: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
init(
|
||||
_name: string,
|
||||
_symbol: string,
|
||||
_decimals: BigNumberish,
|
||||
_underlying: string,
|
||||
_addressesProvider: string
|
||||
): Promise<BigNumber>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
rate: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
name(): Promise<BigNumber>;
|
||||
|
||||
principalBalanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
symbol(): Promise<BigNumber>;
|
||||
|
||||
totalSupply(): Promise<BigNumber>;
|
||||
|
||||
transfer(recipient: string, amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
transferFrom(
|
||||
sender: string,
|
||||
recipient: string,
|
||||
amount: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
underlyingAssetAddress(): Promise<BigNumber>;
|
||||
};
|
||||
}
|
528
types/StableDebtTokenFactory.ts
Normal file
528
types/StableDebtTokenFactory.ts
Normal file
File diff suppressed because one or more lines are too long
354
types/VariableDebtToken.d.ts
vendored
Normal file
354
types/VariableDebtToken.d.ts
vendored
Normal file
|
@ -0,0 +1,354 @@
|
|||
/* Generated by ts-generator ver. 0.0.8 */
|
||||
/* tslint:disable */
|
||||
|
||||
import { Contract, ContractTransaction, EventFilter, Signer } from "ethers";
|
||||
import { Listener, Provider } from "ethers/providers";
|
||||
import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils";
|
||||
import {
|
||||
TransactionOverrides,
|
||||
TypedEventDescription,
|
||||
TypedFunctionDescription
|
||||
} from ".";
|
||||
|
||||
interface VariableDebtTokenInterface extends Interface {
|
||||
functions: {
|
||||
allowance: TypedFunctionDescription<{
|
||||
encode([owner, spender]: [string, string]): string;
|
||||
}>;
|
||||
|
||||
approve: TypedFunctionDescription<{
|
||||
encode([spender, amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
balanceOf: TypedFunctionDescription<{
|
||||
encode([account]: [string]): string;
|
||||
}>;
|
||||
|
||||
burn: TypedFunctionDescription<{
|
||||
encode([account, amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
decimals: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
decreaseAllowance: TypedFunctionDescription<{
|
||||
encode([spender, subtractedValue]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
increaseAllowance: TypedFunctionDescription<{
|
||||
encode([spender, addedValue]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
init: TypedFunctionDescription<{
|
||||
encode([_name, _symbol, _decimals, _underlying, _addressesProvider]: [
|
||||
string,
|
||||
string,
|
||||
BigNumberish,
|
||||
string,
|
||||
string
|
||||
]): string;
|
||||
}>;
|
||||
|
||||
mint: TypedFunctionDescription<{
|
||||
encode([account, amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
name: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
principalBalanceOf: TypedFunctionDescription<{
|
||||
encode([account]: [string]): string;
|
||||
}>;
|
||||
|
||||
symbol: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
totalSupply: TypedFunctionDescription<{ encode([]: []): string }>;
|
||||
|
||||
transfer: TypedFunctionDescription<{
|
||||
encode([recipient, amount]: [string, BigNumberish]): string;
|
||||
}>;
|
||||
|
||||
transferFrom: TypedFunctionDescription<{
|
||||
encode([sender, recipient, amount]: [
|
||||
string,
|
||||
string,
|
||||
BigNumberish
|
||||
]): string;
|
||||
}>;
|
||||
|
||||
underlyingAssetAddress: TypedFunctionDescription<{
|
||||
encode([]: []): string;
|
||||
}>;
|
||||
};
|
||||
|
||||
events: {
|
||||
Approval: TypedEventDescription<{
|
||||
encodeTopics([owner, spender, value]: [
|
||||
string | null,
|
||||
string | null,
|
||||
null
|
||||
]): string[];
|
||||
}>;
|
||||
|
||||
Transfer: TypedEventDescription<{
|
||||
encodeTopics([from, to, value]: [
|
||||
string | null,
|
||||
string | null,
|
||||
null
|
||||
]): string[];
|
||||
}>;
|
||||
|
||||
burnDebt: TypedEventDescription<{
|
||||
encodeTopics([
|
||||
_user,
|
||||
_amount,
|
||||
_previousBalance,
|
||||
_currentBalance,
|
||||
_balanceIncrease,
|
||||
_index
|
||||
]: [null, null, null, null, null, null]): string[];
|
||||
}>;
|
||||
|
||||
mintDebt: TypedEventDescription<{
|
||||
encodeTopics([
|
||||
_user,
|
||||
_amount,
|
||||
_previousBalance,
|
||||
_currentBalance,
|
||||
_balanceIncrease,
|
||||
_index
|
||||
]: [null, null, null, null, null, null]): string[];
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
export class VariableDebtToken extends Contract {
|
||||
connect(signerOrProvider: Signer | Provider | string): VariableDebtToken;
|
||||
attach(addressOrName: string): VariableDebtToken;
|
||||
deployed(): Promise<VariableDebtToken>;
|
||||
|
||||
on(event: EventFilter | string, listener: Listener): VariableDebtToken;
|
||||
once(event: EventFilter | string, listener: Listener): VariableDebtToken;
|
||||
addListener(
|
||||
eventName: EventFilter | string,
|
||||
listener: Listener
|
||||
): VariableDebtToken;
|
||||
removeAllListeners(eventName: EventFilter | string): VariableDebtToken;
|
||||
removeListener(eventName: any, listener: Listener): VariableDebtToken;
|
||||
|
||||
interface: VariableDebtTokenInterface;
|
||||
|
||||
functions: {
|
||||
allowance(owner: string, spender: string): Promise<BigNumber>;
|
||||
|
||||
approve(
|
||||
spender: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
balanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
burn(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
decimals(): Promise<number>;
|
||||
|
||||
decreaseAllowance(
|
||||
spender: string,
|
||||
subtractedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
increaseAllowance(
|
||||
spender: string,
|
||||
addedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
init(
|
||||
_name: string,
|
||||
_symbol: string,
|
||||
_decimals: BigNumberish,
|
||||
_underlying: string,
|
||||
_addressesProvider: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
name(): Promise<string>;
|
||||
|
||||
principalBalanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
symbol(): Promise<string>;
|
||||
|
||||
totalSupply(): Promise<BigNumber>;
|
||||
|
||||
transfer(
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
transferFrom(
|
||||
sender: string,
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
underlyingAssetAddress(): Promise<string>;
|
||||
};
|
||||
|
||||
allowance(owner: string, spender: string): Promise<BigNumber>;
|
||||
|
||||
approve(
|
||||
spender: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
balanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
burn(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
decimals(): Promise<number>;
|
||||
|
||||
decreaseAllowance(
|
||||
spender: string,
|
||||
subtractedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
increaseAllowance(
|
||||
spender: string,
|
||||
addedValue: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
init(
|
||||
_name: string,
|
||||
_symbol: string,
|
||||
_decimals: BigNumberish,
|
||||
_underlying: string,
|
||||
_addressesProvider: string,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
mint(
|
||||
account: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
name(): Promise<string>;
|
||||
|
||||
principalBalanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
symbol(): Promise<string>;
|
||||
|
||||
totalSupply(): Promise<BigNumber>;
|
||||
|
||||
transfer(
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
transferFrom(
|
||||
sender: string,
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
overrides?: TransactionOverrides
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
underlyingAssetAddress(): Promise<string>;
|
||||
|
||||
filters: {
|
||||
Approval(
|
||||
owner: string | null,
|
||||
spender: string | null,
|
||||
value: null
|
||||
): EventFilter;
|
||||
|
||||
Transfer(from: string | null, to: string | null, value: null): EventFilter;
|
||||
|
||||
burnDebt(
|
||||
_user: null,
|
||||
_amount: null,
|
||||
_previousBalance: null,
|
||||
_currentBalance: null,
|
||||
_balanceIncrease: null,
|
||||
_index: null
|
||||
): EventFilter;
|
||||
|
||||
mintDebt(
|
||||
_user: null,
|
||||
_amount: null,
|
||||
_previousBalance: null,
|
||||
_currentBalance: null,
|
||||
_balanceIncrease: null,
|
||||
_index: null
|
||||
): EventFilter;
|
||||
};
|
||||
|
||||
estimate: {
|
||||
allowance(owner: string, spender: string): Promise<BigNumber>;
|
||||
|
||||
approve(spender: string, amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
balanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
burn(account: string, amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
decimals(): Promise<BigNumber>;
|
||||
|
||||
decreaseAllowance(
|
||||
spender: string,
|
||||
subtractedValue: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
increaseAllowance(
|
||||
spender: string,
|
||||
addedValue: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
init(
|
||||
_name: string,
|
||||
_symbol: string,
|
||||
_decimals: BigNumberish,
|
||||
_underlying: string,
|
||||
_addressesProvider: string
|
||||
): Promise<BigNumber>;
|
||||
|
||||
mint(account: string, amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
name(): Promise<BigNumber>;
|
||||
|
||||
principalBalanceOf(account: string): Promise<BigNumber>;
|
||||
|
||||
symbol(): Promise<BigNumber>;
|
||||
|
||||
totalSupply(): Promise<BigNumber>;
|
||||
|
||||
transfer(recipient: string, amount: BigNumberish): Promise<BigNumber>;
|
||||
|
||||
transferFrom(
|
||||
sender: string,
|
||||
recipient: string,
|
||||
amount: BigNumberish
|
||||
): Promise<BigNumber>;
|
||||
|
||||
underlyingAssetAddress(): Promise<BigNumber>;
|
||||
};
|
||||
}
|
497
types/VariableDebtTokenFactory.ts
Normal file
497
types/VariableDebtTokenFactory.ts
Normal file
File diff suppressed because one or more lines are too long
|
@ -134,4 +134,4 @@ const _abi = [
|
|||
];
|
||||
|
||||
const _bytecode =
|
||||
"0x608060405234801561001057600080fd5b5060405161099e38038061099e8339818101604052602081101561003357600080fd5b5051600080546001600160a01b039092166001600160a01b0319909216919091179055610939806100656000396000f3fe6080604052600436106100385760003560e01c80639e3c930914610083578063b59b28ef1461014f578063f7888aec146102d35761007e565b3661007e5761004633610320565b61007c576040805162461bcd60e51b8152602060048201526002602482015261191960f11b604482015290519081900360640190fd5b005b600080fd5b34801561008f57600080fd5b506100b6600480360360208110156100a657600080fd5b50356001600160a01b031661035c565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100fa5781810151838201526020016100e2565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610139578181015183820152602001610121565b5050505090500194505050505060405180910390f35b34801561015b57600080fd5b506102836004803603604081101561017257600080fd5b81019060208101813564010000000081111561018d57600080fd5b82018360208201111561019f57600080fd5b803590602001918460208302840111640100000000831117156101c157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561021157600080fd5b82018360208201111561022357600080fd5b8035906020019184602083028401116401000000008311171561024557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506106a9945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102bf5781810151838201526020016102a7565b505050509050019250505060405180910390f35b3480156102df57600080fd5b5061030e600480360360408110156102f657600080fd5b506001600160a01b0381358116916020013516610841565b60408051918252519081900360200190f35b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061035457508115155b949350505050565b60608060008060009054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156103ae57600080fd5b505afa1580156103c2573d6000803e3d6000fd5b505050506040513d60208110156103d857600080fd5b505160408051630240bc6b60e21b815290519192506060916001600160a01b03841691630902f1ac916004808301926000929190829003018186803b15801561042057600080fd5b505afa158015610434573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561045d57600080fd5b810190808051604051939291908464010000000082111561047d57600080fd5b90830190602082018581111561049257600080fd5b82518660208202830111640100000000821117156104af57600080fd5b82525081516020918201928201910280838360005b838110156104dc5781810151838201526020016104c4565b5050505090500160405250505090506060815167ffffffffffffffff8111801561050557600080fd5b5060405190808252806020026020018201604052801561052f578160200160208202803683370190505b50905060005b825181101561069d576000846001600160a01b0316633e15014185848151811061055b57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b031681526020019150506101406040518083038186803b1580156105aa57600080fd5b505afa1580156105be573d6000803e3d6000fd5b505050506040513d6101408110156105d557600080fd5b5061010001519050806106025760008383815181106105f057fe5b60200260200101818152505050610695565b61060a6108eb565b6001600160a01b031684838151811061061f57fe5b60200260200101516001600160a01b03161461066f576106528885848151811061064557fe5b6020026020010151610841565b83838151811061065e57fe5b602002602001018181525050610693565b876001600160a01b03163183838151811061068657fe5b6020026020010181815250505b505b600101610535565b50909350915050915091565b606080825184510267ffffffffffffffff811180156106c757600080fd5b506040519080825280602002602001820160405280156106f1578160200160208202803683370190505b50905060005b84518110156108375760005b845181101561082e57845182026107186108eb565b6001600160a01b031686838151811061072d57fe5b60200260200101516001600160a01b031614156107815786838151811061075057fe5b60200260200101516001600160a01b031631848383018151811061077057fe5b602002602001018181525050610825565b6107a686838151811061079057fe5b60200260200101516001600160a01b0316610320565b6107e7576040805162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22faa27a5a2a760991b604482015290519081900360640190fd5b61080a8784815181106107f657fe5b602002602001015187848151811061064557fe5b848383018151811061081857fe5b6020026020010181815250505b50600101610703565b506001016106f7565b5090505b92915050565b6000610855826001600160a01b0316610320565b156108e357816001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156108b057600080fd5b505afa1580156108c4573d6000803e3d6000fd5b505050506040513d60208110156108da57600080fd5b5051905061083b565b50600061083b565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee9056fea2646970667358221220c55061105db32b5ffbe17936cb06af117ec14e7ad4e1c3288fffe7c2858f9d9d64736f6c63430006080033";
|
||||
"0x608060405234801561001057600080fd5b5060405161099e38038061099e8339818101604052602081101561003357600080fd5b5051600080546001600160a01b039092166001600160a01b0319909216919091179055610939806100656000396000f3fe6080604052600436106100385760003560e01c80639e3c930914610083578063b59b28ef1461014f578063f7888aec146102d35761007e565b3661007e5761004633610320565b61007c576040805162461bcd60e51b8152602060048201526002602482015261191960f11b604482015290519081900360640190fd5b005b600080fd5b34801561008f57600080fd5b506100b6600480360360208110156100a657600080fd5b50356001600160a01b031661035c565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100fa5781810151838201526020016100e2565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610139578181015183820152602001610121565b5050505090500194505050505060405180910390f35b34801561015b57600080fd5b506102836004803603604081101561017257600080fd5b81019060208101813564010000000081111561018d57600080fd5b82018360208201111561019f57600080fd5b803590602001918460208302840111640100000000831117156101c157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561021157600080fd5b82018360208201111561022357600080fd5b8035906020019184602083028401116401000000008311171561024557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506106a9945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102bf5781810151838201526020016102a7565b505050509050019250505060405180910390f35b3480156102df57600080fd5b5061030e600480360360408110156102f657600080fd5b506001600160a01b0381358116916020013516610841565b60408051918252519081900360200190f35b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061035457508115155b949350505050565b60608060008060009054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156103ae57600080fd5b505afa1580156103c2573d6000803e3d6000fd5b505050506040513d60208110156103d857600080fd5b505160408051630240bc6b60e21b815290519192506060916001600160a01b03841691630902f1ac916004808301926000929190829003018186803b15801561042057600080fd5b505afa158015610434573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561045d57600080fd5b810190808051604051939291908464010000000082111561047d57600080fd5b90830190602082018581111561049257600080fd5b82518660208202830111640100000000821117156104af57600080fd5b82525081516020918201928201910280838360005b838110156104dc5781810151838201526020016104c4565b5050505090500160405250505090506060815167ffffffffffffffff8111801561050557600080fd5b5060405190808252806020026020018201604052801561052f578160200160208202803683370190505b50905060005b825181101561069d576000846001600160a01b0316633e15014185848151811061055b57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b031681526020019150506101406040518083038186803b1580156105aa57600080fd5b505afa1580156105be573d6000803e3d6000fd5b505050506040513d6101408110156105d557600080fd5b5061010001519050806106025760008383815181106105f057fe5b60200260200101818152505050610695565b61060a6108eb565b6001600160a01b031684838151811061061f57fe5b60200260200101516001600160a01b03161461066f576106528885848151811061064557fe5b6020026020010151610841565b83838151811061065e57fe5b602002602001018181525050610693565b876001600160a01b03163183838151811061068657fe5b6020026020010181815250505b505b600101610535565b50909350915050915091565b606080825184510267ffffffffffffffff811180156106c757600080fd5b506040519080825280602002602001820160405280156106f1578160200160208202803683370190505b50905060005b84518110156108375760005b845181101561082e57845182026107186108eb565b6001600160a01b031686838151811061072d57fe5b60200260200101516001600160a01b031614156107815786838151811061075057fe5b60200260200101516001600160a01b031631848383018151811061077057fe5b602002602001018181525050610825565b6107a686838151811061079057fe5b60200260200101516001600160a01b0316610320565b6107e7576040805162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22faa27a5a2a760991b604482015290519081900360640190fd5b61080a8784815181106107f657fe5b602002602001015187848151811061064557fe5b848383018151811061081857fe5b6020026020010181815250505b50600101610703565b506001016106f7565b5090505b92915050565b6000610855826001600160a01b0316610320565b156108e357816001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156108b057600080fd5b505afa1580156108c4573d6000803e3d6000fd5b505050506040513d60208110156108da57600080fd5b5051905061083b565b50600061083b565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee9056fea26469706673582212207285b910f911868636ce78fa21192b5ac0a86df35b25c04e8445ba9b97d183ea64736f6c63430006080033";
|
||||
|
|
Loading…
Reference in New Issue
Block a user