creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/20240409_AaveV2Ethereum_InterimAAMPLDistribution/AaveV2Ethereum_InterimAAMPLDistribution_20240409.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol';\nimport {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol';\nimport {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol';\n\ninterface IDistributionCreator {\n  struct CampaignParameters {\n    // POPULATED ONCE CREATED\n\n    // ID of the campaign. This can be left as a null bytes32 when creating campaigns\n    // on Merkl.\n    bytes32 campaignId;\n    // CHOSEN BY CAMPAIGN CREATOR\n\n    // Address of the campaign creator, if marked as address(0), it will be overriden with the\n    // address of the `msg.sender` creating the campaign\n    address creator;\n    // Address of the token used as a reward\n    address rewardToken;\n    // Amount of `rewardToken` to distribute across all the epochs\n    // Amount distributed per epoch is `amount/numEpoch`\n    uint256 amount;\n    // Type of campaign\n    uint32 campaignType;\n    // Timestamp at which the campaign should start\n    uint32 startTimestamp;\n    // Duration of the campaign in seconds. Has to be a multiple of EPOCH = 3600\n    uint32 duration;\n    // Extra data to pass to specify the campaign\n    bytes campaignData;\n  }\n\n  function campaign(bytes32 id) external view returns (CampaignParameters memory);\n\n  function acceptConditions() external;\n\n  function createCampaign(CampaignParameters memory newCampaign) external returns (bytes32);\n}\n\n/**\n * @title Interim aAMPL distribution\n * @author BGD Labs\n * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0xb7226dd6441b67225924082215f7a512bfd98252897ee43a879084e07ab53607\n * - Discussion: https://governance.aave.com/t/arfc-aampl-interim-distribution/17184\n */\ncontract AaveV2Ethereum_InterimAAMPLDistribution_20240409 is IProposalGenericExecutor {\n  IDistributionCreator public constant DISTRIBUTION_CREATOR =\n    IDistributionCreator(0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd);\n  address public constant REWARD_TOKEN = AaveV2EthereumAssets.USDC_UNDERLYING;\n  uint256 public constant REWARD_AMOUNT_PLUS_FEES = 298_543_522_440;\n  string public constant FILE_URL =\n    'https://angle-blog.infura-ipfs.io/ipfs/Qmb9uJbEdppQsL8W4aVKxREoHo42iXtcp4CV1FLE5tY8Rt';\n\n  function execute() external {\n    // 1. send funds to executor\n    // 0.5% fee for angle merkle distributor\n    AaveV2Ethereum.COLLECTOR.transfer(\n      AaveV2EthereumAssets.USDC_A_TOKEN,\n      address(this),\n      REWARD_AMOUNT_PLUS_FEES + 1 // account for imprecision on transfer\n    );\n    AaveV2Ethereum.POOL.withdraw(REWARD_TOKEN, REWARD_AMOUNT_PLUS_FEES, address(this));\n    // 2. approve to merkl\n    IERC20(REWARD_TOKEN).approve(address(DISTRIBUTION_CREATOR), REWARD_AMOUNT_PLUS_FEES);\n    // 3. accept tos\n    DISTRIBUTION_CREATOR.acceptConditions();\n    // 4.create campaign\n    IDistributionCreator.CampaignParameters memory newCampaign = IDistributionCreator\n      .CampaignParameters({\n        campaignId: '',\n        creator: address(0),\n        rewardToken: REWARD_TOKEN,\n        amount: REWARD_AMOUNT_PLUS_FEES,\n        campaignType: 4,\n        startTimestamp: uint32(block.timestamp + 2 hours),\n        duration: 1 hours,\n        campaignData: abi.encode(FILE_URL, string(''), bytes('0x'))\n      });\n    DISTRIBUTION_CREATOR.createCampaign(newCampaign);\n  }\n}\n"
      },
      "lib/aave-helpers/lib/solidity-utils/src/contracts/oz-common/interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n// From commit https://github.com/OpenZeppelin/openzeppelin-contracts/commit/a035b235b4f2c9af4ba88edc4447f02e37f8d124\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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  /**\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 `to`.\n   *\n   * Returns a boolean value indicating whether the operation succeeded.\n   *\n   * Emits a {Transfer} event.\n   */\n  function transfer(address to, 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 `from` to `to` 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(address from, address to, uint256 amount) external returns (bool);\n}\n"
      },
      "lib/aave-helpers/lib/aave-address-book/src/AaveV2Ethereum.sol": {
        "content": "// AUTOGENERATED - MANUALLY CHANGES WILL BE REVERTED BY THE GENERATOR\n// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0;\n\nimport {ILendingPoolAddressesProvider, ILendingPool, ILendingPoolConfigurator, IAaveOracle, IAaveProtocolDataProvider, ILendingRateOracle} from './AaveV2.sol';\nimport {ICollector} from './common/ICollector.sol';\n\nlibrary AaveV2Ethereum {\n  // https://etherscan.io/address/0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5\n  ILendingPoolAddressesProvider internal constant POOL_ADDRESSES_PROVIDER =\n    ILendingPoolAddressesProvider(0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5);\n\n  // https://etherscan.io/address/0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9\n  ILendingPool internal constant POOL = ILendingPool(0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9);\n\n  // https://etherscan.io/address/0x085E34722e04567Df9E6d2c32e82fd74f3342e79\n  address internal constant POOL_IMPL = 0x085E34722e04567Df9E6d2c32e82fd74f3342e79;\n\n  // https://etherscan.io/address/0x311Bb771e4F8952E6Da169b425E7e92d6Ac45756\n  ILendingPoolConfigurator internal constant POOL_CONFIGURATOR =\n    ILendingPoolConfigurator(0x311Bb771e4F8952E6Da169b425E7e92d6Ac45756);\n\n  // https://etherscan.io/address/0x246ca67522dF5895cD6cf8807Ec161954ea1bA61\n  address internal constant POOL_CONFIGURATOR_IMPL = 0x246ca67522dF5895cD6cf8807Ec161954ea1bA61;\n\n  // https://etherscan.io/address/0xA50ba011c48153De246E5192C8f9258A2ba79Ca9\n  IAaveOracle internal constant ORACLE = IAaveOracle(0xA50ba011c48153De246E5192C8f9258A2ba79Ca9);\n\n  // https://etherscan.io/address/0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D\n  ILendingRateOracle internal constant LENDING_RATE_ORACLE =\n    ILendingRateOracle(0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D);\n\n  // https://etherscan.io/address/0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d\n  IAaveProtocolDataProvider internal constant AAVE_PROTOCOL_DATA_PROVIDER =\n    IAaveProtocolDataProvider(0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d);\n\n  // https://etherscan.io/address/0x5300A1a15135EA4dc7aD5a167152C01EFc9b192A\n  address internal constant POOL_ADMIN = 0x5300A1a15135EA4dc7aD5a167152C01EFc9b192A;\n\n  // https://etherscan.io/address/0xCA76Ebd8617a03126B6FB84F9b1c1A0fB71C2633\n  address internal constant EMERGENCY_ADMIN = 0xCA76Ebd8617a03126B6FB84F9b1c1A0fB71C2633;\n\n  // https://etherscan.io/address/0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c\n  ICollector internal constant COLLECTOR = ICollector(0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c);\n\n  // https://etherscan.io/address/0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5\n  address internal constant DEFAULT_INCENTIVES_CONTROLLER =\n    0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5;\n\n  // https://etherscan.io/address/0xEE56e2B3D491590B5b31738cC34d5232F378a8D5\n  address internal constant EMISSION_MANAGER = 0xEE56e2B3D491590B5b31738cC34d5232F378a8D5;\n\n  // https://etherscan.io/address/0x368e6441bB27159c6e8e6d3bbd9147BEcBA915E3\n  address internal constant LENDING_POOL_COLLATERAL_MANAGER =\n    0x368e6441bB27159c6e8e6d3bbd9147BEcBA915E3;\n\n  // https://etherscan.io/address/0x6A6FA664D4Fa49a6a780a1D6143f079f8dd7C33d\n  address internal constant DEBT_SWAP_ADAPTER = 0x6A6FA664D4Fa49a6a780a1D6143f079f8dd7C33d;\n\n  // https://etherscan.io/address/0x9eCed0293e7B73CFf4a2b4F9C82aAc8346158bd9\n  address internal constant CONFIG_ENGINE = 0x9eCed0293e7B73CFf4a2b4F9C82aAc8346158bd9;\n\n  // https://etherscan.io/address/0xB748952c7BC638F31775245964707Bcc5DDFabFC\n  address internal constant MIGRATION_HELPER = 0xB748952c7BC638F31775245964707Bcc5DDFabFC;\n\n  // https://etherscan.io/address/0x52D306e36E3B6B02c153d0266ff0f85d18BCD413\n  address internal constant POOL_ADDRESSES_PROVIDER_REGISTRY =\n    0x52D306e36E3B6B02c153d0266ff0f85d18BCD413;\n\n  // https://etherscan.io/address/0xbD37610BBB1ddc2a22797F7e3f531B59902b7bA7\n  address internal constant RATES_FACTORY = 0xbD37610BBB1ddc2a22797F7e3f531B59902b7bA7;\n\n  // https://etherscan.io/address/0x80Aca0C645fEdABaa20fd2Bf0Daf57885A309FE6\n  address internal constant REPAY_WITH_COLLATERAL_ADAPTER =\n    0x80Aca0C645fEdABaa20fd2Bf0Daf57885A309FE6;\n\n  // https://etherscan.io/address/0x135896DE8421be2ec868E0b811006171D9df802A\n  address internal constant SWAP_COLLATERAL_ADAPTER = 0x135896DE8421be2ec868E0b811006171D9df802A;\n\n  // https://etherscan.io/address/0xD01ab9a6577E1D84F142e44D49380e23A340387d\n  address internal constant UI_INCENTIVE_DATA_PROVIDER = 0xD01ab9a6577E1D84F142e44D49380e23A340387d;\n\n  // https://etherscan.io/address/0x00e50FAB64eBB37b87df06Aa46b8B35d5f1A4e1A\n  address internal constant UI_POOL_DATA_PROVIDER = 0x00e50FAB64eBB37b87df06Aa46b8B35d5f1A4e1A;\n\n  // https://etherscan.io/address/0x8E8dAd5409E0263a51C0aB5055dA66Be28cFF922\n  address internal constant WALLET_BALANCE_PROVIDER = 0x8E8dAd5409E0263a51C0aB5055dA66Be28cFF922;\n\n  // https://etherscan.io/address/0xa0d9C1E9E48Ca30c8d8C3B5D69FF5dc1f6DFfC24\n  address internal constant WETH_GATEWAY = 0xa0d9C1E9E48Ca30c8d8C3B5D69FF5dc1f6DFfC24;\n}\n\nlibrary AaveV2EthereumAssets {\n  // https://etherscan.io/address/0xdAC17F958D2ee523a2206206994597C13D831ec7\n  address internal constant USDT_UNDERLYING = 0xdAC17F958D2ee523a2206206994597C13D831ec7;\n\n  uint8 internal constant USDT_DECIMALS = 6;\n\n  // https://etherscan.io/address/0x3Ed3B47Dd13EC9a98b44e6204A523E766B225811\n  address internal constant USDT_A_TOKEN = 0x3Ed3B47Dd13EC9a98b44e6204A523E766B225811;\n\n  // https://etherscan.io/address/0x531842cEbbdD378f8ee36D171d6cC9C4fcf475Ec\n  address internal constant USDT_V_TOKEN = 0x531842cEbbdD378f8ee36D171d6cC9C4fcf475Ec;\n\n  // https://etherscan.io/address/0xe91D55AB2240594855aBd11b3faAE801Fd4c4687\n  address internal constant USDT_S_TOKEN = 0xe91D55AB2240594855aBd11b3faAE801Fd4c4687;\n\n  // https://etherscan.io/address/0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46\n  address internal constant USDT_ORACLE = 0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46;\n\n  // https://etherscan.io/address/0xF02EC9CA513ca505f0F5347E7D784Fa6165F8a99\n  address internal constant USDT_INTEREST_RATE_STRATEGY =\n    0xF02EC9CA513ca505f0F5347E7D784Fa6165F8a99;\n\n  // https://etherscan.io/address/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\n  address internal constant WBTC_UNDERLYING = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;\n\n  uint8 internal constant WBTC_DECIMALS = 8;\n\n  // https://etherscan.io/address/0x9ff58f4fFB29fA2266Ab25e75e2A8b3503311656\n  address internal constant WBTC_A_TOKEN = 0x9ff58f4fFB29fA2266Ab25e75e2A8b3503311656;\n\n  // https://etherscan.io/address/0x9c39809Dec7F95F5e0713634a4D0701329B3b4d2\n  address internal constant WBTC_V_TOKEN = 0x9c39809Dec7F95F5e0713634a4D0701329B3b4d2;\n\n  // https://etherscan.io/address/0x51B039b9AFE64B78758f8Ef091211b5387eA717c\n  address internal constant WBTC_S_TOKEN = 0x51B039b9AFE64B78758f8Ef091211b5387eA717c;\n\n  // https://etherscan.io/address/0xFD858c8bC5ac5e10f01018bC78471bb0DC392247\n  address internal constant WBTC_ORACLE = 0xFD858c8bC5ac5e10f01018bC78471bb0DC392247;\n\n  // https://etherscan.io/address/0x32f3A6134590fc2d9440663d35a2F0a6265F04c4\n  address internal constant WBTC_INTEREST_RATE_STRATEGY =\n    0x32f3A6134590fc2d9440663d35a2F0a6265F04c4;\n\n  // https://etherscan.io/address/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n  address internal constant WETH_UNDERLYING = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n\n  uint8 internal constant WETH_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x030bA81f1c18d280636F32af80b9AAd02Cf0854e\n  address internal constant WETH_A_TOKEN = 0x030bA81f1c18d280636F32af80b9AAd02Cf0854e;\n\n  // https://etherscan.io/address/0xF63B34710400CAd3e044cFfDcAb00a0f32E33eCf\n  address internal constant WETH_V_TOKEN = 0xF63B34710400CAd3e044cFfDcAb00a0f32E33eCf;\n\n  // https://etherscan.io/address/0x4e977830ba4bd783C0BB7F15d3e243f73FF57121\n  address internal constant WETH_S_TOKEN = 0x4e977830ba4bd783C0BB7F15d3e243f73FF57121;\n\n  // https://etherscan.io/address/0xb8975328Aa52c00B9Ec1e11e518C4900f2e6C62a\n  address internal constant WETH_INTEREST_RATE_STRATEGY =\n    0xb8975328Aa52c00B9Ec1e11e518C4900f2e6C62a;\n\n  // https://etherscan.io/address/0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e\n  address internal constant YFI_UNDERLYING = 0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e;\n\n  uint8 internal constant YFI_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x5165d24277cD063F5ac44Efd447B27025e888f37\n  address internal constant YFI_A_TOKEN = 0x5165d24277cD063F5ac44Efd447B27025e888f37;\n\n  // https://etherscan.io/address/0x7EbD09022Be45AD993BAA1CEc61166Fcc8644d97\n  address internal constant YFI_V_TOKEN = 0x7EbD09022Be45AD993BAA1CEc61166Fcc8644d97;\n\n  // https://etherscan.io/address/0xca823F78C2Dd38993284bb42Ba9b14152082F7BD\n  address internal constant YFI_S_TOKEN = 0xca823F78C2Dd38993284bb42Ba9b14152082F7BD;\n\n  // https://etherscan.io/address/0x7c5d4F8345e66f68099581Db340cd65B078C41f4\n  address internal constant YFI_ORACLE = 0x7c5d4F8345e66f68099581Db340cd65B078C41f4;\n\n  // https://etherscan.io/address/0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069\n  address internal constant YFI_INTEREST_RATE_STRATEGY = 0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069;\n\n  // https://etherscan.io/address/0xE41d2489571d322189246DaFA5ebDe1F4699F498\n  address internal constant ZRX_UNDERLYING = 0xE41d2489571d322189246DaFA5ebDe1F4699F498;\n\n  uint8 internal constant ZRX_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xDf7FF54aAcAcbFf42dfe29DD6144A69b629f8C9e\n  address internal constant ZRX_A_TOKEN = 0xDf7FF54aAcAcbFf42dfe29DD6144A69b629f8C9e;\n\n  // https://etherscan.io/address/0x85791D117A392097590bDeD3bD5abB8d5A20491A\n  address internal constant ZRX_V_TOKEN = 0x85791D117A392097590bDeD3bD5abB8d5A20491A;\n\n  // https://etherscan.io/address/0x071B4323a24E73A5afeEbe34118Cd21B8FAAF7C3\n  address internal constant ZRX_S_TOKEN = 0x071B4323a24E73A5afeEbe34118Cd21B8FAAF7C3;\n\n  // https://etherscan.io/address/0x2Da4983a622a8498bb1a21FaE9D8F6C664939962\n  address internal constant ZRX_ORACLE = 0x2Da4983a622a8498bb1a21FaE9D8F6C664939962;\n\n  // https://etherscan.io/address/0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069\n  address internal constant ZRX_INTEREST_RATE_STRATEGY = 0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069;\n\n  // https://etherscan.io/address/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984\n  address internal constant UNI_UNDERLYING = 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984;\n\n  uint8 internal constant UNI_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xB9D7CB55f463405CDfBe4E90a6D2Df01C2B92BF1\n  address internal constant UNI_A_TOKEN = 0xB9D7CB55f463405CDfBe4E90a6D2Df01C2B92BF1;\n\n  // https://etherscan.io/address/0x5BdB050A92CADcCfCDcCCBFC17204a1C9cC0Ab73\n  address internal constant UNI_V_TOKEN = 0x5BdB050A92CADcCfCDcCCBFC17204a1C9cC0Ab73;\n\n  // https://etherscan.io/address/0xD939F7430dC8D5a427f156dE1012A56C18AcB6Aa\n  address internal constant UNI_S_TOKEN = 0xD939F7430dC8D5a427f156dE1012A56C18AcB6Aa;\n\n  // https://etherscan.io/address/0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e\n  address internal constant UNI_ORACLE = 0xD6aA3D25116d8dA79Ea0246c4826EB951872e02e;\n\n  // https://etherscan.io/address/0x87cCa171a2125efca9868F9Bc1FfD7B7c80dC5a3\n  address internal constant UNI_INTEREST_RATE_STRATEGY = 0x87cCa171a2125efca9868F9Bc1FfD7B7c80dC5a3;\n\n  // https://etherscan.io/address/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9\n  address internal constant AAVE_UNDERLYING = 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9;\n\n  uint8 internal constant AAVE_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xFFC97d72E13E01096502Cb8Eb52dEe56f74DAD7B\n  address internal constant AAVE_A_TOKEN = 0xFFC97d72E13E01096502Cb8Eb52dEe56f74DAD7B;\n\n  // https://etherscan.io/address/0xF7DBA49d571745D9d7fcb56225B05BEA803EBf3C\n  address internal constant AAVE_V_TOKEN = 0xF7DBA49d571745D9d7fcb56225B05BEA803EBf3C;\n\n  // https://etherscan.io/address/0x079D6a3E844BcECf5720478A718Edb6575362C5f\n  address internal constant AAVE_S_TOKEN = 0x079D6a3E844BcECf5720478A718Edb6575362C5f;\n\n  // https://etherscan.io/address/0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012\n  address internal constant AAVE_ORACLE = 0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012;\n\n  // https://etherscan.io/address/0xd4cA26F2496195C4F886D464D8578368236bB747\n  address internal constant AAVE_INTEREST_RATE_STRATEGY =\n    0xd4cA26F2496195C4F886D464D8578368236bB747;\n\n  // https://etherscan.io/address/0x0D8775F648430679A709E98d2b0Cb6250d2887EF\n  address internal constant BAT_UNDERLYING = 0x0D8775F648430679A709E98d2b0Cb6250d2887EF;\n\n  uint8 internal constant BAT_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x05Ec93c0365baAeAbF7AefFb0972ea7ECdD39CF1\n  address internal constant BAT_A_TOKEN = 0x05Ec93c0365baAeAbF7AefFb0972ea7ECdD39CF1;\n\n  // https://etherscan.io/address/0xfc218A6Dfe6901CB34B1a5281FC6f1b8e7E56877\n  address internal constant BAT_V_TOKEN = 0xfc218A6Dfe6901CB34B1a5281FC6f1b8e7E56877;\n\n  // https://etherscan.io/address/0x277f8676FAcf4dAA5a6EA38ba511B7F65AA02f9F\n  address internal constant BAT_S_TOKEN = 0x277f8676FAcf4dAA5a6EA38ba511B7F65AA02f9F;\n\n  // https://etherscan.io/address/0x0d16d4528239e9ee52fa531af613AcdB23D88c94\n  address internal constant BAT_ORACLE = 0x0d16d4528239e9ee52fa531af613AcdB23D88c94;\n\n  // https://etherscan.io/address/0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069\n  address internal constant BAT_INTEREST_RATE_STRATEGY = 0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069;\n\n  // https://etherscan.io/address/0x4Fabb145d64652a948d72533023f6E7A623C7C53\n  address internal constant BUSD_UNDERLYING = 0x4Fabb145d64652a948d72533023f6E7A623C7C53;\n\n  uint8 internal constant BUSD_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xA361718326c15715591c299427c62086F69923D9\n  address internal constant BUSD_A_TOKEN = 0xA361718326c15715591c299427c62086F69923D9;\n\n  // https://etherscan.io/address/0xbA429f7011c9fa04cDd46a2Da24dc0FF0aC6099c\n  address internal constant BUSD_V_TOKEN = 0xbA429f7011c9fa04cDd46a2Da24dc0FF0aC6099c;\n\n  // https://etherscan.io/address/0x4A7A63909A72D268b1D8a93a9395d098688e0e5C\n  address internal constant BUSD_S_TOKEN = 0x4A7A63909A72D268b1D8a93a9395d098688e0e5C;\n\n  // https://etherscan.io/address/0x614715d2Af89E6EC99A233818275142cE88d1Cfd\n  address internal constant BUSD_ORACLE = 0x614715d2Af89E6EC99A233818275142cE88d1Cfd;\n\n  // https://etherscan.io/address/0xF1AafF9a4Da6Bf4Fb8fc18d39C8ffdafbAACce69\n  address internal constant BUSD_INTEREST_RATE_STRATEGY =\n    0xF1AafF9a4Da6Bf4Fb8fc18d39C8ffdafbAACce69;\n\n  // https://etherscan.io/address/0x6B175474E89094C44Da98b954EedeAC495271d0F\n  address internal constant DAI_UNDERLYING = 0x6B175474E89094C44Da98b954EedeAC495271d0F;\n\n  uint8 internal constant DAI_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x028171bCA77440897B824Ca71D1c56caC55b68A3\n  address internal constant DAI_A_TOKEN = 0x028171bCA77440897B824Ca71D1c56caC55b68A3;\n\n  // https://etherscan.io/address/0x6C3c78838c761c6Ac7bE9F59fe808ea2A6E4379d\n  address internal constant DAI_V_TOKEN = 0x6C3c78838c761c6Ac7bE9F59fe808ea2A6E4379d;\n\n  // https://etherscan.io/address/0x778A13D3eeb110A4f7bb6529F99c000119a08E92\n  address internal constant DAI_S_TOKEN = 0x778A13D3eeb110A4f7bb6529F99c000119a08E92;\n\n  // https://etherscan.io/address/0x773616E4d11A78F511299002da57A0a94577F1f4\n  address internal constant DAI_ORACLE = 0x773616E4d11A78F511299002da57A0a94577F1f4;\n\n  // https://etherscan.io/address/0xab7f8ca781C736EB624A9E321cd043F8E6292C96\n  address internal constant DAI_INTEREST_RATE_STRATEGY = 0xab7f8ca781C736EB624A9E321cd043F8E6292C96;\n\n  // https://etherscan.io/address/0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c\n  address internal constant ENJ_UNDERLYING = 0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c;\n\n  uint8 internal constant ENJ_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xaC6Df26a590F08dcC95D5a4705ae8abbc88509Ef\n  address internal constant ENJ_A_TOKEN = 0xaC6Df26a590F08dcC95D5a4705ae8abbc88509Ef;\n\n  // https://etherscan.io/address/0x38995F292a6E31b78203254fE1cdd5Ca1010A446\n  address internal constant ENJ_V_TOKEN = 0x38995F292a6E31b78203254fE1cdd5Ca1010A446;\n\n  // https://etherscan.io/address/0x943DcCA156b5312Aa24c1a08769D67FEce4ac14C\n  address internal constant ENJ_S_TOKEN = 0x943DcCA156b5312Aa24c1a08769D67FEce4ac14C;\n\n  // https://etherscan.io/address/0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B\n  address internal constant ENJ_ORACLE = 0x24D9aB51950F3d62E9144fdC2f3135DAA6Ce8D1B;\n\n  // https://etherscan.io/address/0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069\n  address internal constant ENJ_INTEREST_RATE_STRATEGY = 0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069;\n\n  // https://etherscan.io/address/0xdd974D5C2e2928deA5F71b9825b8b646686BD200\n  address internal constant KNC_UNDERLYING = 0xdd974D5C2e2928deA5F71b9825b8b646686BD200;\n\n  uint8 internal constant KNC_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x39C6b3e42d6A679d7D776778Fe880BC9487C2EDA\n  address internal constant KNC_A_TOKEN = 0x39C6b3e42d6A679d7D776778Fe880BC9487C2EDA;\n\n  // https://etherscan.io/address/0x6B05D1c608015Ccb8e205A690cB86773A96F39f1\n  address internal constant KNC_V_TOKEN = 0x6B05D1c608015Ccb8e205A690cB86773A96F39f1;\n\n  // https://etherscan.io/address/0x9915dfb872778B2890a117DA1F35F335eb06B54f\n  address internal constant KNC_S_TOKEN = 0x9915dfb872778B2890a117DA1F35F335eb06B54f;\n\n  // https://etherscan.io/address/0x656c0544eF4C98A6a98491833A89204Abb045d6b\n  address internal constant KNC_ORACLE = 0x656c0544eF4C98A6a98491833A89204Abb045d6b;\n\n  // https://etherscan.io/address/0xeB65a3163Fd8900F4fE9a044e18966706b69A74D\n  address internal constant KNC_INTEREST_RATE_STRATEGY = 0xeB65a3163Fd8900F4fE9a044e18966706b69A74D;\n\n  // https://etherscan.io/address/0x514910771AF9Ca656af840dff83E8264EcF986CA\n  address internal constant LINK_UNDERLYING = 0x514910771AF9Ca656af840dff83E8264EcF986CA;\n\n  uint8 internal constant LINK_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xa06bC25B5805d5F8d82847D191Cb4Af5A3e873E0\n  address internal constant LINK_A_TOKEN = 0xa06bC25B5805d5F8d82847D191Cb4Af5A3e873E0;\n\n  // https://etherscan.io/address/0x0b8f12b1788BFdE65Aa1ca52E3e9F3Ba401be16D\n  address internal constant LINK_V_TOKEN = 0x0b8f12b1788BFdE65Aa1ca52E3e9F3Ba401be16D;\n\n  // https://etherscan.io/address/0xFB4AEc4Cc858F2539EBd3D37f2a43eAe5b15b98a\n  address internal constant LINK_S_TOKEN = 0xFB4AEc4Cc858F2539EBd3D37f2a43eAe5b15b98a;\n\n  // https://etherscan.io/address/0xDC530D9457755926550b59e8ECcdaE7624181557\n  address internal constant LINK_ORACLE = 0xDC530D9457755926550b59e8ECcdaE7624181557;\n\n  // https://etherscan.io/address/0xED6547b83276B076B771B88FcCbD68BDeDb3927f\n  address internal constant LINK_INTEREST_RATE_STRATEGY =\n    0xED6547b83276B076B771B88FcCbD68BDeDb3927f;\n\n  // https://etherscan.io/address/0x0F5D2fB29fb7d3CFeE444a200298f468908cC942\n  address internal constant MANA_UNDERLYING = 0x0F5D2fB29fb7d3CFeE444a200298f468908cC942;\n\n  uint8 internal constant MANA_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xa685a61171bb30d4072B338c80Cb7b2c865c873E\n  address internal constant MANA_A_TOKEN = 0xa685a61171bb30d4072B338c80Cb7b2c865c873E;\n\n  // https://etherscan.io/address/0x0A68976301e46Ca6Ce7410DB28883E309EA0D352\n  address internal constant MANA_V_TOKEN = 0x0A68976301e46Ca6Ce7410DB28883E309EA0D352;\n\n  // https://etherscan.io/address/0xD86C74eA2224f4B8591560652b50035E4e5c0a3b\n  address internal constant MANA_S_TOKEN = 0xD86C74eA2224f4B8591560652b50035E4e5c0a3b;\n\n  // https://etherscan.io/address/0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9\n  address internal constant MANA_ORACLE = 0x82A44D92D6c329826dc557c5E1Be6ebeC5D5FeB9;\n\n  // https://etherscan.io/address/0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069\n  address internal constant MANA_INTEREST_RATE_STRATEGY =\n    0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069;\n\n  // https://etherscan.io/address/0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2\n  address internal constant MKR_UNDERLYING = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2;\n\n  uint8 internal constant MKR_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xc713e5E149D5D0715DcD1c156a020976e7E56B88\n  address internal constant MKR_A_TOKEN = 0xc713e5E149D5D0715DcD1c156a020976e7E56B88;\n\n  // https://etherscan.io/address/0xba728eAd5e496BE00DCF66F650b6d7758eCB50f8\n  address internal constant MKR_V_TOKEN = 0xba728eAd5e496BE00DCF66F650b6d7758eCB50f8;\n\n  // https://etherscan.io/address/0xC01C8E4b12a89456a9fD4e4e75B72546Bf53f0B5\n  address internal constant MKR_S_TOKEN = 0xC01C8E4b12a89456a9fD4e4e75B72546Bf53f0B5;\n\n  // https://etherscan.io/address/0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2\n  address internal constant MKR_ORACLE = 0x24551a8Fb2A7211A25a17B1481f043A8a8adC7f2;\n\n  // https://etherscan.io/address/0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069\n  address internal constant MKR_INTEREST_RATE_STRATEGY = 0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069;\n\n  // https://etherscan.io/address/0x408e41876cCCDC0F92210600ef50372656052a38\n  address internal constant REN_UNDERLYING = 0x408e41876cCCDC0F92210600ef50372656052a38;\n\n  uint8 internal constant REN_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xCC12AbE4ff81c9378D670De1b57F8e0Dd228D77a\n  address internal constant REN_A_TOKEN = 0xCC12AbE4ff81c9378D670De1b57F8e0Dd228D77a;\n\n  // https://etherscan.io/address/0xcd9D82d33bd737De215cDac57FE2F7f04DF77FE0\n  address internal constant REN_V_TOKEN = 0xcd9D82d33bd737De215cDac57FE2F7f04DF77FE0;\n\n  // https://etherscan.io/address/0x3356Ec1eFA75d9D150Da1EC7d944D9EDf73703B7\n  address internal constant REN_S_TOKEN = 0x3356Ec1eFA75d9D150Da1EC7d944D9EDf73703B7;\n\n  // https://etherscan.io/address/0x3147D7203354Dc06D9fd350c7a2437bcA92387a4\n  address internal constant REN_ORACLE = 0x3147D7203354Dc06D9fd350c7a2437bcA92387a4;\n\n  // https://etherscan.io/address/0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069\n  address internal constant REN_INTEREST_RATE_STRATEGY = 0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069;\n\n  // https://etherscan.io/address/0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F\n  address internal constant SNX_UNDERLYING = 0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F;\n\n  uint8 internal constant SNX_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x35f6B052C598d933D69A4EEC4D04c73A191fE6c2\n  address internal constant SNX_A_TOKEN = 0x35f6B052C598d933D69A4EEC4D04c73A191fE6c2;\n\n  // https://etherscan.io/address/0x267EB8Cf715455517F9BD5834AeAE3CeA1EBdbD8\n  address internal constant SNX_V_TOKEN = 0x267EB8Cf715455517F9BD5834AeAE3CeA1EBdbD8;\n\n  // https://etherscan.io/address/0x8575c8ae70bDB71606A53AeA1c6789cB0fBF3166\n  address internal constant SNX_S_TOKEN = 0x8575c8ae70bDB71606A53AeA1c6789cB0fBF3166;\n\n  // https://etherscan.io/address/0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c\n  address internal constant SNX_ORACLE = 0x79291A9d692Df95334B1a0B3B4AE6bC606782f8c;\n\n  // https://etherscan.io/address/0xB2D822cAdb9040F3164829BC34e41a93cA3E01e5\n  address internal constant SNX_INTEREST_RATE_STRATEGY = 0xB2D822cAdb9040F3164829BC34e41a93cA3E01e5;\n\n  // https://etherscan.io/address/0x57Ab1ec28D129707052df4dF418D58a2D46d5f51\n  address internal constant sUSD_UNDERLYING = 0x57Ab1ec28D129707052df4dF418D58a2D46d5f51;\n\n  uint8 internal constant sUSD_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x6C5024Cd4F8A59110119C56f8933403A539555EB\n  address internal constant sUSD_A_TOKEN = 0x6C5024Cd4F8A59110119C56f8933403A539555EB;\n\n  // https://etherscan.io/address/0xdC6a3Ab17299D9C2A412B0e0a4C1f55446AE0817\n  address internal constant sUSD_V_TOKEN = 0xdC6a3Ab17299D9C2A412B0e0a4C1f55446AE0817;\n\n  // https://etherscan.io/address/0x30B0f7324feDF89d8eff397275F8983397eFe4af\n  address internal constant sUSD_S_TOKEN = 0x30B0f7324feDF89d8eff397275F8983397eFe4af;\n\n  // https://etherscan.io/address/0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757\n  address internal constant sUSD_ORACLE = 0x8e0b7e6062272B5eF4524250bFFF8e5Bd3497757;\n\n  // https://etherscan.io/address/0x28fc7a5F0e7652B6f5E398F5E656A3eB36a1F3DE\n  address internal constant sUSD_INTEREST_RATE_STRATEGY =\n    0x28fc7a5F0e7652B6f5E398F5E656A3eB36a1F3DE;\n\n  // https://etherscan.io/address/0x0000000000085d4780B73119b644AE5ecd22b376\n  address internal constant TUSD_UNDERLYING = 0x0000000000085d4780B73119b644AE5ecd22b376;\n\n  uint8 internal constant TUSD_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x101cc05f4A51C0319f570d5E146a8C625198e636\n  address internal constant TUSD_A_TOKEN = 0x101cc05f4A51C0319f570d5E146a8C625198e636;\n\n  // https://etherscan.io/address/0x01C0eb1f8c6F1C1bF74ae028697ce7AA2a8b0E92\n  address internal constant TUSD_V_TOKEN = 0x01C0eb1f8c6F1C1bF74ae028697ce7AA2a8b0E92;\n\n  // https://etherscan.io/address/0x7f38d60D94652072b2C44a18c0e14A481EC3C0dd\n  address internal constant TUSD_S_TOKEN = 0x7f38d60D94652072b2C44a18c0e14A481EC3C0dd;\n\n  // https://etherscan.io/address/0x3886BA987236181D98F2401c507Fb8BeA7871dF2\n  address internal constant TUSD_ORACLE = 0x3886BA987236181D98F2401c507Fb8BeA7871dF2;\n\n  // https://etherscan.io/address/0xb70e28437Aec70a8cfE5240F54c463cF849bE17C\n  address internal constant TUSD_INTEREST_RATE_STRATEGY =\n    0xb70e28437Aec70a8cfE5240F54c463cF849bE17C;\n\n  // https://etherscan.io/address/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\n  address internal constant USDC_UNDERLYING = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;\n\n  uint8 internal constant USDC_DECIMALS = 6;\n\n  // https://etherscan.io/address/0xBcca60bB61934080951369a648Fb03DF4F96263C\n  address internal constant USDC_A_TOKEN = 0xBcca60bB61934080951369a648Fb03DF4F96263C;\n\n  // https://etherscan.io/address/0x619beb58998eD2278e08620f97007e1116D5D25b\n  address internal constant USDC_V_TOKEN = 0x619beb58998eD2278e08620f97007e1116D5D25b;\n\n  // https://etherscan.io/address/0xE4922afAB0BbaDd8ab2a88E0C79d884Ad337fcA6\n  address internal constant USDC_S_TOKEN = 0xE4922afAB0BbaDd8ab2a88E0C79d884Ad337fcA6;\n\n  // https://etherscan.io/address/0x986b5E1e1755e3C2440e960477f25201B0a8bbD4\n  address internal constant USDC_ORACLE = 0x986b5E1e1755e3C2440e960477f25201B0a8bbD4;\n\n  // https://etherscan.io/address/0xb72F23adE9b9980c2E731Ca504105fC860643619\n  address internal constant USDC_INTEREST_RATE_STRATEGY =\n    0xb72F23adE9b9980c2E731Ca504105fC860643619;\n\n  // https://etherscan.io/address/0xD533a949740bb3306d119CC777fa900bA034cd52\n  address internal constant CRV_UNDERLYING = 0xD533a949740bb3306d119CC777fa900bA034cd52;\n\n  uint8 internal constant CRV_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x8dAE6Cb04688C62d939ed9B68d32Bc62e49970b1\n  address internal constant CRV_A_TOKEN = 0x8dAE6Cb04688C62d939ed9B68d32Bc62e49970b1;\n\n  // https://etherscan.io/address/0x00ad8eBF64F141f1C81e9f8f792d3d1631c6c684\n  address internal constant CRV_V_TOKEN = 0x00ad8eBF64F141f1C81e9f8f792d3d1631c6c684;\n\n  // https://etherscan.io/address/0x9288059a74f589C919c7Cf1Db433251CdFEB874B\n  address internal constant CRV_S_TOKEN = 0x9288059a74f589C919c7Cf1Db433251CdFEB874B;\n\n  // https://etherscan.io/address/0x8a12Be339B0cD1829b91Adc01977caa5E9ac121e\n  address internal constant CRV_ORACLE = 0x8a12Be339B0cD1829b91Adc01977caa5E9ac121e;\n\n  // https://etherscan.io/address/0x35FE8C9924718f286463e659be35b4122eEe907F\n  address internal constant CRV_INTEREST_RATE_STRATEGY = 0x35FE8C9924718f286463e659be35b4122eEe907F;\n\n  // https://etherscan.io/address/0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd\n  address internal constant GUSD_UNDERLYING = 0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd;\n\n  uint8 internal constant GUSD_DECIMALS = 2;\n\n  // https://etherscan.io/address/0xD37EE7e4f452C6638c96536e68090De8cBcdb583\n  address internal constant GUSD_A_TOKEN = 0xD37EE7e4f452C6638c96536e68090De8cBcdb583;\n\n  // https://etherscan.io/address/0x279AF5b99540c1A3A7E3CDd326e19659401eF99e\n  address internal constant GUSD_V_TOKEN = 0x279AF5b99540c1A3A7E3CDd326e19659401eF99e;\n\n  // https://etherscan.io/address/0xf8aC64ec6Ff8E0028b37EB89772d21865321bCe0\n  address internal constant GUSD_S_TOKEN = 0xf8aC64ec6Ff8E0028b37EB89772d21865321bCe0;\n\n  // https://etherscan.io/address/0xEc6f4Cd64d28Ef32507e2dc399948aAe9Bbedd7e\n  address internal constant GUSD_ORACLE = 0xEc6f4Cd64d28Ef32507e2dc399948aAe9Bbedd7e;\n\n  // https://etherscan.io/address/0x999F449fEAfaAd78CE5702A9ebc460633478D4a4\n  address internal constant GUSD_INTEREST_RATE_STRATEGY =\n    0x999F449fEAfaAd78CE5702A9ebc460633478D4a4;\n\n  // https://etherscan.io/address/0xba100000625a3754423978a60c9317c58a424e3D\n  address internal constant BAL_UNDERLYING = 0xba100000625a3754423978a60c9317c58a424e3D;\n\n  uint8 internal constant BAL_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x272F97b7a56a387aE942350bBC7Df5700f8a4576\n  address internal constant BAL_A_TOKEN = 0x272F97b7a56a387aE942350bBC7Df5700f8a4576;\n\n  // https://etherscan.io/address/0x13210D4Fe0d5402bd7Ecbc4B5bC5cFcA3b71adB0\n  address internal constant BAL_V_TOKEN = 0x13210D4Fe0d5402bd7Ecbc4B5bC5cFcA3b71adB0;\n\n  // https://etherscan.io/address/0xe569d31590307d05DA3812964F1eDd551D665a0b\n  address internal constant BAL_S_TOKEN = 0xe569d31590307d05DA3812964F1eDd551D665a0b;\n\n  // https://etherscan.io/address/0xC1438AA3823A6Ba0C159CfA8D98dF5A994bA120b\n  address internal constant BAL_ORACLE = 0xC1438AA3823A6Ba0C159CfA8D98dF5A994bA120b;\n\n  // https://etherscan.io/address/0xb873ec463CAC50112B0e14d060fbc4192406279f\n  address internal constant BAL_INTEREST_RATE_STRATEGY = 0xb873ec463CAC50112B0e14d060fbc4192406279f;\n\n  // https://etherscan.io/address/0x8798249c2E607446EfB7Ad49eC89dD1865Ff4272\n  address internal constant xSUSHI_UNDERLYING = 0x8798249c2E607446EfB7Ad49eC89dD1865Ff4272;\n\n  uint8 internal constant xSUSHI_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xF256CC7847E919FAc9B808cC216cAc87CCF2f47a\n  address internal constant xSUSHI_A_TOKEN = 0xF256CC7847E919FAc9B808cC216cAc87CCF2f47a;\n\n  // https://etherscan.io/address/0xfAFEDF95E21184E3d880bd56D4806c4b8d31c69A\n  address internal constant xSUSHI_V_TOKEN = 0xfAFEDF95E21184E3d880bd56D4806c4b8d31c69A;\n\n  // https://etherscan.io/address/0x73Bfb81D7dbA75C904f430eA8BAe82DB0D41187B\n  address internal constant xSUSHI_S_TOKEN = 0x73Bfb81D7dbA75C904f430eA8BAe82DB0D41187B;\n\n  // https://etherscan.io/address/0xF05D9B6C08757EAcb1fbec18e36A1B7566a13DEB\n  address internal constant xSUSHI_ORACLE = 0xF05D9B6C08757EAcb1fbec18e36A1B7566a13DEB;\n\n  // https://etherscan.io/address/0x6855E5544Cd803BF24c9612b3F12C009116B0ee1\n  address internal constant xSUSHI_INTEREST_RATE_STRATEGY =\n    0x6855E5544Cd803BF24c9612b3F12C009116B0ee1;\n\n  // https://etherscan.io/address/0xD5147bc8e386d91Cc5DBE72099DAC6C9b99276F5\n  address internal constant renFIL_UNDERLYING = 0xD5147bc8e386d91Cc5DBE72099DAC6C9b99276F5;\n\n  uint8 internal constant renFIL_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x514cd6756CCBe28772d4Cb81bC3156BA9d1744aa\n  address internal constant renFIL_A_TOKEN = 0x514cd6756CCBe28772d4Cb81bC3156BA9d1744aa;\n\n  // https://etherscan.io/address/0x348e2eBD5E962854871874E444F4122399c02755\n  address internal constant renFIL_V_TOKEN = 0x348e2eBD5E962854871874E444F4122399c02755;\n\n  // https://etherscan.io/address/0xcAad05C49E14075077915cB5C820EB3245aFb950\n  address internal constant renFIL_S_TOKEN = 0xcAad05C49E14075077915cB5C820EB3245aFb950;\n\n  // https://etherscan.io/address/0x0606Be69451B1C9861Ac6b3626b99093b713E801\n  address internal constant renFIL_ORACLE = 0x0606Be69451B1C9861Ac6b3626b99093b713E801;\n\n  // https://etherscan.io/address/0x311C866D55456e465e314A3E9830276B438A73f0\n  address internal constant renFIL_INTEREST_RATE_STRATEGY =\n    0x311C866D55456e465e314A3E9830276B438A73f0;\n\n  // https://etherscan.io/address/0x03ab458634910AaD20eF5f1C8ee96F1D6ac54919\n  address internal constant RAI_UNDERLYING = 0x03ab458634910AaD20eF5f1C8ee96F1D6ac54919;\n\n  uint8 internal constant RAI_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xc9BC48c72154ef3e5425641a3c747242112a46AF\n  address internal constant RAI_A_TOKEN = 0xc9BC48c72154ef3e5425641a3c747242112a46AF;\n\n  // https://etherscan.io/address/0xB5385132EE8321977FfF44b60cDE9fE9AB0B4e6b\n  address internal constant RAI_V_TOKEN = 0xB5385132EE8321977FfF44b60cDE9fE9AB0B4e6b;\n\n  // https://etherscan.io/address/0x9C72B8476C33AE214ee3e8C20F0bc28496a62032\n  address internal constant RAI_S_TOKEN = 0x9C72B8476C33AE214ee3e8C20F0bc28496a62032;\n\n  // https://etherscan.io/address/0x4ad7B025127e89263242aB68F0f9c4E5C033B489\n  address internal constant RAI_ORACLE = 0x4ad7B025127e89263242aB68F0f9c4E5C033B489;\n\n  // https://etherscan.io/address/0xc83cDb49F234EC6666D7857B3EAa1302b109394C\n  address internal constant RAI_INTEREST_RATE_STRATEGY = 0xc83cDb49F234EC6666D7857B3EAa1302b109394C;\n\n  // https://etherscan.io/address/0xD46bA6D942050d489DBd938a2C909A5d5039A161\n  address internal constant AMPL_UNDERLYING = 0xD46bA6D942050d489DBd938a2C909A5d5039A161;\n\n  uint8 internal constant AMPL_DECIMALS = 9;\n\n  // https://etherscan.io/address/0x1E6bb68Acec8fefBD87D192bE09bb274170a0548\n  address internal constant AMPL_A_TOKEN = 0x1E6bb68Acec8fefBD87D192bE09bb274170a0548;\n\n  // https://etherscan.io/address/0xf013D90E4e4E3Baf420dFea60735e75dbd42f1e1\n  address internal constant AMPL_V_TOKEN = 0xf013D90E4e4E3Baf420dFea60735e75dbd42f1e1;\n\n  // https://etherscan.io/address/0x18152C9f77DAdc737006e9430dB913159645fa87\n  address internal constant AMPL_S_TOKEN = 0x18152C9f77DAdc737006e9430dB913159645fa87;\n\n  // https://etherscan.io/address/0x492575FDD11a0fCf2C6C719867890a7648d526eB\n  address internal constant AMPL_ORACLE = 0x492575FDD11a0fCf2C6C719867890a7648d526eB;\n\n  // https://etherscan.io/address/0xa324C768Bdd002b3387CE1c691A549268f63250b\n  address internal constant AMPL_INTEREST_RATE_STRATEGY =\n    0xa324C768Bdd002b3387CE1c691A549268f63250b;\n\n  // https://etherscan.io/address/0x8E870D67F660D95d5be530380D0eC0bd388289E1\n  address internal constant USDP_UNDERLYING = 0x8E870D67F660D95d5be530380D0eC0bd388289E1;\n\n  uint8 internal constant USDP_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x2e8F4bdbE3d47d7d7DE490437AeA9915D930F1A3\n  address internal constant USDP_A_TOKEN = 0x2e8F4bdbE3d47d7d7DE490437AeA9915D930F1A3;\n\n  // https://etherscan.io/address/0xFDb93B3b10936cf81FA59A02A7523B6e2149b2B7\n  address internal constant USDP_V_TOKEN = 0xFDb93B3b10936cf81FA59A02A7523B6e2149b2B7;\n\n  // https://etherscan.io/address/0x2387119bc85A74e0BBcbe190d80676CB16F10D4F\n  address internal constant USDP_S_TOKEN = 0x2387119bc85A74e0BBcbe190d80676CB16F10D4F;\n\n  // https://etherscan.io/address/0x3a08ebBaB125224b7b6474384Ee39fBb247D2200\n  address internal constant USDP_ORACLE = 0x3a08ebBaB125224b7b6474384Ee39fBb247D2200;\n\n  // https://etherscan.io/address/0x40a76E018dd4aFe1391F51f0C8c8E4eA70476e15\n  address internal constant USDP_INTEREST_RATE_STRATEGY =\n    0x40a76E018dd4aFe1391F51f0C8c8E4eA70476e15;\n\n  // https://etherscan.io/address/0x1494CA1F11D487c2bBe4543E90080AeBa4BA3C2b\n  address internal constant DPI_UNDERLYING = 0x1494CA1F11D487c2bBe4543E90080AeBa4BA3C2b;\n\n  uint8 internal constant DPI_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x6F634c6135D2EBD550000ac92F494F9CB8183dAe\n  address internal constant DPI_A_TOKEN = 0x6F634c6135D2EBD550000ac92F494F9CB8183dAe;\n\n  // https://etherscan.io/address/0x4dDff5885a67E4EffeC55875a3977D7E60F82ae0\n  address internal constant DPI_V_TOKEN = 0x4dDff5885a67E4EffeC55875a3977D7E60F82ae0;\n\n  // https://etherscan.io/address/0xa3953F07f389d719F99FC378ebDb9276177d8A6e\n  address internal constant DPI_S_TOKEN = 0xa3953F07f389d719F99FC378ebDb9276177d8A6e;\n\n  // https://etherscan.io/address/0x029849bbc0b1d93b85a8b6190e979fd38F5760E2\n  address internal constant DPI_ORACLE = 0x029849bbc0b1d93b85a8b6190e979fd38F5760E2;\n\n  // https://etherscan.io/address/0xA12D7bB07379ad6de4497B80088e28D4C00932D1\n  address internal constant DPI_INTEREST_RATE_STRATEGY = 0xA12D7bB07379ad6de4497B80088e28D4C00932D1;\n\n  // https://etherscan.io/address/0x853d955aCEf822Db058eb8505911ED77F175b99e\n  address internal constant FRAX_UNDERLYING = 0x853d955aCEf822Db058eb8505911ED77F175b99e;\n\n  uint8 internal constant FRAX_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xd4937682df3C8aEF4FE912A96A74121C0829E664\n  address internal constant FRAX_A_TOKEN = 0xd4937682df3C8aEF4FE912A96A74121C0829E664;\n\n  // https://etherscan.io/address/0xfE8F19B17fFeF0fDbfe2671F248903055AFAA8Ca\n  address internal constant FRAX_V_TOKEN = 0xfE8F19B17fFeF0fDbfe2671F248903055AFAA8Ca;\n\n  // https://etherscan.io/address/0x3916e3B6c84b161df1b2733dFfc9569a1dA710c2\n  address internal constant FRAX_S_TOKEN = 0x3916e3B6c84b161df1b2733dFfc9569a1dA710c2;\n\n  // https://etherscan.io/address/0x14d04Fff8D21bd62987a5cE9ce543d2F1edF5D3E\n  address internal constant FRAX_ORACLE = 0x14d04Fff8D21bd62987a5cE9ce543d2F1edF5D3E;\n\n  // https://etherscan.io/address/0x28fc7a5F0e7652B6f5E398F5E656A3eB36a1F3DE\n  address internal constant FRAX_INTEREST_RATE_STRATEGY =\n    0x28fc7a5F0e7652B6f5E398F5E656A3eB36a1F3DE;\n\n  // https://etherscan.io/address/0x956F47F50A910163D8BF957Cf5846D573E7f87CA\n  address internal constant FEI_UNDERLYING = 0x956F47F50A910163D8BF957Cf5846D573E7f87CA;\n\n  uint8 internal constant FEI_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x683923dB55Fead99A79Fa01A27EeC3cB19679cC3\n  address internal constant FEI_A_TOKEN = 0x683923dB55Fead99A79Fa01A27EeC3cB19679cC3;\n\n  // https://etherscan.io/address/0xC2e10006AccAb7B45D9184FcF5b7EC7763f5BaAe\n  address internal constant FEI_V_TOKEN = 0xC2e10006AccAb7B45D9184FcF5b7EC7763f5BaAe;\n\n  // https://etherscan.io/address/0xd89cF9E8A858F8B4b31Faf793505e112d6c17449\n  address internal constant FEI_S_TOKEN = 0xd89cF9E8A858F8B4b31Faf793505e112d6c17449;\n\n  // https://etherscan.io/address/0xac3AF0f4A52C577Cc2C241dF51a01FDe3D06D93B\n  address internal constant FEI_ORACLE = 0xac3AF0f4A52C577Cc2C241dF51a01FDe3D06D93B;\n\n  // https://etherscan.io/address/0x795dC59EA6472Dfa4298A454C6E8Dcb005643A13\n  address internal constant FEI_INTEREST_RATE_STRATEGY = 0x795dC59EA6472Dfa4298A454C6E8Dcb005643A13;\n\n  // https://etherscan.io/address/0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84\n  address internal constant stETH_UNDERLYING = 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84;\n\n  uint8 internal constant stETH_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x1982b2F5814301d4e9a8b0201555376e62F82428\n  address internal constant stETH_A_TOKEN = 0x1982b2F5814301d4e9a8b0201555376e62F82428;\n\n  // https://etherscan.io/address/0xA9DEAc9f00Dc4310c35603FCD9D34d1A750f81Db\n  address internal constant stETH_V_TOKEN = 0xA9DEAc9f00Dc4310c35603FCD9D34d1A750f81Db;\n\n  // https://etherscan.io/address/0x66457616Dd8489dF5D0AFD8678F4A260088aAF55\n  address internal constant stETH_S_TOKEN = 0x66457616Dd8489dF5D0AFD8678F4A260088aAF55;\n\n  // https://etherscan.io/address/0xADE6CBA6c45aa8E9d0337cAc3D2619eabc39D901\n  address internal constant stETH_ORACLE = 0xADE6CBA6c45aa8E9d0337cAc3D2619eabc39D901;\n\n  // https://etherscan.io/address/0xff04ed5f7a6C3a0F1e5Ea20617F8C6f513D5A77c\n  address internal constant stETH_INTEREST_RATE_STRATEGY =\n    0xff04ed5f7a6C3a0F1e5Ea20617F8C6f513D5A77c;\n\n  // https://etherscan.io/address/0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72\n  address internal constant ENS_UNDERLYING = 0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72;\n\n  uint8 internal constant ENS_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x9a14e23A58edf4EFDcB360f68cd1b95ce2081a2F\n  address internal constant ENS_A_TOKEN = 0x9a14e23A58edf4EFDcB360f68cd1b95ce2081a2F;\n\n  // https://etherscan.io/address/0x176808047cc9b7A2C9AE202c593ED42dDD7C0D13\n  address internal constant ENS_V_TOKEN = 0x176808047cc9b7A2C9AE202c593ED42dDD7C0D13;\n\n  // https://etherscan.io/address/0x34441FFD1948E49dC7a607882D0c38Efd0083815\n  address internal constant ENS_S_TOKEN = 0x34441FFD1948E49dC7a607882D0c38Efd0083815;\n\n  // https://etherscan.io/address/0xd4641b75015E6536E8102D98479568D05D7123Db\n  address internal constant ENS_ORACLE = 0xd4641b75015E6536E8102D98479568D05D7123Db;\n\n  // https://etherscan.io/address/0x6855E5544Cd803BF24c9612b3F12C009116B0ee1\n  address internal constant ENS_INTEREST_RATE_STRATEGY = 0x6855E5544Cd803BF24c9612b3F12C009116B0ee1;\n\n  // https://etherscan.io/address/0xa693B19d2931d498c5B318dF961919BB4aee87a5\n  address internal constant UST_UNDERLYING = 0xa693B19d2931d498c5B318dF961919BB4aee87a5;\n\n  uint8 internal constant UST_DECIMALS = 6;\n\n  // https://etherscan.io/address/0xc2e2152647F4C26028482Efaf64b2Aa28779EFC4\n  address internal constant UST_A_TOKEN = 0xc2e2152647F4C26028482Efaf64b2Aa28779EFC4;\n\n  // https://etherscan.io/address/0xaf32001cf2E66C4C3af4205F6EA77112AA4160FE\n  address internal constant UST_V_TOKEN = 0xaf32001cf2E66C4C3af4205F6EA77112AA4160FE;\n\n  // https://etherscan.io/address/0x7FDbfB0412700D94403c42cA3CAEeeA183F07B26\n  address internal constant UST_S_TOKEN = 0x7FDbfB0412700D94403c42cA3CAEeeA183F07B26;\n\n  // https://etherscan.io/address/0xa20623070413d42a5C01Db2c8111640DD7A5A03a\n  address internal constant UST_ORACLE = 0xa20623070413d42a5C01Db2c8111640DD7A5A03a;\n\n  // https://etherscan.io/address/0xc83cDb49F234EC6666D7857B3EAa1302b109394C\n  address internal constant UST_INTEREST_RATE_STRATEGY = 0xc83cDb49F234EC6666D7857B3EAa1302b109394C;\n\n  // https://etherscan.io/address/0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B\n  address internal constant CVX_UNDERLYING = 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B;\n\n  uint8 internal constant CVX_DECIMALS = 18;\n\n  // https://etherscan.io/address/0x952749E07d7157bb9644A894dFAF3Bad5eF6D918\n  address internal constant CVX_A_TOKEN = 0x952749E07d7157bb9644A894dFAF3Bad5eF6D918;\n\n  // https://etherscan.io/address/0x4Ae5E4409C6Dbc84A00f9f89e4ba096603fb7d50\n  address internal constant CVX_V_TOKEN = 0x4Ae5E4409C6Dbc84A00f9f89e4ba096603fb7d50;\n\n  // https://etherscan.io/address/0xB01Eb1cE1Da06179136D561766fc2d609C5F55Eb\n  address internal constant CVX_S_TOKEN = 0xB01Eb1cE1Da06179136D561766fc2d609C5F55Eb;\n\n  // https://etherscan.io/address/0xC9CbF687f43176B302F03f5e58470b77D07c61c6\n  address internal constant CVX_ORACLE = 0xC9CbF687f43176B302F03f5e58470b77D07c61c6;\n\n  // https://etherscan.io/address/0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069\n  address internal constant CVX_INTEREST_RATE_STRATEGY = 0x2c206fa2127aB7f1CE3dc987daf683Ed5B9CF069;\n\n  // https://etherscan.io/address/0x111111111117dC0aa78b770fA6A738034120C302\n  address internal constant ONE_INCH_UNDERLYING = 0x111111111117dC0aa78b770fA6A738034120C302;\n\n  uint8 internal constant ONE_INCH_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xB29130CBcC3F791f077eAdE0266168E808E5151e\n  address internal constant ONE_INCH_A_TOKEN = 0xB29130CBcC3F791f077eAdE0266168E808E5151e;\n\n  // https://etherscan.io/address/0xD7896C1B9b4455aFf31473908eB15796ad2295DA\n  address internal constant ONE_INCH_V_TOKEN = 0xD7896C1B9b4455aFf31473908eB15796ad2295DA;\n\n  // https://etherscan.io/address/0x1278d6ED804d59d2d18a5Aa5638DfD591A79aF0a\n  address internal constant ONE_INCH_S_TOKEN = 0x1278d6ED804d59d2d18a5Aa5638DfD591A79aF0a;\n\n  // https://etherscan.io/address/0x72AFAECF99C9d9C8215fF44C77B94B99C28741e8\n  address internal constant ONE_INCH_ORACLE = 0x72AFAECF99C9d9C8215fF44C77B94B99C28741e8;\n\n  // https://etherscan.io/address/0x6855E5544Cd803BF24c9612b3F12C009116B0ee1\n  address internal constant ONE_INCH_INTEREST_RATE_STRATEGY =\n    0x6855E5544Cd803BF24c9612b3F12C009116B0ee1;\n\n  // https://etherscan.io/address/0x5f98805A4E8be255a32880FDeC7F6728C6568bA0\n  address internal constant LUSD_UNDERLYING = 0x5f98805A4E8be255a32880FDeC7F6728C6568bA0;\n\n  uint8 internal constant LUSD_DECIMALS = 18;\n\n  // https://etherscan.io/address/0xce1871f791548600cb59efbefFC9c38719142079\n  address internal constant LUSD_A_TOKEN = 0xce1871f791548600cb59efbefFC9c38719142079;\n\n  // https://etherscan.io/address/0x411066489AB40442d6Fc215aD7c64224120D33F2\n  address internal constant LUSD_V_TOKEN = 0x411066489AB40442d6Fc215aD7c64224120D33F2;\n\n  // https://etherscan.io/address/0x39f010127274b2dBdB770B45e1de54d974974526\n  address internal constant LUSD_S_TOKEN = 0x39f010127274b2dBdB770B45e1de54d974974526;\n\n  // https://etherscan.io/address/0x60c0b047133f696334a2b7f68af0b49d2F3D4F72\n  address internal constant LUSD_ORACLE = 0x60c0b047133f696334a2b7f68af0b49d2F3D4F72;\n\n  // https://etherscan.io/address/0xab7f8ca781C736EB624A9E321cd043F8E6292C96\n  address internal constant LUSD_INTEREST_RATE_STRATEGY =\n    0xab7f8ca781C736EB624A9E321cd043F8E6292C96;\n}\n"
      },
      "lib/aave-helpers/src/interfaces/IProposalGenericExecutor.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @dev Generic proposal interface allowing execution via MockExecutor\n */\ninterface IProposalGenericExecutor {\n  function execute() external;\n}\n"
      },
      "lib/aave-helpers/lib/aave-address-book/src/AaveV2.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport {AggregatorInterface} from './common/AggregatorInterface.sol';\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 {\n    NONE,\n    STABLE,\n    VARIABLE\n  }\n}\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\nlibrary ConfiguratorInputTypes {\n  struct InitReserveInput {\n    address aTokenImpl;\n    address stableDebtTokenImpl;\n    address variableDebtTokenImpl;\n    uint8 underlyingAssetDecimals;\n    address interestRateStrategyAddress;\n    address underlyingAsset;\n    address treasury;\n    address incentivesController;\n    string underlyingAssetName;\n    string aTokenName;\n    string aTokenSymbol;\n    string variableDebtTokenName;\n    string variableDebtTokenSymbol;\n    string stableDebtTokenName;\n    string stableDebtTokenSymbol;\n    bytes params;\n  }\n\n  struct UpdateATokenInput {\n    address asset;\n    address treasury;\n    address incentivesController;\n    string name;\n    string symbol;\n    address implementation;\n    bytes params;\n  }\n\n  struct UpdateDebtTokenInput {\n    address asset;\n    address incentivesController;\n    string name;\n    string symbol;\n    address implementation;\n    bytes params;\n  }\n}\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\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(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) 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(address asset, uint256 amount, address to) 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(\n    address user\n  )\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(\n    address reserve,\n    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(\n    address asset\n  ) external view 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(\n    address user\n  ) external view 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\ninterface ILendingPoolConfigurator {\n  /**\n   * @dev Emitted when a reserve is initialized.\n   * @param asset The address of the underlying asset of the reserve\n   * @param aToken The address of the associated aToken contract\n   * @param stableDebtToken The address of the associated stable rate debt token\n   * @param variableDebtToken The address of the associated variable rate debt token\n   * @param interestRateStrategyAddress The address of the interest rate strategy for the reserve\n   **/\n  event ReserveInitialized(\n    address indexed asset,\n    address indexed aToken,\n    address stableDebtToken,\n    address variableDebtToken,\n    address interestRateStrategyAddress\n  );\n\n  /**\n   * @dev Emitted when borrowing is enabled on a reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @param stableRateEnabled True if stable rate borrowing is enabled, false otherwise\n   **/\n  event BorrowingEnabledOnReserve(address indexed asset, bool stableRateEnabled);\n\n  /**\n   * @dev Emitted when borrowing is disabled on a reserve\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  event BorrowingDisabledOnReserve(address indexed asset);\n\n  /**\n   * @dev Emitted when the collateralization risk parameters for the specified asset are updated.\n   * @param asset The address of the underlying asset of the reserve\n   * @param ltv The loan to value of the asset when used as collateral\n   * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized\n   * @param liquidationBonus The bonus liquidators receive to liquidate this asset\n   **/\n  event CollateralConfigurationChanged(\n    address indexed asset,\n    uint256 ltv,\n    uint256 liquidationThreshold,\n    uint256 liquidationBonus\n  );\n\n  /**\n   * @dev Emitted when stable rate borrowing is enabled on a reserve\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  event StableRateEnabledOnReserve(address indexed asset);\n\n  /**\n   * @dev Emitted when stable rate borrowing is disabled on a reserve\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  event StableRateDisabledOnReserve(address indexed asset);\n\n  /**\n   * @dev Emitted when a reserve is activated\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  event ReserveActivated(address indexed asset);\n\n  /**\n   * @dev Emitted when a reserve is deactivated\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  event ReserveDeactivated(address indexed asset);\n\n  /**\n   * @dev Emitted when a reserve is frozen\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  event ReserveFrozen(address indexed asset);\n\n  /**\n   * @dev Emitted when a reserve is unfrozen\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  event ReserveUnfrozen(address indexed asset);\n\n  /**\n   * @dev Emitted when a reserve factor is updated\n   * @param asset The address of the underlying asset of the reserve\n   * @param factor The new reserve factor\n   **/\n  event ReserveFactorChanged(address indexed asset, uint256 factor);\n\n  /**\n   * @dev Emitted when the reserve decimals are updated\n   * @param asset The address of the underlying asset of the reserve\n   * @param decimals The new decimals\n   **/\n  event ReserveDecimalsChanged(address indexed asset, uint256 decimals);\n\n  /**\n   * @dev Emitted when a reserve interest strategy contract is updated\n   * @param asset The address of the underlying asset of the reserve\n   * @param strategy The new address of the interest strategy contract\n   **/\n  event ReserveInterestRateStrategyChanged(address indexed asset, address strategy);\n\n  /**\n   * @dev Emitted when an aToken implementation is upgraded\n   * @param asset The address of the underlying asset of the reserve\n   * @param proxy The aToken proxy address\n   * @param implementation The new aToken implementation\n   **/\n  event ATokenUpgraded(\n    address indexed asset,\n    address indexed proxy,\n    address indexed implementation\n  );\n\n  /**\n   * @dev Emitted when the implementation of a stable debt token is upgraded\n   * @param asset The address of the underlying asset of the reserve\n   * @param proxy The stable debt token proxy address\n   * @param implementation The new aToken implementation\n   **/\n  event StableDebtTokenUpgraded(\n    address indexed asset,\n    address indexed proxy,\n    address indexed implementation\n  );\n\n  /**\n   * @dev Emitted when the implementation of a variable debt token is upgraded\n   * @param asset The address of the underlying asset of the reserve\n   * @param proxy The variable debt token proxy address\n   * @param implementation The new aToken implementation\n   **/\n  event VariableDebtTokenUpgraded(\n    address indexed asset,\n    address indexed proxy,\n    address indexed implementation\n  );\n\n  /**\n   * @dev Initializes a reserve\n   * @param aTokenImpl  The address of the aToken contract implementation\n   * @param stableDebtTokenImpl The address of the stable debt token contract\n   * @param variableDebtTokenImpl The address of the variable debt token contract\n   * @param underlyingAssetDecimals The decimals of the reserve underlying asset\n   * @param interestRateStrategyAddress The address of the interest rate strategy contract for this reserve\n   **/\n  function initReserve(\n    address aTokenImpl,\n    address stableDebtTokenImpl,\n    address variableDebtTokenImpl,\n    uint8 underlyingAssetDecimals,\n    address interestRateStrategyAddress\n  ) external;\n\n  function batchInitReserve(ConfiguratorInputTypes.InitReserveInput[] calldata input) external;\n\n  /**\n   * @dev Updates the aToken implementation for the reserve\n   * @param asset The address of the underlying asset of the reserve to be updated\n   * @param implementation The address of the new aToken implementation\n   **/\n  function updateAToken(address asset, address implementation) external;\n\n  /**\n   * @dev Updates the stable debt token implementation for the reserve\n   * @param asset The address of the underlying asset of the reserve to be updated\n   * @param implementation The address of the new aToken implementation\n   **/\n  function updateStableDebtToken(address asset, address implementation) external;\n\n  /**\n   * @dev Updates the variable debt token implementation for the asset\n   * @param asset The address of the underlying asset of the reserve to be updated\n   * @param implementation The address of the new aToken implementation\n   **/\n  function updateVariableDebtToken(address asset, address implementation) external;\n\n  /**\n   * @dev Enables borrowing on a reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @param stableBorrowRateEnabled True if stable borrow rate needs to be enabled by default on this reserve\n   **/\n  function enableBorrowingOnReserve(address asset, bool stableBorrowRateEnabled) external;\n\n  /**\n   * @dev Disables borrowing on a reserve\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  function disableBorrowingOnReserve(address asset) external;\n\n  /**\n   * @dev Configures the reserve collateralization parameters\n   * all the values are expressed in percentages with two decimals of precision. A valid value is 10000, which means 100.00%\n   * @param asset The address of the underlying asset of the reserve\n   * @param ltv The loan to value of the asset when used as collateral\n   * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized\n   * @param liquidationBonus The bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105%\n   * means the liquidator will receive a 5% bonus\n   **/\n  function configureReserveAsCollateral(\n    address asset,\n    uint256 ltv,\n    uint256 liquidationThreshold,\n    uint256 liquidationBonus\n  ) external;\n\n  /**\n   * @dev Enable stable rate borrowing on a reserve\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  function enableReserveStableRate(address asset) external;\n\n  /**\n   * @dev Disable stable rate borrowing on a reserve\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  function disableReserveStableRate(address asset) external;\n\n  /**\n   * @dev Activates a reserve\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  function activateReserve(address asset) external;\n\n  /**\n   * @dev Deactivates a reserve\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  function deactivateReserve(address asset) external;\n\n  /**\n   * @dev Freezes a reserve. A frozen reserve doesn't allow any new deposit, borrow or rate swap\n   *  but allows repayments, liquidations, rate rebalances and withdrawals\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  function freezeReserve(address asset) external;\n\n  /**\n   * @dev Unfreezes a reserve\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  function unfreezeReserve(address asset) external;\n\n  /**\n   * @dev Updates the reserve factor of a reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @param reserveFactor The new reserve factor of the reserve\n   **/\n  function setReserveFactor(address asset, uint256 reserveFactor) external;\n\n  /**\n   * @dev Sets the interest rate strategy of a reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @param rateStrategyAddress The new address of the interest strategy contract\n   **/\n  function setReserveInterestRateStrategyAddress(\n    address asset,\n    address rateStrategyAddress\n  ) external;\n\n  /**\n   * @dev pauses or unpauses all the actions of the protocol, including aToken transfers\n   * @param val true if protocol needs to be paused, false otherwise\n   **/\n  function setPoolPause(bool val) external;\n}\n\ninterface IAaveOracle {\n  event WethSet(address indexed weth);\n  event AssetSourceUpdated(address indexed asset, address indexed source);\n  event FallbackOracleUpdated(address indexed fallbackOracle);\n\n  /// @notice Returns the WETH address (reference asset of the oracle)\n  function WETH() external returns (address);\n\n  /// @notice External function called by the Aave governance to set or replace sources of assets\n  /// @param assets The addresses of the assets\n  /// @param sources The address of the source of each asset\n  function setAssetSources(address[] calldata assets, address[] calldata sources) external;\n\n  /// @notice Sets the fallbackOracle\n  /// - Callable only by the Aave governance\n  /// @param fallbackOracle The address of the fallbackOracle\n  function setFallbackOracle(address fallbackOracle) external;\n\n  /// @notice Gets an asset price by address\n  /// @param asset The asset address\n  function getAssetPrice(address asset) external view returns (uint256);\n\n  /// @notice Gets a list of prices from a list of assets addresses\n  /// @param assets The list of assets addresses\n  function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory);\n\n  /// @notice Gets the address of the source for an asset address\n  /// @param asset The address of the asset\n  /// @return address The address of the source\n  function getSourceOfAsset(address asset) external view returns (address);\n\n  /// @notice Gets the address of the fallback oracle\n  /// @return address The address of the fallback oracle\n  function getFallbackOracle() external view returns (address);\n}\n\nstruct TokenData {\n  string symbol;\n  address tokenAddress;\n}\n\n// TODO: incomplete interface\ninterface IAaveProtocolDataProvider {\n  function getReserveConfigurationData(\n    address asset\n  )\n    external\n    view\n    returns (\n      uint256 decimals,\n      uint256 ltv,\n      uint256 liquidationThreshold,\n      uint256 liquidationBonus,\n      uint256 reserveFactor,\n      bool usageAsCollateralEnabled,\n      bool borrowingEnabled,\n      bool stableBorrowRateEnabled,\n      bool isActive,\n      bool isFrozen\n    );\n\n  function getAllReservesTokens() external view returns (TokenData[] memory);\n\n  function getReserveTokensAddresses(\n    address asset\n  )\n    external\n    view\n    returns (\n      address aTokenAddress,\n      address stableDebtTokenAddress,\n      address variableDebtTokenAddress\n    );\n\n  function getUserReserveData(\n    address asset,\n    address user\n  )\n    external\n    view\n    returns (\n      uint256 currentATokenBalance,\n      uint256 currentStableDebt,\n      uint256 currentVariableDebt,\n      uint256 principalStableDebt,\n      uint256 scaledVariableDebt,\n      uint256 stableBorrowRate,\n      uint256 liquidityRate,\n      uint40 stableRateLastUpdated,\n      bool usageAsCollateralEnabled\n    );\n}\n\ninterface ILendingRateOracle {\n  /**\n    @dev returns the market borrow rate in ray\n    **/\n  function getMarketBorrowRate(address asset) external view returns (uint256);\n\n  /**\n    @dev sets the market borrow rate. Rate value must be in ray\n    **/\n  function setMarketBorrowRate(address asset, uint256 rate) external;\n}\n\ninterface IDefaultInterestRateStrategy {\n  function EXCESS_UTILIZATION_RATE() external view returns (uint256);\n\n  function OPTIMAL_UTILIZATION_RATE() external view returns (uint256);\n\n  function addressesProvider() external view returns (address);\n\n  function baseVariableBorrowRate() external view returns (uint256);\n\n  function calculateInterestRates(\n    address reserve,\n    uint256 availableLiquidity,\n    uint256 totalStableDebt,\n    uint256 totalVariableDebt,\n    uint256 averageStableBorrowRate,\n    uint256 reserveFactor\n  ) external view returns (uint256, uint256, uint256);\n\n  function getMaxVariableBorrowRate() external view returns (uint256);\n\n  function stableRateSlope1() external view returns (uint256);\n\n  function stableRateSlope2() external view returns (uint256);\n\n  function variableRateSlope1() external view returns (uint256);\n\n  function variableRateSlope2() external view returns (uint256);\n}\n\ninterface IATokenV2 {\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 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 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(address user, uint256 amount, uint256 index) external returns (bool);\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(address user, address receiverOfUnderlying, uint256 amount, uint256 index) 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(address from, address to, uint256 value) 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 nonce of the given user.\n   * @param user The user to fetch the nonce for.\n   */\n  function _nonces(address user) external view returns (uint256);\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\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) external view returns (uint256, uint256, uint256);\n\n  /*\n   * LEGACY **************************\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 assets(address asset) external view returns (uint128, uint128, uint256);\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(\n    address[] calldata assets,\n    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(address asset, uint256 userBalance, uint256 totalSupply) 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(\n    address[] calldata assets,\n    address user\n  ) external view 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  /**\n   * @dev Gets the distribution end timestamp of the emissions\n   */\n  function DISTRIBUTION_END() external view returns (uint256);\n}\n"
      },
      "lib/aave-helpers/lib/aave-address-book/src/common/ICollector.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0;\n\n/**\n * @title ICollector\n * @notice Defines the interface of the Collector contract\n * @author Aave\n **/\ninterface ICollector {\n  struct Stream {\n    uint256 deposit;\n    uint256 ratePerSecond;\n    uint256 remainingBalance;\n    uint256 startTime;\n    uint256 stopTime;\n    address recipient;\n    address sender;\n    address tokenAddress;\n    bool isEntity;\n  }\n\n  /** @notice Emitted when the funds admin changes\n   * @param fundsAdmin The new funds admin.\n   **/\n  event NewFundsAdmin(address indexed fundsAdmin);\n\n  /** @notice Emitted when the new stream is created\n   * @param streamId The identifier of the stream.\n   * @param sender The address of the collector.\n   * @param recipient The address towards which the money is streamed.\n   * @param deposit The amount of money to be streamed.\n   * @param tokenAddress The ERC20 token to use as streaming currency.\n   * @param startTime The unix timestamp for when the stream starts.\n   * @param stopTime The unix timestamp for when the stream stops.\n   **/\n  event CreateStream(\n    uint256 indexed streamId,\n    address indexed sender,\n    address indexed recipient,\n    uint256 deposit,\n    address tokenAddress,\n    uint256 startTime,\n    uint256 stopTime\n  );\n\n  /**\n   * @notice Emmitted when withdraw happens from the contract to the recipient's account.\n   * @param streamId The id of the stream to withdraw tokens from.\n   * @param recipient The address towards which the money is streamed.\n   * @param amount The amount of tokens to withdraw.\n   */\n  event WithdrawFromStream(uint256 indexed streamId, address indexed recipient, uint256 amount);\n\n  /**\n   * @notice Emmitted when the stream is canceled.\n   * @param streamId The id of the stream to withdraw tokens from.\n   * @param sender The address of the collector.\n   * @param recipient The address towards which the money is streamed.\n   * @param senderBalance The sender's balance at the moment of cancelling.\n   * @param recipientBalance The recipient's balance at the moment of cancelling.\n   */\n  event CancelStream(\n    uint256 indexed streamId,\n    address indexed sender,\n    address indexed recipient,\n    uint256 senderBalance,\n    uint256 recipientBalance\n  );\n\n  /** @notice Returns the mock ETH reference address\n   * @return address The address\n   **/\n  function ETH_MOCK_ADDRESS() external pure returns (address);\n\n  /** @notice Initializes the contracts\n   * @param fundsAdmin Funds admin address\n   * @param nextStreamId StreamId to set, applied if greater than 0\n   **/\n  function initialize(address fundsAdmin, uint256 nextStreamId) external;\n\n  /**\n   * @notice Return the funds admin, only entity to be able to interact with this contract (controller of reserve)\n   * @return address The address of the funds admin\n   **/\n  function getFundsAdmin() external view returns (address);\n\n  /**\n   * @notice Returns the available funds for the given stream id and address.\n   * @param streamId The id of the stream for which to query the balance.\n   * @param who The address for which to query the balance.\n   * @notice Returns the total funds allocated to `who` as uint256.\n   */\n  function balanceOf(uint256 streamId, address who) external view returns (uint256 balance);\n\n  /**\n   * @dev Function for the funds admin to give ERC20 allowance to other parties\n   * @param token The address of the token to give allowance from\n   * @param recipient Allowance's recipient\n   * @param amount Allowance to approve\n   **/\n  function approve(\n    //IERC20 token,\n    address token,\n    address recipient,\n    uint256 amount\n  ) external;\n\n  /**\n   * @notice Function for the funds admin to transfer ERC20 tokens to other parties\n   * @param token The address of the token to transfer\n   * @param recipient Transfer's recipient\n   * @param amount Amount to transfer\n   **/\n  function transfer(\n    //IERC20 token,\n    address token,\n    address recipient,\n    uint256 amount\n  ) external;\n\n  /**\n   * @dev Transfer the ownership of the funds administrator role.\n          This function should only be callable by the current funds administrator.\n   * @param admin The address of the new funds administrator\n   */\n  function setFundsAdmin(address admin) external;\n\n  /**\n   * @notice Creates a new stream funded by this contracts itself and paid towards `recipient`.\n   * @param recipient The address towards which the money is streamed.\n   * @param deposit The amount of money to be streamed.\n   * @param tokenAddress The ERC20 token to use as streaming currency.\n   * @param startTime The unix timestamp for when the stream starts.\n   * @param stopTime The unix timestamp for when the stream stops.\n   * @return streamId the uint256 id of the newly created stream.\n   */\n  function createStream(\n    address recipient,\n    uint256 deposit,\n    address tokenAddress,\n    uint256 startTime,\n    uint256 stopTime\n  ) external returns (uint256 streamId);\n\n  /**\n   * @notice Returns the stream with all its properties.\n   * @dev Throws if the id does not point to a valid stream.\n   * @param streamId The id of the stream to query.\n   * @notice Returns the stream object.\n   */\n  function getStream(\n    uint256 streamId\n  )\n    external\n    view\n    returns (\n      address sender,\n      address recipient,\n      uint256 deposit,\n      address tokenAddress,\n      uint256 startTime,\n      uint256 stopTime,\n      uint256 remainingBalance,\n      uint256 ratePerSecond\n    );\n\n  /**\n   * @notice Withdraws from the contract to the recipient's account.\n   * @param streamId The id of the stream to withdraw tokens from.\n   * @param amount The amount of tokens to withdraw.\n   * @return bool Returns true if successful.\n   */\n  function withdrawFromStream(uint256 streamId, uint256 amount) external returns (bool);\n\n  /**\n   * @notice Cancels the stream and transfers the tokens back on a pro rata basis.\n   * @param streamId The id of the stream to cancel.\n   * @return bool Returns true if successful.\n   */\n  function cancelStream(uint256 streamId) external returns (bool);\n\n  /**\n   * @notice Returns the next available stream id\n   * @return nextStreamId Returns the stream id.\n   */\n  function getNextStreamId() external view returns (uint256);\n}\n"
      },
      "lib/aave-helpers/lib/aave-address-book/src/common/AggregatorInterface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0;\n\ninterface AggregatorInterface {\n  function latestAnswer() external view returns (int256);\n\n  function latestTimestamp() external view returns (uint256);\n\n  function latestRound() external view returns (uint256);\n\n  function getAnswer(uint256 roundId) external view returns (int256);\n\n  function getTimestamp(uint256 roundId) external view returns (uint256);\n\n  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);\n\n  event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@aave/core-v3/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-core/",
        "@aave/periphery-v3/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-periphery/",
        "aave-address-book/=lib/aave-helpers/lib/aave-address-book/src/",
        "aave-helpers/=lib/aave-helpers/src/",
        "aave-v3-core/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-core/",
        "aave-v3-periphery/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-periphery/",
        "ds-test/=lib/aave-helpers/lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/aave-helpers/lib/forge-std/src/",
        "solidity-utils/=lib/aave-helpers/lib/solidity-utils/src/",
        "governance-crosschain-bridges/=lib/aave-helpers/lib/governance-crosschain-bridges/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}