mirror of
				https://github.com/Instadapp/aave-protocol-v2.git
				synced 2024-07-29 21:47:30 +00:00 
			
		
		
		
	added comments, cleaned up variable debt token, base debt token
This commit is contained in:
		
							parent
							
								
									7813e8cec0
								
							
						
					
					
						commit
						77be1963d1
					
				| 
						 | 
				
			
			@ -9,6 +9,12 @@ import {WadRayMath} from '../libraries/WadRayMath.sol';
 | 
			
		|||
import '@nomiclabs/buidler/console.sol';
 | 
			
		||||
import {IVariableDebtToken} from './interfaces/IVariableDebtToken.sol';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @title interface IVariableDebtToken
 | 
			
		||||
* @author Aave
 | 
			
		||||
* @notice defines the basic interface for a variable debt token.
 | 
			
		||||
* @dev does not inherit from IERC20 to save in contract size
 | 
			
		||||
**/
 | 
			
		||||
contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
 | 
			
		||||
  using SafeMath for uint256;
 | 
			
		||||
  using WadRayMath for uint256;
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +22,15 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
 | 
			
		|||
 | 
			
		||||
  mapping(address => uint256) private userIndexes;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  * @dev emitted when new variable debt is minted
 | 
			
		||||
  * @param _user the user receiving the debt
 | 
			
		||||
  * @param _amount the amount of debt being minted
 | 
			
		||||
  * @param _previousBalance the previous balance of the user
 | 
			
		||||
  * @param _currentBalance the current balance of the user
 | 
			
		||||
  * @param _balanceIncrease the debt accumulated since the last action
 | 
			
		||||
  * @param _index the index of the user
 | 
			
		||||
  **/
 | 
			
		||||
  event mintDebt(
 | 
			
		||||
    address _user,
 | 
			
		||||
    uint256 _amount,
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +39,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
 | 
			
		|||
    uint256 _balanceIncrease,
 | 
			
		||||
    uint256 _index
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  * @dev emitted when variable debt is burnt
 | 
			
		||||
  * @param _user the user which debt has been burned
 | 
			
		||||
  * @param _amount the amount of debt being burned
 | 
			
		||||
  * @param _previousBalance the previous balance of the user
 | 
			
		||||
  * @param _currentBalance the current balance of the user
 | 
			
		||||
  * @param _balanceIncrease the debt accumulated since the last action
 | 
			
		||||
  * @param _index the index of the user
 | 
			
		||||
  **/
 | 
			
		||||
  event burnDebt(
 | 
			
		||||
    address _user,
 | 
			
		||||
    uint256 _amount,
 | 
			
		||||
| 
						 | 
				
			
			@ -33,19 +58,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
 | 
			
		|||
    uint256 _index
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @dev See {IERC20-balanceOf}.
 | 
			
		||||
   */
 | 
			
		||||
  function balanceOf(address account) public virtual override view returns (uint256) {
 | 
			
		||||
    if (balances[account] == 0) {
 | 
			
		||||
  function balanceOf(address _user) public virtual override view returns (uint256) {
 | 
			
		||||
    if (balances[_user] == 0) {
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return
 | 
			
		||||
      balances[account]
 | 
			
		||||
      balances[_user]
 | 
			
		||||
        .wadToRay()
 | 
			
		||||
        .rayMul(pool.getReserveNormalizedVariableDebt(underlyingAssetAddress))
 | 
			
		||||
        .rayDiv(userIndexes[account])
 | 
			
		||||
        .rayDiv(userIndexes[_user])
 | 
			
		||||
        .rayToWad();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,57 +75,48 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
 | 
			
		|||
    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 {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  * @dev mints new variable debt
 | 
			
		||||
  * @param _user the user receiving the debt
 | 
			
		||||
  * @param _amount the amount of debt being minted
 | 
			
		||||
  **/
 | 
			
		||||
  function mint(address _user, uint256 _amount) public override onlyLendingPool {
 | 
			
		||||
    (
 | 
			
		||||
      uint256 previousBalance,
 | 
			
		||||
      uint256 currentBalance,
 | 
			
		||||
      uint256 balanceIncrease
 | 
			
		||||
    ) = internalCumulateBalance(account);
 | 
			
		||||
    ) = _cumulateBalance(_user);
 | 
			
		||||
 | 
			
		||||
    _mint(account, amount);
 | 
			
		||||
    _mint(_user, _amount);
 | 
			
		||||
 | 
			
		||||
    userIndexes[account] = pool.getReserveNormalizedVariableDebt(underlyingAssetAddress);
 | 
			
		||||
    userIndexes[_user] = pool.getReserveNormalizedVariableDebt(underlyingAssetAddress);
 | 
			
		||||
 | 
			
		||||
    emit mintDebt(account, amount, previousBalance, currentBalance, balanceIncrease, userIndexes[account]);
 | 
			
		||||
    emit mintDebt(_user, _amount, previousBalance, currentBalance, balanceIncrease, userIndexes[_user]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @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 {
 | 
			
		||||
  * @dev burns user variable debt
 | 
			
		||||
  * @param _user the user which debt is burnt
 | 
			
		||||
  * @param _amount the amount of debt being burned
 | 
			
		||||
  **/
 | 
			
		||||
  function burn(address _user, uint256 _amount) public override onlyLendingPool {
 | 
			
		||||
    (
 | 
			
		||||
      uint256 previousBalance,
 | 
			
		||||
      uint256 currentBalance,
 | 
			
		||||
      uint256 balanceIncrease
 | 
			
		||||
    ) = internalCumulateBalance(account);
 | 
			
		||||
    ) = _cumulateBalance(_user);
 | 
			
		||||
 | 
			
		||||
    _burn(account, amount);
 | 
			
		||||
    _burn(_user, _amount);
 | 
			
		||||
 | 
			
		||||
    //if user repaid everything
 | 
			
		||||
    if (currentBalance == amount) {
 | 
			
		||||
      userIndexes[account] = 0;
 | 
			
		||||
    if (currentBalance == _amount) {
 | 
			
		||||
      userIndexes[_user] = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
      userIndexes[account] = pool.getReserveNormalizedVariableDebt(underlyingAssetAddress);
 | 
			
		||||
      userIndexes[_user] = pool.getReserveNormalizedVariableDebt(underlyingAssetAddress);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    emit burnDebt(account, amount, previousBalance, currentBalance, balanceIncrease, userIndexes[account]);
 | 
			
		||||
    emit burnDebt(_user, _amount, previousBalance, currentBalance, balanceIncrease, userIndexes[_user]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +125,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
 | 
			
		|||
   * @return the previous principal balance, the new principal balance, the balance increase
 | 
			
		||||
   * and the new user index
 | 
			
		||||
   **/
 | 
			
		||||
  function internalCumulateBalance(address _user)
 | 
			
		||||
  function _cumulateBalance(address _user)
 | 
			
		||||
    internal
 | 
			
		||||
    returns (
 | 
			
		||||
      uint256,
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +142,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
 | 
			
		|||
    //calculate the accrued interest since the last accumulation
 | 
			
		||||
    uint256 balanceIncrease = balanceOf(_user).sub(previousPrincipalBalance);
 | 
			
		||||
 | 
			
		||||
    //mints an amount of tokens equivalent to the amount accumulated
 | 
			
		||||
    //mints an _amount of tokens equivalent to the _amount accumulated
 | 
			
		||||
    _mint(_user, balanceIncrease);
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,17 @@
 | 
			
		|||
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 {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 {Address} from '@openzeppelin/contracts/utils/Address.sol';
 | 
			
		||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
 | 
			
		||||
import {LendingPool} from '../../lendingpool/LendingPool.sol';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
* @title contract DebtTokenBase
 | 
			
		||||
* @author Aave
 | 
			
		||||
* @notice base contract for StableDebtToken and VariableDebtToken 
 | 
			
		||||
*/ 
 | 
			
		||||
abstract contract DebtTokenBase is IERC20 {
 | 
			
		||||
  using SafeMath for uint256;
 | 
			
		||||
  using Address for address;
 | 
			
		||||
| 
						 | 
				
			
			@ -16,31 +20,27 @@ abstract contract DebtTokenBase is IERC20 {
 | 
			
		|||
 | 
			
		||||
  string public name;
 | 
			
		||||
  string public symbol;
 | 
			
		||||
  uint8  public decimals;
 | 
			
		||||
  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 only lending pool can call functions marked by this modifier
 | 
			
		||||
  **/
 | 
			
		||||
  modifier onlyLendingPool {
 | 
			
		||||
    require(msg.sender == address(pool), 'INVALID_CALLER');
 | 
			
		||||
    _;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @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.
 | 
			
		||||
   * @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
 | 
			
		||||
   * @param _underlying the underlying asset of the debt token
 | 
			
		||||
   * @param _addressesProvider the addresses provider of the protocol
 | 
			
		||||
   */
 | 
			
		||||
  function init(
 | 
			
		||||
    string memory _name,
 | 
			
		||||
| 
						 | 
				
			
			@ -56,35 +56,48 @@ abstract contract DebtTokenBase is IERC20 {
 | 
			
		|||
    pool = LendingPool(payable(_addressesProvider.getLendingPool()));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @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 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 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];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @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) {
 | 
			
		||||
  * @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 
 | 
			
		||||
  * standard ERC20 functions for transfer and allowance. 
 | 
			
		||||
  **/
 | 
			
		||||
  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
 | 
			
		||||
| 
						 | 
				
			
			@ -95,55 +108,22 @@ abstract contract DebtTokenBase is IERC20 {
 | 
			
		|||
    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) {
 | 
			
		||||
  function approve(address spender, uint256 _amount) public virtual override returns (bool) {
 | 
			
		||||
    revert('APPROVAL_NOT_SUPPORTED');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function transferFrom(
 | 
			
		||||
    address sender,
 | 
			
		||||
    address recipient,
 | 
			
		||||
    uint256 amount
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			@ -151,14 +131,4 @@ abstract contract DebtTokenBase is IERC20 {
 | 
			
		|||
  {
 | 
			
		||||
    revert('ALLOWANCE_NOT_SUPPORTED');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function _mint(address account, uint256 amount) internal {
 | 
			
		||||
    totalSupply = totalSupply.add(amount);
 | 
			
		||||
    balances[account] = balances[account].add(amount);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function _burn(address account, uint256 amount) internal {
 | 
			
		||||
    totalSupply = totalSupply.sub(amount);
 | 
			
		||||
    balances[account] = balances[account].sub(amount);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,32 @@
 | 
			
		|||
pragma solidity ^0.6.0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @title interface IVariableDebtToken
 | 
			
		||||
* @author Aave
 | 
			
		||||
* @notice defines the basic interface for a variable debt token.
 | 
			
		||||
* @dev does not inherit from IERC20 to save in contract size
 | 
			
		||||
**/
 | 
			
		||||
interface IVariableDebtToken {
 | 
			
		||||
 | 
			
		||||
  function mint(address account, uint256 amount) external virtual;
 | 
			
		||||
  /**
 | 
			
		||||
  * @dev mints new variable debt
 | 
			
		||||
  * @param _user the user receiving the debt
 | 
			
		||||
  * @param _amount the amount of debt being minted
 | 
			
		||||
  **/
 | 
			
		||||
  function mint(address _user, uint256 _amount) external virtual;
 | 
			
		||||
 | 
			
		||||
  function burn(address _account, uint256 _amount) external virtual;
 | 
			
		||||
  /**
 | 
			
		||||
  * @dev burns user variable debt
 | 
			
		||||
  * @param _user the user which debt is burnt
 | 
			
		||||
  * @param _amount the amount of debt being burned
 | 
			
		||||
  **/
 | 
			
		||||
  function burn(address _user, uint256 _amount) external virtual;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  * @dev returns the last index of the user
 | 
			
		||||
  * @return the index of the user
 | 
			
		||||
  **/
 | 
			
		||||
  function getUserIndex(address _user) external virtual view returns(uint256);
 | 
			
		||||
 | 
			
		||||
  function getUserIndex(address _account) external virtual view returns(uint256);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1209,7 +1209,6 @@ const calcExpectedAverageStableBorrowRate = (
 | 
			
		|||
  amountChanged: string | BigNumber,
 | 
			
		||||
  rate: BigNumber
 | 
			
		||||
) => {
 | 
			
		||||
  console.log(avgStableRateBefore, totalBorrowsStableBefore);
 | 
			
		||||
  const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalBorrowsStableBefore);
 | 
			
		||||
  const weightedAmountBorrowed = rate.multipliedBy(amountChanged);
 | 
			
		||||
  const totalBorrowedStable = totalBorrowsStableBefore.plus(new BigNumber(amountChanged));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user