{"sources":{"lib/aave-umbrella/src/contracts/rewards/RewardsController.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.27;\n\nimport {Initializable} from 'openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol';\nimport {AccessControlUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol';\n\nimport {IERC4626} from 'openzeppelin-contracts/contracts/interfaces/IERC4626.sol';\nimport {IERC20Metadata} from 'openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol';\n\nimport {SafeCast} from 'openzeppelin-contracts/contracts/utils/math/SafeCast.sol';\nimport {SafeERC20} from 'openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol';\n\nimport {IRescuableBase} from 'solidity-utils/contracts/utils/interfaces/IRescuableBase.sol';\nimport {IRescuable} from 'solidity-utils/contracts/utils/interfaces/IRescuable.sol';\nimport {RescuableBase} from 'solidity-utils/contracts/utils/RescuableBase.sol';\nimport {RescuableACL} from 'solidity-utils/contracts/utils/RescuableACL.sol';\n\nimport {IRewardsDistributor} from './interfaces/IRewardsDistributor.sol';\nimport {IRewardsController} from './interfaces/IRewardsController.sol';\n\nimport {InternalStructs} from './libraries/InternalStructs.sol';\nimport {EmissionMath} from './libraries/EmissionMath.sol';\n\nimport {RewardsDistributor} from './RewardsDistributor.sol';\n\n/**\n * @title RewardsController\n * @notice RewardsController is a contract that is intended for configuring assets,\n * the corresponding rewards for them, as well as updating data related to the distribution of rewards.\n * Calculation of rewards emission will be carried out by the `EmissionMath` library.\n * @author BGD labs\n */\ncontract RewardsController is\n  Initializable,\n  RewardsDistributor,\n  AccessControlUpgradeable,\n  RescuableACL,\n  IRewardsController\n{\n  using SafeERC20 for IERC20Metadata;\n  using SafeCast for uint256;\n  using EmissionMath for *;\n\n  /// @custom:storage-location erc7201:umbrella.storage.RewardsController\n  struct RewardsControllerStorage {\n    /// @notice Map of asset addresses and their data\n    mapping(address asset => InternalStructs.AssetData) assetsData;\n    // Array of all initialized assets\n    address[] assets;\n  }\n\n  // keccak256(abi.encode(uint256(keccak256(\"umbrella.storage.RewardsController\")) - 1)) & ~bytes32(uint256(0xff))\n  bytes32 private constant RewardsControllerStorageLocation =\n    0x7a5f91582c97dd0b2921808fbdbab73d3de091aefc8bf8607868e058abb2e300;\n\n  function _getRewardsControllerStorage()\n    private\n    pure\n    returns (RewardsControllerStorage storage $)\n  {\n    assembly {\n      $.slot := RewardsControllerStorageLocation\n    }\n  }\n\n  uint256 public constant MAX_REWARDS_LENGTH = 8;\n\n  bytes32 public constant REWARDS_ADMIN_ROLE = keccak256('REWARDS_ADMIN_ROLE');\n\n  constructor() {\n    _disableInitializers();\n  }\n\n  function initialize(address governance) external initializer {\n    require(governance != address(0), ZeroAddress());\n\n    __AccessControl_init();\n    __RewardsDistributor_init();\n\n    _grantRole(DEFAULT_ADMIN_ROLE, governance);\n    _grantRole(REWARDS_ADMIN_ROLE, governance);\n  }\n\n  /// @inheritdoc IRewardsController\n  function configureAssetWithRewards(\n    address asset,\n    uint256 targetLiquidity,\n    RewardSetupConfig[] calldata newRewardConfigs\n  ) external onlyRole(DEFAULT_ADMIN_ROLE) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n\n    _configureAsset(assetData, asset, targetLiquidity);\n\n    for (uint256 i; i < newRewardConfigs.length; ++i) {\n      _setUpReward(assetData, newRewardConfigs[i], asset);\n    }\n\n    // Due to the fact that we have a dependency between `maxEmissionPerSecond` and `targetLiquidity`,\n    // we need to validate that rewards with unchanged `maxEmissionPerSecond` meet our requirements by changing `targetLiquidity`\n    _validateOtherRewardEmissions(assetData, targetLiquidity);\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function setClaimer(\n    address user,\n    address claimer,\n    bool flag\n  ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n    require(user != address(0), ZeroAddress());\n\n    _setClaimer(user, claimer, flag);\n  }\n\n  /// @inheritdoc IRewardsController\n  function configureRewards(\n    address asset,\n    RewardSetupConfig[] calldata newRewardConfigs\n  ) external onlyRole(REWARDS_ADMIN_ROLE) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n\n    _updateData(\n      assetData,\n      _getExtraParamsForIndex(assetData.targetLiquidity, asset),\n      asset,\n      address(0),\n      0\n    );\n\n    for (uint256 i; i < newRewardConfigs.length; ++i) {\n      require(\n        _isRewardInitialized(assetData.data[newRewardConfigs[i].reward].rewardData),\n        RewardNotInitialized(newRewardConfigs[i].reward)\n      );\n\n      _configureReward(assetData, newRewardConfigs[i], asset);\n    }\n  }\n\n  /// @inheritdoc IRewardsController\n  function handleAction(\n    uint256 totalSupply,\n    uint256 totalAssets,\n    address user,\n    uint256 userBalance\n  ) external {\n    address asset = _msgSender();\n\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n    _updateData(\n      assetData,\n      InternalStructs.ExtraParamsForIndex({\n        targetLiquidity: assetData.targetLiquidity,\n        totalAssets: totalAssets,\n        totalSupply: totalSupply\n      }),\n      asset,\n      user,\n      userBalance\n    );\n  }\n\n  /// @inheritdoc IRewardsController\n  function updateAsset(address asset) external {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n    InternalStructs.ExtraParamsForIndex memory extraParams = _getExtraParamsForIndex(\n      assetData.targetLiquidity,\n      asset\n    );\n\n    if (extraParams.totalSupply != 0) {\n      _updateData(assetData, extraParams, asset, address(0), 0);\n    }\n  }\n\n  /// @inheritdoc IRewardsController\n  function getAllAssets() external view returns (address[] memory) {\n    RewardsControllerStorage storage $ = _getRewardsControllerStorage();\n    address[] memory assets = new address[]($.assets.length);\n\n    for (uint256 i; i < assets.length; ++i) {\n      assets[i] = $.assets[i];\n    }\n\n    return assets;\n  }\n\n  /// @inheritdoc IRewardsController\n  function getAssetAndRewardsData(\n    address asset\n  ) external view returns (AssetDataExternal memory, RewardDataExternal[] memory) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n\n    AssetDataExternal memory assetDataExternal = getAssetData(asset);\n    RewardDataExternal[] memory rewardsDataExternal = new RewardDataExternal[](\n      assetData.rewardsInfo.length\n    );\n\n    for (uint256 i; i < rewardsDataExternal.length; ++i) {\n      rewardsDataExternal[i] = getRewardData(asset, assetData.rewardsInfo[i].addr);\n    }\n\n    return (assetDataExternal, rewardsDataExternal);\n  }\n\n  /// @inheritdoc IRewardsController\n  function getEmissionData(\n    address asset,\n    address reward\n  ) external view returns (EmissionData memory) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n    InternalStructs.RewardData memory rewardData = assetData.data[reward].rewardData;\n    uint256 maxEmissionPerSecond = block.timestamp < rewardData.distributionEnd\n      ? rewardData.maxEmissionPerSecondScaled.scaleDown(rewardData.decimalsScaling)\n      : 0;\n\n    return EmissionMath.calculateEmissionParams(maxEmissionPerSecond, assetData.targetLiquidity);\n  }\n\n  /// @inheritdoc IRewardsController\n  function calculateCurrentEmissionScaled(\n    address asset,\n    address reward\n  ) external view returns (uint256) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n    InternalStructs.RewardData memory rewardData = assetData.data[reward].rewardData;\n\n    if (block.timestamp > rewardData.distributionEnd) {\n      return 0;\n    }\n\n    return\n      EmissionMath.getEmissionPerSecondScaled(\n        rewardData.maxEmissionPerSecondScaled,\n        assetData.targetLiquidity,\n        IERC4626(asset).totalAssets()\n      ) / EmissionMath.SCALING_FACTOR;\n  }\n\n  /// @inheritdoc IRewardsController\n  function calculateCurrentEmission(address asset, address reward) external view returns (uint256) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n    InternalStructs.RewardData memory rewardData = assetData.data[reward].rewardData;\n\n    if (block.timestamp > rewardData.distributionEnd) {\n      return 0;\n    }\n\n    return\n      EmissionMath.getEmissionPerSecondScaled(\n        rewardData.maxEmissionPerSecondScaled,\n        assetData.targetLiquidity,\n        IERC4626(asset).totalAssets()\n      ) / (EmissionMath.SCALING_FACTOR.scaleUp(rewardData.decimalsScaling));\n  }\n\n  /// @inheritdoc IRewardsController\n  function calculateRewardIndexes(\n    address asset\n  ) external view returns (address[] memory, uint256[] memory) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n\n    address[] memory rewards = new address[](assetData.rewardsInfo.length);\n    uint256[] memory rewardsIndexes = new uint256[](rewards.length);\n\n    for (uint256 i; i < rewards.length; ++i) {\n      rewards[i] = assetData.rewardsInfo[i].addr;\n      rewardsIndexes[i] = calculateRewardIndex(asset, rewards[i]);\n    }\n\n    return (rewards, rewardsIndexes);\n  }\n\n  /// @inheritdoc IRewardsController\n  function getUserDataByAsset(\n    address asset,\n    address user\n  ) external view returns (address[] memory, UserDataExternal[] memory) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n\n    address[] memory rewards = new address[](assetData.rewardsInfo.length);\n    UserDataExternal[] memory userData = new UserDataExternal[](rewards.length);\n    InternalStructs.UserData memory userDataCache;\n\n    for (uint256 i; i < rewards.length; ++i) {\n      rewards[i] = assetData.rewardsInfo[i].addr;\n\n      InternalStructs.RewardAndUserData storage rewardAndUserData = assetData.data[rewards[i]];\n      userDataCache = rewardAndUserData.userData[user];\n\n      userData[i] = UserDataExternal({\n        index: userDataCache.index,\n        accrued: userDataCache.accrued.scaleDown(rewardAndUserData.rewardData.decimalsScaling)\n      });\n    }\n\n    return (rewards, userData);\n  }\n\n  /// @inheritdoc IRewardsController\n  function getUserDataByReward(\n    address asset,\n    address reward,\n    address user\n  ) external view returns (UserDataExternal memory) {\n    InternalStructs.RewardAndUserData storage data = _getRewardsControllerStorage()\n      .assetsData[asset]\n      .data[reward];\n    InternalStructs.UserData memory userDataCache = data.userData[user];\n\n    return\n      UserDataExternal({\n        index: userDataCache.index,\n        accrued: userDataCache.accrued.scaleDown(data.rewardData.decimalsScaling)\n      });\n  }\n\n  /// @inheritdoc IRewardsController\n  function calculateCurrentUserRewards(\n    address asset,\n    address user\n  ) external view returns (address[] memory, uint256[] memory) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n\n    address[] memory rewards = new address[](assetData.rewardsInfo.length);\n    uint256[] memory accruedAmounts = new uint256[](rewards.length);\n\n    for (uint256 i; i < rewards.length; ++i) {\n      rewards[i] = assetData.rewardsInfo[i].addr;\n      accruedAmounts[i] = calculateCurrentUserReward(asset, rewards[i], user);\n    }\n\n    return (rewards, accruedAmounts);\n  }\n\n  /// @inheritdoc IRewardsController\n  function getAllRewards(\n    address asset\n  ) public view override(IRewardsController, RewardsDistributor) returns (address[] memory) {\n    InternalStructs.RewardAddrAndDistrEnd[] storage rewardsInfo = _getRewardsControllerStorage()\n      .assetsData[asset]\n      .rewardsInfo;\n\n    address[] memory rewards = new address[](rewardsInfo.length);\n\n    for (uint256 i; i < rewards.length; ++i) {\n      rewards[i] = rewardsInfo[i].addr;\n    }\n\n    return rewards;\n  }\n\n  /// @inheritdoc IRewardsController\n  function getAssetData(address asset) public view returns (AssetDataExternal memory) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n\n    return\n      AssetDataExternal({\n        targetLiquidity: assetData.targetLiquidity,\n        lastUpdateTimestamp: assetData.lastUpdateTimestamp\n      });\n  }\n\n  /// @inheritdoc IRewardsController\n  function getRewardData(\n    address asset,\n    address reward\n  ) public view returns (RewardDataExternal memory) {\n    InternalStructs.RewardData memory rewardData = _getRewardsControllerStorage()\n      .assetsData[asset]\n      .data[reward]\n      .rewardData;\n    uint256 maxEmissionPerSecond = block.timestamp < rewardData.distributionEnd\n      ? rewardData.maxEmissionPerSecondScaled.scaleDown(rewardData.decimalsScaling)\n      : 0;\n\n    return\n      RewardDataExternal({\n        addr: reward,\n        index: rewardData.index,\n        maxEmissionPerSecond: maxEmissionPerSecond,\n        distributionEnd: rewardData.distributionEnd\n      });\n  }\n\n  /// @inheritdoc IRewardsController\n  function calculateRewardIndex(address asset, address reward) public view returns (uint256) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n\n    InternalStructs.RewardData memory rewardData = assetData.data[reward].rewardData;\n    uint32 lastUpdateTimestamp = assetData.lastUpdateTimestamp;\n\n    if (lastUpdateTimestamp >= rewardData.distributionEnd) {\n      return rewardData.index;\n    }\n\n    return\n      rewardData.index +\n      EmissionMath.calculateIndexIncrease(\n        _getExtraParamsForIndex(assetData.targetLiquidity, asset),\n        rewardData.maxEmissionPerSecondScaled,\n        rewardData.distributionEnd,\n        lastUpdateTimestamp\n      );\n  }\n\n  /// @inheritdoc IRewardsController\n  function calculateCurrentUserReward(\n    address asset,\n    address reward,\n    address user\n  ) public view returns (uint256) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n    InternalStructs.RewardAndUserData storage rewardAndUserData = assetData.data[reward];\n\n    InternalStructs.RewardData memory rewardData = rewardAndUserData.rewardData;\n    InternalStructs.UserData memory userData = rewardAndUserData.userData[user];\n\n    uint32 lastUpdateTimestamp = assetData.lastUpdateTimestamp;\n    uint256 userBalance = IERC4626(asset).balanceOf(user);\n\n    if (lastUpdateTimestamp < rewardData.distributionEnd) {\n      rewardData.index += EmissionMath.calculateIndexIncrease(\n        _getExtraParamsForIndex(assetData.targetLiquidity, asset),\n        rewardData.maxEmissionPerSecondScaled,\n        rewardData.distributionEnd,\n        lastUpdateTimestamp\n      );\n    }\n\n    return\n      (userData.accrued +\n        EmissionMath.calculateAccrued(rewardData.index, userData.index, userBalance)).scaleDown(\n          rewardData.decimalsScaling\n        );\n  }\n\n  function maxRescue(\n    address\n  ) public pure override(IRescuableBase, RescuableBase) returns (uint256) {\n    return type(uint256).max;\n  }\n\n  function _configureAsset(\n    InternalStructs.AssetData storage assetData,\n    address asset,\n    uint256 targetLiquidity\n  ) internal {\n    if (_isAssetInitialized(assetData)) {\n      // We need to update data, cause asset was previously initialized and `targetLiquidity` may change during this tx,\n      // so we need to recalculate all existing reward indexes\n      _updateData(\n        assetData,\n        _getExtraParamsForIndex(assetData.targetLiquidity, asset),\n        asset,\n        address(0),\n        0\n      );\n    } else {\n      // otherwise we need to initialize asset\n      _getRewardsControllerStorage().assets.push(asset);\n\n      emit AssetInitialized(asset);\n\n      _updateTimestamp(assetData, asset);\n    }\n\n    _updateTarget(assetData, asset, targetLiquidity);\n  }\n\n  function _setUpReward(\n    InternalStructs.AssetData storage assetData,\n    RewardSetupConfig memory newConfig,\n    address asset\n  ) internal {\n    require(newConfig.reward != address(0), ZeroAddress());\n\n    if (_isRewardInitialized(assetData.data[newConfig.reward].rewardData)) {\n      _configureReward(assetData, newConfig, asset);\n    } else {\n      _initializeReward(assetData, newConfig, asset);\n    }\n  }\n\n  function _initializeReward(\n    InternalStructs.AssetData storage assetData,\n    RewardSetupConfig memory newConfig,\n    address asset\n  ) internal {\n    require(assetData.rewardsInfo.length < MAX_REWARDS_LENGTH, MaxRewardsLengthReached());\n\n    uint8 decimalsScaling = EmissionMath.MAX_DECIMALS - IERC20Metadata(newConfig.reward).decimals();\n    uint256 maxEmissionPerSecondScaled = newConfig.maxEmissionPerSecond.scaleUp(decimalsScaling);\n\n    EmissionMath.validateMaxEmission(maxEmissionPerSecondScaled, assetData.targetLiquidity);\n\n    // We can't initialize reward with disabled distribution.\n    require(newConfig.distributionEnd > block.timestamp, InvalidDistributionEnd());\n\n    assetData.rewardsInfo.push(\n      InternalStructs.RewardAddrAndDistrEnd(newConfig.reward, newConfig.distributionEnd.toUint32())\n    );\n\n    // `decimalsScaling` set only once during initialization\n    InternalStructs.RewardAndUserData storage rewardAndUserData = assetData.data[newConfig.reward];\n    rewardAndUserData.rewardData.decimalsScaling = decimalsScaling;\n\n    emit RewardInitialized(asset, newConfig.reward);\n\n    _updateRewardConfig(rewardAndUserData, newConfig, asset);\n  }\n\n  function _configureReward(\n    InternalStructs.AssetData storage assetData,\n    RewardSetupConfig memory newConfig,\n    address asset\n  ) internal {\n    InternalStructs.RewardAndUserData storage rewardAndUserData = assetData.data[newConfig.reward];\n    InternalStructs.RewardData memory rewardData = rewardAndUserData.rewardData;\n    uint256 maxEmissionPerSecondScaled;\n\n    if (newConfig.distributionEnd <= block.timestamp || newConfig.maxEmissionPerSecond == 0) {\n      // if reward should be disabled, then we need to set `maxEmissionPerSecond` to zero and `distributionEnd` to block.timestamp\n      newConfig.distributionEnd = block.timestamp;\n      newConfig.maxEmissionPerSecond = 0;\n    } else {\n      // otherwise we need to validate `maxEmissionPerSecond` parameter\n      maxEmissionPerSecondScaled = newConfig.maxEmissionPerSecond.scaleUp(\n        rewardData.decimalsScaling\n      );\n      EmissionMath.validateMaxEmission(maxEmissionPerSecondScaled, assetData.targetLiquidity);\n    }\n\n    if (rewardData.distributionEnd != newConfig.distributionEnd) {\n      _updateDistributionEndInRewardsInfo(assetData, newConfig.reward, newConfig.distributionEnd);\n    }\n\n    _updateRewardConfig(rewardAndUserData, newConfig, asset);\n  }\n\n  function _updateTarget(\n    InternalStructs.AssetData storage assetData,\n    address asset,\n    uint256 newTargetLiquidity\n  ) internal {\n    EmissionMath.validateTargetLiquidity(newTargetLiquidity, IERC20Metadata(asset).decimals());\n\n    assetData.targetLiquidity = newTargetLiquidity.toUint160();\n\n    emit TargetLiquidityUpdated(asset, newTargetLiquidity);\n  }\n\n  function _updateTimestamp(InternalStructs.AssetData storage assetData, address asset) internal {\n    assetData.lastUpdateTimestamp = (block.timestamp).toUint32();\n\n    emit LastTimestampUpdated(asset, block.timestamp);\n  }\n\n  function _updateRewardConfig(\n    InternalStructs.RewardAndUserData storage rewardAndUserData,\n    RewardSetupConfig memory newConfig,\n    address asset\n  ) internal {\n    require(newConfig.rewardPayer != address(0), ZeroAddress());\n\n    InternalStructs.RewardData memory rewardData = rewardAndUserData.rewardData;\n\n    // if `newConfig.maxEmissionPerSecond == 0`, then zero will be set\n    // otherwise already validated value will be set\n    rewardData.maxEmissionPerSecondScaled = (\n      newConfig.maxEmissionPerSecond.scaleUp(rewardData.decimalsScaling)\n    ).toUint72();\n\n    // `distributionEnd >= block.timestamp` already validated before\n    rewardData.distributionEnd = newConfig.distributionEnd.toUint32();\n\n    // `index` and `decimalsScaling` shouldn't change during this action\n    rewardAndUserData.rewardData = rewardData;\n    rewardAndUserData.rewardPayer = newConfig.rewardPayer;\n\n    emit RewardConfigUpdated(\n      asset,\n      newConfig.reward,\n      newConfig.maxEmissionPerSecond,\n      newConfig.distributionEnd,\n      newConfig.rewardPayer\n    );\n  }\n\n  function _updateDistributionEndInRewardsInfo(\n    InternalStructs.AssetData storage assetData,\n    address reward,\n    uint256 distributionEnd\n  ) internal {\n    uint256 rewardsLength = assetData.rewardsInfo.length;\n\n    for (uint256 i; i < rewardsLength; ++i) {\n      if (assetData.rewardsInfo[i].addr == reward) {\n        assetData.rewardsInfo[i].distributionEnd = distributionEnd.toUint32();\n\n        break;\n      }\n    }\n  }\n\n  function _updateData(\n    InternalStructs.AssetData storage assetData,\n    InternalStructs.ExtraParamsForIndex memory extraParamsForIndexScaled,\n    address asset,\n    address user,\n    uint256 userBalance\n  ) internal {\n    // instead of `isAssetInitialized(assetData)` we can place here this check, cause `extraParamsForIndexScaled.targetLiquidity` is get from `assetData.targetLiquidity`\n    require(extraParamsForIndexScaled.targetLiquidity != 0, AssetNotInitialized(asset));\n\n    uint32 lastUpdateTimestamp = assetData.lastUpdateTimestamp;\n    uint256 rewardsLength = assetData.rewardsInfo.length;\n\n    // we will cache pointer to `RewardAndUserData` struct in storage and reuse it inside `updateRewardIndex` and `updateUserData` functions\n    // because recalculating the `_getRewardsControllerStorage().assetsData[asset].data[reward]` for pointer requires ~200 gas every time\n    InternalStructs.RewardAndUserData storage rewardAndUserData;\n    InternalStructs.RewardAddrAndDistrEnd memory rewardInfo;\n\n    for (uint256 i; i < rewardsLength; ++i) {\n      rewardInfo = assetData.rewardsInfo[i];\n      rewardAndUserData = assetData.data[rewardInfo.addr];\n\n      if (lastUpdateTimestamp < rewardInfo.distributionEnd) {\n        _updateRewardIndex(\n          rewardAndUserData,\n          extraParamsForIndexScaled,\n          asset,\n          rewardInfo.addr,\n          lastUpdateTimestamp\n        );\n      }\n\n      if (user != address(0)) {\n        _updateUserData(rewardAndUserData, asset, rewardInfo.addr, user, userBalance);\n      }\n    }\n\n    _updateTimestamp(assetData, asset);\n  }\n\n  function _updateRewardIndex(\n    InternalStructs.RewardAndUserData storage rewardAndUserData,\n    InternalStructs.ExtraParamsForIndex memory extraParamsForIndexScaled,\n    address asset,\n    address reward,\n    uint256 lastUpdateTimestamp\n  ) internal {\n    if (lastUpdateTimestamp == block.timestamp) {\n      return;\n    }\n\n    InternalStructs.RewardData memory rewardData = rewardAndUserData.rewardData;\n\n    rewardData.index += EmissionMath.calculateIndexIncrease(\n      extraParamsForIndexScaled,\n      rewardData.maxEmissionPerSecondScaled,\n      rewardData.distributionEnd,\n      lastUpdateTimestamp\n    );\n\n    if (block.timestamp >= rewardData.distributionEnd) {\n      rewardData.maxEmissionPerSecondScaled = 0;\n    }\n\n    // `index` should be updated\n    // `maxEmissionPerSecond` could be updated\n    // `distributionEnd` and `decimalsScaling` should not be updated\n    rewardAndUserData.rewardData = rewardData;\n\n    emit RewardIndexUpdated(asset, reward, rewardData.index);\n  }\n\n  function _updateUserData(\n    InternalStructs.RewardAndUserData storage rewardAndUserData,\n    address asset,\n    address reward,\n    address user,\n    uint256 userBalance\n  ) internal {\n    InternalStructs.UserData memory userData = rewardAndUserData.userData[user];\n    InternalStructs.RewardData memory rewardData = rewardAndUserData.rewardData;\n\n    if (userData.index == rewardData.index) {\n      return;\n    }\n\n    uint112 newAccruedAmount = EmissionMath.calculateAccrued(\n      rewardData.index,\n      userData.index,\n      userBalance\n    );\n\n    userData.accrued += newAccruedAmount;\n    userData.index = rewardData.index;\n\n    rewardAndUserData.userData[user] = userData;\n\n    emit UserDataUpdated(\n      asset,\n      reward,\n      user,\n      userData.index,\n      newAccruedAmount.scaleDown(rewardData.decimalsScaling)\n    );\n  }\n\n  function _claimSelectedRewards(\n    address asset,\n    address[] memory rewards,\n    address user,\n    address receiver\n  ) internal override returns (uint256[] memory) {\n    InternalStructs.AssetData storage assetData = _getRewardsControllerStorage().assetsData[asset];\n    uint256[] memory accruedAmounts = new uint256[](rewards.length);\n\n    _updateData(\n      assetData,\n      _getExtraParamsForIndex(assetData.targetLiquidity, asset),\n      asset,\n      user,\n      IERC4626(asset).balanceOf(user)\n    );\n\n    for (uint256 i; i < rewards.length; ++i) {\n      InternalStructs.RewardAndUserData storage rewardAndUserData = assetData.data[rewards[i]];\n      InternalStructs.UserData memory userData = rewardAndUserData.userData[user];\n\n      uint8 decimalsScaling = rewardAndUserData.rewardData.decimalsScaling;\n      accruedAmounts[i] = userData.accrued.scaleDown(decimalsScaling);\n\n      if (accruedAmounts[i] == 0) {\n        continue;\n      }\n\n      // virtual dust could remain here\n      rewardAndUserData.userData[user].accrued -= (accruedAmounts[i].scaleUp(decimalsScaling))\n        .toUint112();\n\n      IERC20Metadata(rewards[i]).safeTransferFrom(\n        rewardAndUserData.rewardPayer,\n        receiver,\n        accruedAmounts[i]\n      );\n\n      emit RewardClaimed(asset, rewards[i], user, receiver, accruedAmounts[i]);\n    }\n\n    return accruedAmounts;\n  }\n\n  function _validateOtherRewardEmissions(\n    InternalStructs.AssetData storage assetData,\n    uint256 targetLiquidity\n  ) internal view {\n    uint256 rewardsLength = assetData.rewardsInfo.length;\n\n    // We will check every reward again, cause gas savings for skipping already validated rewards isn't worth the additional complexity of code\n    for (uint256 i; i < rewardsLength; ++i) {\n      address reward = assetData.rewardsInfo[i].addr;\n\n      // zero means that emission has been disabled\n      if (assetData.data[reward].rewardData.maxEmissionPerSecondScaled != 0) {\n        EmissionMath.validateMaxEmission(\n          assetData.data[reward].rewardData.maxEmissionPerSecondScaled,\n          targetLiquidity\n        );\n      }\n    }\n  }\n\n  function _getExtraParamsForIndex(\n    uint256 targetLiquidity,\n    address asset\n  ) internal view returns (InternalStructs.ExtraParamsForIndex memory) {\n    return\n      InternalStructs.ExtraParamsForIndex({\n        targetLiquidity: targetLiquidity,\n        totalAssets: IERC4626(asset).totalAssets(),\n        totalSupply: IERC4626(asset).totalSupply()\n      });\n  }\n\n  function _isAssetInitialized(\n    InternalStructs.AssetData storage assetData\n  ) internal view returns (bool) {\n    return assetData.targetLiquidity != 0;\n  }\n\n  function _isRewardInitialized(\n    InternalStructs.RewardData storage rewardData\n  ) internal view returns (bool) {\n    return rewardData.distributionEnd != 0;\n  }\n\n  function _checkRescueGuardian() internal view override {\n    require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), IRescuable.OnlyRescueGuardian());\n  }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"@openzeppelin/contracts/access/IAccessControl.sol\";\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"../utils/introspection/ERC165Upgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {\n    struct RoleData {\n        mapping(address account => bool) hasRole;\n        bytes32 adminRole;\n    }\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.AccessControl\n    struct AccessControlStorage {\n        mapping(bytes32 role => RoleData) _roles;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.AccessControl\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;\n\n    function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {\n        assembly {\n            $.slot := AccessControlStorageLocation\n        }\n    }\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with an {AccessControlUnauthorizedAccount} error including the required role.\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    function __AccessControl_init() internal onlyInitializing {\n    }\n\n    function __AccessControl_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        return $._roles[role].hasRole[account];\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n     * is missing `role`.\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert AccessControlUnauthorizedAccount(account, role);\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        return $._roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n        if (callerConfirmation != _msgSender()) {\n            revert AccessControlBadConfirmation();\n        }\n\n        _revokeRole(role, callerConfirmation);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        $._roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        if (!hasRole(role, account)) {\n            $._roles[role].hasRole[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        if (hasRole(role, account)) {\n            $._roles[role].hasRole[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC4626.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\nimport {IERC20Metadata} from \"../token/ERC20/extensions/IERC20Metadata.sol\";\n\n/**\n * @dev Interface of the ERC-4626 \"Tokenized Vault Standard\", as defined in\n * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].\n */\ninterface IERC4626 is IERC20, IERC20Metadata {\n    event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);\n\n    event Withdraw(\n        address indexed sender,\n        address indexed receiver,\n        address indexed owner,\n        uint256 assets,\n        uint256 shares\n    );\n\n    /**\n     * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.\n     *\n     * - MUST be an ERC-20 token contract.\n     * - MUST NOT revert.\n     */\n    function asset() external view returns (address assetTokenAddress);\n\n    /**\n     * @dev Returns the total amount of the underlying asset that is “managed” by Vault.\n     *\n     * - SHOULD include any compounding that occurs from yield.\n     * - MUST be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT revert.\n     */\n    function totalAssets() external view returns (uint256 totalManagedAssets);\n\n    /**\n     * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToShares(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToAssets(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,\n     * through a deposit call.\n     *\n     * - MUST return a limited value if receiver is subject to some deposit limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.\n     * - MUST NOT revert.\n     */\n    function maxDeposit(address receiver) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit\n     *   call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called\n     *   in the same transaction.\n     * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the\n     *   deposit would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewDeposit(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   deposit execution, and are accounted for during deposit.\n     * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function deposit(uint256 assets, address receiver) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.\n     * - MUST return a limited value if receiver is subject to some mint limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.\n     * - MUST NOT revert.\n     */\n    function maxMint(address receiver) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call\n     *   in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the\n     *   same transaction.\n     * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint\n     *   would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by minting.\n     */\n    function previewMint(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint\n     *   execution, and are accounted for during mint.\n     * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function mint(uint256 shares, address receiver) external returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the\n     * Vault, through a withdraw call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxWithdraw(address owner) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw\n     *   call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if\n     *   called\n     *   in the same transaction.\n     * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though\n     *   the withdrawal would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewWithdraw(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   withdraw execution, and are accounted for during withdraw.\n     * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,\n     * through a redeem call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxRedeem(address owner) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call\n     *   in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the\n     *   same transaction.\n     * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the\n     *   redemption would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by redeeming.\n     */\n    function previewRedeem(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   redeem execution, and are accounted for during redeem.\n     * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev An uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\nimport {Address} from \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            // bubble errors\n            if iszero(success) {\n                let ptr := mload(0x40)\n                returndatacopy(ptr, 0, returndatasize())\n                revert(ptr, returndatasize())\n            }\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n\n        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        bool success;\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/src/contracts/utils/interfaces/IRescuableBase.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n/**\n * @title IRescuableBase\n * @author BGD Labs\n * @notice interface containing the objects, events and methods definitions of the RescuableBase contract\n */\ninterface IRescuableBase {\n  error EthTransferFailed();\n  /**\n   * @notice emitted when erc20 tokens get rescued\n   * @param caller address that triggers the rescue\n   * @param token address of the rescued token\n   * @param to address that will receive the rescued tokens\n   * @param amount quantity of tokens rescued\n   */\n  event ERC20Rescued(\n    address indexed caller,\n    address indexed token,\n    address indexed to,\n    uint256 amount\n  );\n\n  /**\n   * @notice emitted when native tokens get rescued\n   * @param caller address that triggers the rescue\n   * @param to address that will receive the rescued tokens\n   * @param amount quantity of tokens rescued\n   */\n  event NativeTokensRescued(address indexed caller, address indexed to, uint256 amount);\n\n  /**\n   * @notice method that defined the maximum amount rescuable for any given asset.\n   * @dev there's currently no way to limit the rescuable \"native asset\", as we assume erc20s as intended underlying.\n   * @return the maximum amount of\n   */\n  function maxRescue(address erc20Token) external view returns (uint256);\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/src/contracts/utils/interfaces/IRescuable.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\nimport {IRescuableBase} from './IRescuableBase.sol';\n\n/**\n * @title IRescuable\n * @author BGD Labs\n * @notice interface containing the objects, events and methods definitions of the Rescuable contract\n */\ninterface IRescuable is IRescuableBase {\n  error OnlyRescueGuardian();\n\n  /**\n   * @notice method called to rescue tokens sent erroneously to the contract. Only callable by owner\n   * @param erc20Token address of the token to rescue\n   * @param to address to send the tokens\n   * @param amount of tokens to rescue\n   */\n  function emergencyTokenTransfer(address erc20Token, address to, uint256 amount) external;\n\n  /**\n   * @notice method called to rescue ether sent erroneously to the contract. Only callable by owner\n   * @param to address to send the eth\n   * @param amount of eth to rescue\n   */\n  function emergencyEtherTransfer(address to, uint256 amount) external;\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/src/contracts/utils/RescuableBase.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\nimport {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from 'openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IRescuableBase} from './interfaces/IRescuableBase.sol';\n\nabstract contract RescuableBase is IRescuableBase {\n  using SafeERC20 for IERC20;\n\n  /// @inheritdoc IRescuableBase\n  function maxRescue(address erc20Token) public view virtual returns (uint256);\n\n  function _emergencyTokenTransfer(address erc20Token, address to, uint256 amount) internal {\n    uint256 max = maxRescue(erc20Token);\n    amount = max > amount ? amount : max;\n    IERC20(erc20Token).safeTransfer(to, amount);\n\n    emit ERC20Rescued(msg.sender, erc20Token, to, amount);\n  }\n\n  function _emergencyEtherTransfer(address to, uint256 amount) internal {\n    (bool success, ) = to.call{value: amount}(new bytes(0));\n    if (!success) {\n      revert EthTransferFailed();\n    }\n\n    emit NativeTokensRescued(msg.sender, to, amount);\n  }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/src/contracts/utils/RescuableACL.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\nimport {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';\nimport {RescuableBase} from './RescuableBase.sol';\nimport {IRescuable} from './interfaces/IRescuable.sol';\n\n/**\n * @title Rescuable specially for ACL models\n * @author BGD Labs\n * @notice abstract contract with the methods to rescue tokens (ERC20 and native) from a contract\n */\nabstract contract RescuableACL is RescuableBase, IRescuable {\n  /// @notice modifier that checks that caller is allowed address\n  modifier onlyRescueGuardian() {\n    _checkRescueGuardian();\n    _;\n  }\n\n  /// @inheritdoc IRescuable\n  function emergencyTokenTransfer(\n    address erc20Token,\n    address to,\n    uint256 amount\n  ) external onlyRescueGuardian {\n    _emergencyTokenTransfer(erc20Token, to, amount);\n  }\n\n  /// @inheritdoc IRescuable\n  function emergencyEtherTransfer(address to, uint256 amount) external onlyRescueGuardian {\n    _emergencyEtherTransfer(to, amount);\n  }\n\n  /// @notice function, that should revert if `msg.sender` isn't allowed to rescue funds\n  function _checkRescueGuardian() internal view virtual;\n}\n"},"lib/aave-umbrella/src/contracts/rewards/interfaces/IRewardsDistributor.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {IRewardsStructs} from './IRewardsStructs.sol';\n\ninterface IRewardsDistributor is IRewardsStructs {\n  /**\n   * @notice Event is emitted when a `user` or admin installs/disables `claimer` for claiming user rewards.\n   * @param user Address of the `user`\n   * @param claimer Address of the `claimer` to install/disable\n   * @param caller Address of the `msg.sender` who changes claimer\n   * @param flag Flag responsible for setting/disabling `claimer`\n   */\n  event ClaimerSet(\n    address indexed user,\n    address indexed claimer,\n    address indexed caller,\n    bool flag\n  );\n\n  /**\n   * @dev Attempted to use signature with expired deadline.\n   */\n  error ExpiredSignature(uint256 deadline);\n\n  /**\n   * @dev Mismatched signature.\n   */\n  error InvalidSigner(address signer, address owner);\n\n  /**\n   * @dev Attempted to claim `reward` without authorization.\n   */\n  error ClaimerNotAuthorized(address claimer, address user);\n\n  /**\n   * @dev Attempted to claim rewards for assets while arrays lengths don't match.\n   */\n  error LengthsDontMatch();\n\n  /**\n   * @dev Attempted to set zero address.\n   */\n  error ZeroAddress();\n\n  // DEFAULT_ADMIN_ROLE\n  /////////////////////////////////////////////////////////////////////////////////////////\n\n  /**\n   * @notice Installs/disables `claimer` for claiming `user` rewards.\n   * @param user Address of the `user`\n   * @param claimer Address of the `claimer` to install/disable\n   * @param flag Flag responsible for setting/disabling `claimer`\n   */\n  function setClaimer(address user, address claimer, bool flag) external;\n\n  /////////////////////////////////////////////////////////////////////////////////////////\n\n  /**\n   * @notice Installs/disables `claimer` for claiming `msg.sender` rewards.\n   * @param claimer Address of the `claimer` to install/disable\n   * @param flag Flag responsible for setting/disabling `claimer`\n   */\n  function setClaimer(address claimer, bool flag) external;\n\n  /**\n   * @notice Claims all existing `rewards` for a certain `asset` on behalf of `msg.sender`.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @dev Always claims all `rewards`.\n   * @param asset Address of the `asset` whose `rewards` should be claimed\n   * @param receiver Address of the funds receiver\n   * @return rewards Array containing the addresses of all `reward` tokens claimed\n   * @return amounts Array containing the corresponding `amounts` of each `reward` claimed\n   */\n  function claimAllRewards(\n    address asset,\n    address receiver\n  ) external returns (address[] memory rewards, uint256[] memory amounts);\n\n  /**\n   * @notice Claims all existing `rewards` on behalf of `user` for a certain `asset` by `msg.sender`.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @dev Always claims all `rewards`.\n   * @param asset Address of the `asset` whose `rewards` should be claimed\n   * @param user Address of user, which accrued `rewards` should be claimed\n   * @param receiver Address of the funds receiver\n   * @return rewards Array containing the addresses of all `reward` tokens claimed\n   * @return amounts Array containing the corresponding `amounts` of each `reward` claimed\n   */\n  function claimAllRewardsOnBehalf(\n    address asset,\n    address user,\n    address receiver\n  ) external returns (address[] memory rewards, uint256[] memory amounts);\n\n  /**\n   * @notice Claims all existing `rewards` on behalf of `user` for a certain `asset` using signature.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @dev Always claims all `rewards`.\n   * @param asset Address of the `asset` whose `rewards` should be claimed\n   * @param user Address of user, which accrued `rewards` should be claimed\n   * @param receiver Address of the funds receiver\n   * @param deadline Signature deadline for claiming\n   * @param sig Signature parameters\n   * @return rewards Array containing the addresses of all `reward` tokens claimed\n   * @return amounts Array containing the corresponding `amounts` of each `reward` claimed\n   */\n  function claimAllRewardsPermit(\n    address asset,\n    address user,\n    address receiver,\n    uint256 deadline,\n    SignatureParams calldata sig\n  ) external returns (address[] memory rewards, uint256[] memory amounts);\n\n  /**\n   * @notice Claims selected `rewards` of `msg.sender` for a certain `asset`.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @param asset Address of the `asset` whose `rewards` should be claimed\n   * @param rewards Array of `reward` addresses, which should be claimed\n   * @param receiver Address of the funds receiver\n   * @return amounts Array containing the corresponding `amounts` of each `reward` claimed\n   */\n  function claimSelectedRewards(\n    address asset,\n    address[] calldata rewards,\n    address receiver\n  ) external returns (uint256[] memory amounts);\n\n  /**\n   * @notice Claims selected `rewards` on behalf of `user` for a certain `asset` by `msg.sender`.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @param asset Address of the `asset` whose `rewards` should be claimed\n   * @param rewards Array of `reward` addresses, which should be claimed\n   * @param user Address of user, which accrued `rewards` should be claimed\n   * @param receiver Address of the funds receiver\n   * @return amounts Array containing the corresponding `amounts` of each `reward` claimed\n   */\n  function claimSelectedRewardsOnBehalf(\n    address asset,\n    address[] calldata rewards,\n    address user,\n    address receiver\n  ) external returns (uint256[] memory amounts);\n\n  /**\n   * @notice Claims selected `rewards` on behalf of `user` for a certain `asset` using signature.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @param asset Address of the `asset` whose `rewards` should be claimed\n   * @param rewards Array of `reward` addresses, which should be claimed\n   * @param user Address of user, which accrued `rewards` should be claimed\n   * @param receiver Address of the funds receiver\n   * @param deadline Signature deadline for claiming\n   * @param sig Signature parameters\n   * @return amounts Array containing the corresponding `amounts` of each `reward` claimed\n   */\n  function claimSelectedRewardsPermit(\n    address asset,\n    address[] calldata rewards,\n    address user,\n    address receiver,\n    uint256 deadline,\n    SignatureParams calldata sig\n  ) external returns (uint256[] memory amounts);\n\n  /**\n   * @notice Claims all existing `rewards` of `msg.sender` across multiple `assets`.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @dev Always claims all `rewards`.\n   * @param assets Array of addresses representing the `assets`, whose `rewards` should be claimed\n   * @param receiver Address of the funds receiver\n   * @return rewards Two-dimensional array where each inner array contains the addresses of `reward` tokens for a specific `asset`\n   * @return amounts Two-dimensional array where each inner array contains the amounts of each `reward` claimed for a specific `asset`\n   */\n  function claimAllRewards(\n    address[] calldata assets,\n    address receiver\n  ) external returns (address[][] memory rewards, uint256[][] memory amounts);\n\n  /**\n   * @notice Claims all existing `rewards` on behalf of `user` across multiple `assets` by `msg.sender`.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @dev Always claims all `rewards`.\n   * @param assets Array of addresses representing the `assets`, whose `rewards` should be claimed\n   * @param user Address of user, which accrued `rewards` should be claimed\n   * @param receiver Address of the funds receiver\n   * @return rewards Two-dimensional array where each inner array contains the addresses of `reward` tokens for a specific `asset`\n   * @return amounts Two-dimensional array where each inner array contains the amounts of each `reward` claimed for a specific `asset`\n   */\n  function claimAllRewardsOnBehalf(\n    address[] calldata assets,\n    address user,\n    address receiver\n  ) external returns (address[][] memory rewards, uint256[][] memory amounts);\n\n  /**\n   * @notice Claims selected `rewards` of `msg.sender` across multiple `assets`.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @param assets Array of addresses representing the `assets`, whose `rewards` should be claimed\n   * @param rewards Two-dimensional array where each inner array contains the addresses of `rewards` for a specific `asset`\n   * @param receiver Address of the funds receiver\n   * @return amounts Two-dimensional array where each inner array contains the amounts of each `reward` claimed for a specific `asset`\n   */\n  function claimSelectedRewards(\n    address[] calldata assets,\n    address[][] calldata rewards,\n    address receiver\n  ) external returns (uint256[][] memory);\n\n  /**\n   * @notice Claims selected `rewards` on behalf of `user` across multiple `assets` by `msg.sender`.\n   * Makes an update and calculates new `index` and `accrued` `rewards` before claim.\n   * @param assets Array of addresses representing the `assets`, whose `rewards` should be claimed\n   * @param rewards Two-dimensional array where each inner array contains the addresses of `rewards` for a specific `asset`\n   * @param user Address of user, which accrued `rewards` should be claimed\n   * @param receiver Address of the funds receiver\n   * @return amounts Two-dimensional array where each inner array contains the amounts of each `reward` claimed for a specific `asset`\n   */\n  function claimSelectedRewardsOnBehalf(\n    address[] calldata assets,\n    address[][] calldata rewards,\n    address user,\n    address receiver\n  ) external returns (uint256[][] memory);\n}\n"},"lib/aave-umbrella/src/contracts/rewards/interfaces/IRewardsController.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {IRewardsDistributor} from './IRewardsDistributor.sol';\n\ninterface IRewardsController is IRewardsDistributor {\n  /**\n   * @notice Event is emitted when an asset is initialized.\n   * @param asset Address of the new `asset` added\n   */\n  event AssetInitialized(address indexed asset);\n\n  /**\n   * @notice Event is emitted when a `targetLiquidity` of the `asset` is changed.\n   * @param asset Address of the `asset`\n   * @param newTargetLiquidity New amount of `targetLiquidity` set for the `asset`\n   */\n  event TargetLiquidityUpdated(address indexed asset, uint256 newTargetLiquidity);\n\n  /**\n   * @notice Event is emitted when a `lastUpdatedTimestamp` of the `asset` is updated.\n   * @param asset Address of the `asset`\n   * @param newTimestamp New value of `lastUpdatedTimestamp` updated for the `asset`\n   */\n  event LastTimestampUpdated(address indexed asset, uint256 newTimestamp);\n\n  /**\n   * @notice Event is emitted when a reward is initialized for concrete `asset`.\n   * @param asset Address of the `asset`\n   * @param reward Address of the `reward`\n   */\n  event RewardInitialized(address indexed asset, address indexed reward);\n\n  /**\n   * @notice Event is emitted when a reward config is updated.\n   * @param asset Address of the `asset`\n   * @param reward Address of the `reward`\n   * @param maxEmissionPerSecond Amount of maximum possible rewards emission per second\n   * @param distributionEnd Timestamp after which distribution ends\n   * @param rewardPayer Address from where rewards will be transferred\n   */\n  event RewardConfigUpdated(\n    address indexed asset,\n    address indexed reward,\n    uint256 maxEmissionPerSecond,\n    uint256 distributionEnd,\n    address rewardPayer\n  );\n\n  /**\n   * @notice Event is emitted when a `reward` index is updated.\n   * @param asset Address of the `asset`\n   * @param reward Address of the `reward`\n   * @param newIndex New `reward` index updated for certain `asset`\n   */\n  event RewardIndexUpdated(address indexed asset, address indexed reward, uint256 newIndex);\n\n  /**\n   * @notice Event is emitted when a user interacts with the asset (transfer, mint, burn)  or manually updates the rewards data or claims them\n   * @param asset Address of the `asset`\n   * @param reward Address of the `reward`, which `user` data is updated\n   * @param user Address of the `user` whose `reward` data is updated\n   * @param newIndex Reward index set after update\n   * @param accruedFromLastUpdate Amount of accrued rewards from last update\n   */\n  event UserDataUpdated(\n    address indexed asset,\n    address indexed reward,\n    address indexed user,\n    uint256 newIndex,\n    uint256 accruedFromLastUpdate\n  );\n\n  /**\n   * @notice Event is emitted when a `user` `reward` is claimed.\n   * @param asset Address of the `asset`, whose `reward` was claimed\n   * @param reward Address of the `reward`, which is claimed\n   * @param user Address of the `user` whose `reward` is claimed\n   * @param receiver Address of the funds receiver\n   * @param amount Amount of the received funds\n   */\n  event RewardClaimed(\n    address indexed asset,\n    address indexed reward,\n    address indexed user,\n    address receiver,\n    uint256 amount\n  );\n\n  /**\n   * @dev Attempted to update data on the `asset` before it was initialized.\n   */\n  error AssetNotInitialized(address asset);\n\n  /**\n   * @dev Attempted to change the configuration of the `reward` before it was initialized.\n   */\n  error RewardNotInitialized(address reward);\n\n  /**\n   * @dev Attempted to set `distributionEnd` less than `block.timestamp` during `reward` initialization.\n   */\n  error InvalidDistributionEnd();\n\n  /**\n   * @dev Attempted to initialize more rewards than limit.\n   */\n  error MaxRewardsLengthReached();\n\n  // DEFAULT_ADMIN_ROLE\n  /////////////////////////////////////////////////////////////////////////////////////////\n\n  /**\n   * @notice Configures asset: sets `targetLiquidity` and updates `lastUpdatedTimestamp`.\n   * If the asset has already been initialized, then updates the rewards indexes and `lastUpdatedTimestamp`,\n   * also changes `targetLiquidity`, otherwise initializes asset and rewards.\n   * @dev `targetLiquidity` should be greater than 1 whole token.\n   * `maxEmissionPerSecond` inside `rewardConfig` should be less than 1000 tokens and greater than 2 wei.\n   * It must also be greater than `targetLiquidity * 1000 / 1e18`. Check EmissionMath.sol for more info.\n   * if `maxEmissionPerSecond` is zero or `distributionEnd` is less than current `block.timestamp`,\n   * then disable distribution for this `reward` if it was previously initialized.\n   * It can't initialize already disabled reward.\n   * @param asset Address of the `asset` to be configured/initialized\n   * @param targetLiquidity Amount of liquidity where will be the maximum emission of rewards per second applied\n   * @param rewardConfigs Optional array of reward configs, can be empty\n   */\n  function configureAssetWithRewards(\n    address asset,\n    uint256 targetLiquidity,\n    RewardSetupConfig[] calldata rewardConfigs\n  ) external;\n\n  // REWARDS_ADMIN_ROLE\n  /////////////////////////////////////////////////////////////////////////////////////////\n\n  /**\n   * @notice Configures already initialized rewards for certain `asset`: sets `distributionEnd` and `maxEmissionPerSecond`.\n   * If any reward hasn't initialized before then it reverts.\n   * Before setting new configuration updates all rewards indexes for `asset`.\n   * @dev `maxEmissionPerSecond` inside `rewardConfig` should be less than 1000 tokens and greater than 2 wei.\n   * It must also be greater than `targetLiquidity * 1000 / 1e18`. Check EmissionMath.sol for more info.\n   * If `maxEmissionPerSecond` is zero or `distributionEnd` is less than the current `block.timestamp`,\n   * then distribution for this `reward` will be disabled.\n   * @param asset Address of the `asset` whose reward should be configured\n   * @param rewardConfigs Array of structs with params to set\n   */\n  function configureRewards(address asset, RewardSetupConfig[] calldata rewardConfigs) external;\n\n  /////////////////////////////////////////////////////////////////////////////////////////\n\n  /**\n   * @notice Special hook, which is called every time `StakeToken` makes `_update` or `slash`.\n   * Makes an update and calculates new `index` and `accrued`. Also updates `lastUpdateTimestamp`.\n   * @dev All variables are passed here before the actual update.\n   * @param totalSupply Total supply of `StakeToken`\n   * @param totalAssets Total assets of `StakeToken`\n   * @param user User, whose `index` and rewards accrued will be updated, if address is zero then skips user update\n   * @param userBalance Amount of `StakeToken` shares owned by user\n   */\n  function handleAction(\n    uint256 totalSupply,\n    uint256 totalAssets,\n    address user,\n    uint256 userBalance\n  ) external;\n\n  /**\n   * @notice Updates all `reward` indexes and `lastUpdateTimestamp` for the `asset`.\n   * @param asset Address of the `asset` whose rewards will be updated\n   */\n  function updateAsset(address asset) external;\n\n  /**\n   * @notice Returns an array of all initialized assets (all `StakeTokens`, which are initialized here).\n   * @dev Return zero data if assets aren't set.\n   * @return assets Array of asset addresses\n   */\n  function getAllAssets() external view returns (address[] memory assets);\n\n  /**\n   * @notice Returns an array of all initialized rewards for a certain `asset`.\n   * @dev Return zero data if asset or rewards aren't set.\n   * @param asset Address of the `asset` whose rewards should be returned\n   * @return rewards Array of reward addresses\n   */\n  function getAllRewards(address asset) external view returns (address[] memory rewards);\n\n  /**\n   * @notice Returns all data about the asset and its rewards.\n   * @dev Return zero data if asset or rewards aren't set.\n   * Function made without some gas optimizations, so it's recommended to avoid calling it often from non-view method or inside batch.\n   * If the emission for a specific reward has ended at the time of the call (i.e., block.timestamp >= distributionEnd),\n   * the function will return a zero emission, even though there may still be remaining rewards.\n   * Note that the actual reward data will be updated the next time someone manually refreshes the data or interacts with the `StakeToken`.\n   * @param asset Address of the `asset` whose params should be returned\n   * @return assetData `targetLiquidity` and `lastUpdatedTimestamp` inside struct\n   * @return rewardsData All data about rewards including addresses and `RewardData`\n   */\n  function getAssetAndRewardsData(\n    address asset\n  )\n    external\n    view\n    returns (AssetDataExternal memory assetData, RewardDataExternal[] memory rewardsData);\n\n  /**\n   * @notice Returns data about the asset.\n   * @dev Return zero data if asset isn't set.\n   * @param asset Address of the `asset` whose params should be returned\n   * @return assetData `targetLiquidity` and `lastUpdatedTimestamp` inside struct\n   */\n  function getAssetData(address asset) external view returns (AssetDataExternal memory assetData);\n\n  /**\n   * @notice Returns data about the reward.\n   * @dev Return zero data if asset or rewards aren't set.\n   * If the emission has ended at the time of the call (i.e., block.timestamp >= distributionEnd), the function will return a zero emission,\n   * even though there may still be remaining rewards.\n   * Note that the actual reward data will be updated the next time someone manually refreshes the data or interacts with the `StakeToken`.\n   * @param asset Address of the `asset` whose `reward` params should be returned\n   * @param reward Address of the `reward` whose params should be returned\n   * @return rewardData `index`, `maxEmissionPerSecond` and `distributionEnd` and address inside struct, address is duplicated from external one\n   */\n  function getRewardData(\n    address asset,\n    address reward\n  ) external view returns (RewardDataExternal memory rewardData);\n\n  /**\n   * @notice Returns data about the reward emission.\n   * @dev Return zero data if asset or rewards aren't set.\n   * If `maxEmissionPerSecond` is equal to 1 wei, then `flatEmission` will be 0, although in fact it is not 0 and emission is taken into account correctly inside the code.\n   * Here this calculation is made specifically to simplify the function behaviour.\n   * If the emission has ended at the time of the call (i.e., block.timestamp >= distributionEnd), the function will return a zero max and flat emissions,\n   * even though there may still be remaining rewards.\n   * Note that the actual reward data will be updated the next time someone manually refreshes the data or interacts with the `StakeToken`.\n   * @param asset Address of the `asset` whose `reward` emission params should be returned\n   * @param reward Address of the `reward` whose emission params should be returned\n   * @return emissionData `targetLiquidity`, `targetLiquidityExcess`, `maxEmission` and `flatEmission` inside struct\n   */\n  function getEmissionData(\n    address asset,\n    address reward\n  ) external view returns (EmissionData memory emissionData);\n\n  /**\n   * @notice Returns `user` `index` and `accrued` for all rewards for certain `asset` at the time of the last user update.\n   * If you want to get current `accrued` of all rewards, see `calculateCurrentUserRewards`.\n   * @dev Return zero data if asset or rewards aren't set.\n   * @param asset Address of the `asset` for which the rewards are accumulated\n   * @param user Address of `user` accumulating rewards\n   * @return rewards Array of `reward` addresses\n   * @return userData `index` and `accrued` inside structs\n   */\n  function getUserDataByAsset(\n    address asset,\n    address user\n  ) external view returns (address[] memory rewards, UserDataExternal[] memory userData);\n\n  /**\n   * @notice Returns `user` `index` and `accrued` for certain `asset` and `reward` at the time of the last user update.\n   * If you want to calculate current `accrued` of the `reward`, see `calculateCurrentUserReward`.\n   * @dev Return zero data if asset or rewards aren't set.\n   * @param asset Address of the `asset` for which the `reward` is accumulated\n   * @param reward Address of the accumulating `reward`\n   * @param user Address of `user` accumulating rewards\n   * @return data `index` and `accrued` inside struct\n   */\n  function getUserDataByReward(\n    address asset,\n    address reward,\n    address user\n  ) external view returns (UserDataExternal memory data);\n\n  /**\n   * @notice Returns current `reward` indexes for `asset`.\n   * @dev Return zero if asset or rewards aren't set.\n   * Function made without some gas optimizations, so it's recommended to avoid calling it often from non-view method or inside batch.\n   * @param asset Address of the `asset` whose indexes of rewards should be calculated\n   * @return rewards Array of `reward` addresses\n   * @return indexes Current indexes\n   */\n  function calculateRewardIndexes(\n    address asset\n  ) external view returns (address[] memory rewards, uint256[] memory indexes);\n\n  /**\n   * @notice Returns current `index` for certain `asset` and `reward`.\n   * @dev Return zero if asset or rewards aren't set.\n   * @param asset Address of the `asset` whose `index` of `reward` should be calculated\n   * @param reward Address of the accumulating `reward`\n   * @return index Current `index`\n   */\n  function calculateRewardIndex(\n    address asset,\n    address reward\n  ) external view returns (uint256 index);\n\n  /**\n   * @notice Returns `emissionPerSecondScaled` for certain `asset` and `reward`. Returned value scaled to 18 decimals.\n   * @dev Return zero if asset or rewards aren't set.\n   * @param asset Address of the `asset` which current emission of `reward` should be returned\n   * @param reward Address of the `reward` which `emissionPerSecond` should be returned\n   * @return emissionPerSecondScaled Current amount of rewards distributed every second (scaled to 18 decimals)\n   */\n  function calculateCurrentEmissionScaled(\n    address asset,\n    address reward\n  ) external view returns (uint256 emissionPerSecondScaled);\n\n  /**\n   * @notice  Returns `emissionPerSecond` for certain `asset` and `reward`.\n   * @dev Return zero if asset or rewards aren't set.\n   * An integer quantity is returned, although the accuracy of the calculations in reality is higher.\n   * @param asset Address of the `asset` which current emission of `reward` should be returned\n   * @param reward Address of the `reward` which `emissionPerSecond` should be returned\n   * @return emissionPerSecond Current amount of rewards distributed every second\n   */\n  function calculateCurrentEmission(\n    address asset,\n    address reward\n  ) external view returns (uint256 emissionPerSecond);\n\n  /**\n   * @notice Calculates and returns `user` `accrued` amounts for all rewards for certain `asset`.\n   * @dev Return zero data if asset or rewards aren't set.\n   * Function made without some gas optimizations, so it's recommended to avoid calling it often from non-view method or inside batch.\n   * @param asset Address of the `asset` whose rewards are accumulated\n   * @param user Address of `user` accumulating rewards\n   * @return rewards Array of `reward` addresses\n   * @return rewardsAccrued Array of current calculated `accrued` amounts\n   */\n  function calculateCurrentUserRewards(\n    address asset,\n    address user\n  ) external view returns (address[] memory rewards, uint256[] memory rewardsAccrued);\n\n  /**\n   * @notice Calculates and returns `user` `accrued` amount for certain `reward` and `asset`.\n   * @dev Return zero if asset or rewards aren't set.\n   * @param asset Address of the `asset` whose reward is accumulated\n   * @param reward Address of the `reward` that accumulates for the user\n   * @param user Address of `user` accumulating rewards\n   * @return rewardAccrued Amount of current calculated `accrued` amount\n   */\n  function calculateCurrentUserReward(\n    address asset,\n    address reward,\n    address user\n  ) external view returns (uint256 rewardAccrued);\n}\n"},"lib/aave-umbrella/src/contracts/rewards/libraries/InternalStructs.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.27;\n\n/**\n * @title InternalStructs library\n * @notice Structs for internal usage only\n * @author BGD labs\n */\nlibrary InternalStructs {\n  struct AssetData {\n    /// @notice Map of reward token addresses with their configuration and user data\n    mapping(address reward => RewardAndUserData) data;\n    /// @notice An array of rewards and the corresponding endings of their distribution (duplicated for optimization)\n    RewardAddrAndDistrEnd[] rewardsInfo;\n    /// @notice The target liquidity value at which the `maxEmissionPerSecond` is applied. (Max value with current `EmissionMath` lib is 1e34/35).\n    uint160 targetLiquidity;\n    /// @notice Timestamp of the last update\n    uint32 lastUpdateTimestamp;\n  }\n\n  struct RewardAndUserData {\n    /// @notice Reward configuration and index\n    RewardData rewardData;\n    /// @notice Map of reward token addresses with their user data\n    mapping(address user => UserData) userData;\n    /// @notice Address from which reward will be transferred\n    address rewardPayer;\n  }\n\n  // @dev All rewards will be calculated as they are all 18-decimals tokens with the help of this variable\n  struct RewardData {\n    /// @notice Liquidity index of the reward (with scaling to 18 decimals and SCALING_FACTOR applied)\n    uint144 index;\n    /// @notice Maximum possible emission rate of rewards per second (scaled to 18 decimals)\n    uint72 maxEmissionPerSecondScaled;\n    /// @notice End of the reward distribution (DUPLICATED for optimization)\n    uint32 distributionEnd;\n    /// @notice Difference between 18 and `reward.decimals()`\n    uint8 decimalsScaling;\n  }\n\n  struct UserData {\n    /// @notice Liquidity index of the reward for the user that was set as a result of the last user rewards update\n    uint144 index;\n    /// @notice Amount of accrued rewards that the user earned at the time of his last index update (pending to claim)\n    uint112 accrued;\n  }\n\n  struct RewardAddrAndDistrEnd {\n    /// @notice Reward address\n    address addr;\n    /// @notice The end of the reward distribution (DUPLICATED for optimization)\n    uint32 distributionEnd;\n  }\n\n  struct ExtraParamsForIndex {\n    /// @notice Liquidity value at which there will be maximum emission per second\n    uint256 targetLiquidity;\n    /// @notice Amount of assets remaining inside the `stakeToken`\n    uint256 totalAssets;\n    /// @notice Amount of `stakeToken` shares minted\n    uint256 totalSupply;\n  }\n}\n"},"lib/aave-umbrella/src/contracts/rewards/libraries/EmissionMath.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.27;\n\nimport {SafeCast} from 'openzeppelin-contracts/contracts/utils/math/SafeCast.sol';\nimport {Math} from 'openzeppelin-contracts/contracts/utils/math/Math.sol';\n\nimport {InternalStructs} from './InternalStructs.sol';\nimport {IRewardsStructs} from '../interfaces/IRewardsStructs.sol';\n\n/**\n * @title EmissionMath contract\n * @notice The emission math contract is designed for the calculation of the index and amount of accrued rewards related to\n * dynamic distribution based on `targetLiquidity`, current `totalAssets`, `totalSupply`, and `maxEmissionPerSecond`.\n * It consists of three segments:\n * 1) Gradual Increase: The first segment features a sharp rise in emission, providing early depositors with a better deal,\n * ultimately reaching `maxEmissionPerSecond`. The dynamics of emission growth decreases with increasing `totalAssets`.\n * 2) Linear Decrease: The second segment represents a linear decrease in emission.\n * 3) Constant Emission: The third segment maintains a constant level of emission.\n * @dev `maxEmissionPerSecond` are assumed to be scaled up to 18 decimals.\n * For example: WBTC minimal `maxEmissionPerSecond` will be 1e10, cause 1e10 is `decimalsScaling`.\n * @author BGD labs\n */\nlibrary EmissionMath {\n  using SafeCast for uint256;\n  using Math for uint256;\n\n  /// @notice 100%\n  uint256 internal constant PERCENTAGE_FACTOR = 100_00;\n\n  /// @notice 120%\n  uint256 internal constant FLAT_EMISSION_LIQUIDITY_BOUND = 120_00;\n\n  /// @notice 80%\n  uint256 internal constant FLAT_EMISSION_BPS = 80_00;\n\n  /// @notice maxEmissionPerSecond should be less than 1_000 tokens, look (/assets/operating_conditions.md) for details\n  uint256 internal constant MAX_EMISSION_VALUE_PER_SECOND = 1_000 * 1e18;\n\n  /// @notice `index` and `emissionPerSecond` scaling factor\n  uint256 public constant SCALING_FACTOR = 1e18;\n\n  /// @notice Reserve in requirement for `maxEmissionPerSecond`, look (/assets/operating_conditions.md) for details\n  uint256 public constant REACHABLE_RATIO = 1000;\n\n  /// @notice Max decimals allowed for reward tokens and max recommended for asset\n  uint8 public constant MAX_DECIMALS = 18;\n\n  /// @notice DEAD_SHARES set to `totalSupply` if it's less than 1e6 value (in order to protect from overflow)\n  uint256 public constant DEAD_SHARES = 1e6;\n\n  /**\n   * @dev Attempted to set `targetLiquidity` with a value less than 1 whole token considering decimals or greater than `1e36`.\n   */\n  error InvalidTargetLiquidity();\n\n  /**\n   * @dev Attempted to set `maxEmissionPerSecond` with a value greater than `MAX_EMISSION_VALUE_PER_SECOND`.\n   */\n  error InvalidMaxEmissionPerSecond();\n\n  /**\n   * @notice Calculates index increase for some period of time\n   * @param extraParamsForIndex Extra params including `targetLiquidity`, `totalAssets`, `totalSupply`\n   * @param maxEmissionPerSecondScaled Amount of rewards distributed every second virtually scaled up to 18 decimals\n   * @param distributionEnd Timestamp when distribution should end\n   * @param lastUpdateTimestamp Timestamp of last update, should be less or equal than `distributionEnd`\n   * @return Index increase value\n   */\n  function calculateIndexIncrease(\n    InternalStructs.ExtraParamsForIndex memory extraParamsForIndex,\n    uint256 maxEmissionPerSecondScaled,\n    uint256 distributionEnd,\n    uint256 lastUpdateTimestamp\n  ) internal view returns (uint144) {\n    uint256 currentEmission = getEmissionPerSecondScaled(\n      maxEmissionPerSecondScaled,\n      extraParamsForIndex.targetLiquidity,\n      extraParamsForIndex.totalAssets\n    );\n\n    uint256 calculateDistributionUntil = block.timestamp > distributionEnd\n      ? distributionEnd\n      : block.timestamp;\n\n    uint256 timeDelta = calculateDistributionUntil - lastUpdateTimestamp;\n\n    if (extraParamsForIndex.totalSupply < DEAD_SHARES) {\n      extraParamsForIndex.totalSupply = DEAD_SHARES;\n    }\n\n    uint256 indexIncrease = (currentEmission * timeDelta) / extraParamsForIndex.totalSupply;\n\n    return indexIncrease.toUint144();\n  }\n\n  /**\n   * @notice Calculates virtual amount of accrued tokens for some period of time\n   * @param newRewardIndex Reward index calculated, should be greater or equal than `oldUserIndex`\n   * @param oldUserIndex The last user's index set during update or `handleAction`\n   * @param userBalance Amount of user's `StakeToken` shares\n   * @return Accrued amount of tokens virtually scaled up to 18 decimals\n   */\n  function calculateAccrued(\n    uint152 newRewardIndex,\n    uint152 oldUserIndex,\n    uint256 userBalance\n  ) internal pure returns (uint112) {\n    return ((userBalance * (newRewardIndex - oldUserIndex)) / SCALING_FACTOR).toUint112();\n  }\n\n  /**\n   * @notice Calculates all emission parameters inside `EmissionData` struct\n   * @param maxEmissionPerSecond Maximum possible emission rate per second\n   * @param targetLiquidity Liquidity value at which `maxEmissionPerSecond` will be applied\n   * @return `EmissionData` struct\n   */\n  function calculateEmissionParams(\n    uint256 maxEmissionPerSecond,\n    uint256 targetLiquidity\n  ) internal pure returns (IRewardsStructs.EmissionData memory) {\n    return\n      IRewardsStructs.EmissionData({\n        targetLiquidity: targetLiquidity,\n        targetLiquidityExcess: _percentMulDiv(targetLiquidity, FLAT_EMISSION_LIQUIDITY_BOUND),\n        maxEmission: maxEmissionPerSecond,\n        flatEmission: _percentMulDiv(maxEmissionPerSecond, FLAT_EMISSION_BPS)\n      });\n  }\n\n  /**\n   * @notice Calculate current virtual emission per second\n   * @param maxEmissionPerSecondScaled Maximum possible emission rate per second virtually scaled up to 18 decimals\n   * @param targetLiquidity Liquidity value at which `maxEmissionPerSecond` will be applied\n   * @param totalAssets Amount of assets remaining inside `StakeToken`\n   * @return Current virtual emission per second\n   */\n  function getEmissionPerSecondScaled(\n    uint256 maxEmissionPerSecondScaled,\n    uint256 targetLiquidity,\n    uint256 totalAssets\n  ) internal pure returns (uint256) {\n    return\n      _getEmissionPerSecondScaled(\n        calculateEmissionParams(maxEmissionPerSecondScaled, targetLiquidity),\n        totalAssets\n      );\n  }\n\n  /**\n   * @notice Validates `maxEmissionPerSecondScaled`\n   * @param maxEmissionPerSecondScaled Maximum possible emission rate per second to validate virtually scaled up to 18 decimals\n   * @param targetLiquidity Target of `totalAssets` for `StakeToken`\n   */\n  function validateMaxEmission(\n    uint256 maxEmissionPerSecondScaled,\n    uint256 targetLiquidity\n  ) internal pure {\n    // We want to check that minimal `maxEmissionPerSecondScaled` should be at least 2 native wei in reward\n    // Considering this, for the flat sector we will get non-zero emission, cause `2 * 80% / 100%` will result in 1 wei\n    uint256 precisionBound = (targetLiquidity * REACHABLE_RATIO) / SCALING_FACTOR;\n    uint256 minBound = precisionBound > 2 ? precisionBound : 2;\n    require(\n      maxEmissionPerSecondScaled <= MAX_EMISSION_VALUE_PER_SECOND &&\n        maxEmissionPerSecondScaled >= minBound,\n      InvalidMaxEmissionPerSecond()\n    );\n  }\n\n  /**\n   * @notice Validates `targetLiquidity`\n   * @param targetLiquidity Liquidity value at which `maxEmissionPerSecond` will be applied\n   * @param decimals Decimals value of `asset`\n   */\n  function validateTargetLiquidity(uint256 targetLiquidity, uint8 decimals) internal pure {\n    require(targetLiquidity >= 10 ** decimals && targetLiquidity <= 1e36, InvalidTargetLiquidity());\n  }\n\n  function _getEmissionPerSecondScaled(\n    IRewardsStructs.EmissionData memory params,\n    uint256 totalAssets\n  ) internal pure returns (uint256) {\n    if (totalAssets <= params.targetLiquidity) {\n      return _slopeCurve(params.maxEmission, params.targetLiquidity, totalAssets);\n    } else if (totalAssets < params.targetLiquidityExcess) {\n      return _linearDecreaseCurve(params, totalAssets);\n    } else {\n      return params.flatEmission * SCALING_FACTOR;\n    }\n  }\n\n  function _slopeCurve(\n    uint256 maxEmissionPerSecond,\n    uint256 targetLiquidity,\n    uint256 totalAssets\n  ) internal pure returns (uint256) {\n    // since `totalAssets` should be always <= `targetLiquidity` here; belongs to [0; targetLiquidity]\n    // `emissionDecrease` belongs to [0; maxEmissionPerSecond * SCALING_FACTOR]\n    uint256 emissionDecrease = (maxEmissionPerSecond * totalAssets * SCALING_FACTOR) /\n      targetLiquidity;\n    // result belongs [0; maxEmissionPerSecond * SCALING_FACTOR]\n    return\n      ((2 * maxEmissionPerSecond * SCALING_FACTOR - emissionDecrease) * totalAssets) /\n      targetLiquidity;\n  }\n\n  function _linearDecreaseCurve(\n    IRewardsStructs.EmissionData memory params,\n    uint256 totalAssets\n  ) internal pure returns (uint256) {\n    // `maxEmission` always > `flatEmission`;\n    // `totalAssets` should be > `targetLiquidity` here; belongs to (targetLiquidity; targetLiquidityExcess)\n    // result belongs to (flatEmission; maxEmission] or (CONST_EMISSION_BPS * maxEmission / PERCENTAGE_FACTOR; maxEmission]\n\n    return\n      (params.maxEmission -\n        (((params.maxEmission - params.flatEmission) * (totalAssets - params.targetLiquidity)) /\n          (params.targetLiquidityExcess - params.targetLiquidity))) * SCALING_FACTOR;\n  }\n\n  function _percentMulDiv(uint256 value, uint256 percent) internal pure returns (uint256) {\n    return value.mulDiv(percent, PERCENTAGE_FACTOR);\n  }\n\n  function scaleUp(uint256 value, uint8 decimals) internal pure returns (uint256) {\n    return value * 10 ** decimals;\n  }\n\n  function scaleDown(uint256 value, uint8 decimals) internal pure returns (uint256) {\n    return value / (10 ** decimals);\n  }\n}\n"},"lib/aave-umbrella/src/contracts/rewards/RewardsDistributor.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.27;\n\nimport {Initializable} from 'openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol';\nimport {NoncesUpgradeable} from 'openzeppelin-contracts-upgradeable/contracts/utils/NoncesUpgradeable.sol';\nimport {EIP712Upgradeable} from 'openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol';\n\nimport {IERC4626} from 'openzeppelin-contracts/contracts/interfaces/IERC4626.sol';\n\nimport {ECDSA} from 'openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol';\n\nimport {IRewardsDistributor} from './interfaces/IRewardsDistributor.sol';\n\n/**\n * @title RewardsDistributor\n * @notice RewardsDistributor is an abstract contract designed to implement external functions responsible for receiving rewards.\n * The accrual of rewards, their quantity and method of transfer must be implemented in the child contract.\n * Rewards can be claimed by yourself or through `authorizedClaimers`, as well as through using signatures.\n * @author BGD labs\n */\nabstract contract RewardsDistributor is\n  Initializable,\n  NoncesUpgradeable,\n  EIP712Upgradeable,\n  IRewardsDistributor\n{\n  /// @custom:storage-location erc7201:umbrella.storage.RewardsDistributor\n  struct RewardsDistributorStorage {\n    /// @notice Addresses capable of claiming rewards instead of user\n    mapping(address user => mapping(address claimer => bool)) authorizedClaimers;\n  }\n\n  // keccak256(abi.encode(uint256(keccak256(\"umbrella.storage.RewardsDistributor\")) - 1)) & ~bytes32(uint256(0xff))\n  bytes32 private constant RewardsDistributorStorageLocation =\n    0x21b0411c7d97c506a34525b56b49eed70b15d28e22527c4589674c84ba9a5200;\n\n  function _getRewardsDistributorStorage()\n    private\n    pure\n    returns (RewardsDistributorStorage storage $)\n  {\n    assembly {\n      $.slot := RewardsDistributorStorageLocation\n    }\n  }\n\n  bytes32 private constant CLAIM_ALL_TYPEHASH =\n    keccak256(\n      'ClaimAllRewards(address asset,address user,address receiver,address caller,uint256 nonce,uint256 deadline)'\n    );\n\n  bytes32 private constant CLAIM_SELECTED_TYPEHASH =\n    keccak256(\n      'ClaimSelectedRewards(address asset,address[] rewards,address user,address receiver,address caller,uint256 nonce,uint256 deadline)'\n    );\n\n  modifier onlyAuthorizedClaimer(address user) {\n    require(isClaimerAuthorized(user, msg.sender), ClaimerNotAuthorized(msg.sender, user));\n\n    _;\n  }\n\n  function __RewardsDistributor_init() internal onlyInitializing {\n    __EIP712_init_unchained('RewardsDistributor', '1');\n  }\n\n  function __RewardsDistributor_init_unchained() internal onlyInitializing {}\n\n  /// @inheritdoc IRewardsDistributor\n  function claimAllRewards(\n    address asset,\n    address receiver\n  ) external returns (address[] memory, uint256[] memory) {\n    return _claimAllRewards(asset, msg.sender, receiver);\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function claimAllRewardsOnBehalf(\n    address asset,\n    address user,\n    address receiver\n  ) external onlyAuthorizedClaimer(user) returns (address[] memory, uint256[] memory) {\n    return _claimAllRewards(asset, user, receiver);\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function claimAllRewardsPermit(\n    address asset,\n    address user,\n    address receiver,\n    uint256 deadline,\n    SignatureParams calldata sig\n  ) external returns (address[] memory, uint256[] memory) {\n    bytes32 structHash = keccak256(\n      abi.encode(CLAIM_ALL_TYPEHASH, asset, user, receiver, msg.sender, _useNonce(user), deadline)\n    );\n\n    _checkSignature(user, structHash, deadline, sig);\n\n    return _claimAllRewards(asset, user, receiver);\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function claimSelectedRewards(\n    address asset,\n    address[] calldata rewards,\n    address receiver\n  ) external returns (uint256[] memory) {\n    return _claimSelectedRewards(asset, rewards, msg.sender, receiver);\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function claimSelectedRewardsOnBehalf(\n    address asset,\n    address[] calldata rewards,\n    address user,\n    address receiver\n  ) external onlyAuthorizedClaimer(user) returns (uint256[] memory) {\n    return _claimSelectedRewards(asset, rewards, user, receiver);\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function claimSelectedRewardsPermit(\n    address asset,\n    address[] calldata rewards,\n    address user,\n    address receiver,\n    uint256 deadline,\n    SignatureParams calldata sig\n  ) external returns (uint256[] memory) {\n    uint256 nonce = _useNonce(user); // cache here, in order to escape stack-too-deep error inside abi.encode\n    bytes32 rewardsHash = keccak256(abi.encodePacked(rewards));\n    bytes32 structHash = keccak256(\n      abi.encode(\n        CLAIM_SELECTED_TYPEHASH,\n        asset,\n        rewardsHash,\n        user,\n        receiver,\n        msg.sender,\n        nonce,\n        deadline\n      )\n    );\n\n    _checkSignature(user, structHash, deadline, sig);\n\n    return _claimSelectedRewards(asset, rewards, user, receiver);\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function claimAllRewards(\n    address[] calldata assets,\n    address receiver\n  ) external returns (address[][] memory, uint256[][] memory) {\n    address[][] memory addresses = new address[][](assets.length);\n    uint256[][] memory amounts = new uint256[][](assets.length);\n\n    for (uint256 i; i < assets.length; ++i) {\n      (addresses[i], amounts[i]) = _claimAllRewards(assets[i], msg.sender, receiver);\n    }\n\n    return (addresses, amounts);\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function claimAllRewardsOnBehalf(\n    address[] calldata assets,\n    address user,\n    address receiver\n  ) external onlyAuthorizedClaimer(user) returns (address[][] memory, uint256[][] memory) {\n    address[][] memory addresses = new address[][](assets.length);\n    uint256[][] memory amounts = new uint256[][](assets.length);\n\n    for (uint256 i; i < assets.length; ++i) {\n      (addresses[i], amounts[i]) = _claimAllRewards(assets[i], user, receiver);\n    }\n\n    return (addresses, amounts);\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function claimSelectedRewards(\n    address[] calldata assets,\n    address[][] calldata rewards,\n    address receiver\n  ) external returns (uint256[][] memory) {\n    require(assets.length == rewards.length, LengthsDontMatch());\n\n    uint256[][] memory amounts = new uint256[][](assets.length);\n\n    for (uint256 i; i < assets.length; ++i) {\n      amounts[i] = _claimSelectedRewards(assets[i], rewards[i], msg.sender, receiver);\n    }\n\n    return amounts;\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function claimSelectedRewardsOnBehalf(\n    address[] calldata assets,\n    address[][] calldata rewards,\n    address user,\n    address receiver\n  ) external onlyAuthorizedClaimer(user) returns (uint256[][] memory) {\n    require(assets.length == rewards.length, LengthsDontMatch());\n\n    uint256[][] memory amounts = new uint256[][](assets.length);\n\n    for (uint256 i; i < assets.length; ++i) {\n      amounts[i] = _claimSelectedRewards(assets[i], rewards[i], user, receiver);\n    }\n\n    return amounts;\n  }\n\n  /// @inheritdoc IRewardsDistributor\n  function setClaimer(address claimer, bool flag) external {\n    _setClaimer(msg.sender, claimer, flag);\n  }\n\n  function isClaimerAuthorized(address user, address claimer) public view returns (bool) {\n    return _getRewardsDistributorStorage().authorizedClaimers[user][claimer];\n  }\n\n  function _setClaimer(address user, address claimer, bool flag) internal {\n    require(claimer != address(0), ZeroAddress());\n\n    _getRewardsDistributorStorage().authorizedClaimers[user][claimer] = flag;\n\n    emit ClaimerSet(user, claimer, msg.sender, flag);\n  }\n\n  function _claimAllRewards(\n    address asset,\n    address user,\n    address receiver\n  ) internal returns (address[] memory, uint256[] memory) {\n    address[] memory rewards = getAllRewards(asset);\n    uint256[] memory claimed = _claimSelectedRewards(asset, rewards, user, receiver);\n\n    return (rewards, claimed);\n  }\n\n  function _checkSignature(\n    address user,\n    bytes32 structHash,\n    uint256 deadline,\n    SignatureParams calldata sig\n  ) internal view {\n    require(block.timestamp <= deadline, ExpiredSignature(deadline));\n\n    bytes32 hash = _hashTypedDataV4(structHash);\n    address signer = ECDSA.recover(hash, sig.v, sig.r, sig.s);\n\n    require(signer == user, InvalidSigner(signer, user));\n  }\n\n  function getAllRewards(address asset) public view virtual returns (address[] memory);\n\n  function _claimSelectedRewards(\n    address asset,\n    address[] memory rewards,\n    address user,\n    address receiver\n  ) internal virtual returns (uint256[] memory);\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev External interface of AccessControl declared to support ERC-165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev The `account` is missing a role.\n     */\n    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n    /**\n     * @dev The caller of a function is not the expected one.\n     *\n     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n     */\n    error AccessControlBadConfirmation();\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).\n     * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165 {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\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 value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens as the allowance of `spender` over the\n     * 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 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` 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 value) external returns (bool);\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\nimport {Errors} from \"./Errors.sol\";\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert Errors.InsufficientBalance(address(this).balance, amount);\n        }\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            revert Errors.FailedCall();\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {Errors.FailedCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert Errors.InsufficientBalance(address(this).balance, value);\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case\n     * of an unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {Errors.FailedCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.\n     */\n    function _revert(bytes memory returndata) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            assembly (\"memory-safe\") {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n}\n"},"lib/aave-umbrella/src/contracts/rewards/interfaces/IRewardsStructs.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title IRewardsStructs interface\n * @notice An interface containing structures that can be used externally.\n * @author BGD labs\n */\ninterface IRewardsStructs {\n  struct RewardSetupConfig {\n    /// @notice Reward address\n    address reward;\n    /// @notice Address, from which this reward will be transferred (should give approval to this address)\n    address rewardPayer;\n    /// @notice Maximum possible emission rate of rewards per second\n    uint256 maxEmissionPerSecond;\n    /// @notice End of the rewards distribution\n    uint256 distributionEnd;\n  }\n\n  struct AssetDataExternal {\n    /// @notice Liquidity value at which there will be maximum emission per second (expected amount of asset to be deposited into `StakeToken`)\n    uint256 targetLiquidity;\n    /// @notice Timestamp of the last update\n    uint256 lastUpdateTimestamp;\n  }\n\n  struct RewardDataExternal {\n    /// @notice Reward address\n    address addr;\n    /// @notice Liquidity index of the reward set during the last update\n    uint256 index;\n    /// @notice Maximum possible emission rate of rewards per second\n    uint256 maxEmissionPerSecond;\n    /// @notice End of the reward distribution\n    uint256 distributionEnd;\n  }\n\n  struct EmissionData {\n    /// @notice Liquidity value at which there will be maximum emission per second applied\n    uint256 targetLiquidity;\n    /// @notice Liquidity value after which emission per second will be flat\n    uint256 targetLiquidityExcess;\n    /// @notice Maximum possible emission rate of rewards per second (can be with or without scaling to 18 decimals, depending on usage in code)\n    uint256 maxEmission;\n    /// @notice Flat emission value per second (can be with or without scaling, depending on usage in code)\n    uint256 flatEmission;\n  }\n\n  struct UserDataExternal {\n    /// @notice Liquidity index of the user reward set during the last update\n    uint256 index;\n    /// @notice Amount of accrued rewards that the user earned at the time of his last index update (pending to claim)\n    uint256 accrued;\n  }\n\n  struct SignatureParams {\n    uint8 v;\n    bytes32 r;\n    bytes32 s;\n  }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with an success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n            // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2²⁵⁶ + prod0.\n            uint256 prod0 = x * y; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= prod1) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\n        for (uint256 i = 0; i < byteArray.length; ++i) {\n            if (byteArray[i] != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        uint256 exp;\n        unchecked {\n            exp = 128 * SafeCast.toUint(value > (1 << 128) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 64 * SafeCast.toUint(value > (1 << 64) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 32 * SafeCast.toUint(value > (1 << 32) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 16 * SafeCast.toUint(value > (1 << 16) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 8 * SafeCast.toUint(value > (1 << 8) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 4 * SafeCast.toUint(value > (1 << 4) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 2 * SafeCast.toUint(value > (1 << 2) - 1);\n            value >>= exp;\n            result += exp;\n\n            result += SafeCast.toUint(value > 1);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        uint256 isGt;\n        unchecked {\n            isGt = SafeCast.toUint(value > (1 << 128) - 1);\n            value >>= isGt * 128;\n            result += isGt * 16;\n\n            isGt = SafeCast.toUint(value > (1 << 64) - 1);\n            value >>= isGt * 64;\n            result += isGt * 8;\n\n            isGt = SafeCast.toUint(value > (1 << 32) - 1);\n            value >>= isGt * 32;\n            result += isGt * 4;\n\n            isGt = SafeCast.toUint(value > (1 << 16) - 1);\n            value >>= isGt * 16;\n            result += isGt * 2;\n\n            result += SafeCast.toUint(value > (1 << 8) - 1);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/NoncesUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol)\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides tracking nonces for addresses. Nonces will only increment.\n */\nabstract contract NoncesUpgradeable is Initializable {\n    /**\n     * @dev The nonce used for an `account` is not the expected current nonce.\n     */\n    error InvalidAccountNonce(address account, uint256 currentNonce);\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.Nonces\n    struct NoncesStorage {\n        mapping(address account => uint256) _nonces;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Nonces\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant NoncesStorageLocation = 0x5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00;\n\n    function _getNoncesStorage() private pure returns (NoncesStorage storage $) {\n        assembly {\n            $.slot := NoncesStorageLocation\n        }\n    }\n\n    function __Nonces_init() internal onlyInitializing {\n    }\n\n    function __Nonces_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Returns the next unused nonce for an address.\n     */\n    function nonces(address owner) public view virtual returns (uint256) {\n        NoncesStorage storage $ = _getNoncesStorage();\n        return $._nonces[owner];\n    }\n\n    /**\n     * @dev Consumes a nonce.\n     *\n     * Returns the current value and increments nonce.\n     */\n    function _useNonce(address owner) internal virtual returns (uint256) {\n        NoncesStorage storage $ = _getNoncesStorage();\n        // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be\n        // decremented or reset. This guarantees that the nonce never overflows.\n        unchecked {\n            // It is important to do x++ and not ++x here.\n            return $._nonces[owner]++;\n        }\n    }\n\n    /**\n     * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`.\n     */\n    function _useCheckedNonce(address owner, uint256 nonce) internal virtual {\n        uint256 current = _useNonce(owner);\n        if (nonce != current) {\n            revert InvalidAccountNonce(owner, current);\n        }\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/EIP712Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.20;\n\nimport {MessageHashUtils} from \"@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol\";\nimport {IERC5267} from \"@openzeppelin/contracts/interfaces/IERC5267.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP-712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose\n * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract\n * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to\n * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP-712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267 {\n    bytes32 private constant TYPE_HASH =\n        keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.EIP712\n    struct EIP712Storage {\n        /// @custom:oz-renamed-from _HASHED_NAME\n        bytes32 _hashedName;\n        /// @custom:oz-renamed-from _HASHED_VERSION\n        bytes32 _hashedVersion;\n\n        string _name;\n        string _version;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.EIP712\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant EIP712StorageLocation = 0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100;\n\n    function _getEIP712Storage() private pure returns (EIP712Storage storage $) {\n        assembly {\n            $.slot := EIP712StorageLocation\n        }\n    }\n\n    /**\n     * @dev Initializes the domain separator and parameter caches.\n     *\n     * The meaning of `name` and `version` is specified in\n     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP-712]:\n     *\n     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n     * - `version`: the current major version of the signing domain.\n     *\n     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n     * contract upgrade].\n     */\n    function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n        __EIP712_init_unchained(name, version);\n    }\n\n    function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n        EIP712Storage storage $ = _getEIP712Storage();\n        $._name = name;\n        $._version = version;\n\n        // Reset prior values in storage if upgrading\n        $._hashedName = 0;\n        $._hashedVersion = 0;\n    }\n\n    /**\n     * @dev Returns the domain separator for the current chain.\n     */\n    function _domainSeparatorV4() internal view returns (bytes32) {\n        return _buildDomainSeparator();\n    }\n\n    function _buildDomainSeparator() private view returns (bytes32) {\n        return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n    }\n\n    /**\n     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n     * function returns the hash of the fully encoded EIP712 message for this domain.\n     *\n     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n     *\n     * ```solidity\n     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n     *     keccak256(\"Mail(address to,string contents)\"),\n     *     mailTo,\n     *     keccak256(bytes(mailContents))\n     * )));\n     * address signer = ECDSA.recover(digest, signature);\n     * ```\n     */\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n        return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);\n    }\n\n    /**\n     * @dev See {IERC-5267}.\n     */\n    function eip712Domain()\n        public\n        view\n        virtual\n        returns (\n            bytes1 fields,\n            string memory name,\n            string memory version,\n            uint256 chainId,\n            address verifyingContract,\n            bytes32 salt,\n            uint256[] memory extensions\n        )\n    {\n        EIP712Storage storage $ = _getEIP712Storage();\n        // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n        // and the EIP712 domain is not reliable, as it will be missing name and version.\n        require($._hashedName == 0 && $._hashedVersion == 0, \"EIP712: Uninitialized\");\n\n        return (\n            hex\"0f\", // 01111\n            _EIP712Name(),\n            _EIP712Version(),\n            block.chainid,\n            address(this),\n            bytes32(0),\n            new uint256[](0)\n        );\n    }\n\n    /**\n     * @dev The name parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712Name() internal view virtual returns (string memory) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        return $._name;\n    }\n\n    /**\n     * @dev The version parameter for the EIP712 domain.\n     *\n     * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n     * are a concern.\n     */\n    function _EIP712Version() internal view virtual returns (string memory) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        return $._version;\n    }\n\n    /**\n     * @dev The hash of the name parameter for the EIP712 domain.\n     *\n     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n     */\n    function _EIP712NameHash() internal view returns (bytes32) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        string memory name = _EIP712Name();\n        if (bytes(name).length > 0) {\n            return keccak256(bytes(name));\n        } else {\n            // If the name is empty, the contract may have been upgraded without initializing the new storage.\n            // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n            bytes32 hashedName = $._hashedName;\n            if (hashedName != 0) {\n                return hashedName;\n            } else {\n                return keccak256(\"\");\n            }\n        }\n    }\n\n    /**\n     * @dev The hash of the version parameter for the EIP712 domain.\n     *\n     * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n     */\n    function _EIP712VersionHash() internal view returns (bytes32) {\n        EIP712Storage storage $ = _getEIP712Storage();\n        string memory version = _EIP712Version();\n        if (bytes(version).length > 0) {\n            return keccak256(bytes(version));\n        } else {\n            // If the version is empty, the contract may have been upgraded without initializing the new storage.\n            // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n            bytes32 hashedVersion = $._hashedVersion;\n            if (hashedVersion != 0) {\n                return hashedVersion;\n            } else {\n                return keccak256(\"\");\n            }\n        }\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS\n    }\n\n    /**\n     * @dev The signature derives the `address(0)`.\n     */\n    error ECDSAInvalidSignature();\n\n    /**\n     * @dev The signature has an invalid length.\n     */\n    error ECDSAInvalidSignatureLength(uint256 length);\n\n    /**\n     * @dev The signature has an S value that is in the upper half order.\n     */\n    error ECDSAInvalidSignatureS(bytes32 s);\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not\n     * return address(0) without also returning an error description. Errors are documented using an enum (error type)\n     * and a bytes32 providing additional information about the error.\n     *\n     * If no error is returned, then the address can be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes memory signature\n    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly (\"memory-safe\") {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures]\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {\n        unchecked {\n            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n            // We do not check for an overflow here since the shift operation results in 0 or 1.\n            uint8 v = uint8((uint256(vs) >> 255) + 27);\n            return tryRecover(hash, v, r, s);\n        }\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS, s);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature, bytes32(0));\n        }\n\n        return (signer, RecoverError.NoError, bytes32(0));\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.\n     */\n    function _throwError(RecoverError error, bytes32 errorArg) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert ECDSAInvalidSignature();\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert ECDSAInvalidSignatureLength(uint256(errorArg));\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert ECDSAInvalidSignatureS(errorArg);\n        }\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Errors.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of common custom errors used in multiple contracts\n *\n * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.\n * It is recommended to avoid relying on the error API for critical functionality.\n *\n * _Available since v5.1._\n */\nlibrary Errors {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error InsufficientBalance(uint256 balance, uint256 needed);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedCall();\n\n    /**\n     * @dev The deployment failed.\n     */\n    error FailedDeployment();\n\n    /**\n     * @dev A necessary precompile is missing.\n     */\n    error MissingPrecompile(address);\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Panic.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/MessageHashUtils.sol)\n\npragma solidity ^0.8.20;\n\nimport {Strings} from \"../Strings.sol\";\n\n/**\n * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.\n *\n * The library provides methods for generating a hash of a message that conforms to the\n * https://eips.ethereum.org/EIPS/eip-191[ERC-191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]\n * specifications.\n */\nlibrary MessageHashUtils {\n    /**\n     * @dev Returns the keccak256 digest of an ERC-191 signed data with version\n     * `0x45` (`personal_sign` messages).\n     *\n     * The digest is calculated by prefixing a bytes32 `messageHash` with\n     * `\"\\x19Ethereum Signed Message:\\n32\"` and hashing the result. It corresponds with the\n     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\n     *\n     * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with\n     * keccak256, although any bytes32 value can be safely used because the final digest will\n     * be re-hashed.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\") // 32 is the bytes-length of messageHash\n            mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix\n            digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)\n        }\n    }\n\n    /**\n     * @dev Returns the keccak256 digest of an ERC-191 signed data with version\n     * `0x45` (`personal_sign` messages).\n     *\n     * The digest is calculated by prefixing an arbitrary `message` with\n     * `\"\\x19Ethereum Signed Message:\\n\" + len(message)` and hashing the result. It corresponds with the\n     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {\n        return\n            keccak256(bytes.concat(\"\\x19Ethereum Signed Message:\\n\", bytes(Strings.toString(message.length)), message));\n    }\n\n    /**\n     * @dev Returns the keccak256 digest of an ERC-191 signed data with version\n     * `0x00` (data with intended validator).\n     *\n     * The digest is calculated by prefixing an arbitrary `data` with `\"\\x19\\x00\"` and the intended\n     * `validator` address. Then hashing the result.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(hex\"19_00\", validator, data));\n    }\n\n    /**\n     * @dev Returns the keccak256 digest of an EIP-712 typed data (ERC-191 version `0x01`).\n     *\n     * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with\n     * `\\x19\\x01` and hashing the result. It corresponds to the hash signed by the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.\n     *\n     * See {ECDSA-recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            mstore(ptr, hex\"19_01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            digest := keccak256(ptr, 0x42)\n        }\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC5267.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.20;\n\ninterface IERC5267 {\n    /**\n     * @dev MAY be emitted to signal that the domain could have changed.\n     */\n    event EIP712DomainChanged();\n\n    /**\n     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n     * signature.\n     */\n    function eip712Domain()\n        external\n        view\n        returns (\n            bytes1 fields,\n            string memory name,\n            string memory version,\n            uint256 chainId,\n            address verifyingContract,\n            bytes32 salt,\n            uint256[] memory extensions\n        );\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Strings.sol)\n\npragma solidity ^0.8.20;\n\nimport {Math} from \"./math/Math.sol\";\nimport {SignedMath} from \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant HEX_DIGITS = \"0123456789abcdef\";\n    uint8 private constant ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev The `value` string doesn't fit in the specified `length`.\n     */\n    error StringsInsufficientHexLength(uint256 value, uint256 length);\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            assembly (\"memory-safe\") {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                assembly (\"memory-safe\") {\n                    mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toStringSigned(int256 value) internal pure returns (string memory) {\n        return string.concat(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value)));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        uint256 localValue = value;\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = HEX_DIGITS[localValue & 0xf];\n            localValue >>= 4;\n        }\n        if (localValue != 0) {\n            revert StringsInsufficientHexLength(value, length);\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal\n     * representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal\n     * representation, according to EIP-55.\n     */\n    function toChecksumHexString(address addr) internal pure returns (string memory) {\n        bytes memory buffer = bytes(toHexString(addr));\n\n        // hash the hex part of buffer (skip length + 2 bytes, length 40)\n        uint256 hashValue;\n        assembly (\"memory-safe\") {\n            hashValue := shr(96, keccak256(add(buffer, 0x22), 40))\n        }\n\n        for (uint256 i = 41; i > 1; --i) {\n            // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f)\n            if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) {\n                // case shift by xoring with 0x20\n                buffer[i] ^= 0x20;\n            }\n            hashValue >>= 4;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"},"lib/aave-umbrella/lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.20;\n\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * int256(SafeCast.toUint(condition)));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // Formula from the \"Bit Twiddling Hacks\" by Sean Eron Anderson.\n            // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift,\n            // taking advantage of the most significant (or \"sign\" bit) in two's complement representation.\n            // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result,\n            // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative).\n            int256 mask = n >> 255;\n\n            // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it.\n            return uint256((n + mask) ^ mask);\n        }\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"name":"AccessControlBadConfirmation","type":"error","inputs":[]},{"name":"AccessControlUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"neededRole","type":"bytes32","internalType":"bytes32"}]},{"name":"AssetNotInitialized","type":"error","inputs":[{"name":"asset","type":"address","internalType":"address"}]},{"name":"ClaimerNotAuthorized","type":"error","inputs":[{"name":"claimer","type":"address","internalType":"address"},{"name":"user","type":"address","internalType":"address"}]},{"name":"ECDSAInvalidSignature","type":"error","inputs":[]},{"name":"ECDSAInvalidSignatureLength","type":"error","inputs":[{"name":"length","type":"uint256","internalType":"uint256"}]},{"name":"ECDSAInvalidSignatureS","type":"error","inputs":[{"name":"s","type":"bytes32","internalType":"bytes32"}]},{"name":"EthTransferFailed","type":"error","inputs":[]},{"name":"ExpiredSignature","type":"error","inputs":[{"name":"deadline","type":"uint256","internalType":"uint256"}]},{"name":"InvalidAccountNonce","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"currentNonce","type":"uint256","internalType":"uint256"}]},{"name":"InvalidDistributionEnd","type":"error","inputs":[]},{"name":"InvalidInitialization","type":"error","inputs":[]},{"name":"InvalidMaxEmissionPerSecond","type":"error","inputs":[]},{"name":"InvalidSigner","type":"error","inputs":[{"name":"signer","type":"address","internalType":"address"},{"name":"owner","type":"address","internalType":"address"}]},{"name":"InvalidTargetLiquidity","type":"error","inputs":[]},{"name":"LengthsDontMatch","type":"error","inputs":[]},{"name":"MaxRewardsLengthReached","type":"error","inputs":[]},{"name":"NotInitializing","type":"error","inputs":[]},{"name":"OnlyRescueGuardian","type":"error","inputs":[]},{"name":"RewardNotInitialized","type":"error","inputs":[{"name":"reward","type":"address","internalType":"address"}]},{"name":"SafeCastOverflowedUintDowncast","type":"error","inputs":[{"name":"bits","type":"uint8","internalType":"uint8"},{"name":"value","type":"uint256","internalType":"uint256"}]},{"name":"SafeERC20FailedOperation","type":"error","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"AssetInitialized","type":"event","inputs":[{"name":"asset","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"ClaimerSet","type":"event","inputs":[{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"claimer","type":"address","indexed":true,"internalType":"address"},{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"flag","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"EIP712DomainChanged","type":"event","inputs":[],"anonymous":false},{"name":"ERC20Rescued","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Initialized","type":"event","inputs":[{"name":"version","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"name":"LastTimestampUpdated","type":"event","inputs":[{"name":"asset","type":"address","indexed":true,"internalType":"address"},{"name":"newTimestamp","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"NativeTokensRescued","type":"event","inputs":[{"name":"caller","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"RewardClaimed","type":"event","inputs":[{"name":"asset","type":"address","indexed":true,"internalType":"address"},{"name":"reward","type":"address","indexed":true,"internalType":"address"},{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"receiver","type":"address","indexed":false,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"RewardConfigUpdated","type":"event","inputs":[{"name":"asset","type":"address","indexed":true,"internalType":"address"},{"name":"reward","type":"address","indexed":true,"internalType":"address"},{"name":"maxEmissionPerSecond","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"distributionEnd","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"rewardPayer","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"RewardIndexUpdated","type":"event","inputs":[{"name":"asset","type":"address","indexed":true,"internalType":"address"},{"name":"reward","type":"address","indexed":true,"internalType":"address"},{"name":"newIndex","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"RewardInitialized","type":"event","inputs":[{"name":"asset","type":"address","indexed":true,"internalType":"address"},{"name":"reward","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"RoleAdminChanged","type":"event","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"previousAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"newAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"}],"anonymous":false},{"name":"RoleGranted","type":"event","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"RoleRevoked","type":"event","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"TargetLiquidityUpdated","type":"event","inputs":[{"name":"asset","type":"address","indexed":true,"internalType":"address"},{"name":"newTargetLiquidity","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"UserDataUpdated","type":"event","inputs":[{"name":"asset","type":"address","indexed":true,"internalType":"address"},{"name":"reward","type":"address","indexed":true,"internalType":"address"},{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"newIndex","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"accruedFromLastUpdate","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"DEFAULT_ADMIN_ROLE","type":"function","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"name":"MAX_REWARDS_LENGTH","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"REWARDS_ADMIN_ROLE","type":"function","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"name":"calculateCurrentEmission","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"reward","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"calculateCurrentEmissionScaled","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"reward","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"calculateCurrentUserReward","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"reward","type":"address","internalType":"address"},{"name":"user","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"calculateCurrentUserRewards","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"user","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address[]","internalType":"address[]"},{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"name":"calculateRewardIndex","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"reward","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"calculateRewardIndexes","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address[]","internalType":"address[]"},{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"name":"claimAllRewards","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address[]","internalType":"address[]"},{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"nonpayable"},{"name":"claimAllRewards","type":"function","inputs":[{"name":"assets","type":"address[]","internalType":"address[]"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address[][]","internalType":"address[][]"},{"name":"","type":"uint256[][]","internalType":"uint256[][]"}],"stateMutability":"nonpayable"},{"name":"claimAllRewardsOnBehalf","type":"function","inputs":[{"name":"assets","type":"address[]","internalType":"address[]"},{"name":"user","type":"address","internalType":"address"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address[][]","internalType":"address[][]"},{"name":"","type":"uint256[][]","internalType":"uint256[][]"}],"stateMutability":"nonpayable"},{"name":"claimAllRewardsOnBehalf","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"user","type":"address","internalType":"address"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address[]","internalType":"address[]"},{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"nonpayable"},{"name":"claimAllRewardsPermit","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"user","type":"address","internalType":"address"},{"name":"receiver","type":"address","internalType":"address"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"sig","type":"tuple","components":[{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}],"internalType":"struct IRewardsStructs.SignatureParams"}],"outputs":[{"name":"","type":"address[]","internalType":"address[]"},{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"nonpayable"},{"name":"claimSelectedRewards","type":"function","inputs":[{"name":"assets","type":"address[]","internalType":"address[]"},{"name":"rewards","type":"address[][]","internalType":"address[][]"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256[][]","internalType":"uint256[][]"}],"stateMutability":"nonpayable"},{"name":"claimSelectedRewards","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"rewards","type":"address[]","internalType":"address[]"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"nonpayable"},{"name":"claimSelectedRewardsOnBehalf","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"rewards","type":"address[]","internalType":"address[]"},{"name":"user","type":"address","internalType":"address"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"nonpayable"},{"name":"claimSelectedRewardsOnBehalf","type":"function","inputs":[{"name":"assets","type":"address[]","internalType":"address[]"},{"name":"rewards","type":"address[][]","internalType":"address[][]"},{"name":"user","type":"address","internalType":"address"},{"name":"receiver","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256[][]","internalType":"uint256[][]"}],"stateMutability":"nonpayable"},{"name":"claimSelectedRewardsPermit","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"rewards","type":"address[]","internalType":"address[]"},{"name":"user","type":"address","internalType":"address"},{"name":"receiver","type":"address","internalType":"address"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"sig","type":"tuple","components":[{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}],"internalType":"struct IRewardsStructs.SignatureParams"}],"outputs":[{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"nonpayable"},{"name":"configureAssetWithRewards","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"targetLiquidity","type":"uint256","internalType":"uint256"},{"name":"newRewardConfigs","type":"tuple[]","components":[{"name":"reward","type":"address","internalType":"address"},{"name":"rewardPayer","type":"address","internalType":"address"},{"name":"maxEmissionPerSecond","type":"uint256","internalType":"uint256"},{"name":"distributionEnd","type":"uint256","internalType":"uint256"}],"internalType":"struct IRewardsStructs.RewardSetupConfig[]"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"configureRewards","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"newRewardConfigs","type":"tuple[]","components":[{"name":"reward","type":"address","internalType":"address"},{"name":"rewardPayer","type":"address","internalType":"address"},{"name":"maxEmissionPerSecond","type":"uint256","internalType":"uint256"},{"name":"distributionEnd","type":"uint256","internalType":"uint256"}],"internalType":"struct IRewardsStructs.RewardSetupConfig[]"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"eip712Domain","type":"function","inputs":[],"outputs":[{"name":"fields","type":"bytes1","internalType":"bytes1"},{"name":"name","type":"string","internalType":"string"},{"name":"version","type":"string","internalType":"string"},{"name":"chainId","type":"uint256","internalType":"uint256"},{"name":"verifyingContract","type":"address","internalType":"address"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"extensions","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"name":"emergencyEtherTransfer","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"emergencyTokenTransfer","type":"function","inputs":[{"name":"erc20Token","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"getAllAssets","type":"function","inputs":[],"outputs":[{"name":"","type":"address[]","internalType":"address[]"}],"stateMutability":"view"},{"name":"getAllRewards","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address[]","internalType":"address[]"}],"stateMutability":"view"},{"name":"getAssetAndRewardsData","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"targetLiquidity","type":"uint256","internalType":"uint256"},{"name":"lastUpdateTimestamp","type":"uint256","internalType":"uint256"}],"internalType":"struct IRewardsStructs.AssetDataExternal"},{"name":"","type":"tuple[]","components":[{"name":"addr","type":"address","internalType":"address"},{"name":"index","type":"uint256","internalType":"uint256"},{"name":"maxEmissionPerSecond","type":"uint256","internalType":"uint256"},{"name":"distributionEnd","type":"uint256","internalType":"uint256"}],"internalType":"struct IRewardsStructs.RewardDataExternal[]"}],"stateMutability":"view"},{"name":"getAssetData","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"targetLiquidity","type":"uint256","internalType":"uint256"},{"name":"lastUpdateTimestamp","type":"uint256","internalType":"uint256"}],"internalType":"struct IRewardsStructs.AssetDataExternal"}],"stateMutability":"view"},{"name":"getEmissionData","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"reward","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"targetLiquidity","type":"uint256","internalType":"uint256"},{"name":"targetLiquidityExcess","type":"uint256","internalType":"uint256"},{"name":"maxEmission","type":"uint256","internalType":"uint256"},{"name":"flatEmission","type":"uint256","internalType":"uint256"}],"internalType":"struct IRewardsStructs.EmissionData"}],"stateMutability":"view"},{"name":"getRewardData","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"reward","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"addr","type":"address","internalType":"address"},{"name":"index","type":"uint256","internalType":"uint256"},{"name":"maxEmissionPerSecond","type":"uint256","internalType":"uint256"},{"name":"distributionEnd","type":"uint256","internalType":"uint256"}],"internalType":"struct IRewardsStructs.RewardDataExternal"}],"stateMutability":"view"},{"name":"getRoleAdmin","type":"function","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"name":"getUserDataByAsset","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"user","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address[]","internalType":"address[]"},{"name":"","type":"tuple[]","components":[{"name":"index","type":"uint256","internalType":"uint256"},{"name":"accrued","type":"uint256","internalType":"uint256"}],"internalType":"struct IRewardsStructs.UserDataExternal[]"}],"stateMutability":"view"},{"name":"getUserDataByReward","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"},{"name":"reward","type":"address","internalType":"address"},{"name":"user","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"index","type":"uint256","internalType":"uint256"},{"name":"accrued","type":"uint256","internalType":"uint256"}],"internalType":"struct IRewardsStructs.UserDataExternal"}],"stateMutability":"view"},{"name":"grantRole","type":"function","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"handleAction","type":"function","inputs":[{"name":"totalSupply","type":"uint256","internalType":"uint256"},{"name":"totalAssets","type":"uint256","internalType":"uint256"},{"name":"user","type":"address","internalType":"address"},{"name":"userBalance","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"hasRole","type":"function","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"initialize","type":"function","inputs":[{"name":"governance","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"isClaimerAuthorized","type":"function","inputs":[{"name":"user","type":"address","internalType":"address"},{"name":"claimer","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"maxRescue","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"pure"},{"name":"nonces","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"renounceRole","type":"function","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"callerConfirmation","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"revokeRole","type":"function","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setClaimer","type":"function","inputs":[{"name":"claimer","type":"address","internalType":"address"},{"name":"flag","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setClaimer","type":"function","inputs":[{"name":"user","type":"address","internalType":"address"},{"name":"claimer","type":"address","internalType":"address"},{"name":"flag","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"updateAsset","type":"function","inputs":[{"name":"asset","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"6422649","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2025-06-05T11:40:33Z","match":"exact_match","chainId":"1","address":"0x85C3371044e49782DbE3dC23de1D77a078aFb5d0"}