creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/Address.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n  /**\n   * @dev Returns true if `account` is a contract.\n   *\n   * [IMPORTANT]\n   * ====\n   * It is unsafe to assume that an address for which this function returns\n   * false is an externally-owned account (EOA) and not a contract.\n   *\n   * Among others, `isContract` will return false for the following\n   * types of addresses:\n   *\n   *  - an externally-owned account\n   *  - a contract in construction\n   *  - an address where a contract will be created\n   *  - an address where a contract lived, but was destroyed\n   * ====\n   */\n  function isContract(address account) internal view returns (bool) {\n    // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n    // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n    // for accounts without code, i.e. `keccak256('')`\n    bytes32 codehash;\n    bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      codehash := extcodehash(account)\n    }\n    return (codehash != accountHash && codehash != 0x0);\n  }\n\n  /**\n   * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n   * `recipient`, forwarding all available gas and reverting on errors.\n   *\n   * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n   * of certain opcodes, possibly making contracts go over the 2300 gas limit\n   * imposed by `transfer`, making them unable to receive funds via\n   * `transfer`. {sendValue} removes this limitation.\n   *\n   * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n   *\n   * IMPORTANT: because control is transferred to `recipient`, care must be\n   * taken to not create reentrancy vulnerabilities. Consider using\n   * {ReentrancyGuard} or the\n   * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n   */\n  function sendValue(address payable recipient, uint256 amount) internal {\n    require(address(this).balance >= amount, 'Address: insufficient balance');\n\n    // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n    (bool success, ) = recipient.call{value: amount}('');\n    require(success, 'Address: unable to send value, recipient may have reverted');\n  }\n}\n"
      },
      "@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.6.12;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n  function _msgSender() internal virtual view returns (address payable) {\n    return msg.sender;\n  }\n\n  function _msgData() internal virtual view returns (bytes memory) {\n    this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n    return msg.data;\n  }\n}\n"
      },
      "@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/IERC20.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n  /**\n   * @dev Returns the amount of tokens in existence.\n   */\n  function totalSupply() external view returns (uint256);\n\n  /**\n   * @dev Returns the amount of tokens owned by `account`.\n   */\n  function balanceOf(address account) external view returns (uint256);\n\n  /**\n   * @dev Moves `amount` tokens from the caller's account to `recipient`.\n   *\n   * Returns a boolean value indicating whether the operation succeeded.\n   *\n   * Emits a {Transfer} event.\n   */\n  function transfer(address recipient, uint256 amount) external returns (bool);\n\n  /**\n   * @dev Returns the remaining number of tokens that `spender` will be\n   * allowed to spend on behalf of `owner` through {transferFrom}. This is\n   * zero by default.\n   *\n   * This value changes when {approve} or {transferFrom} are called.\n   */\n  function allowance(address owner, address spender) external view returns (uint256);\n\n  /**\n   * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n   *\n   * Returns a boolean value indicating whether the operation succeeded.\n   *\n   * IMPORTANT: Beware that changing an allowance with this method brings the risk\n   * that someone may use both the old and the new allowance by unfortunate\n   * transaction ordering. One possible solution to mitigate this race\n   * condition is to first reduce the spender's allowance to 0 and set the\n   * desired value afterwards:\n   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n   *\n   * Emits an {Approval} event.\n   */\n  function approve(address spender, uint256 amount) external returns (bool);\n\n  /**\n   * @dev Moves `amount` tokens from `sender` to `recipient` using the\n   * allowance mechanism. `amount` is then deducted from the caller's\n   * allowance.\n   *\n   * Returns a boolean value indicating whether the operation succeeded.\n   *\n   * Emits a {Transfer} event.\n   */\n  function transferFrom(\n    address sender,\n    address recipient,\n    uint256 amount\n  ) external returns (bool);\n\n  /**\n   * @dev Emitted when `value` tokens are moved from one account (`from`) to\n   * another (`to`).\n   *\n   * Note that `value` may be zero.\n   */\n  event Transfer(address indexed from, address indexed to, uint256 value);\n\n  /**\n   * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n   * a call to {approve}. `value` is the new allowance.\n   */\n  event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\nimport {IERC20} from './IERC20.sol';\n\ninterface IERC20Detailed is IERC20 {\n  function name() external view returns (string memory);\n\n  function symbol() external view returns (string memory);\n\n  function decimals() external view returns (uint8);\n}\n"
      },
      "@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.6.12;\n\nimport {IERC20} from './IERC20.sol';\nimport {SafeMath} from './SafeMath.sol';\nimport {Address} from './Address.sol';\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n  using SafeMath for uint256;\n  using Address for address;\n\n  function safeTransfer(\n    IERC20 token,\n    address to,\n    uint256 value\n  ) internal {\n    callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n  }\n\n  function safeTransferFrom(\n    IERC20 token,\n    address from,\n    address to,\n    uint256 value\n  ) internal {\n    callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n  }\n\n  function safeApprove(\n    IERC20 token,\n    address spender,\n    uint256 value\n  ) internal {\n    require(\n      (value == 0) || (token.allowance(address(this), spender) == 0),\n      'SafeERC20: approve from non-zero to non-zero allowance'\n    );\n    callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n  }\n\n  function callOptionalReturn(IERC20 token, bytes memory data) private {\n    require(address(token).isContract(), 'SafeERC20: call to non-contract');\n\n    // solhint-disable-next-line avoid-low-level-calls\n    (bool success, bytes memory returndata) = address(token).call(data);\n    require(success, 'SafeERC20: low-level call failed');\n\n    if (returndata.length > 0) {\n      // Return data is optional\n      // solhint-disable-next-line max-line-length\n      require(abi.decode(returndata, (bool)), 'SafeERC20: ERC20 operation did not succeed');\n    }\n  }\n}\n"
      },
      "@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/SafeMath.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n  /**\n   * @dev Returns the addition of two unsigned integers, reverting on\n   * overflow.\n   *\n   * Counterpart to Solidity's `+` operator.\n   *\n   * Requirements:\n   * - Addition cannot overflow.\n   */\n  function add(uint256 a, uint256 b) internal pure returns (uint256) {\n    uint256 c = a + b;\n    require(c >= a, 'SafeMath: addition overflow');\n\n    return c;\n  }\n\n  /**\n   * @dev Returns the subtraction of two unsigned integers, reverting on\n   * overflow (when the result is negative).\n   *\n   * Counterpart to Solidity's `-` operator.\n   *\n   * Requirements:\n   * - Subtraction cannot overflow.\n   */\n  function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n    return sub(a, b, 'SafeMath: subtraction overflow');\n  }\n\n  /**\n   * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n   * overflow (when the result is negative).\n   *\n   * Counterpart to Solidity's `-` operator.\n   *\n   * Requirements:\n   * - Subtraction cannot overflow.\n   */\n  function sub(\n    uint256 a,\n    uint256 b,\n    string memory errorMessage\n  ) internal pure returns (uint256) {\n    require(b <= a, errorMessage);\n    uint256 c = a - b;\n\n    return c;\n  }\n\n  /**\n   * @dev Returns the multiplication of two unsigned integers, reverting on\n   * overflow.\n   *\n   * Counterpart to Solidity's `*` operator.\n   *\n   * Requirements:\n   * - Multiplication cannot overflow.\n   */\n  function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n    // benefit is lost if 'b' is also tested.\n    // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n    if (a == 0) {\n      return 0;\n    }\n\n    uint256 c = a * b;\n    require(c / a == b, 'SafeMath: multiplication overflow');\n\n    return c;\n  }\n\n  /**\n   * @dev Returns the integer division of two unsigned integers. Reverts on\n   * division by zero. The result is rounded towards zero.\n   *\n   * Counterpart to Solidity's `/` operator. Note: this function uses a\n   * `revert` opcode (which leaves remaining gas untouched) while Solidity\n   * uses an invalid opcode to revert (consuming all remaining gas).\n   *\n   * Requirements:\n   * - The divisor cannot be zero.\n   */\n  function div(uint256 a, uint256 b) internal pure returns (uint256) {\n    return div(a, b, 'SafeMath: division by zero');\n  }\n\n  /**\n   * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n   * division by zero. The result is rounded towards zero.\n   *\n   * Counterpart to Solidity's `/` operator. Note: this function uses a\n   * `revert` opcode (which leaves remaining gas untouched) while Solidity\n   * uses an invalid opcode to revert (consuming all remaining gas).\n   *\n   * Requirements:\n   * - The divisor cannot be zero.\n   */\n  function div(\n    uint256 a,\n    uint256 b,\n    string memory errorMessage\n  ) internal pure returns (uint256) {\n    // Solidity only automatically asserts when dividing by 0\n    require(b > 0, errorMessage);\n    uint256 c = a / b;\n    // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n    return c;\n  }\n\n  /**\n   * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n   * Reverts when dividing by zero.\n   *\n   * Counterpart to Solidity's `%` operator. This function uses a `revert`\n   * opcode (which leaves remaining gas untouched) while Solidity uses an\n   * invalid opcode to revert (consuming all remaining gas).\n   *\n   * Requirements:\n   * - The divisor cannot be zero.\n   */\n  function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n    return mod(a, b, 'SafeMath: modulo by zero');\n  }\n\n  /**\n   * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n   * Reverts with custom message when dividing by zero.\n   *\n   * Counterpart to Solidity's `%` operator. This function uses a `revert`\n   * opcode (which leaves remaining gas untouched) while Solidity uses an\n   * invalid opcode to revert (consuming all remaining gas).\n   *\n   * Requirements:\n   * - The divisor cannot be zero.\n   */\n  function mod(\n    uint256 a,\n    uint256 b,\n    string memory errorMessage\n  ) internal pure returns (uint256) {\n    require(b != 0, errorMessage);\n    return a % b;\n  }\n}\n"
      },
      "@aave/protocol-v2/contracts/interfaces/ILendingPool.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol';\nimport {DataTypes} from '../protocol/libraries/types/DataTypes.sol';\n\ninterface ILendingPool {\n  /**\n   * @dev Emitted on deposit()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address initiating the deposit\n   * @param onBehalfOf The beneficiary of the deposit, receiving the aTokens\n   * @param amount The amount deposited\n   * @param referral The referral code used\n   **/\n  event Deposit(\n    address indexed reserve,\n    address user,\n    address indexed onBehalfOf,\n    uint256 amount,\n    uint16 indexed referral\n  );\n\n  /**\n   * @dev Emitted on withdraw()\n   * @param reserve The address of the underlyng asset being withdrawn\n   * @param user The address initiating the withdrawal, owner of aTokens\n   * @param to Address that will receive the underlying\n   * @param amount The amount to be withdrawn\n   **/\n  event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount);\n\n  /**\n   * @dev Emitted on borrow() and flashLoan() when debt needs to be opened\n   * @param reserve The address of the underlying asset being borrowed\n   * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just\n   * initiator of the transaction on flashLoan()\n   * @param onBehalfOf The address that will be getting the debt\n   * @param amount The amount borrowed out\n   * @param borrowRateMode The rate mode: 1 for Stable, 2 for Variable\n   * @param borrowRate The numeric rate at which the user has borrowed\n   * @param referral The referral code used\n   **/\n  event Borrow(\n    address indexed reserve,\n    address user,\n    address indexed onBehalfOf,\n    uint256 amount,\n    uint256 borrowRateMode,\n    uint256 borrowRate,\n    uint16 indexed referral\n  );\n\n  /**\n   * @dev Emitted on repay()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The beneficiary of the repayment, getting his debt reduced\n   * @param repayer The address of the user initiating the repay(), providing the funds\n   * @param amount The amount repaid\n   **/\n  event Repay(\n    address indexed reserve,\n    address indexed user,\n    address indexed repayer,\n    uint256 amount\n  );\n\n  /**\n   * @dev Emitted on swapBorrowRateMode()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address of the user swapping his rate mode\n   * @param rateMode The rate mode that the user wants to swap to\n   **/\n  event Swap(address indexed reserve, address indexed user, uint256 rateMode);\n\n  /**\n   * @dev Emitted on setUserUseReserveAsCollateral()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address of the user enabling the usage as collateral\n   **/\n  event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user);\n\n  /**\n   * @dev Emitted on setUserUseReserveAsCollateral()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address of the user enabling the usage as collateral\n   **/\n  event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);\n\n  /**\n   * @dev Emitted on rebalanceStableBorrowRate()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address of the user for which the rebalance has been executed\n   **/\n  event RebalanceStableBorrowRate(address indexed reserve, address indexed user);\n\n  /**\n   * @dev Emitted on flashLoan()\n   * @param target The address of the flash loan receiver contract\n   * @param initiator The address initiating the flash loan\n   * @param asset The address of the asset being flash borrowed\n   * @param amount The amount flash borrowed\n   * @param premium The fee flash borrowed\n   * @param referralCode The referral code used\n   **/\n  event FlashLoan(\n    address indexed target,\n    address indexed initiator,\n    address indexed asset,\n    uint256 amount,\n    uint256 premium,\n    uint16 referralCode\n  );\n\n  /**\n   * @dev Emitted when the pause is triggered.\n   */\n  event Paused();\n\n  /**\n   * @dev Emitted when the pause is lifted.\n   */\n  event Unpaused();\n\n  /**\n   * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via\n   * LendingPoolCollateral manager using a DELEGATECALL\n   * This allows to have the events in the generated ABI for LendingPool.\n   * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation\n   * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation\n   * @param user The address of the borrower getting liquidated\n   * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover\n   * @param liquidatedCollateralAmount The amount of collateral received by the liiquidator\n   * @param liquidator The address of the liquidator\n   * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants\n   * to receive the underlying collateral asset directly\n   **/\n  event LiquidationCall(\n    address indexed collateralAsset,\n    address indexed debtAsset,\n    address indexed user,\n    uint256 debtToCover,\n    uint256 liquidatedCollateralAmount,\n    address liquidator,\n    bool receiveAToken\n  );\n\n  /**\n   * @dev Emitted when the state of a reserve is updated. NOTE: This event is actually declared\n   * in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal,\n   * the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it\n   * gets added to the LendingPool ABI\n   * @param reserve The address of the underlying asset of the reserve\n   * @param liquidityRate The new liquidity rate\n   * @param stableBorrowRate The new stable borrow rate\n   * @param variableBorrowRate The new variable borrow rate\n   * @param liquidityIndex The new liquidity index\n   * @param variableBorrowIndex The new variable borrow index\n   **/\n  event ReserveDataUpdated(\n    address indexed reserve,\n    uint256 liquidityRate,\n    uint256 stableBorrowRate,\n    uint256 variableBorrowRate,\n    uint256 liquidityIndex,\n    uint256 variableBorrowIndex\n  );\n\n  /**\n   * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.\n   * - E.g. User deposits 100 USDC and gets in return 100 aUSDC\n   * @param asset The address of the underlying asset to deposit\n   * @param amount The amount to be deposited\n   * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user\n   *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens\n   *   is a different wallet\n   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   **/\n  function deposit(\n    address asset,\n    uint256 amount,\n    address onBehalfOf,\n    uint16 referralCode\n  ) external;\n\n  /**\n   * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned\n   * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC\n   * @param asset The address of the underlying asset to withdraw\n   * @param amount The underlying amount to be withdrawn\n   *   - Send the value type(uint256).max in order to withdraw the whole aToken balance\n   * @param to Address that will receive the underlying, same as msg.sender if the user\n   *   wants to receive it on his own wallet, or a different address if the beneficiary is a\n   *   different wallet\n   * @return The final amount withdrawn\n   **/\n  function withdraw(\n    address asset,\n    uint256 amount,\n    address to\n  ) external returns (uint256);\n\n  /**\n   * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower\n   * already deposited enough collateral, or he was given enough allowance by a credit delegator on the\n   * corresponding debt token (StableDebtToken or VariableDebtToken)\n   * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet\n   *   and 100 stable/variable debt tokens, depending on the `interestRateMode`\n   * @param asset The address of the underlying asset to borrow\n   * @param amount The amount to be borrowed\n   * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable\n   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   * @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself\n   * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator\n   * if he has been given credit delegation allowance\n   **/\n  function borrow(\n    address asset,\n    uint256 amount,\n    uint256 interestRateMode,\n    uint16 referralCode,\n    address onBehalfOf\n  ) external;\n\n  /**\n   * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned\n   * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address\n   * @param asset The address of the borrowed underlying asset previously borrowed\n   * @param amount The amount to repay\n   * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`\n   * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable\n   * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the\n   * user calling the function if he wants to reduce/remove his own debt, or the address of any other\n   * other borrower whose debt should be removed\n   * @return The final amount repaid\n   **/\n  function repay(\n    address asset,\n    uint256 amount,\n    uint256 rateMode,\n    address onBehalfOf\n  ) external returns (uint256);\n\n  /**\n   * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa\n   * @param asset The address of the underlying asset borrowed\n   * @param rateMode The rate mode that the user wants to swap to\n   **/\n  function swapBorrowRateMode(address asset, uint256 rateMode) external;\n\n  /**\n   * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.\n   * - Users can be rebalanced if the following conditions are satisfied:\n   *     1. Usage ratio is above 95%\n   *     2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been\n   *        borrowed at a stable rate and depositors are not earning enough\n   * @param asset The address of the underlying asset borrowed\n   * @param user The address of the user to be rebalanced\n   **/\n  function rebalanceStableBorrowRate(address asset, address user) external;\n\n  /**\n   * @dev Allows depositors to enable/disable a specific deposited asset as collateral\n   * @param asset The address of the underlying asset deposited\n   * @param useAsCollateral `true` if the user wants to use the deposit as collateral, `false` otherwise\n   **/\n  function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external;\n\n  /**\n   * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1\n   * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives\n   *   a proportionally amount of the `collateralAsset` plus a bonus to cover market risk\n   * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation\n   * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation\n   * @param user The address of the borrower getting liquidated\n   * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover\n   * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants\n   * to receive the underlying collateral asset directly\n   **/\n  function liquidationCall(\n    address collateralAsset,\n    address debtAsset,\n    address user,\n    uint256 debtToCover,\n    bool receiveAToken\n  ) external;\n\n  /**\n   * @dev Allows smartcontracts to access the liquidity of the pool within one transaction,\n   * as long as the amount taken plus a fee is returned.\n   * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration.\n   * For further details please visit https://developers.aave.com\n   * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface\n   * @param assets The addresses of the assets being flash-borrowed\n   * @param amounts The amounts amounts being flash-borrowed\n   * @param modes Types of the debt to open if the flash loan is not returned:\n   *   0 -> Don't open any debt, just revert if funds can't be transferred from the receiver\n   *   1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address\n   *   2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address\n   * @param onBehalfOf The address  that will receive the debt in the case of using on `modes` 1 or 2\n   * @param params Variadic packed params to pass to the receiver as extra information\n   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   **/\n  function flashLoan(\n    address receiverAddress,\n    address[] calldata assets,\n    uint256[] calldata amounts,\n    uint256[] calldata modes,\n    address onBehalfOf,\n    bytes calldata params,\n    uint16 referralCode\n  ) external;\n\n  /**\n   * @dev Returns the user account data across all the reserves\n   * @param user The address of the user\n   * @return totalCollateralETH the total collateral in ETH of the user\n   * @return totalDebtETH the total debt in ETH of the user\n   * @return availableBorrowsETH the borrowing power left of the user\n   * @return currentLiquidationThreshold the liquidation threshold of the user\n   * @return ltv the loan to value of the user\n   * @return healthFactor the current health factor of the user\n   **/\n  function getUserAccountData(address user)\n    external\n    view\n    returns (\n      uint256 totalCollateralETH,\n      uint256 totalDebtETH,\n      uint256 availableBorrowsETH,\n      uint256 currentLiquidationThreshold,\n      uint256 ltv,\n      uint256 healthFactor\n    );\n\n  function initReserve(\n    address reserve,\n    address aTokenAddress,\n    address stableDebtAddress,\n    address variableDebtAddress,\n    address interestRateStrategyAddress\n  ) external;\n\n  function setReserveInterestRateStrategyAddress(address reserve, address rateStrategyAddress)\n    external;\n\n  function setConfiguration(address reserve, uint256 configuration) external;\n\n  /**\n   * @dev Returns the configuration of the reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @return The configuration of the reserve\n   **/\n  function getConfiguration(address asset)\n    external\n    view\n    returns (DataTypes.ReserveConfigurationMap memory);\n\n  /**\n   * @dev Returns the configuration of the user across all the reserves\n   * @param user The user address\n   * @return The configuration of the user\n   **/\n  function getUserConfiguration(address user)\n    external\n    view\n    returns (DataTypes.UserConfigurationMap memory);\n\n  /**\n   * @dev Returns the normalized income normalized income of the reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @return The reserve's normalized income\n   */\n  function getReserveNormalizedIncome(address asset) external view returns (uint256);\n\n  /**\n   * @dev Returns the normalized variable debt per unit of asset\n   * @param asset The address of the underlying asset of the reserve\n   * @return The reserve normalized variable debt\n   */\n  function getReserveNormalizedVariableDebt(address asset) external view returns (uint256);\n\n  /**\n   * @dev Returns the state and configuration of the reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @return The state of the reserve\n   **/\n  function getReserveData(address asset) external view returns (DataTypes.ReserveData memory);\n\n  function finalizeTransfer(\n    address asset,\n    address from,\n    address to,\n    uint256 amount,\n    uint256 balanceFromAfter,\n    uint256 balanceToBefore\n  ) external;\n\n  function getReservesList() external view returns (address[] memory);\n\n  function getAddressesProvider() external view returns (ILendingPoolAddressesProvider);\n\n  function setPause(bool val) external;\n\n  function paused() external view returns (bool);\n}\n"
      },
      "@aave/protocol-v2/contracts/interfaces/ILendingPoolAddressesProvider.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\n/**\n * @title LendingPoolAddressesProvider contract\n * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles\n * - Acting also as factory of proxies and admin of those, so with right to change its implementations\n * - Owned by the Aave Governance\n * @author Aave\n **/\ninterface ILendingPoolAddressesProvider {\n  event MarketIdSet(string newMarketId);\n  event LendingPoolUpdated(address indexed newAddress);\n  event ConfigurationAdminUpdated(address indexed newAddress);\n  event EmergencyAdminUpdated(address indexed newAddress);\n  event LendingPoolConfiguratorUpdated(address indexed newAddress);\n  event LendingPoolCollateralManagerUpdated(address indexed newAddress);\n  event PriceOracleUpdated(address indexed newAddress);\n  event LendingRateOracleUpdated(address indexed newAddress);\n  event ProxyCreated(bytes32 id, address indexed newAddress);\n  event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy);\n\n  function getMarketId() external view returns (string memory);\n\n  function setMarketId(string calldata marketId) external;\n\n  function setAddress(bytes32 id, address newAddress) external;\n\n  function setAddressAsProxy(bytes32 id, address impl) external;\n\n  function getAddress(bytes32 id) external view returns (address);\n\n  function getLendingPool() external view returns (address);\n\n  function setLendingPoolImpl(address pool) external;\n\n  function getLendingPoolConfigurator() external view returns (address);\n\n  function setLendingPoolConfiguratorImpl(address configurator) external;\n\n  function getLendingPoolCollateralManager() external view returns (address);\n\n  function setLendingPoolCollateralManager(address manager) external;\n\n  function getPoolAdmin() external view returns (address);\n\n  function setPoolAdmin(address admin) external;\n\n  function getEmergencyAdmin() external view returns (address);\n\n  function setEmergencyAdmin(address admin) external;\n\n  function getPriceOracle() external view returns (address);\n\n  function setPriceOracle(address priceOracle) external;\n\n  function getLendingRateOracle() external view returns (address);\n\n  function setLendingRateOracle(address lendingRateOracle) external;\n}\n"
      },
      "@aave/protocol-v2/contracts/interfaces/IScaledBalanceToken.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\ninterface IScaledBalanceToken {\n  /**\n   * @dev Returns the scaled balance of the user. The scaled balance is the sum of all the\n   * updated stored balance divided by the reserve's liquidity index at the moment of the update\n   * @param user The user whose balance is calculated\n   * @return The scaled balance of the user\n   **/\n  function scaledBalanceOf(address user) external view returns (uint256);\n\n  /**\n   * @dev Returns the scaled balance of the user and the scaled total supply.\n   * @param user The address of the user\n   * @return The scaled balance of the user\n   * @return The scaled balance and the scaled total supply\n   **/\n  function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256);\n\n  /**\n   * @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index)\n   * @return The scaled total supply\n   **/\n  function scaledTotalSupply() external view returns (uint256);\n}\n"
      },
      "@aave/protocol-v2/contracts/protocol/libraries/helpers/Errors.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\n/**\n * @title Errors library\n * @author Aave\n * @notice Defines the error messages emitted by the different contracts of the Aave protocol\n * @dev Error messages prefix glossary:\n *  - VL = ValidationLogic\n *  - MATH = Math libraries\n *  - CT = Common errors between tokens (AToken, VariableDebtToken and StableDebtToken)\n *  - AT = AToken\n *  - SDT = StableDebtToken\n *  - VDT = VariableDebtToken\n *  - LP = LendingPool\n *  - LPAPR = LendingPoolAddressesProviderRegistry\n *  - LPC = LendingPoolConfiguration\n *  - RL = ReserveLogic\n *  - LPCM = LendingPoolCollateralManager\n *  - P = Pausable\n */\nlibrary Errors {\n  //common errors\n  string public constant CALLER_NOT_POOL_ADMIN = '33'; // 'The caller must be the pool admin'\n  string public constant BORROW_ALLOWANCE_NOT_ENOUGH = '59'; // User borrows on behalf, but allowance are too small\n\n  //contract specific errors\n  string public constant VL_INVALID_AMOUNT = '1'; // 'Amount must be greater than 0'\n  string public constant VL_NO_ACTIVE_RESERVE = '2'; // 'Action requires an active reserve'\n  string public constant VL_RESERVE_FROZEN = '3'; // 'Action cannot be performed because the reserve is frozen'\n  string public constant VL_CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = '4'; // 'The current liquidity is not enough'\n  string public constant VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5'; // 'User cannot withdraw more than the available balance'\n  string public constant VL_TRANSFER_NOT_ALLOWED = '6'; // 'Transfer cannot be allowed.'\n  string public constant VL_BORROWING_NOT_ENABLED = '7'; // 'Borrowing is not enabled'\n  string public constant VL_INVALID_INTEREST_RATE_MODE_SELECTED = '8'; // 'Invalid interest rate mode selected'\n  string public constant VL_COLLATERAL_BALANCE_IS_0 = '9'; // 'The collateral balance is 0'\n  string public constant VL_HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = '10'; // 'Health factor is lesser than the liquidation threshold'\n  string public constant VL_COLLATERAL_CANNOT_COVER_NEW_BORROW = '11'; // 'There is not enough collateral to cover a new borrow'\n  string public constant VL_STABLE_BORROWING_NOT_ENABLED = '12'; // stable borrowing not enabled\n  string public constant VL_COLLATERAL_SAME_AS_BORROWING_CURRENCY = '13'; // collateral is (mostly) the same currency that is being borrowed\n  string public constant VL_AMOUNT_BIGGER_THAN_MAX_LOAN_SIZE_STABLE = '14'; // 'The requested amount is greater than the max loan size in stable rate mode\n  string public constant VL_NO_DEBT_OF_SELECTED_TYPE = '15'; // 'for repayment of stable debt, the user needs to have stable debt, otherwise, he needs to have variable debt'\n  string public constant VL_NO_EXPLICIT_AMOUNT_TO_REPAY_ON_BEHALF = '16'; // 'To repay on behalf of an user an explicit amount to repay is needed'\n  string public constant VL_NO_STABLE_RATE_LOAN_IN_RESERVE = '17'; // 'User does not have a stable rate loan in progress on this reserve'\n  string public constant VL_NO_VARIABLE_RATE_LOAN_IN_RESERVE = '18'; // 'User does not have a variable rate loan in progress on this reserve'\n  string public constant VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0 = '19'; // 'The underlying balance needs to be greater than 0'\n  string public constant VL_DEPOSIT_ALREADY_IN_USE = '20'; // 'User deposit is already being used as collateral'\n  string public constant LP_NOT_ENOUGH_STABLE_BORROW_BALANCE = '21'; // 'User does not have any stable rate loan for this reserve'\n  string public constant LP_INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET = '22'; // 'Interest rate rebalance conditions were not met'\n  string public constant LP_LIQUIDATION_CALL_FAILED = '23'; // 'Liquidation call failed'\n  string public constant LP_NOT_ENOUGH_LIQUIDITY_TO_BORROW = '24'; // 'There is not enough liquidity available to borrow'\n  string public constant LP_REQUESTED_AMOUNT_TOO_SMALL = '25'; // 'The requested amount is too small for a FlashLoan.'\n  string public constant LP_INCONSISTENT_PROTOCOL_ACTUAL_BALANCE = '26'; // 'The actual balance of the protocol is inconsistent'\n  string public constant LP_CALLER_NOT_LENDING_POOL_CONFIGURATOR = '27'; // 'The caller of the function is not the lending pool configurator'\n  string public constant LP_INCONSISTENT_FLASHLOAN_PARAMS = '28';\n  string public constant CT_CALLER_MUST_BE_LENDING_POOL = '29'; // 'The caller of this function must be a lending pool'\n  string public constant CT_CANNOT_GIVE_ALLOWANCE_TO_HIMSELF = '30'; // 'User cannot give allowance to himself'\n  string public constant CT_TRANSFER_AMOUNT_NOT_GT_0 = '31'; // 'Transferred amount needs to be greater than zero'\n  string public constant RL_RESERVE_ALREADY_INITIALIZED = '32'; // 'Reserve has already been initialized'\n  string public constant LPC_RESERVE_LIQUIDITY_NOT_0 = '34'; // 'The liquidity of the reserve needs to be 0'\n  string public constant LPC_INVALID_ATOKEN_POOL_ADDRESS = '35'; // 'The liquidity of the reserve needs to be 0'\n  string public constant LPC_INVALID_STABLE_DEBT_TOKEN_POOL_ADDRESS = '36'; // 'The liquidity of the reserve needs to be 0'\n  string public constant LPC_INVALID_VARIABLE_DEBT_TOKEN_POOL_ADDRESS = '37'; // 'The liquidity of the reserve needs to be 0'\n  string public constant LPC_INVALID_STABLE_DEBT_TOKEN_UNDERLYING_ADDRESS = '38'; // 'The liquidity of the reserve needs to be 0'\n  string public constant LPC_INVALID_VARIABLE_DEBT_TOKEN_UNDERLYING_ADDRESS = '39'; // 'The liquidity of the reserve needs to be 0'\n  string public constant LPC_INVALID_ADDRESSES_PROVIDER_ID = '40'; // 'The liquidity of the reserve needs to be 0'\n  string public constant LPC_INVALID_CONFIGURATION = '75'; // 'Invalid risk parameters for the reserve'\n  string public constant LPC_CALLER_NOT_EMERGENCY_ADMIN = '76'; // 'The caller must be the emergency admin'\n  string public constant LPAPR_PROVIDER_NOT_REGISTERED = '41'; // 'Provider is not registered'\n  string public constant LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD = '42'; // 'Health factor is not below the threshold'\n  string public constant LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED = '43'; // 'The collateral chosen cannot be liquidated'\n  string public constant LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = '44'; // 'User did not borrow the specified currency'\n  string public constant LPCM_NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE = '45'; // \"There isn't enough liquidity available to liquidate\"\n  string public constant LPCM_NO_ERRORS = '46'; // 'No errors'\n  string public constant LP_INVALID_FLASHLOAN_MODE = '47'; //Invalid flashloan mode selected\n  string public constant MATH_MULTIPLICATION_OVERFLOW = '48';\n  string public constant MATH_ADDITION_OVERFLOW = '49';\n  string public constant MATH_DIVISION_BY_ZERO = '50';\n  string public constant RL_LIQUIDITY_INDEX_OVERFLOW = '51'; //  Liquidity index overflows uint128\n  string public constant RL_VARIABLE_BORROW_INDEX_OVERFLOW = '52'; //  Variable borrow index overflows uint128\n  string public constant RL_LIQUIDITY_RATE_OVERFLOW = '53'; //  Liquidity rate overflows uint128\n  string public constant RL_VARIABLE_BORROW_RATE_OVERFLOW = '54'; //  Variable borrow rate overflows uint128\n  string public constant RL_STABLE_BORROW_RATE_OVERFLOW = '55'; //  Stable borrow rate overflows uint128\n  string public constant CT_INVALID_MINT_AMOUNT = '56'; //invalid amount to mint\n  string public constant LP_FAILED_REPAY_WITH_COLLATERAL = '57';\n  string public constant CT_INVALID_BURN_AMOUNT = '58'; //invalid amount to burn\n  string public constant LP_FAILED_COLLATERAL_SWAP = '60';\n  string public constant LP_INVALID_EQUAL_ASSETS_TO_SWAP = '61';\n  string public constant LP_REENTRANCY_NOT_ALLOWED = '62';\n  string public constant LP_CALLER_MUST_BE_AN_ATOKEN = '63';\n  string public constant LP_IS_PAUSED = '64'; // 'Pool is paused'\n  string public constant LP_NO_MORE_RESERVES_ALLOWED = '65';\n  string public constant LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN = '66';\n  string public constant RC_INVALID_LTV = '67';\n  string public constant RC_INVALID_LIQ_THRESHOLD = '68';\n  string public constant RC_INVALID_LIQ_BONUS = '69';\n  string public constant RC_INVALID_DECIMALS = '70';\n  string public constant RC_INVALID_RESERVE_FACTOR = '71';\n  string public constant LPAPR_INVALID_ADDRESSES_PROVIDER_ID = '72';\n  string public constant VL_INCONSISTENT_FLASHLOAN_PARAMS = '73';\n  string public constant LP_INCONSISTENT_PARAMS_LENGTH = '74';\n  string public constant UL_INVALID_INDEX = '77';\n  string public constant LP_NOT_CONTRACT = '78';\n  string public constant SDT_STABLE_DEBT_OVERFLOW = '79';\n  string public constant SDT_BURN_EXCEEDS_BALANCE = '80';\n\n  enum CollateralManagerErrors {\n    NO_ERROR,\n    NO_COLLATERAL_AVAILABLE,\n    COLLATERAL_CANNOT_BE_LIQUIDATED,\n    CURRRENCY_NOT_BORROWED,\n    HEALTH_FACTOR_ABOVE_THRESHOLD,\n    NOT_ENOUGH_LIQUIDITY,\n    NO_ACTIVE_RESERVE,\n    HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD,\n    INVALID_EQUAL_ASSETS_TO_SWAP,\n    FROZEN_RESERVE\n  }\n}\n"
      },
      "@aave/protocol-v2/contracts/protocol/libraries/math/WadRayMath.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\nimport {Errors} from '../helpers/Errors.sol';\n\n/**\n * @title WadRayMath library\n * @author Aave\n * @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits)\n **/\n\nlibrary WadRayMath {\n  uint256 internal constant WAD = 1e18;\n  uint256 internal constant halfWAD = WAD / 2;\n\n  uint256 internal constant RAY = 1e27;\n  uint256 internal constant halfRAY = RAY / 2;\n\n  uint256 internal constant WAD_RAY_RATIO = 1e9;\n\n  /**\n   * @return One ray, 1e27\n   **/\n  function ray() internal pure returns (uint256) {\n    return RAY;\n  }\n\n  /**\n   * @return One wad, 1e18\n   **/\n\n  function wad() internal pure returns (uint256) {\n    return WAD;\n  }\n\n  /**\n   * @return Half ray, 1e27/2\n   **/\n  function halfRay() internal pure returns (uint256) {\n    return halfRAY;\n  }\n\n  /**\n   * @return Half ray, 1e18/2\n   **/\n  function halfWad() internal pure returns (uint256) {\n    return halfWAD;\n  }\n\n  /**\n   * @dev Multiplies two wad, rounding half up to the nearest wad\n   * @param a Wad\n   * @param b Wad\n   * @return The result of a*b, in wad\n   **/\n  function wadMul(uint256 a, uint256 b) internal pure returns (uint256) {\n    if (a == 0 || b == 0) {\n      return 0;\n    }\n\n    require(a <= (type(uint256).max - halfWAD) / b, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (a * b + halfWAD) / WAD;\n  }\n\n  /**\n   * @dev Divides two wad, rounding half up to the nearest wad\n   * @param a Wad\n   * @param b Wad\n   * @return The result of a/b, in wad\n   **/\n  function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n    require(b != 0, Errors.MATH_DIVISION_BY_ZERO);\n    uint256 halfB = b / 2;\n\n    require(a <= (type(uint256).max - halfB) / WAD, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (a * WAD + halfB) / b;\n  }\n\n  /**\n   * @dev Multiplies two ray, rounding half up to the nearest ray\n   * @param a Ray\n   * @param b Ray\n   * @return The result of a*b, in ray\n   **/\n  function rayMul(uint256 a, uint256 b) internal pure returns (uint256) {\n    if (a == 0 || b == 0) {\n      return 0;\n    }\n\n    require(a <= (type(uint256).max - halfRAY) / b, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (a * b + halfRAY) / RAY;\n  }\n\n  /**\n   * @dev Divides two ray, rounding half up to the nearest ray\n   * @param a Ray\n   * @param b Ray\n   * @return The result of a/b, in ray\n   **/\n  function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n    require(b != 0, Errors.MATH_DIVISION_BY_ZERO);\n    uint256 halfB = b / 2;\n\n    require(a <= (type(uint256).max - halfB) / RAY, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (a * RAY + halfB) / b;\n  }\n\n  /**\n   * @dev Casts ray down to wad\n   * @param a Ray\n   * @return a casted to wad, rounded half up to the nearest wad\n   **/\n  function rayToWad(uint256 a) internal pure returns (uint256) {\n    uint256 halfRatio = WAD_RAY_RATIO / 2;\n    uint256 result = halfRatio + a;\n    require(result >= halfRatio, Errors.MATH_ADDITION_OVERFLOW);\n\n    return result / WAD_RAY_RATIO;\n  }\n\n  /**\n   * @dev Converts wad up to ray\n   * @param a Wad\n   * @return a converted in ray\n   **/\n  function wadToRay(uint256 a) internal pure returns (uint256) {\n    uint256 result = a * WAD_RAY_RATIO;\n    require(result / WAD_RAY_RATIO == a, Errors.MATH_MULTIPLICATION_OVERFLOW);\n    return result;\n  }\n}\n"
      },
      "@aave/protocol-v2/contracts/protocol/libraries/types/DataTypes.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\nlibrary DataTypes {\n  // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.\n  struct ReserveData {\n    //stores the reserve configuration\n    ReserveConfigurationMap configuration;\n    //the liquidity index. Expressed in ray\n    uint128 liquidityIndex;\n    //variable borrow index. Expressed in ray\n    uint128 variableBorrowIndex;\n    //the current supply rate. Expressed in ray\n    uint128 currentLiquidityRate;\n    //the current variable borrow rate. Expressed in ray\n    uint128 currentVariableBorrowRate;\n    //the current stable borrow rate. Expressed in ray\n    uint128 currentStableBorrowRate;\n    uint40 lastUpdateTimestamp;\n    //tokens addresses\n    address aTokenAddress;\n    address stableDebtTokenAddress;\n    address variableDebtTokenAddress;\n    //address of the interest rate strategy\n    address interestRateStrategyAddress;\n    //the id of the reserve. Represents the position in the list of the active reserves\n    uint8 id;\n  }\n\n  struct ReserveConfigurationMap {\n    //bit 0-15: LTV\n    //bit 16-31: Liq. threshold\n    //bit 32-47: Liq. bonus\n    //bit 48-55: Decimals\n    //bit 56: Reserve is active\n    //bit 57: reserve is frozen\n    //bit 58: borrowing is enabled\n    //bit 59: stable rate borrowing enabled\n    //bit 60-63: reserved\n    //bit 64-79: reserve factor\n    uint256 data;\n  }\n\n  struct UserConfigurationMap {\n    uint256 data;\n  }\n\n  enum InterestRateMode {NONE, STABLE, VARIABLE}\n}\n"
      },
      "contracts/plugins/assets/aave/IStaticATokenLM.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport { IERC20 } from \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/IERC20.sol\";\nimport { ILendingPool } from \"@aave/protocol-v2/contracts/interfaces/ILendingPool.sol\";\nimport { IAaveIncentivesController } from \"./vendor/IAaveIncentivesController.sol\";\n\ninterface IStaticATokenLM is IERC20 {\n    struct SignatureParams {\n        uint8 v;\n        bytes32 r;\n        bytes32 s;\n    }\n\n    /**\n     * @notice Deposits `ASSET` in the Aave protocol and mints static aTokens to msg.sender\n     * @param recipient The address that will receive the static aTokens\n     * @param amount The amount of underlying `ASSET` to deposit (e.g. deposit of 100 USDC)\n     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n     *   0 if the action is executed directly by the user, without any middle-man\n     * @param fromUnderlying bool\n     * - `true` if the msg.sender comes with underlying tokens (e.g. USDC)\n     * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC)\n     * @return uint256 The amount of StaticAToken minted, static balance\n     **/\n    function deposit(\n        address recipient,\n        uint256 amount,\n        uint16 referralCode,\n        bool fromUnderlying\n    ) external returns (uint256);\n\n    /**\n     * @notice Burns `amount` of static aToken, with recipient receiving the corresponding amount of `ASSET`\n     * @param recipient The address that will receive the amount of `ASSET` withdrawn from the Aave protocol\n     * @param amount The amount to withdraw, in static balance of StaticAToken\n     * @param toUnderlying bool\n     * - `true` for the recipient to get underlying tokens (e.g. USDC)\n     * - `false` for the recipient to get aTokens (e.g. aUSDC)\n     * @return amountToBurn: StaticATokens burnt, static balance\n     * @return amountToWithdraw: underlying/aToken send to `recipient`, dynamic balance\n     **/\n    function withdraw(\n        address recipient,\n        uint256 amount,\n        bool toUnderlying\n    ) external returns (uint256, uint256);\n\n    /**\n     * @notice Burns `amount` of static aToken, with recipient receiving the corresponding amount of `ASSET`\n     * @param recipient The address that will receive the amount of `ASSET` withdrawn from the Aave protocol\n     * @param amount The amount to withdraw, in dynamic balance of aToken/underlying asset\n     * @param toUnderlying bool\n     * - `true` for the recipient to get underlying tokens (e.g. USDC)\n     * - `false` for the recipient to get aTokens (e.g. aUSDC)\n     * @return amountToBurn: StaticATokens burnt, static balance\n     * @return amountToWithdraw: underlying/aToken send to `recipient`, dynamic balance\n     **/\n    function withdrawDynamicAmount(\n        address recipient,\n        uint256 amount,\n        bool toUnderlying\n    ) external returns (uint256, uint256);\n\n    /**\n     * @notice Implements the permit function as for\n     * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md\n     * @param owner The owner of the funds\n     * @param spender The spender\n     * @param value The amount\n     * @param deadline The deadline timestamp, type(uint256).max for max deadline\n     * @param v Signature param\n     * @param s Signature param\n     * @param r Signature param\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @notice Allows to deposit on Aave via meta-transaction\n     * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md\n     * @param depositor Address from which the funds to deposit are going to be pulled\n     * @param recipient Address that will receive the staticATokens, in the average case, same as the `depositor`\n     * @param value The amount to deposit\n     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n     *   0 if the action is executed directly by the user, without any middle-man\n     * @param fromUnderlying bool\n     * - `true` if the msg.sender comes with underlying tokens (e.g. USDC)\n     * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC)\n     * @param deadline The deadline timestamp, type(uint256).max for max deadline\n     * @param sigParams Signature params: v,r,s\n     * @return uint256 The amount of StaticAToken minted, static balance\n     */\n    function metaDeposit(\n        address depositor,\n        address recipient,\n        uint256 value,\n        uint16 referralCode,\n        bool fromUnderlying,\n        uint256 deadline,\n        SignatureParams calldata sigParams\n    ) external returns (uint256);\n\n    /**\n     * @notice Allows to withdraw from Aave via meta-transaction\n     * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md\n     * @param owner Address owning the staticATokens\n     * @param recipient Address that will receive the underlying withdrawn from Aave\n     * @param staticAmount The amount of staticAToken to withdraw. If > 0, `dynamicAmount` needs to be 0\n     * @param dynamicAmount The amount of underlying/aToken to withdraw. If > 0, `staticAmount` needs to be 0\n     * @param toUnderlying bool\n     * - `true` for the recipient to get underlying tokens (e.g. USDC)\n     * - `false` for the recipient to get aTokens (e.g. aUSDC)\n     * @param deadline The deadline timestamp, type(uint256).max for max deadline\n     * @param sigParams Signature params: v,r,s\n     * @return amountToBurn: StaticATokens burnt, static balance\n     * @return amountToWithdraw: underlying/aToken send to `recipient`, dynamic balance\n     */\n    function metaWithdraw(\n        address owner,\n        address recipient,\n        uint256 staticAmount,\n        uint256 dynamicAmount,\n        bool toUnderlying,\n        uint256 deadline,\n        SignatureParams calldata sigParams\n    ) external returns (uint256, uint256);\n\n    /**\n     * @notice Utility method to get the current aToken balance of an user, from his staticAToken balance\n     * @param account The address of the user\n     * @return uint256 The aToken balance\n     **/\n    function dynamicBalanceOf(address account) external view returns (uint256);\n\n    /**\n     * @notice Converts a static amount (scaled balance on aToken) to the aToken/underlying value,\n     * using the current liquidity index on Aave\n     * @param amount The amount to convert from\n     * @return uint256 The dynamic amount\n     **/\n    function staticToDynamicAmount(uint256 amount) external view returns (uint256);\n\n    /**\n     * @notice Converts an aToken or underlying amount to the what it is denominated on the aToken as\n     * scaled balance, function of the principal and the liquidity index\n     * @param amount The amount to convert from\n     * @return uint256 The static (scaled) amount\n     **/\n    function dynamicToStaticAmount(uint256 amount) external view returns (uint256);\n\n    /**\n     * @notice Returns the Aave liquidity index of the underlying aToken, denominated rate here\n     * as it can be considered as an ever-increasing exchange rate\n     * @return The liquidity index\n     **/\n    function rate() external view returns (uint256);\n\n    /**\n     * @notice Function to return a dynamic domain separator, in order to be compatible with forks changing chainId\n     * @return bytes32 The domain separator\n     **/\n    function getDomainSeparator() external view returns (bytes32);\n\n    /**\n     * @notice Claims rewards from `INCENTIVES_CONTROLLER` and updates internal accounting of rewards.\n     */\n    function collectAndUpdateRewards() external;\n\n    /**\n     * @notice Claim rewards on behalf of a user and send them to a receiver\n     * @dev Only callable by if sender is onBehalfOf or sender is approved claimer\n     * @param onBehalfOf The address to claim on behalf of\n     * @param receiver The address to receive the rewards\n     * @param forceUpdate Flag to retrieve latest rewards from `INCENTIVES_CONTROLLER`\n     */\n    function claimRewardsOnBehalf(\n        address onBehalfOf,\n        address receiver,\n        bool forceUpdate\n    ) external;\n\n    /**\n     * @notice Claim rewards and send them to a receiver\n     * @param receiver The address to receive the rewards\n     * @param forceUpdate Flag to retrieve latest rewards from `INCENTIVES_CONTROLLER`\n     */\n    function claimRewards(address receiver, bool forceUpdate) external;\n\n    /**\n     * @notice Claim rewards\n     * @param forceUpdate Flag to retrieve latest rewards from `INCENTIVES_CONTROLLER`\n     */\n    function claimRewardsToSelf(bool forceUpdate) external;\n\n    /**\n     * @notice Get the total claimable rewards of the contract.\n     * @return The current balance + pending rewards from the `_incentivesController`\n     */\n    function getTotalClaimableRewards() external view returns (uint256);\n\n    /**\n     * @notice Get the total claimable rewards for a user in WAD\n     * @param user The address of the user\n     * @return The claimable amount of rewards in WAD\n     */\n    function getClaimableRewards(address user) external view returns (uint256);\n\n    /**\n     * @notice The unclaimed rewards for a user in WAD\n     * @param user The address of the user\n     * @return The unclaimed amount of rewards in WAD\n     */\n    function getUnclaimedRewards(address user) external view returns (uint256);\n\n    function getAccRewardsPerToken() external view returns (uint256);\n\n    function getLifetimeRewardsClaimed() external view returns (uint256);\n\n    function getLifetimeRewards() external view returns (uint256);\n\n    function getLastRewardBlock() external view returns (uint256);\n\n    function LENDING_POOL() external view returns (ILendingPool);\n\n    function INCENTIVES_CONTROLLER() external view returns (IAaveIncentivesController);\n\n    function ATOKEN() external view returns (IERC20);\n\n    function ASSET() external view returns (IERC20);\n\n    function REWARD_TOKEN() external view returns (IERC20);\n\n    function UNDERLYING_ASSET_ADDRESS() external view returns (address);\n\n    function getIncentivesController() external view returns (IAaveIncentivesController);\n}\n"
      },
      "contracts/plugins/assets/aave/StaticATokenErrors.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\nlibrary StaticATokenErrors {\n    string public constant INVALID_OWNER = \"1\";\n    string public constant INVALID_EXPIRATION = \"2\";\n    string public constant INVALID_SIGNATURE = \"3\";\n    string public constant INVALID_DEPOSITOR = \"4\";\n    string public constant INVALID_RECIPIENT = \"5\";\n    string public constant INVALID_CLAIMER = \"6\";\n    string public constant ONLY_ONE_AMOUNT_FORMAT_ALLOWED = \"7\";\n}\n"
      },
      "contracts/plugins/assets/aave/StaticATokenLM.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport { ILendingPool } from \"@aave/protocol-v2/contracts/interfaces/ILendingPool.sol\";\nimport { IERC20 } from \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/IERC20.sol\";\n\nimport { IERC20Detailed } from \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/IERC20Detailed.sol\";\nimport { IAToken } from \"./vendor/IAToken.sol\";\nimport { IStaticATokenLM } from \"./IStaticATokenLM.sol\";\nimport { IAaveIncentivesController } from \"./vendor/IAaveIncentivesController.sol\";\n\nimport { StaticATokenErrors } from \"./StaticATokenErrors.sol\";\n\nimport { ERC20 } from \"./vendor/ERC20.sol\";\nimport { ReentrancyGuard } from \"./vendor/ReentrancyGuard.sol\";\n\nimport { SafeERC20 } from \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/SafeERC20.sol\";\nimport { WadRayMath } from \"@aave/protocol-v2/contracts/protocol/libraries/math/WadRayMath.sol\";\nimport { RayMathNoRounding } from \"./vendor/RayMathNoRounding.sol\";\nimport { SafeMath } from \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/SafeMath.sol\";\n\n/**\n * @title StaticATokenLM\n * @dev Do not use on Arbitrum!\n * @notice Wrapper token that allows to deposit tokens on the Aave protocol and receive\n * a token which balance doesn't increase automatically, but uses an ever-increasing exchange rate.\n *\n * The token supports claiming liquidity mining rewards from the Aave system. However, there might be\n * be permanent loss of rewards for the sender of the token when a `transfer` is performed. This is due\n * to the fact that only rewards previously collected from the Incentives Controller are processed (and\n * assigned to the `sender`) when tokens are transferred. Any rewards pending to be collected are ignored\n * on `transfer`, and might be later claimed by the `receiver`. It was designed this way to reduce gas\n * costs on every transfer which would probably outweigh any missing/unprocessed/unclaimed rewards.\n * It is important to remark that several operations such as `deposit`, `withdraw`, `collectAndUpdateRewards`,\n * among others, will update rewards balances correctly, so while it is true that under certain circumstances\n * rewards may not be fully accurate, we expect them only to be slightly off.\n *\n * Users should also be careful when claiming rewards using `forceUpdate=false` as this will result on permanent\n * loss of pending/uncollected rewards. It is recommended to always claim rewards using `forceUpdate=true`\n * unless the user is sure that gas costs would exceed the lost rewards.\n *\n *\n * @author Aave\n * From: https://github.com/aave/protocol-v2/blob/238e5af2a95c3fbb83b0c8f44501ed2541215122/contracts/protocol/tokenization/StaticATokenLM.sol#L255\n **/\ncontract StaticATokenLM is\n    ReentrancyGuard,\n    ERC20(\"STATIC_ATOKEN_IMPL\", \"STATIC_ATOKEN_IMPL\"),\n    IStaticATokenLM\n{\n    using SafeERC20 for IERC20;\n    using SafeMath for uint256;\n    using WadRayMath for uint256;\n    using RayMathNoRounding for uint256;\n\n    /// Emitted whenever a reward token balance is claimed\n    event RewardsClaimed(IERC20 indexed erc20, uint256 amount);\n\n    bytes public constant EIP712_REVISION = bytes(\"1\");\n    bytes32 internal constant EIP712_DOMAIN =\n        keccak256(\n            \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n        );\n    bytes32 public constant PERMIT_TYPEHASH =\n        keccak256(\n            \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n        );\n    bytes32 public constant METADEPOSIT_TYPEHASH =\n        keccak256(\n            \"Deposit(address depositor,address recipient,uint256 value,uint16 referralCode,bool fromUnderlying,uint256 nonce,uint256 deadline)\"\n        );\n    bytes32 public constant METAWITHDRAWAL_TYPEHASH =\n        keccak256(\n            \"Withdraw(address owner,address recipient,uint256 staticAmount,uint256 dynamicAmount,bool toUnderlying,uint256 nonce,uint256 deadline)\"\n        );\n\n    uint256 public constant STATIC_ATOKEN_LM_REVISION = 0x1;\n\n    ILendingPool public override LENDING_POOL;\n    IAaveIncentivesController public override INCENTIVES_CONTROLLER;\n    IERC20 public override ATOKEN;\n    IERC20 public override ASSET;\n    IERC20 public override REWARD_TOKEN;\n\n    mapping(address => uint256) public _nonces;\n\n    uint256 internal _accRewardsPerToken;\n    uint256 internal _lifetimeRewardsClaimed;\n    uint256 internal _lifetimeRewards;\n    uint256 internal _lastRewardBlock;\n\n    // user => _accRewardsPerToken at last interaction (in RAYs)\n    mapping(address => uint256) private _userSnapshotRewardsPerToken;\n    // user => unclaimedRewards (in RAYs)\n    mapping(address => uint256) private _unclaimedRewards;\n\n    constructor(\n        ILendingPool pool,\n        address aToken,\n        string memory staticATokenName,\n        string memory staticATokenSymbol\n    ) public {\n        LENDING_POOL = pool;\n        ATOKEN = IERC20(aToken);\n\n        _name = staticATokenName;\n        _symbol = staticATokenSymbol;\n        _setupDecimals(IERC20Detailed(aToken).decimals());\n\n        try IAToken(aToken).getIncentivesController() returns (\n            IAaveIncentivesController incentivesController\n        ) {\n            if (address(incentivesController) != address(0)) {\n                INCENTIVES_CONTROLLER = incentivesController;\n                REWARD_TOKEN = IERC20(INCENTIVES_CONTROLLER.REWARD_TOKEN());\n            }\n        } catch {}\n\n        ASSET = IERC20(IAToken(aToken).UNDERLYING_ASSET_ADDRESS());\n        ASSET.safeApprove(address(pool), type(uint256).max);\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function deposit(\n        address recipient,\n        uint256 amount,\n        uint16 referralCode,\n        bool fromUnderlying\n    ) external override nonReentrant returns (uint256) {\n        return _deposit(msg.sender, recipient, amount, referralCode, fromUnderlying);\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function withdraw(\n        address recipient,\n        uint256 amount,\n        bool toUnderlying\n    ) external override nonReentrant returns (uint256, uint256) {\n        return _withdraw(msg.sender, recipient, amount, 0, toUnderlying);\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function withdrawDynamicAmount(\n        address recipient,\n        uint256 amount,\n        bool toUnderlying\n    ) external override nonReentrant returns (uint256, uint256) {\n        return _withdraw(msg.sender, recipient, 0, amount, toUnderlying);\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external override {\n        require(owner != address(0), StaticATokenErrors.INVALID_OWNER);\n        //solium-disable-next-line\n        require(block.timestamp <= deadline, StaticATokenErrors.INVALID_EXPIRATION);\n        uint256 currentValidNonce = _nonces[owner];\n        bytes32 digest = keccak256(\n            abi.encodePacked(\n                \"\\x19\\x01\",\n                getDomainSeparator(),\n                keccak256(\n                    abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline)\n                )\n            )\n        );\n        require(owner == ecrecover(digest, v, r, s), StaticATokenErrors.INVALID_SIGNATURE);\n        _nonces[owner] = currentValidNonce.add(1);\n        _approve(owner, spender, value);\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function metaDeposit(\n        address depositor,\n        address recipient,\n        uint256 value,\n        uint16 referralCode,\n        bool fromUnderlying,\n        uint256 deadline,\n        SignatureParams calldata sigParams\n    ) external override nonReentrant returns (uint256) {\n        require(depositor != address(0), StaticATokenErrors.INVALID_DEPOSITOR);\n        //solium-disable-next-line\n        require(block.timestamp <= deadline, StaticATokenErrors.INVALID_EXPIRATION);\n        uint256 currentValidNonce = _nonces[depositor];\n        bytes32 digest = keccak256(\n            abi.encodePacked(\n                \"\\x19\\x01\",\n                getDomainSeparator(),\n                keccak256(\n                    abi.encode(\n                        METADEPOSIT_TYPEHASH,\n                        depositor,\n                        recipient,\n                        value,\n                        referralCode,\n                        fromUnderlying,\n                        currentValidNonce,\n                        deadline\n                    )\n                )\n            )\n        );\n        require(\n            depositor == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s),\n            StaticATokenErrors.INVALID_SIGNATURE\n        );\n        _nonces[depositor] = currentValidNonce.add(1);\n        return _deposit(depositor, recipient, value, referralCode, fromUnderlying);\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function metaWithdraw(\n        address owner,\n        address recipient,\n        uint256 staticAmount,\n        uint256 dynamicAmount,\n        bool toUnderlying,\n        uint256 deadline,\n        SignatureParams calldata sigParams\n    ) external override nonReentrant returns (uint256, uint256) {\n        require(owner != address(0), StaticATokenErrors.INVALID_OWNER);\n        //solium-disable-next-line\n        require(block.timestamp <= deadline, StaticATokenErrors.INVALID_EXPIRATION);\n        uint256 currentValidNonce = _nonces[owner];\n        bytes32 digest = keccak256(\n            abi.encodePacked(\n                \"\\x19\\x01\",\n                getDomainSeparator(),\n                keccak256(\n                    abi.encode(\n                        METAWITHDRAWAL_TYPEHASH,\n                        owner,\n                        recipient,\n                        staticAmount,\n                        dynamicAmount,\n                        toUnderlying,\n                        currentValidNonce,\n                        deadline\n                    )\n                )\n            )\n        );\n\n        require(\n            owner == ecrecover(digest, sigParams.v, sigParams.r, sigParams.s),\n            StaticATokenErrors.INVALID_SIGNATURE\n        );\n        _nonces[owner] = currentValidNonce.add(1);\n        return _withdraw(owner, recipient, staticAmount, dynamicAmount, toUnderlying);\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    function dynamicBalanceOf(address account) external view override returns (uint256) {\n        return _staticToDynamicAmount(balanceOf(account), rate());\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    function staticToDynamicAmount(uint256 amount) external view override returns (uint256) {\n        return _staticToDynamicAmount(amount, rate());\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    function dynamicToStaticAmount(uint256 amount) external view override returns (uint256) {\n        return _dynamicToStaticAmount(amount, rate());\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    function rate() public view override returns (uint256) {\n        return LENDING_POOL.getReserveNormalizedIncome(address(ASSET));\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    function getDomainSeparator() public view override returns (bytes32) {\n        uint256 chainId;\n        assembly {\n            chainId := chainid()\n        }\n        return\n            keccak256(\n                abi.encode(\n                    EIP712_DOMAIN,\n                    keccak256(bytes(name())),\n                    keccak256(EIP712_REVISION),\n                    chainId,\n                    address(this)\n                )\n            );\n    }\n\n    function _dynamicToStaticAmount(uint256 amount, uint256 rate_) internal pure returns (uint256) {\n        return amount.rayDiv(rate_);\n    }\n\n    function _staticToDynamicAmount(uint256 amount, uint256 rate_) internal pure returns (uint256) {\n        return amount.rayMul(rate_);\n    }\n\n    function _deposit(\n        address depositor,\n        address recipient,\n        uint256 amount,\n        uint16 referralCode,\n        bool fromUnderlying\n    ) internal returns (uint256) {\n        require(recipient != address(0), StaticATokenErrors.INVALID_RECIPIENT);\n        _updateRewards();\n\n        if (fromUnderlying) {\n            ASSET.safeTransferFrom(depositor, address(this), amount);\n            LENDING_POOL.deposit(address(ASSET), amount, address(this), referralCode);\n        } else {\n            ATOKEN.safeTransferFrom(depositor, address(this), amount);\n        }\n\n        uint256 amountToMint = _dynamicToStaticAmount(amount, rate());\n        _mint(recipient, amountToMint);\n\n        return amountToMint;\n    }\n\n    function _withdraw(\n        address owner,\n        address recipient,\n        uint256 staticAmount,\n        uint256 dynamicAmount,\n        bool toUnderlying\n    ) internal returns (uint256, uint256) {\n        require(recipient != address(0), StaticATokenErrors.INVALID_RECIPIENT);\n        require(\n            staticAmount == 0 || dynamicAmount == 0,\n            StaticATokenErrors.ONLY_ONE_AMOUNT_FORMAT_ALLOWED\n        );\n        _updateRewards();\n\n        uint256 userBalance = balanceOf(owner);\n\n        uint256 amountToWithdraw;\n        uint256 amountToBurn;\n\n        uint256 currentRate = rate();\n        if (staticAmount != 0) {\n            amountToBurn = (staticAmount > userBalance) ? userBalance : staticAmount;\n            amountToWithdraw = _staticToDynamicAmount(amountToBurn, currentRate);\n        } else {\n            uint256 dynamicUserBalance = _staticToDynamicAmount(userBalance, currentRate);\n            amountToWithdraw = (dynamicAmount > dynamicUserBalance)\n                ? dynamicUserBalance\n                : dynamicAmount;\n            amountToBurn = _dynamicToStaticAmount(amountToWithdraw, currentRate);\n        }\n\n        _burn(owner, amountToBurn);\n\n        if (toUnderlying) {\n            uint256 amt = LENDING_POOL.withdraw(address(ASSET), amountToWithdraw, recipient);\n            assert(amt == amountToWithdraw);\n        } else {\n            ATOKEN.safeTransfer(recipient, amountToWithdraw);\n        }\n\n        return (amountToBurn, amountToWithdraw);\n    }\n\n    /**\n     * @notice Updates rewards for senders and receiver in a transfer (not updating rewards for address(0))\n     *  Only rewards which were previously collected from the Incentives Controller will be updated on\n     *  every transfer. It is designed this way to reduce gas costs on `transfer`, which will likely\n     *  outweigh the pending (uncollected) rewards for the sender under certain circumstances.\n     * @param from The address of the sender of tokens\n     * @param to The address of the receiver of tokens\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256\n    ) internal override {\n        if (address(INCENTIVES_CONTROLLER) == address(0)) {\n            return;\n        }\n        if (from != address(0)) {\n            _updateUser(from);\n        }\n        if (to != address(0)) {\n            _updateUser(to);\n        }\n    }\n\n    /**\n     * @notice Updates virtual internal accounting of rewards.\n     */\n    function _updateRewards() internal {\n        if (address(INCENTIVES_CONTROLLER) == address(0)) {\n            return;\n        }\n        // Alert! block.number is incompatible with Arbitrum!\n        // Should be fine because Aave V2 is not currently deployed to Arbitrum\n        if (block.number > _lastRewardBlock) {\n            _lastRewardBlock = block.number;\n            uint256 supply = totalSupply();\n            if (supply == 0) {\n                // No rewards can have accrued since last because there were no funds.\n                return;\n            }\n\n            address[] memory assets = new address[](1);\n            assets[0] = address(ATOKEN);\n\n            uint256 freshRewards = INCENTIVES_CONTROLLER.getRewardsBalance(assets, address(this));\n            uint256 lifetimeRewards = _lifetimeRewardsClaimed.add(freshRewards);\n            uint256 rewardsAccrued = lifetimeRewards.sub(_lifetimeRewards).wadToRay();\n\n            _accRewardsPerToken = _accRewardsPerToken.add(\n                (rewardsAccrued).rayDivNoRounding(supply.wadToRay())\n            );\n            _lifetimeRewards = lifetimeRewards;\n        }\n    }\n\n    function _collectAndUpdateRewards() internal {\n        if (address(INCENTIVES_CONTROLLER) == address(0)) {\n            return;\n        }\n\n        _lastRewardBlock = block.number;\n        uint256 supply = totalSupply();\n\n        address[] memory assets = new address[](1);\n        assets[0] = address(ATOKEN);\n\n        uint256 freshlyClaimed = INCENTIVES_CONTROLLER.claimRewards(\n            assets,\n            type(uint256).max,\n            address(this)\n        );\n        uint256 lifetimeRewards = _lifetimeRewardsClaimed.add(freshlyClaimed);\n        uint256 rewardsAccrued = lifetimeRewards.sub(_lifetimeRewards).wadToRay();\n        if (supply != 0 && rewardsAccrued != 0) {\n            _accRewardsPerToken = _accRewardsPerToken.add(\n                (rewardsAccrued).rayDivNoRounding(supply.wadToRay())\n            );\n        }\n\n        if (rewardsAccrued != 0) {\n            _lifetimeRewards = lifetimeRewards;\n        }\n\n        _lifetimeRewardsClaimed = lifetimeRewards;\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function collectAndUpdateRewards() external override nonReentrant {\n        _collectAndUpdateRewards();\n    }\n\n    /**\n     * @notice Claim rewards on behalf of a user and send them to a receiver\n     *  Users should be careful when claiming rewards using `forceUpdate=false` as this will result on permanent\n     * loss of pending/uncollected rewards. Always claim rewards using `forceUpdate=true` when possible.\n     * @param onBehalfOf The address to claim on behalf of\n     * @param receiver The address to receive the rewards\n     * @param forceUpdate Flag to retrieve latest rewards from `INCENTIVES_CONTROLLER`\n     */\n    function _claimRewardsOnBehalf(\n        address onBehalfOf,\n        address receiver,\n        bool forceUpdate\n    ) internal {\n        if (forceUpdate) {\n            _collectAndUpdateRewards();\n        }\n\n        uint256 balance = balanceOf(onBehalfOf);\n        uint256 reward = _getClaimableRewards(onBehalfOf, balance, false);\n        uint256 totBal = REWARD_TOKEN.balanceOf(address(this));\n\n        if (reward > totBal) {\n            reward = totBal;\n        }\n        if (reward != 0) {\n            _unclaimedRewards[onBehalfOf] = 0;\n            _updateUserSnapshotRewardsPerToken(onBehalfOf);\n            REWARD_TOKEN.safeTransfer(receiver, reward);\n        }\n    }\n\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function claimRewardsOnBehalf(\n        address onBehalfOf,\n        address receiver,\n        bool forceUpdate\n    ) external override nonReentrant {\n        if (address(INCENTIVES_CONTROLLER) == address(0)) {\n            return;\n        }\n\n        require(\n            msg.sender == onBehalfOf || msg.sender == INCENTIVES_CONTROLLER.getClaimer(onBehalfOf),\n            StaticATokenErrors.INVALID_CLAIMER\n        );\n        _claimRewardsOnBehalf(onBehalfOf, receiver, forceUpdate);\n    }\n\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function claimRewards(address receiver, bool forceUpdate) external override nonReentrant {\n        if (address(INCENTIVES_CONTROLLER) == address(0)) {\n            return;\n        }\n        _claimRewardsOnBehalf(msg.sender, receiver, forceUpdate);\n    }\n\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function claimRewardsToSelf(bool forceUpdate) external override nonReentrant {\n        if (address(INCENTIVES_CONTROLLER) == address(0)) {\n            return;\n        }\n        _claimRewardsOnBehalf(msg.sender, msg.sender, forceUpdate);\n    }\n\n    // untested:\n    //      nonReentrant line is assumed to be working. cost/benefit of direct testing is high\n    function claimRewards() external virtual nonReentrant {\n        if (address(INCENTIVES_CONTROLLER) == address(0)) {\n            return;\n        }\n        uint256 oldBal = REWARD_TOKEN.balanceOf(msg.sender);\n        _claimRewardsOnBehalf(msg.sender, msg.sender, true);\n        emit RewardsClaimed(REWARD_TOKEN, REWARD_TOKEN.balanceOf(msg.sender) - oldBal);\n    }\n\n    /**\n     * @notice Update the rewardDebt for a user with balance as his balance\n     * @param user The user to update\n     */\n    function _updateUserSnapshotRewardsPerToken(address user) internal {\n        _userSnapshotRewardsPerToken[user] = _accRewardsPerToken;\n    }\n\n    /**\n     * @notice Adding the pending rewards to the unclaimed for specific user and updating user index\n     * @param user The address of the user to update\n     */\n    function _updateUser(address user) internal {\n        uint256 balance = balanceOf(user);\n        if (balance != 0) {\n            uint256 pending = _getPendingRewards(user, balance, false);\n            _unclaimedRewards[user] = _unclaimedRewards[user].add(pending);\n        }\n        _updateUserSnapshotRewardsPerToken(user);\n    }\n\n    /**\n     * @notice Compute the pending in RAY (rounded down). Pending is the amount to add (not yet unclaimed) rewards in RAY (rounded down).\n     * @param user The user to compute for\n     * @param balance The balance of the user\n     * @param fresh Flag to account for rewards not claimed by contract yet\n     * @return The amount of pending rewards in RAY\n     */\n    function _getPendingRewards(\n        address user,\n        uint256 balance,\n        bool fresh\n    ) internal view returns (uint256) {\n        if (address(INCENTIVES_CONTROLLER) == address(0)) {\n            return 0;\n        }\n\n        if (balance == 0) {\n            return 0;\n        }\n\n        uint256 rayBalance = balance.wadToRay();\n\n        uint256 supply = totalSupply();\n        uint256 accRewardsPerToken = _accRewardsPerToken;\n\n        if (supply != 0 && fresh) {\n            address[] memory assets = new address[](1);\n            assets[0] = address(ATOKEN);\n\n            uint256 freshReward = INCENTIVES_CONTROLLER.getRewardsBalance(assets, address(this));\n            uint256 lifetimeRewards = _lifetimeRewardsClaimed.add(freshReward);\n            uint256 rewardsAccrued = lifetimeRewards.sub(_lifetimeRewards).wadToRay();\n            accRewardsPerToken = accRewardsPerToken.add(\n                (rewardsAccrued).rayDivNoRounding(supply.wadToRay())\n            );\n        }\n\n        return\n            rayBalance.rayMulNoRounding(accRewardsPerToken.sub(_userSnapshotRewardsPerToken[user]));\n    }\n\n    /**\n     * @notice Compute the claimable rewards for a user\n     * @param user The address of the user\n     * @param balance The balance of the user in WAD\n     * @param fresh Flag to account for rewards not claimed by contract yet\n     * @return The total rewards that can be claimed by the user (if `fresh` flag true, after updating rewards)\n     */\n    function _getClaimableRewards(\n        address user,\n        uint256 balance,\n        bool fresh\n    ) internal view returns (uint256) {\n        uint256 reward = _unclaimedRewards[user].add(_getPendingRewards(user, balance, fresh));\n        return reward.rayToWadNoRounding();\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    function getTotalClaimableRewards() external view override returns (uint256) {\n        if (address(INCENTIVES_CONTROLLER) == address(0)) {\n            return 0;\n        }\n\n        address[] memory assets = new address[](1);\n        assets[0] = address(ATOKEN);\n        uint256 freshRewards = INCENTIVES_CONTROLLER.getRewardsBalance(assets, address(this));\n        return REWARD_TOKEN.balanceOf(address(this)).add(freshRewards);\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    function getClaimableRewards(address user) external view override returns (uint256) {\n        return _getClaimableRewards(user, balanceOf(user), true);\n    }\n\n    ///@inheritdoc IStaticATokenLM\n    function getUnclaimedRewards(address user) external view override returns (uint256) {\n        return _unclaimedRewards[user].rayToWadNoRounding();\n    }\n\n    function getAccRewardsPerToken() external view override returns (uint256) {\n        return _accRewardsPerToken;\n    }\n\n    function getLifetimeRewardsClaimed() external view override returns (uint256) {\n        return _lifetimeRewardsClaimed;\n    }\n\n    function getLifetimeRewards() external view override returns (uint256) {\n        return _lifetimeRewards;\n    }\n\n    function getLastRewardBlock() external view override returns (uint256) {\n        return _lastRewardBlock;\n    }\n\n    function getIncentivesController() external view override returns (IAaveIncentivesController) {\n        return INCENTIVES_CONTROLLER;\n    }\n\n    function UNDERLYING_ASSET_ADDRESS() external view override returns (address) {\n        return address(ASSET);\n    }\n}\n"
      },
      "contracts/plugins/assets/aave/vendor/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/Context.sol\";\nimport \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/IERC20.sol\";\nimport \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/SafeMath.sol\";\nimport \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/Address.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n    using SafeMath for uint256;\n    using Address for address;\n\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string internal _name;\n    string internal _symbol;\n    uint8 private _decimals;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n     * a default value of 18.\n     *\n     * To select a different value for {decimals}, use {_setupDecimals}.\n     *\n     * All three of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name, string memory symbol) public {\n        _name = name;\n        _symbol = symbol;\n        _decimals = 18;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n     * called.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view returns (uint8) {\n        return _decimals;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(_msgSender(), recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender)\n        public\n        view\n        virtual\n        override\n        returns (uint256)\n    {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        _approve(_msgSender(), spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20};\n     *\n     * Requirements:\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``sender``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) public virtual override returns (bool) {\n        _transfer(sender, recipient, amount);\n        _approve(\n            sender,\n            _msgSender(),\n            _allowances[sender][_msgSender()].sub(\n                amount,\n                \"ERC20: transfer amount exceeds allowance\"\n            )\n        );\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue)\n        public\n        virtual\n        returns (bool)\n    {\n        _approve(\n            _msgSender(),\n            spender,\n            _allowances[_msgSender()][spender].sub(\n                subtractedValue,\n                \"ERC20: decreased allowance below zero\"\n            )\n        );\n        return true;\n    }\n\n    /**\n     * @dev Moves tokens `amount` from `sender` to `recipient`.\n     *\n     * This is internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) internal virtual {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(sender, recipient, amount);\n\n        _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n        _balances[recipient] = _balances[recipient].add(amount);\n        emit Transfer(sender, recipient, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements\n     *\n     * - `to` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply = _totalSupply.add(amount);\n        _balances[account] = _balances[account].add(amount);\n        emit Transfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n        _totalSupply = _totalSupply.sub(amount);\n        emit Transfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n     *\n     * This is internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Sets {decimals} to a value other than the default one of 18.\n     *\n     * WARNING: This function should only be called from the constructor. Most\n     * applications that interact with token contracts will not expect\n     * {decimals} to ever change, and may work incorrectly if it does.\n     */\n    function _setupDecimals(uint8 decimals_) internal {\n        _decimals = decimals_;\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be to transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n}\n"
      },
      "contracts/plugins/assets/aave/vendor/IAaveIncentivesController.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\ninterface IAaveIncentivesController {\n    event RewardsAccrued(address indexed user, uint256 amount);\n\n    event RewardsClaimed(address indexed user, address indexed to, uint256 amount);\n\n    event RewardsClaimed(\n        address indexed user,\n        address indexed to,\n        address indexed claimer,\n        uint256 amount\n    );\n\n    event ClaimerSet(address indexed user, address indexed claimer);\n\n    /*\n     * @dev Returns the configuration of the distribution for a certain asset\n     * @param asset The address of the reference asset of the distribution\n     * @return The asset index, the emission per second and the last updated timestamp\n     **/\n    function getAssetData(address asset)\n        external\n        view\n        returns (\n            uint256,\n            uint256,\n            uint256\n        );\n\n    /**\n     * @dev Whitelists an address to claim the rewards on behalf of another address\n     * @param user The address of the user\n     * @param claimer The address of the claimer\n     */\n    function setClaimer(address user, address claimer) external;\n\n    /**\n     * @dev Returns the whitelisted claimer for a certain address (0x0 if not set)\n     * @param user The address of the user\n     * @return The claimer address\n     */\n    function getClaimer(address user) external view returns (address);\n\n    /**\n     * @dev Configure assets for a certain rewards emission\n     * @param assets The assets to incentivize\n     * @param emissionsPerSecond The emission for each asset\n     */\n    function configureAssets(address[] calldata assets, uint256[] calldata emissionsPerSecond)\n        external;\n\n    /**\n     * @dev Called by the corresponding asset on any update that affects the rewards distribution\n     * @param asset The address of the user\n     * @param userBalance The balance of the user of the asset in the lending pool\n     * @param totalSupply The total supply of the asset in the lending pool\n     **/\n    function handleAction(\n        address asset,\n        uint256 userBalance,\n        uint256 totalSupply\n    ) external;\n\n    /**\n     * @dev Returns the total of rewards of an user, already accrued + not yet accrued\n     * @param user The address of the user\n     * @return The rewards\n     **/\n    function getRewardsBalance(address[] calldata assets, address user)\n        external\n        view\n        returns (uint256);\n\n    /**\n     * @dev Claims reward for an user, on all the assets of the lending pool, accumulating the pending rewards\n     * @param amount Amount of rewards to claim\n     * @param to Address that will be receiving the rewards\n     * @return Rewards claimed\n     **/\n    function claimRewards(\n        address[] calldata assets,\n        uint256 amount,\n        address to\n    ) external returns (uint256);\n\n    /**\n     * @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must\n     * be whitelisted via \"allowClaimOnBehalf\" function by the RewardsAdmin role manager\n     * @param amount Amount of rewards to claim\n     * @param user Address to check and claim rewards\n     * @param to Address that will be receiving the rewards\n     * @return Rewards claimed\n     **/\n    function claimRewardsOnBehalf(\n        address[] calldata assets,\n        uint256 amount,\n        address user,\n        address to\n    ) external returns (uint256);\n\n    /**\n     * @dev returns the unclaimed rewards of the user\n     * @param user the address of the user\n     * @return the unclaimed user rewards\n     */\n    function getUserUnclaimedRewards(address user) external view returns (uint256);\n\n    /**\n     * @dev returns the unclaimed rewards of the user\n     * @param user the address of the user\n     * @param asset The asset to incentivize\n     * @return the user index for the asset\n     */\n    function getUserAssetData(address user, address asset) external view returns (uint256);\n\n    /**\n     * @dev for backward compatibility with previous implementation of the Incentives controller\n     */\n    function REWARD_TOKEN() external view returns (address);\n\n    /**\n     * @dev for backward compatibility with previous implementation of the Incentives controller\n     */\n    function PRECISION() external view returns (uint8);\n}\n"
      },
      "contracts/plugins/assets/aave/vendor/IAToken.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\n\nimport \"@aave/protocol-v2/contracts/dependencies/openzeppelin/contracts/IERC20.sol\";\nimport \"@aave/protocol-v2/contracts/interfaces/IScaledBalanceToken.sol\";\nimport \"./IAaveIncentivesController.sol\";\n\ninterface IAToken is IERC20, IScaledBalanceToken {\n    /**\n     * @dev Emitted after the mint action\n     * @param from The address performing the mint\n     * @param value The amount being\n     * @param index The new liquidity index of the reserve\n     **/\n    event Mint(address indexed from, uint256 value, uint256 index);\n\n    /**\n     * @dev Mints `amount` aTokens to `user`\n     * @param user The address receiving the minted tokens\n     * @param amount The amount of tokens getting minted\n     * @param index The new liquidity index of the reserve\n     * @return `true` if the the previous balance of the user was 0\n     */\n    function mint(\n        address user,\n        uint256 amount,\n        uint256 index\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted after aTokens are burned\n     * @param from The owner of the aTokens, getting them burned\n     * @param target The address that will receive the underlying\n     * @param value The amount being burned\n     * @param index The new liquidity index of the reserve\n     **/\n    event Burn(address indexed from, address indexed target, uint256 value, uint256 index);\n\n    /**\n     * @dev Emitted during the transfer action\n     * @param from The user whose tokens are being transferred\n     * @param to The recipient\n     * @param value The amount being transferred\n     * @param index The new liquidity index of the reserve\n     **/\n    event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index);\n\n    /**\n     * @dev Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying`\n     * @param user The owner of the aTokens, getting them burned\n     * @param receiverOfUnderlying The address that will receive the underlying\n     * @param amount The amount being burned\n     * @param index The new liquidity index of the reserve\n     **/\n    function burn(\n        address user,\n        address receiverOfUnderlying,\n        uint256 amount,\n        uint256 index\n    ) external;\n\n    /**\n     * @dev Mints aTokens to the reserve treasury\n     * @param amount The amount of tokens getting minted\n     * @param index The new liquidity index of the reserve\n     */\n    function mintToTreasury(uint256 amount, uint256 index) external;\n\n    /**\n     * @dev Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken\n     * @param from The address getting liquidated, current owner of the aTokens\n     * @param to The recipient\n     * @param value The amount of tokens getting transferred\n     **/\n    function transferOnLiquidation(\n        address from,\n        address to,\n        uint256 value\n    ) external;\n\n    /**\n     * @dev Transfers the underlying asset to `target`. Used by the LendingPool to transfer\n     * assets in borrow(), withdraw() and flashLoan()\n     * @param user The recipient of the underlying\n     * @param amount The amount getting transferred\n     * @return The amount transferred\n     **/\n    function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);\n\n    /**\n     * @dev Invoked to execute actions on the aToken side after a repayment.\n     * @param user The user executing the repayment\n     * @param amount The amount getting repaid\n     **/\n    function handleRepayment(address user, uint256 amount) external;\n\n    /**\n     * @dev Returns the address of the incentives controller contract\n     **/\n    function getIncentivesController() external view returns (IAaveIncentivesController);\n\n    /**\n     * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)\n     **/\n    function UNDERLYING_ASSET_ADDRESS() external view returns (address);\n}\n"
      },
      "contracts/plugins/assets/aave/vendor/RayMathNoRounding.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport { Errors } from \"@aave/protocol-v2/contracts/protocol/libraries/helpers/Errors.sol\";\n\nlibrary RayMathNoRounding {\n    uint256 internal constant RAY = 1e27;\n    uint256 internal constant WAD_RAY_RATIO = 1e9;\n\n    function rayMulNoRounding(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0 || b == 0) {\n            return 0;\n        }\n        require(a <= type(uint256).max / b, Errors.MATH_MULTIPLICATION_OVERFLOW);\n        return (a * b) / RAY;\n    }\n\n    function rayDivNoRounding(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b != 0, Errors.MATH_DIVISION_BY_ZERO);\n        require(a <= (type(uint256).max) / RAY, Errors.MATH_MULTIPLICATION_OVERFLOW);\n        return (a * RAY) / b;\n    }\n\n    function rayToWadNoRounding(uint256 a) internal pure returns (uint256) {\n        return a / WAD_RAY_RATIO;\n    }\n}\n"
      },
      "contracts/plugins/assets/aave/vendor/ReentrancyGuard.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    constructor() internal {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and make it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}