mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
- Refactored ERC20 and adapted derived contracts.
This commit is contained in:
parent
b32ee6536c
commit
da734aa68a
80
contracts/interfaces/IERC20.sol
Normal file
80
contracts/interfaces/IERC20.sol
Normal file
|
@ -0,0 +1,80 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.8;
|
||||
|
||||
/**
|
||||
* @dev Interface of the ERC20 standard as defined in the EIP.
|
||||
*/
|
||||
interface IERC20 {
|
||||
/**
|
||||
* @dev Returns the amount of tokens in existence.
|
||||
*/
|
||||
function totalSupply() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the amount of tokens owned by `account`.
|
||||
*/
|
||||
function balanceOf(address account) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Moves `amount` tokens from the caller's account to `recipient`.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*/
|
||||
function transfer(address recipient, uint256 amount) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Returns the remaining number of tokens that `spender` will be
|
||||
* allowed to spend on behalf of `owner` through {transferFrom}. This is
|
||||
* zero by default.
|
||||
*
|
||||
* This value changes when {approve} or {transferFrom} are called.
|
||||
*/
|
||||
function allowance(address owner, address spender) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* IMPORTANT: Beware that changing an allowance with this method brings the risk
|
||||
* that someone may use both the old and the new allowance by unfortunate
|
||||
* transaction ordering. One possible solution to mitigate this race
|
||||
* condition is to first reduce the spender's allowance to 0 and set the
|
||||
* desired value afterwards:
|
||||
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
|
||||
*
|
||||
* Emits an {Approval} event.
|
||||
*/
|
||||
function approve(address spender, uint256 amount) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Moves `amount` tokens from `sender` to `recipient` using the
|
||||
* allowance mechanism. `amount` is then deducted from the caller's
|
||||
* allowance.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*/
|
||||
function transferFrom(
|
||||
address sender,
|
||||
address recipient,
|
||||
uint256 amount
|
||||
) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Emitted when `value` tokens are moved from one account (`from`) to
|
||||
* another (`to`).
|
||||
*
|
||||
* Note that `value` may be zero.
|
||||
*/
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
|
||||
* a call to {approve}. `value` is the new allowance.
|
||||
*/
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {IERC20} from './IERC20.sol';
|
||||
|
||||
interface IERC20Detailed is IERC20 {
|
||||
function name() external view returns (string memory);
|
||||
|
|
163
contracts/libraries/math/SafeMath.sol
Normal file
163
contracts/libraries/math/SafeMath.sol
Normal file
|
@ -0,0 +1,163 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.8;
|
||||
|
||||
/**
|
||||
* @dev Wrappers over Solidity's arithmetic operations with added overflow
|
||||
* checks.
|
||||
*
|
||||
* Arithmetic operations in Solidity wrap on overflow. This can easily result
|
||||
* in bugs, because programmers usually assume that an overflow raises an
|
||||
* error, which is the standard behavior in high level programming languages.
|
||||
* `SafeMath` restores this intuition by reverting the transaction when an
|
||||
* operation overflows.
|
||||
*
|
||||
* Using this library instead of the unchecked operations eliminates an entire
|
||||
* class of bugs, so it's recommended to use it always.
|
||||
*/
|
||||
library SafeMath {
|
||||
/**
|
||||
* @dev Returns the addition of two unsigned integers, reverting on
|
||||
* overflow.
|
||||
*
|
||||
* Counterpart to Solidity's `+` operator.
|
||||
*
|
||||
* Requirements:
|
||||
* - Addition cannot overflow.
|
||||
*/
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a, 'SafeMath: addition overflow');
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the subtraction of two unsigned integers, reverting on
|
||||
* overflow (when the result is negative).
|
||||
*
|
||||
* Counterpart to Solidity's `-` operator.
|
||||
*
|
||||
* Requirements:
|
||||
* - Subtraction cannot overflow.
|
||||
*/
|
||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return sub(a, b, 'SafeMath: subtraction overflow');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
|
||||
* overflow (when the result is negative).
|
||||
*
|
||||
* Counterpart to Solidity's `-` operator.
|
||||
*
|
||||
* Requirements:
|
||||
* - Subtraction cannot overflow.
|
||||
*/
|
||||
function sub(
|
||||
uint256 a,
|
||||
uint256 b,
|
||||
string memory errorMessage
|
||||
) internal pure returns (uint256) {
|
||||
require(b <= a, errorMessage);
|
||||
uint256 c = a - b;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the multiplication of two unsigned integers, reverting on
|
||||
* overflow.
|
||||
*
|
||||
* Counterpart to Solidity's `*` operator.
|
||||
*
|
||||
* Requirements:
|
||||
* - Multiplication cannot overflow.
|
||||
*/
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint256 c = a * b;
|
||||
require(c / a == b, 'SafeMath: multiplication overflow');
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the integer division of two unsigned integers. Reverts on
|
||||
* division by zero. The result is rounded towards zero.
|
||||
*
|
||||
* Counterpart to Solidity's `/` operator. Note: this function uses a
|
||||
* `revert` opcode (which leaves remaining gas untouched) while Solidity
|
||||
* uses an invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return div(a, b, 'SafeMath: division by zero');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
|
||||
* division by zero. The result is rounded towards zero.
|
||||
*
|
||||
* Counterpart to Solidity's `/` operator. Note: this function uses a
|
||||
* `revert` opcode (which leaves remaining gas untouched) while Solidity
|
||||
* uses an invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function div(
|
||||
uint256 a,
|
||||
uint256 b,
|
||||
string memory errorMessage
|
||||
) internal pure returns (uint256) {
|
||||
// Solidity only automatically asserts when dividing by 0
|
||||
require(b > 0, errorMessage);
|
||||
uint256 c = a / b;
|
||||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
|
||||
* Reverts when dividing by zero.
|
||||
*
|
||||
* Counterpart to Solidity's `%` operator. This function uses a `revert`
|
||||
* opcode (which leaves remaining gas untouched) while Solidity uses an
|
||||
* invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return mod(a, b, 'SafeMath: modulo by zero');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
|
||||
* Reverts with custom message when dividing by zero.
|
||||
*
|
||||
* Counterpart to Solidity's `%` operator. This function uses a `revert`
|
||||
* opcode (which leaves remaining gas untouched) while Solidity uses an
|
||||
* invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function mod(
|
||||
uint256 a,
|
||||
uint256 b,
|
||||
string memory errorMessage
|
||||
) internal pure returns (uint256) {
|
||||
require(b != 0, errorMessage);
|
||||
return a % b;
|
||||
}
|
||||
}
|
61
contracts/misc/Address.sol
Normal file
61
contracts/misc/Address.sol
Normal file
|
@ -0,0 +1,61 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.8;
|
||||
|
||||
/**
|
||||
* @dev Collection of functions related to the address type
|
||||
*/
|
||||
library Address {
|
||||
/**
|
||||
* @dev Returns true if `account` is a contract.
|
||||
*
|
||||
* [IMPORTANT]
|
||||
* ====
|
||||
* It is unsafe to assume that an address for which this function returns
|
||||
* false is an externally-owned account (EOA) and not a contract.
|
||||
*
|
||||
* Among others, `isContract` will return false for the following
|
||||
* types of addresses:
|
||||
*
|
||||
* - an externally-owned account
|
||||
* - a contract in construction
|
||||
* - an address where a contract will be created
|
||||
* - an address where a contract lived, but was destroyed
|
||||
* ====
|
||||
*/
|
||||
function isContract(address account) internal view returns (bool) {
|
||||
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
|
||||
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
|
||||
// for accounts without code, i.e. `keccak256('')`
|
||||
bytes32 codehash;
|
||||
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
codehash := extcodehash(account)
|
||||
}
|
||||
return (codehash != accountHash && codehash != 0x0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
|
||||
* `recipient`, forwarding all available gas and reverting on errors.
|
||||
*
|
||||
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
|
||||
* of certain opcodes, possibly making contracts go over the 2300 gas limit
|
||||
* imposed by `transfer`, making them unable to receive funds via
|
||||
* `transfer`. {sendValue} removes this limitation.
|
||||
*
|
||||
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
|
||||
*
|
||||
* IMPORTANT: because control is transferred to `recipient`, care must be
|
||||
* taken to not create reentrancy vulnerabilities. Consider using
|
||||
* {ReentrancyGuard} or the
|
||||
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
|
||||
*/
|
||||
function sendValue(address payable recipient, uint256 amount) internal {
|
||||
require(address(this).balance >= amount, 'Address: insufficient balance');
|
||||
|
||||
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
|
||||
(bool success, ) = recipient.call{value: amount}('');
|
||||
require(success, 'Address: unable to send value, recipient may have reverted');
|
||||
}
|
||||
}
|
23
contracts/misc/Context.sol
Normal file
23
contracts/misc/Context.sol
Normal file
|
@ -0,0 +1,23 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.6.8;
|
||||
|
||||
/*
|
||||
* @dev Provides information about the current execution context, including the
|
||||
* sender of the transaction and its data. While these are generally available
|
||||
* via msg.sender and msg.data, they should not be accessed in such a direct
|
||||
* manner, since when dealing with GSN meta-transactions the account sending and
|
||||
* paying for execution may not be the actual sender (as far as an application
|
||||
* is concerned).
|
||||
*
|
||||
* This contract is only required for intermediate, library-like contracts.
|
||||
*/
|
||||
abstract contract Context {
|
||||
function _msgSender() internal virtual view returns (address payable) {
|
||||
return msg.sender;
|
||||
}
|
||||
|
||||
function _msgData() internal virtual view returns (bytes memory) {
|
||||
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
|
||||
return msg.data;
|
||||
}
|
||||
}
|
49
contracts/misc/SafeERC20.sol
Normal file
49
contracts/misc/SafeERC20.sol
Normal file
|
@ -0,0 +1,49 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity 0.6.8;
|
||||
|
||||
import {IERC20} from "../interfaces/IERC20.sol";
|
||||
import {SafeMath} from "../libraries/math/SafeMath.sol";
|
||||
import {Address} from "./Address.sol";
|
||||
|
||||
/**
|
||||
* @title SafeERC20
|
||||
* @dev Wrappers around ERC20 operations that throw on failure (when the token
|
||||
* contract returns false). Tokens that return no value (and instead revert or
|
||||
* throw on failure) are also supported, non-reverting calls are assumed to be
|
||||
* successful.
|
||||
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
|
||||
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
|
||||
*/
|
||||
library SafeERC20 {
|
||||
using SafeMath for uint256;
|
||||
using Address for address;
|
||||
|
||||
function safeTransfer(IERC20 token, address to, uint256 value) internal {
|
||||
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
|
||||
}
|
||||
|
||||
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
|
||||
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
|
||||
}
|
||||
|
||||
function safeApprove(IERC20 token, address spender, uint256 value) internal {
|
||||
require((value == 0) || (token.allowance(address(this), spender) == 0),
|
||||
"SafeERC20: approve from non-zero to non-zero allowance"
|
||||
);
|
||||
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
|
||||
}
|
||||
|
||||
function callOptionalReturn(IERC20 token, bytes memory data) private {
|
||||
require(address(token).isContract(), "SafeERC20: call to non-contract");
|
||||
|
||||
// solhint-disable-next-line avoid-low-level-calls
|
||||
(bool success, bytes memory returndata) = address(token).call(data);
|
||||
require(success, "SafeERC20: low-level call failed");
|
||||
|
||||
if (returndata.length > 0) { // Return data is optional
|
||||
// solhint-disable-next-line max-line-length
|
||||
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ pragma solidity ^0.6.8;
|
|||
|
||||
import {AToken} from '../../tokenization/AToken.sol';
|
||||
import {LendingPool} from '../../lendingpool/LendingPool.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
|
||||
contract MockAToken is AToken {
|
||||
constructor(
|
||||
|
@ -22,8 +21,8 @@ contract MockAToken is AToken {
|
|||
string calldata _tokenName,
|
||||
string calldata _tokenSymbol
|
||||
) external virtual override initializer {
|
||||
_name = _tokenName;
|
||||
_symbol = _tokenSymbol;
|
||||
_setupDecimals(_underlyingAssetDecimals);
|
||||
_setName(_tokenName);
|
||||
_setSymbol(_tokenSymbol);
|
||||
_setDecimals(_underlyingAssetDecimals);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ pragma solidity ^0.6.8;
|
|||
|
||||
import {StableDebtToken} from '../../tokenization/StableDebtToken.sol';
|
||||
import {LendingPool} from '../../lendingpool/LendingPool.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
|
||||
contract MockStableDebtToken is StableDebtToken {
|
||||
constructor(
|
||||
|
|
|
@ -3,7 +3,6 @@ pragma solidity ^0.6.8;
|
|||
|
||||
import {VariableDebtToken} from '../../tokenization/VariableDebtToken.sol';
|
||||
import {LendingPool} from '../../lendingpool/LendingPool.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
|
||||
contract MockVariableDebtToken is VariableDebtToken {
|
||||
constructor(
|
||||
|
|
|
@ -5,11 +5,12 @@ import {ERC20} from './ERC20.sol';
|
|||
import {LendingPool} from '../lendingpool/LendingPool.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {
|
||||
VersionedInitializable
|
||||
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import {IAToken, IERC20} from './interfaces/IAToken.sol';
|
||||
import {IAToken} from './interfaces/IAToken.sol';
|
||||
import {IERC20} from '../interfaces/IERC20.sol';
|
||||
import {SafeERC20} from "../misc/SafeERC20.sol";
|
||||
|
||||
/**
|
||||
* @title Aave ERC20 AToken
|
||||
|
@ -49,7 +50,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
|
|||
address underlyingAssetAddress,
|
||||
string memory tokenName,
|
||||
string memory tokenSymbol
|
||||
) public ERC20(tokenName, tokenSymbol) {
|
||||
) public ERC20(tokenName, tokenSymbol, 18) {
|
||||
_pool = pool;
|
||||
UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress;
|
||||
}
|
||||
|
@ -63,9 +64,9 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
|
|||
string calldata tokenName,
|
||||
string calldata tokenSymbol
|
||||
) external virtual initializer {
|
||||
_name = tokenName;
|
||||
_symbol = tokenSymbol;
|
||||
_setupDecimals(underlyingAssetDecimals);
|
||||
_setName(tokenName);
|
||||
_setSymbol(tokenSymbol);
|
||||
_setDecimals(underlyingAssetDecimals);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,124 +1,88 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.8;
|
||||
|
||||
import {Context} from '@openzeppelin/contracts/GSN/Context.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {Context} from '../misc/Context.sol';
|
||||
import {IERC20} from '../interfaces/IERC20.sol';
|
||||
import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol';
|
||||
import {SafeMath} from '../libraries/math/SafeMath.sol';
|
||||
|
||||
/**
|
||||
* @dev Implementation of the {IERC20} interface.
|
||||
*
|
||||
* This implementation is agnostic to the way tokens are created. This means
|
||||
* that a supply mechanism has to be added in a derived contract using {_mint}.
|
||||
* For a generic mechanism see {ERC20MinterPauser}.
|
||||
*
|
||||
* TIP: For a detailed writeup see our guide
|
||||
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
|
||||
* to implement supply mechanisms].
|
||||
*
|
||||
* We have followed general OpenZeppelin guidelines: functions revert instead
|
||||
* of returning `false` on failure. This behavior is nonetheless conventional
|
||||
* and does not conflict with the expectations of ERC20 applications.
|
||||
*
|
||||
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
|
||||
* This allows applications to reconstruct the allowance for all accounts just
|
||||
* by listening to said events. Other implementations of the EIP may not emit
|
||||
* these events, as it isn't required by the specification.
|
||||
*
|
||||
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
|
||||
* functions have been added to mitigate the well-known issues around setting
|
||||
* allowances. See {IERC20-approve}.
|
||||
*/
|
||||
contract ERC20 is Context, IERC20 {
|
||||
* @title ERC20
|
||||
* @notice Basic ERC20 implementation
|
||||
* @author Aave
|
||||
**/
|
||||
contract ERC20 is Context, IERC20, IERC20Detailed {
|
||||
using SafeMath for uint256;
|
||||
|
||||
mapping(address => uint256) private _balances;
|
||||
|
||||
mapping(address => mapping(address => uint256)) private _allowances;
|
||||
|
||||
uint256 private _totalSupply;
|
||||
|
||||
string internal _name;
|
||||
string internal _symbol;
|
||||
string private _name;
|
||||
string private _symbol;
|
||||
uint8 private _decimals;
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
constructor(string memory name, string memory symbol) public {
|
||||
constructor(
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
uint8 decimals
|
||||
) public {
|
||||
_name = name;
|
||||
_symbol = symbol;
|
||||
_decimals = 18;
|
||||
_decimals = decimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the name of the token.
|
||||
*/
|
||||
function name() public view returns (string memory) {
|
||||
* @return the name of the token
|
||||
**/
|
||||
function name() public override view returns (string memory) {
|
||||
return _name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the symbol of the token, usually a shorter version of the
|
||||
* name.
|
||||
*/
|
||||
function symbol() public view returns (string memory) {
|
||||
* @return the symbol of the token
|
||||
**/
|
||||
function symbol() public override view returns (string memory) {
|
||||
return _symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the number of decimals used to get its user representation.
|
||||
* For example, if `decimals` equals `2`, a balance of `505` tokens should
|
||||
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
|
||||
*
|
||||
* Tokens usually opt for a value of 18, imitating the relationship between
|
||||
* Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
|
||||
* called.
|
||||
*
|
||||
* NOTE: This information is only used for _display_ purposes: it in
|
||||
* no way affects any of the arithmetic of the contract, including
|
||||
* {IERC20-balanceOf} and {IERC20-transfer}.
|
||||
*/
|
||||
function decimals() public view returns (uint8) {
|
||||
* @return the decimals of the token
|
||||
**/
|
||||
function decimals() public override view returns (uint8) {
|
||||
return _decimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-totalSupply}.
|
||||
*/
|
||||
* @return the total supply of the token
|
||||
**/
|
||||
function totalSupply() public virtual override view returns (uint256) {
|
||||
return _totalSupply;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-balanceOf}.
|
||||
*/
|
||||
* @return the balance of the token
|
||||
**/
|
||||
function balanceOf(address account) public virtual override 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`.
|
||||
*/
|
||||
* @dev executes a transfer of tokens from msg.sender to recipient
|
||||
* @param recipient the recipient of the tokens
|
||||
* @param amount the amount of tokens being transferred
|
||||
* @return true if the transfer succeeds, false otherwise
|
||||
**/
|
||||
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
|
||||
_transfer(_msgSender(), recipient, amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-allowance}.
|
||||
*/
|
||||
* @dev returns the allowance of spender on the tokens owned by owner
|
||||
* @param owner the owner of the tokens
|
||||
* @param spender the user allowed to spend the owner's tokens
|
||||
* @return the amount of owner's tokens spender is allowed to spend
|
||||
**/
|
||||
function allowance(address owner, address spender)
|
||||
public
|
||||
virtual
|
||||
|
@ -130,29 +94,22 @@ contract ERC20 is Context, IERC20 {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-approve}.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `spender` cannot be the zero address.
|
||||
*/
|
||||
* @dev allows spender to spend the tokens owned by msg.sender
|
||||
* @param spender the user allowed to spend msg.sender tokens
|
||||
* @return true
|
||||
**/
|
||||
function approve(address spender, uint256 amount) public virtual override returns (bool) {
|
||||
_approve(_msgSender(), spender, amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC20-transferFrom}.
|
||||
*
|
||||
* Emits an {Approval} event indicating the updated allowance. This is not
|
||||
* required by the EIP. See the note at the beginning of {ERC20};
|
||||
*
|
||||
* Requirements:
|
||||
* - `sender` and `recipient` cannot be the zero address.
|
||||
* - `sender` must have a balance of at least `amount`.
|
||||
* - the caller must have allowance for ``sender``'s tokens of at least
|
||||
* `amount`.
|
||||
*/
|
||||
* @dev executes a transfer of token from sender to recipient, if msg.sender is allowed to do so
|
||||
* @param sender the owner of the tokens
|
||||
* @param recipient the recipient of the tokens
|
||||
* @param amount the amount of tokens being transferred
|
||||
* @return true if the transfer succeeds, false otherwise
|
||||
**/
|
||||
function transferFrom(
|
||||
address sender,
|
||||
address recipient,
|
||||
|
@ -168,36 +125,22 @@ contract ERC20 is Context, IERC20 {
|
|||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
* @dev increases the allowance of spender to spend msg.sender tokens
|
||||
* @param spender the user allowed to spend on behalf of msg.sender
|
||||
* @param addedValue the amount being added to the allowance
|
||||
* @return true
|
||||
**/
|
||||
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
|
||||
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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`.
|
||||
*/
|
||||
* @dev decreases the allowance of spender to spend msg.sender tokens
|
||||
* @param spender the user allowed to spend on behalf of msg.sender
|
||||
* @param subtractedValue the amount being subtracted to the allowance
|
||||
* @return true
|
||||
**/
|
||||
function decreaseAllowance(address spender, uint256 subtractedValue)
|
||||
public
|
||||
virtual
|
||||
|
@ -214,20 +157,6 @@ contract ERC20 is Context, IERC20 {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Moves tokens `amount` from `sender` to `recipient`.
|
||||
*
|
||||
* This is internal function is equivalent to {transfer}, and can be used to
|
||||
* e.g. implement automatic token fees, slashing mechanisms, etc.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `sender` cannot be the zero address.
|
||||
* - `recipient` cannot be the zero address.
|
||||
* - `sender` must have a balance of at least `amount`.
|
||||
*/
|
||||
function _transfer(
|
||||
address sender,
|
||||
address recipient,
|
||||
|
@ -243,15 +172,6 @@ contract ERC20 is Context, IERC20 {
|
|||
emit Transfer(sender, recipient, amount);
|
||||
}
|
||||
|
||||
/** @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) internal virtual {
|
||||
require(account != address(0), 'ERC20: mint to the zero address');
|
||||
|
||||
|
@ -262,17 +182,6 @@ contract ERC20 is Context, IERC20 {
|
|||
emit Transfer(address(0), account, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) internal virtual {
|
||||
require(account != address(0), 'ERC20: burn from the zero address');
|
||||
|
||||
|
@ -283,19 +192,6 @@ contract ERC20 is Context, IERC20 {
|
|||
emit Transfer(account, address(0), amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
|
||||
*
|
||||
* This is internal function is equivalent to `approve`, and can be used to
|
||||
* e.g. set automatic allowances for certain subsystems, etc.
|
||||
*
|
||||
* Emits an {Approval} event.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `owner` cannot be the zero address.
|
||||
* - `spender` cannot be the zero address.
|
||||
*/
|
||||
function _approve(
|
||||
address owner,
|
||||
address spender,
|
||||
|
@ -308,31 +204,18 @@ contract ERC20 is Context, IERC20 {
|
|||
emit Approval(owner, spender, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sets {decimals} to a value other than the default one of 18.
|
||||
*
|
||||
* WARNING: This function should only be called from the constructor. Most
|
||||
* applications that interact with token contracts will not expect
|
||||
* {decimals} to ever change, and may work incorrectly if it does.
|
||||
*/
|
||||
function _setupDecimals(uint8 decimals_) internal {
|
||||
_decimals = decimals_;
|
||||
function _setName(string memory newName) internal {
|
||||
_name = newName;
|
||||
}
|
||||
|
||||
function _setSymbol(string memory newSymbol) internal {
|
||||
_symbol = newSymbol;
|
||||
}
|
||||
|
||||
function _setDecimals(uint8 newDecimals) internal {
|
||||
_decimals = newDecimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Hook that is called before any transfer of tokens. This includes
|
||||
* minting and burning.
|
||||
*
|
||||
* Calling conditions:
|
||||
*
|
||||
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
|
||||
* will be to transferred to `to`.
|
||||
* - when `from` is zero, `amount` tokens will be minted for `to`.
|
||||
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
|
||||
* - `from` and `to` are never both zero.
|
||||
*
|
||||
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
|
||||
*/
|
||||
function _beforeTokenTransfer(
|
||||
address from,
|
||||
address to,
|
||||
|
|
|
@ -20,7 +20,6 @@ import {IStableDebtToken} from './interfaces/IStableDebtToken.sol';
|
|||
*
|
||||
**/
|
||||
contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
|
||||
uint256 public constant DEBT_TOKEN_REVISION = 0x1;
|
||||
|
@ -78,7 +77,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
* @return the accumulated debt of the user
|
||||
**/
|
||||
function balanceOf(address account) public virtual override view returns (uint256) {
|
||||
uint256 accountBalance = _balances[account];
|
||||
uint256 accountBalance = principalBalanceOf(account);
|
||||
if (accountBalance == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -120,7 +119,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
uint256 balanceIncrease
|
||||
) = _calculateBalanceIncrease(user);
|
||||
|
||||
vars.supplyBeforeMint = _totalSupply.add(balanceIncrease);
|
||||
vars.supplyBeforeMint = totalSupply().add(balanceIncrease);
|
||||
vars.supplyAfterMint = vars.supplyBeforeMint.add(amount);
|
||||
|
||||
vars.amountInRay = amount.wadToRay();
|
||||
|
@ -167,7 +166,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
uint256 balanceIncrease
|
||||
) = _calculateBalanceIncrease(user);
|
||||
|
||||
uint256 supplyBeforeBurn = _totalSupply.add(balanceIncrease);
|
||||
uint256 supplyBeforeBurn = totalSupply().add(balanceIncrease);
|
||||
uint256 supplyAfterBurn = supplyBeforeBurn.sub(amount);
|
||||
|
||||
if (supplyAfterBurn == 0) {
|
||||
|
|
|
@ -15,7 +15,6 @@ import {IVariableDebtToken} from './interfaces/IVariableDebtToken.sol';
|
|||
* @dev does not inherit from IERC20 to save in contract size
|
||||
**/
|
||||
contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
|
||||
uint256 public constant DEBT_TOKEN_REVISION = 0x1;
|
||||
|
@ -42,7 +41,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
* @return the debt balance of the user
|
||||
**/
|
||||
function balanceOf(address user) public virtual override view returns (uint256) {
|
||||
uint256 userBalance = _balances[user];
|
||||
uint256 userBalance = principalBalanceOf(user);
|
||||
if (userBalance == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -50,7 +49,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
return
|
||||
userBalance
|
||||
.wadToRay()
|
||||
.rayMul(_pool.getReserveNormalizedVariableDebt(_underlyingAssetAddress))
|
||||
.rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET))
|
||||
.rayDiv(_userIndexes[user])
|
||||
.rayToWad();
|
||||
}
|
||||
|
@ -78,7 +77,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
|
||||
_mint(user, amount.add(balanceIncrease));
|
||||
|
||||
uint256 newUserIndex = _pool.getReserveNormalizedVariableDebt(_underlyingAssetAddress);
|
||||
uint256 newUserIndex = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET);
|
||||
_userIndexes[user] = newUserIndex;
|
||||
|
||||
emit MintDebt(user, amount, previousBalance, currentBalance, balanceIncrease, newUserIndex);
|
||||
|
@ -105,7 +104,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
uint256 newUserIndex = 0;
|
||||
//if user not repaid everything
|
||||
if (currentBalance != amount) {
|
||||
newUserIndex = _pool.getReserveNormalizedVariableDebt(_underlyingAssetAddress);
|
||||
newUserIndex = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET);
|
||||
}
|
||||
_userIndexes[user] = newUserIndex;
|
||||
|
||||
|
|
|
@ -5,185 +5,119 @@ import {Context} from '@openzeppelin/contracts/GSN/Context.sol';
|
|||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {
|
||||
VersionedInitializable
|
||||
} from '../../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import {IERC20Detailed} from '../../interfaces/IERC20Detailed.sol';
|
||||
import {VersionedInitializable} from '../../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import {ERC20} from '../ERC20.sol';
|
||||
import {Errors} from '../../libraries/helpers/Errors.sol';
|
||||
|
||||
/**
|
||||
* @title contract DebtTokenBase
|
||||
* @title DebtTokenBase
|
||||
* @notice Base contract for different types of debt tokens, like StableDebtToken or VariableDebtToken
|
||||
* @author Aave
|
||||
* @notice base contract for StableDebtToken and VariableDebtToken
|
||||
*/
|
||||
|
||||
abstract contract DebtTokenBase is IERC20Detailed, VersionedInitializable {
|
||||
using SafeMath for uint256;
|
||||
abstract contract DebtTokenBase is ERC20, VersionedInitializable {
|
||||
|
||||
uint256 internal _totalSupply;
|
||||
|
||||
string internal _name;
|
||||
string internal _symbol;
|
||||
uint8 internal _decimals;
|
||||
address internal immutable _underlyingAssetAddress;
|
||||
|
||||
ILendingPool internal immutable _pool;
|
||||
mapping(address => uint256) internal _balances;
|
||||
address internal immutable UNDERLYING_ASSET;
|
||||
ILendingPool internal immutable POOL;
|
||||
|
||||
/**
|
||||
* @dev only lending pool can call functions marked by this modifier
|
||||
* @dev Only lending pool can call functions marked by this modifier
|
||||
**/
|
||||
modifier onlyLendingPool {
|
||||
require(msg.sender == address(_pool), Errors.CALLER_MUST_BE_LENDING_POOL);
|
||||
require(msg.sender == address(POOL), Errors.CALLER_MUST_BE_LENDING_POOL);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev The metadata of the token will be set on the proxy, that the reason of
|
||||
* passing "NULL" and 0 as metadata
|
||||
*/
|
||||
constructor(
|
||||
address pool,
|
||||
address underlyingAssetAddress,
|
||||
string memory name,
|
||||
string memory symbol
|
||||
) public {
|
||||
_pool = ILendingPool(pool);
|
||||
_underlyingAssetAddress = underlyingAssetAddress;
|
||||
_name = name;
|
||||
_symbol = symbol;
|
||||
string memory symbol
|
||||
) public ERC20(name, symbol, 18) {
|
||||
POOL = ILendingPool(pool);
|
||||
UNDERLYING_ASSET = underlyingAssetAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev initializes the debt token.
|
||||
* @param name the name of the token
|
||||
* @param symbol the symbol of the token
|
||||
* @param decimals the decimals of the token
|
||||
* @dev Initializes the debt token.
|
||||
* @param name The name of the token
|
||||
* @param symbol The symbol of the token
|
||||
* @param decimals The decimals of the token
|
||||
*/
|
||||
function initialize(
|
||||
uint8 decimals,
|
||||
string memory name,
|
||||
string memory symbol
|
||||
) public initializer {
|
||||
_name = name;
|
||||
_symbol = symbol;
|
||||
_decimals = decimals;
|
||||
}
|
||||
|
||||
function name() public override view returns (string memory) {
|
||||
return _name;
|
||||
}
|
||||
|
||||
function symbol() public override view returns (string memory) {
|
||||
return _symbol;
|
||||
}
|
||||
|
||||
function decimals() public override view returns (uint8) {
|
||||
return _decimals;
|
||||
}
|
||||
|
||||
function totalSupply() public override view returns (uint256) {
|
||||
return _totalSupply;
|
||||
_setName(name);
|
||||
_setSymbol(symbol);
|
||||
_setDecimals(decimals);
|
||||
}
|
||||
|
||||
function underlyingAssetAddress() public view returns (address) {
|
||||
return _underlyingAssetAddress;
|
||||
return UNDERLYING_ASSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev calculates the accumulated debt balance of the user
|
||||
* @return the debt balance of the user
|
||||
**/
|
||||
function balanceOf(address user) public virtual override view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev returns the principal debt balance of the user from
|
||||
* @return the debt balance of the user since the last burn/mint action
|
||||
* @dev Returns the principal debt balance of the user from
|
||||
* @return The debt balance of the user since the last burn/mint action
|
||||
**/
|
||||
function principalBalanceOf(address user) public view returns (uint256) {
|
||||
return _balances[user];
|
||||
return super.balanceOf(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev basic accounting for the mint action
|
||||
* @dev _user the target user of the minting action
|
||||
* @dev _amount the amount to mint
|
||||
**/
|
||||
function _mint(address user, uint256 amount) internal {
|
||||
_totalSupply = _totalSupply.add(amount);
|
||||
_balances[user] = _balances[user].add(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev basic accounting for the burn action
|
||||
* @dev _user the target user of the burning action
|
||||
* @dev _amount the amount to burn
|
||||
**/
|
||||
function _burn(address user, uint256 amount) internal {
|
||||
_totalSupply = _totalSupply.sub(amount);
|
||||
_balances[user] = _balances[user].sub(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev being non transferrable, the debt token does not implement any of the
|
||||
* @dev Being non transferrable, the debt token does not implement any of the
|
||||
* standard ERC20 functions for transfer and allowance.
|
||||
**/
|
||||
function transfer(address recipient, uint256 amount) external virtual override returns (bool) {
|
||||
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
|
||||
recipient; amount;
|
||||
revert('TRANSFER_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
function allowance(address owner, address spender)
|
||||
external
|
||||
virtual
|
||||
override
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
function allowance(address owner, address spender) public virtual override view returns (uint256) {
|
||||
owner; spender;
|
||||
revert('ALLOWANCE_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
function approve(address spender, uint256 amount) external virtual override returns (bool) {
|
||||
function approve(address spender, uint256 amount) public virtual override returns (bool) {
|
||||
spender; amount;
|
||||
revert('APPROVAL_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
function transferFrom(
|
||||
address sender,
|
||||
address recipient,
|
||||
uint256 amount
|
||||
) external virtual override returns (bool) {
|
||||
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
|
||||
sender; recipient; amount;
|
||||
revert('TRANSFER_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) {
|
||||
function increaseAllowance(address spender, uint256 addedValue) public virtual override returns (bool) {
|
||||
spender; addedValue;
|
||||
revert('ALLOWANCE_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
function decreaseAllowance(address spender, uint256 subtractedValue)
|
||||
external
|
||||
virtual
|
||||
returns (bool)
|
||||
{
|
||||
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual override returns (bool) {
|
||||
spender; subtractedValue;
|
||||
revert('ALLOWANCE_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev calculates the increase in balance since the last user interaction
|
||||
* @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
|
||||
* @dev Calculates the increase in balance since the last user interaction
|
||||
* @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 _calculateBalanceIncrease(address user)
|
||||
internal
|
||||
view
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
uint256
|
||||
)
|
||||
{
|
||||
uint256 previousPrincipalBalance = _balances[user];
|
||||
function _calculateBalanceIncrease(address user) internal view returns (uint256, uint256, uint256) {
|
||||
uint256 previousPrincipalBalance = principalBalanceOf(user);
|
||||
|
||||
if (previousPrincipalBalance == 0) {
|
||||
return (0, 0, 0);
|
||||
}
|
||||
|
||||
//calculate the accrued interest since the last accumulation
|
||||
// Calculation of the accrued interest since the last accumulation
|
||||
uint256 balanceIncrease = balanceOf(user).sub(previousPrincipalBalance);
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {IERC20} from '../../interfaces/IERC20.sol';
|
||||
|
||||
interface IAToken is IERC20 {
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue
Block a user