RebalanceIncentivesController

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/misc/incentives/rebalance/RebalanceIncentivesController.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "@openzeppelin/contracts/access/Ownable.sol";

import "../../../libraries/utils/HealthFactorCalculator.sol";
import "../../../interfaces/internal/vault/IVaultCore.sol";
import "../../../interfaces/internal/vault/IVaultRegistry.sol";
import "../../../interfaces/internal/strategy/lending/ILenderStrategy.sol";
import "../../../interfaces/internal/strategy/farming/IFarmDispatcher.sol";
import "../../../interfaces/internal/misc/incentives/rebalance/IRebalanceIncentivesController.sol";

/**
 * @title RebalanceIncentivesController
 * @dev Contract to incentivise addresses that are processing vault rebalancing under certain conditions
 * @dev rewards for stabilizing the protocol
 * @dev note: placeholder contract - incentives are not active yet
 * @author Altitude Labs
 **/

contract RebalanceIncentivesController is Ownable, IRebalanceIncentivesController {
    uint256 public override minDeviation;
    uint256 public override maxDeviation;

    address public immutable override vault;

    /// @notice The token used for rewards payment
    address public immutable rewardToken;

    /// @notice When true, allows a single forced rebalance; resets to false after successful rebalance
    bool public forceRebalance;

    /**
     * @param rewardToken_ The token being paid out as a reward
     * @param vaultAddress_ The vault the incentives will be provided for
     * @param minDeviation_ The threshold deviation below on to send incentives
     * @param maxDeviation_ The threshold deviation above on to send incentives
     */
    constructor(address rewardToken_, address vaultAddress_, uint256 minDeviation_, uint256 maxDeviation_) {
        vault = vaultAddress_;
        rewardToken = rewardToken_;

        _setDeviation(minDeviation_, maxDeviation_);
    }

    /// @notice Set rebalance deviation
    /// @param minDeviation_ minDeviation_ value
    /// @param maxDeviation_ maxDeviation_ value
    function setDeviation(uint256 minDeviation_, uint256 maxDeviation_) external override onlyOwner {
        _setDeviation(minDeviation_, maxDeviation_);
    }

    /// @notice Force-enable canRebalance until a successful rebalance occurs
    /// @param forceRebalance_ New force flag value
    function setForceRebalance(bool forceRebalance_) external override onlyOwner {
        forceRebalance = forceRebalance_;
        emit UpdateForceRebalance(forceRebalance_);
    }

    function rebalance() external override {
        if (!canRebalance()) {
            revert RIC_CAN_NOT_REBALANCE();
        }

        // Clear force flag before a rebalance
        if (forceRebalance) {
            forceRebalance = false;
        }
        IVaultCoreV1(vault).rebalance();
    }

    /// @return The current LTV ratio of the vault, 18 decimals
    function currentThreshold() public view override returns (uint256) {
        ILenderStrategy activeLenderStrategy = ILenderStrategy(IVaultCoreV1(vault).activeLenderStrategy());

        uint256 supplyInBase = activeLenderStrategy.convertToBase(
            activeLenderStrategy.supplyBalance(),
            activeLenderStrategy.supplyAsset(),
            activeLenderStrategy.borrowAsset()
        );

        uint256 totalBorrowed = activeLenderStrategy.borrowBalance();

        return (totalBorrowed * 1e18) / supplyInBase;
    }

    /// @notice check if the msg.sender will be incentivised for processing the rebalance
    /// @return true if the msg.sender will be incentivised for processing the rebalance
    /// @dev note: placeholder function - incentives are not active yet
    function canRebalance() public view override returns (bool) {
        if (forceRebalance) {
            return true;
        }
        uint256 threshold = currentThreshold();
        address activeFarmStrategy = IVaultCoreV1(vault).activeFarmStrategy();

        uint256 targetThreshold = IVaultCoreV1(vault).targetThreshold();
        uint256 minThreshold = targetThreshold - (targetThreshold * minDeviation) / 1e18;
        uint256 maxThreshold = targetThreshold + (targetThreshold * maxDeviation) / 1e18;

        if (threshold < minThreshold) {
            // should borrow
            if (IFarmDispatcher(activeFarmStrategy).availableLimit() > 0) {
                // has space to deposit
                return true;
            }
        }
        if (threshold > maxThreshold) {
            (uint256 balanceAvailable, ) = IFarmDispatcher(activeFarmStrategy).balanceAvailable();
            // should repay
            if (balanceAvailable > 0 && IVaultCoreV1(vault).debtToken().balanceOf(address(vault)) > 0) {
                // has funds to withdraw
                return true;
            }
        }
        return false;
    }

    /// @notice validate the provided deviations
    /// @param minDeviation_ minDeviation_ value
    /// @param maxDeviation_ maxDeviation_ value
    function _validateDeviations(uint256 minDeviation_, uint256 maxDeviation_) internal pure {
        // Check that the maxDeviation is not too high
        if (maxDeviation_ > 1e18) {
            // 1e18 represents a 100%. maxDeviation_ is in percentage
            revert RIC_INVALID_DEVIATIONS();
        }

        // Check that the minDeviation is not too high
        if (minDeviation_ > 1e18) {
            // 1e18 represents a 100%. minDeviation_ is in percentage
            revert RIC_INVALID_DEVIATIONS();
        }
    }

    /// @notice Internal function to set rebalance deviation
    /// @param minDeviation_ minDeviation_ value
    /// @param maxDeviation_ maxDeviation_ value
    function _setDeviation(uint256 minDeviation_, uint256 maxDeviation_) internal {
        _validateDeviations(minDeviation_, maxDeviation_);
        minDeviation = minDeviation_;
        maxDeviation = maxDeviation_;

        emit UpdateRebalanceDeviation(minDeviation_, maxDeviation_);
    }
}
"
    },
    "node_modules/@openzeppelin/contracts/access/Ownable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
"
    },
    "contracts/libraries/utils/HealthFactorCalculator.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "../../interfaces/internal/strategy/lending/ILenderStrategy.sol";

/**
 * @title HealthFactorCalculator
 * @dev Calculate borrow parameters based on the deposited and borrowed amount of a user
 * @author Altitude Labs
 **/

library HealthFactorCalculator {
    /// @notice Calculate the current position's factor for a given user
    /// @param liquidationThreshold to calculate with (typically for the vault)
    /// @param totalSuppliedInBase total supplied amount in base token
    /// @param totalBorrowed total borrowed amount in base token
    /// @return User's health factor factor with 18 decimals (like liquidationThreshold)
    function healthFactor(
        uint256 liquidationThreshold,
        uint256 totalSuppliedInBase,
        uint256 totalBorrowed
    ) internal pure returns (uint256) {
        if (totalBorrowed == 0) return type(uint256).max;

        return (totalSuppliedInBase * liquidationThreshold) / totalBorrowed;
    }

    /// @notice Provides information if a user's position is healthy
    /// @param activeLenderStrategy address of the active lending strategy
    /// @param supplyUnderlying address of the underlying token of the supply token
    /// @param borrowUnderlying address of the underlying token of the borrow token
    /// @param liquidationThreshold to calculate with (typically for the vault)
    /// @param supplyAmount amount of supply tokens
    /// @param borrowAmount amount of borrow tokens
    /// @return true if the position is healthy, false if position can be liquidated
    function isPositionHealthy(
        address activeLenderStrategy,
        address supplyUnderlying,
        address borrowUnderlying,
        uint256 liquidationThreshold,
        uint256 supplyAmount,
        uint256 borrowAmount
    ) internal view returns (bool) {
        uint256 totalSuppliedInBase = ILenderStrategy(activeLenderStrategy).convertToBase(
            supplyAmount,
            supplyUnderlying,
            borrowUnderlying
        );

        return healthFactor(liquidationThreshold, totalSuppliedInBase, borrowAmount) >= 1e18; // 1e18 represents 1. In case the health factor is lower than 1, it is unhealthy position
    }

    /// @notice Calculate the amount the user can borrow
    /// @param supplyThreshold to calculate with (typically for the vault)
    /// @param totalSuppliedInBase total supplied amount in base token
    /// @param totalBorrowed total borrowed amount in base token
    /// @return Amount that can be borrowed
    function availableBorrow(
        uint256 supplyThreshold,
        uint256 totalSuppliedInBase,
        uint256 totalBorrowed
    ) internal pure returns (uint256) {
        uint256 borrowedAmountAvailable = (totalSuppliedInBase * supplyThreshold) / 1e18; // 1e18 represents a 100%. supplyThreshold is in percentage
        if (borrowedAmountAvailable < totalBorrowed) {
            return 0;
        }

        return borrowedAmountAvailable - totalBorrowed;
    }

    /// @notice Calculate our desired borrow for a given supply amount
    /// @param activeLenderStrategy address of the active lending strategy
    /// @param supplyUnderlying address of the underlying token of the supply token
    /// @param borrowUnderlying address of the underlying token of the borrow token
    /// @param targetThreshold to calculate with (typically for the vault)
    /// @param supplyAmount amount of supply tokens
    function targetBorrow(
        address activeLenderStrategy,
        address supplyUnderlying,
        address borrowUnderlying,
        uint256 targetThreshold,
        uint256 supplyAmount
    ) internal view returns (uint256) {
        return
            (ILenderStrategy(activeLenderStrategy).convertToBase(supplyAmount, supplyUnderlying, borrowUnderlying) *
                targetThreshold) / 1e18; // 1e18 represents a 100%. targetThreshold is in percentage
    }
}
"
    },
    "contracts/interfaces/internal/vault/IVaultCore.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "./IVaultStorage.sol";
import "./extensions/groomable/IGroomableVault.sol";
import "./extensions/snapshotable/ISnapshotableVault.sol";
import "./extensions/liquidatable/ILiquidatableVault.sol";
import "./extensions/configurable/IConfigurableVault.sol";

/**
 * @author Altitude Protocol
 **/

interface IVaultCoreV1 is
    IVaultStorage,
    IConfigurableVaultV1,
    IGroomableVaultV1,
    ILiquidatableVaultV1,
    ISnapshotableVaultV1
{
    event Deposit(address indexed depositor, address indexed onBehalfOf, uint256 amount);
    event Borrow(address indexed borrower, address indexed onBehalfOf, uint256 amount);
    event Withdraw(
        address indexed withdrawer,
        address indexed recipient,
        uint256 amount,
        uint256 fee,
        uint256 lenderFee
    );
    event Repay(address indexed repayer, address indexed onBehalfOf, uint256 amount);
    event RepayBadDebt(address indexed repayer, address indexed onBehalfOf, uint256 amount);

    // Vault Core V1 Errors
    error VC_V1_USER_HAS_SUPPLY();
    error VC_V1_NOT_ENOUGH_SUPPLY();
    error VC_V1_INVALID_REPAY_AMOUNT();
    error VC_V1_INVALID_BORROW_AMOUNT();
    error VC_V1_INVALID_DEPOSIT_AMOUNT();
    error VC_V1_INVALID_WITHDRAW_AMOUNT();
    error VC_V1_ETH_INSUFFICIENT_AMOUNT();
    error VC_V1_FARM_WITHDRAW_INSUFFICIENT();
    error VC_V1_NOT_ALLOWED_TO_ACT_ON_BEHALF();
    error VC_V1_NOT_AUTHORIZED_TO_DEAL_WITH_TRANSFERS();
    error VC_V1_UNHEALTHY_VAULT_RISK();
    error VC_V1_NO_DEBT_TO_REPAY();

    function preTransfer(address from, address to, uint256 amount, bytes4 transferSelector) external;

    function postTransfer(address from, address to) external;

    function deposit(uint256 amount, address onBehalfOf) external payable;

    function borrow(uint256 amount) external;

    function borrowOnBehalfOf(uint256 amount, address onBehalfOf, uint256 deadline, bytes calldata signature) external;

    function withdraw(uint256 amount, address to) external returns (uint256);

    function repay(uint256 amount, address onBehalfOf) external returns (uint256);

    function repayBadDebt(uint256 amount, address onBehalfOf) external returns (uint256);

    function depositAndBorrow(uint256 depositAmount, uint256 borrowAmount) external payable;

    function repayAndWithdraw(
        uint256 repayAmount,
        uint256 withdrawAmount,
        address to
    ) external returns (uint256, uint256);

    function calcWithdrawFee(address account, uint256 withdrawAmount) external view returns (uint256, uint256);
}
"
    },
    "contracts/interfaces/internal/vault/IVaultRegistry.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "../../../libraries/types/VaultTypes.sol";

/**
 * @author Altitude Protocol
 **/

interface IVaultRegistryV1 {
    enum ManagingRoles {
        FUNCTIONS,
        FUNCTIONALITY,
        EMERGENCY
    }

    event SetManager(address manager, ManagingRoles role);
    event VaultDeployed(
        address vault,
        address indexed supplyAsset,
        address indexed borrowAsset,
        address supplyToken,
        address debtToken
    );

    event UpdateVaultConfig(
        address indexed vault,
        address configurableManager,
        address swapStrategy,
        address ingressControl,
        address borrowVerifier,
        uint256 withdrawFeeFactor,
        uint256 withdrawFeePeriod
    );
    event UpdateSnapshotableConfig(address indexed vault, address snapshotableManager, uint256 reserveFactor);
    event UpdateGroomableConfig(
        address indexed vault,
        address groomableManager,
        address flashLoanStrategy,
        uint256 maxMigrationFeePercentage
    );
    event UpdateLiquidationConfig(
        address indexed vault,
        address liquidatableManager,
        uint256 maxPositionLiquidation,
        uint256 liquidationBonus
    );

    event UpdateBorrowLimits(
        address indexed vault,
        uint256 supplyThreshold,
        uint256 liquidationThreshold,
        uint256 targetThreshold
    );

    event DisableOnBehalfValidation(address indexed vault, bytes4[] functions, bool toDisable);
    event WithdrawnReserve(address indexed vault, address receiver, uint256 amount, uint256 amountWithdrawn);
    event InjectSupply(address indexed vault, uint256 amount);
    event UpdateProxyAdmin(address newProxyAdmin);
    event UpdateInitImpl(address newInitImpl);
    event UpdateTokensFactory(address newTokensFactory);
    event SetVaultReserveReceiver(address receiver);
    event ReduceTargetThreshold(address indexed vault, uint256 targetThreshold);

    // Vault Registry V1 Errors
    error VR_V1_ZERO_ADDRESS();
    error VR_V1_NONEXISTING_VAUlT();
    error VR_V1_NOT_EMERGENCY_MANAGER();
    error VR_V1_NOT_FUNCTIONS_MANAGER();
    error VR_V1_ALREADY_EXISTING_VAULT();
    error VR_V1_NOT_FUNCTIONALITY_MANAGER();

    function tokensFactory() external view returns (address);

    function vaultInitImpl() external view returns (address);

    function vaultInitCodeHash() external view returns (bytes32);

    function proxyAdmin() external view returns (address);

    function vaultsArray(uint256 index) external view returns (address);

    function vaults(address supplyAsset, address borrowAsset) external view returns (address);

    function initialize(VaultTypes.RegistryConfiguration memory config) external;

    function vaultAddress(address supplyAsset, address borrowAsset) external view returns (address);

    function vaultReserveReceiver() external view returns (address);

    function createVault(
        address supplyAsset,
        address borrowAsset,
        uint256 supplyMathUnits,
        uint256 debtMathUnits,
        address vaultLogic,
        VaultTypes.VaultData memory vaultData
    ) external;

    function harvestVault(address supplyAsset, address borrowAsset, uint256 price) external;

    function injectBorrowAssetsInVault(address supplyAsset, address borrowAsset, uint256 amount) external;

    function changeVaultLendingProvider(address supplyAsset, address borrowAsset, address newProvider) external;

    function changeVaultFarmDispatcher(address supplyAsset, address borrowAsset, address newFarmDispatcher) external;

    function setVaultConfig(
        address supplyAsset,
        address borrowAsset,
        VaultTypes.VaultConfig memory vaultConfig
    ) external;

    function setSnapshotableConfig(
        address supplyAsset,
        address borrowAsset,
        VaultTypes.SnapshotableConfig memory snapshotableConfig
    ) external;

    function setGroomableConfig(
        address supplyAsset,
        address borrowAsset,
        VaultTypes.GroomableConfig memory groomableConfig
    ) external;

    function setLiquidationConfig(
        address supplyAsset,
        address borrowAsset,
        VaultTypes.LiquidatableConfig memory liquidatableConfig
    ) external;

    function setVaultBorrowLimits(
        address supplyAsset,
        address borrowAsset,
        VaultTypes.BorrowLimits memory borrowLimits
    ) external;

    function reduceVaultTargetThreshold(address supplyAsset, address borrowAsset, uint256 targetThreshold) external;

    function setProxyAdmin(address newProxyAdmin) external;

    function setInitImpl(address newInitImpl) external;

    function setTokensFactory(address newTokensFactory) external;

    function disableVaultOnBehalfValidation(
        address supplyAsset,
        address borrowAsset,
        bytes4[] memory functions,
        bool toDisable
    ) external;

    function setVaultReserveReceiver(address receiver) external;

    function withdrawVaultReserve(address supplyAsset, address borrowAsset, uint256 amount) external;

    function injectSupplyInVault(address supplyAsset, address borrowAsset, uint256 amount, uint256 index) external;

    function vaultsCount() external view returns (uint256);
}
"
    },
    "contracts/interfaces/internal/strategy/lending/ILenderStrategy.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "../swap/ISwapStrategyConfiguration.sol";

/**
 * @author Altitude Protocol
 **/

interface ILenderStrategy is ISwapStrategyConfiguration {
    event SetMaxDepositFee(uint256 depositFee);
    event RewardsRecognition(uint256 rewards);
    event ReconcileBorrowLoss(uint256 amount);

    error LS_ONLY_VAULT();
    error LS_ZERO_ADDRESS();
    error LS_DEPOSIT_FEE_TOO_BIG();
    error LS_WITHDRAW_INSUFFICIENT();
    error LS_BORROW_INSUFFICIENT(uint256 requestedBorrow, uint256 actualBorrow);
    error LS_INVALID_ASSET_PAIR();

    function vault() external view returns (address);

    function supplyAsset() external view returns (address);

    function borrowAsset() external view returns (address);

    function maxDepositFee() external view returns (uint256);

    function supplyPrincipal() external view returns (uint256);

    function borrowPrincipal() external view returns (uint256);

    function rewardsRecipient() external view returns (address);

    function setMaxDepositFee(uint256 depositFee) external;

    function deposit(uint256 amount) external returns (uint256);

    function withdraw(uint256 amount) external returns (uint256 amountOut);

    function borrow(uint256 amount) external;

    function repay(uint256 amount) external;

    function withdrawAll() external;

    function getLendingPool() external view returns (address);

    function borrowBalance() external view returns (uint256);

    function supplyBalance() external view returns (uint256);

    function hasSupplyLoss() external view returns (bool);

    function availableBorrowLiquidity() external view returns (uint256);

    function preSupplyLossSnapshot() external returns (uint256 supplyLoss, uint256 borrowLoss, uint256 fee);

    function updatePrincipal() external;

    function reconcileBorrowLoss() external;

    function resetPrincipal(uint256 supplyPrincipal, uint256 borrowPrincipal) external;

    function getInBase(address fromAsset, address toAsset) external view returns (uint256);

    function convertToBase(uint256 amount, address fromAsset, address toAsset) external view returns (uint256);

    function paidLiquidationFee(uint256 supplyLoss) external view returns (uint256 fee);

    function recogniseRewardsInBase() external returns (uint256 rewards);
}
"
    },
    "contracts/interfaces/internal/strategy/farming/IFarmDispatcher.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";

interface IFarmDispatcher is IAccessControl {
    struct Strategy {
        bool active;
        uint256 maxAmount;
        uint256 totalDeposit;
        address prev;
        address next;
    }

    event Disable(uint256 amount);
    event Enable(uint256 amount);
    event Withdraw(uint256 amount);
    event WithdrawAll(uint256 amount);
    event SetStrategyMax(address strategyAddress, uint256 max);
    event SetStrategyPiority(address strategy, address strategyPosition);
    event Dispatch(uint256 amount);
    event StrategyError(address strategy, bytes lowLevelData);

    event DeactivateStrategy(address strategyAddress, bool toWithdraw);
    event AddStrategy(address strategyAddress, uint256 max, address position);
    event RecogniseRewards(uint256 allRewards, uint256 failedStrategies);

    error FD_ONLY_VAULT();
    error FD_VAULT_OR_OWNER();
    error FD_STRATEGY_EXISTS();
    error FD_ZERO_ASSET();
    error FS_EMPTY_STRATEGIES();
    error FS_STRATEGIES_MISMATCH();
    error FD_ZERO_STRATEGY_REMOVAL();
    error FD_STRATEGY_PRIORITY_THE_SAME();
    error FD_INACTIVE_STRATEGY();
    error FD_INACTIVE_STRATEGY_POSITION();
    error FD_INVALID_STRATEGY_DISPATCHER();

    function vault() external view returns (address);

    function asset() external view returns (address);

    function STRATEGY_ZERO() external view returns (address);

    function strategies(address) external view returns (bool, uint256, uint256, address, address);

    function initialize(address vaultAddress, address workingAsset, address owner) external;

    function setStrategyPriority(address strategyAddress, address strategyPosition) external;

    function setStrategyMax(address strategyAddress, uint256 max) external;

    function addStrategy(address strategyAddress, uint256 max, address position) external;

    function addStrategies(address[] calldata strategies, uint256[] calldata max, address position) external;

    function deactivateStrategy(address strategyAddress, bool toWithdraw) external;

    function dispatch() external;

    function withdraw(uint256 amountRequested) external returns (uint256 amountWithdrawn);

    function balance() external view returns (uint256 totalBalance);

    function balanceAvailable() external view returns (uint256 totalBalance, uint256 failedStrategies);

    function getNextStrategy(address strategy) external view returns (address);

    function recogniseRewards() external returns (uint256 allRewards, uint256 failedStrategies);

    function availableLimit() external view returns (uint256 amount);
}
"
    },
    "contracts/interfaces/internal/misc/incentives/rebalance/IRebalanceIncentivesController.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

/**
 * @author Altitude Labs
 **/

interface IRebalanceIncentivesController {
    event UpdateRebalanceDeviation(uint256 minDeviation_, uint256 maxDeviation_);
    event UpdateForceRebalance(bool forceRebalance_);

    // Rebalance Incentives Controller Errors
    error RIC_CAN_NOT_REBALANCE();
    error RIC_INVALID_DEVIATIONS();

    function vault() external view returns (address);

    function minDeviation() external view returns (uint256);

    function maxDeviation() external view returns (uint256);

    function rewardToken() external view returns (address);

    function forceRebalance() external view returns (bool);

    function currentThreshold() external view returns (uint256);

    function canRebalance() external view returns (bool);

    function setDeviation(uint256 minDeviation_, uint256 maxDeviation_) external;

    function setForceRebalance(bool forceRebalance_) external;

    function rebalance() external;
}
"
    },
    "node_modules/@openzeppelin/contracts/utils/Context.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
"
    },
    "contracts/interfaces/internal/vault/IVaultStorage.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "../tokens/ISupplyToken.sol";
import "../tokens/IDebtToken.sol";
import "../misc/IBorrowVerifier.sol";

/**
 * @author Altitude Protocol
 **/

interface IVaultStorage {
    // Vault Storage V1 Errors
    error VS_V1_ONLY_OWNER();

    function owner() external view returns (address);

    function supplyToken() external view returns (ISupplyToken);

    function debtToken() external view returns (IDebtToken);

    function supplyUnderlying() external view returns (address);

    function borrowUnderlying() external view returns (address);

    function borrowVerifier() external view returns (IBorrowVerifier);

    function userLastDepositBlock(address) external view returns (uint256);

    function withdrawFeeFactor() external view returns (uint256);

    function withdrawFeePeriod() external view returns (uint256);

    function supplyThreshold() external view returns (uint256);

    function liquidationThreshold() external view returns (uint256);

    function targetThreshold() external view returns (uint256);

    function activeFarmStrategy() external view returns (address);

    function activeLenderStrategy() external view returns (address);

    function allowOnBehalfList(address, address) external view returns (bool);

    function onBehalfFunctions(bytes4) external view returns (bool);

    function snapshots(uint256) external view returns (uint256, uint256, uint256, uint256);

    function userSnapshots(address) external view returns (uint256);

    function configurableManager() external view returns (address);

    function swapStrategy() external view returns (address);

    function ingressControl() external view returns (address);
}
"
    },
    "contracts/interfaces/internal/vault/extensions/groomable/IGroomableVault.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "../../../../../libraries/types/VaultTypes.sol";
import "./IGroomableManager.sol";

/**
 * @author Altitude Protocol
 **/

interface IGroomableVaultV1 is IGroomableManager {
    // Groomable Vault Errors
    error GR_V1_MIGRATION_PERCENTAGE_OUT_OF_RANGE();

    function migrateLender(address newStrategy) external;

    function migrateFarmDispatcher(address newFarmDispatcher) external;

    function rebalance() external;

    function setGroomableConfig(VaultTypes.GroomableConfig memory) external;

    function getGroomableConfig() external view returns (address, address, uint256);
}
"
    },
    "contracts/interfaces/internal/vault/extensions/snapshotable/ISnapshotableVault.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "./ISnapshotableManager.sol";
import "../harvestable/IHarvestableVault.sol";
import "../supply-loss/ISupplyLossVault.sol";
import "../../../../../libraries/types/VaultTypes.sol";

/**
 * @author Altitude Protocol
 **/

interface ISnapshotableVaultV1 is ISnapshotableManager, IHarvestableVaultV1, ISupplyLossVaultV1 {
    function setSnapshotableConfig(VaultTypes.SnapshotableConfig memory config) external;

    function getSnapshotableConfig() external view returns (address, uint256);

    function calcCommitUser(
        address account,
        uint256 snapshotId
    ) external view returns (HarvestTypes.UserCommit memory commit);

    function totalSnapshots() external view returns (uint256);

    function getSnapshot(uint256 id) external view returns (CommonTypes.SnapshotType memory);
}
"
    },
    "contracts/interfaces/internal/vault/extensions/liquidatable/ILiquidatableVault.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "./ILiquidatableManager.sol";
import "../../../../../libraries/types/VaultTypes.sol";

/**
 * @author Altitude Protocol
 **/

interface ILiquidatableVaultV1 is ILiquidatableManager {
    function isUserForLiquidation(address userAddress) external view returns (bool isUserForLiquidator);

    function setLiquidationConfig(VaultTypes.LiquidatableConfig memory liqConfig) external;

    function getLiquidationConfig() external view returns (address, uint256, uint256);
}
"
    },
    "contracts/interfaces/internal/vault/extensions/configurable/IConfigurableVault.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

/**
 * @author Altitude Protocol
 **/

interface IConfigurableVaultV1 {
    // Configurable vault Errors
    error VCONF_V1_TARGET_THRESHOLD_NOT_REDUCED();
    error VCONF_V1_TARGET_THRESHOLD_OUT_OF_RANGE();
    error VCONF_V1_SUPPLY_THRESHOLD_OUT_OF_RANGE();
    error VCONF_V1_WITHDRAW_FEE_FACTOR_OUT_OF_RANGE();
    error VCONF_V1_LIQUIDATION_THRESHOLD_OUT_OF_RANGE();

    function setConfig(
        address confugrableManager_,
        address swapStrategy_,
        address ingressControl_,
        address borrowVerifier_,
        uint256 withdrawFeeFactor_,
        uint256 withdrawFeePeriod_
    ) external;

    function setBorrowLimits(
        uint256 supplyThreshold_,
        uint256 liquidationThreshold_,
        uint256 targetThreshold_
    ) external;

    function reduceTargetThreshold(uint256 targetThreshold_) external;

    function allowOnBehalf(address[] memory allowees, bool toAllow) external;

    function disableOnBehalfValidation(bytes4[] memory functions, bool toDisable) external;
}
"
    },
    "contracts/libraries/types/VaultTypes.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

/**
 * @title VaultTypes
 * @dev Input parameters for not having "Stack too deep"
 * @author Altitude Labs
 **/

library VaultTypes {
    /// @notice RegistryConfiguration parameters
    struct RegistryConfiguration {
        address registryAdmin; // global registry admin used to grant roles/access
        address tokensFactory; // tokens factory implementation
        address vaultInitImpl; // vault init implementation
        address proxyAdmin; // proxy admin implementation
    }

    /// @notice Vault BorrowLimit configuration parameters
    struct BorrowLimits {
        uint256 supplyThreshold; // loan-to-value up to which the user can borrow
        uint256 liquidationThreshold; // loan-to-value after which the user can be liquidated
        uint256 targetThreshold; // loan-to-value the vault targets to rebalance to
    }

    /// @notice Vault DefiProviders configuration parameters
    struct DefiProviders {
        address lending; // address of lending provider
        address farming; // address of farming provider
    }

    /// @notice Vault configuration parameters
    struct SnapshotableConfig {
        address snapshotableManager; // snapshotable manager implementation
        uint256 reserveFactor; // percentage of earnings to be allocated to the reserve
    }

    /// @notice Vault configuration parameters
    struct VaultConfig {
        address borrowVerifier; // borrow verifier implementation
        uint256 withdrawFeeFactor; // percentage of the withdraw fee
        uint256 withdrawFeePeriod; // number of blocks the withdraw fee is applied
        address configurableManager; // configurable manager implementation
        address swapStrategy; // swap strategy implementation
        address ingressControl; // ingress control implementation
    }

    /// @notice Vault Liquidation configuration parameters
    struct LiquidatableConfig {
        address liquidatableManager; // liquidatable manager implementation
        uint256 maxPositionLiquidation; // The maximum liquidation allowed by the contract, 18 decimals
        uint256 liquidationBonus; // The supply bonus that will be received by the liquidator, 18 decimals
    }

    /// @notice Vault Groomable configuration parameters
    struct GroomableConfig {
        address groomableManager; // groomable manager implementation
        address flashLoanStrategy; // flash loan strategy implementation
        uint256 maxMigrationFeePercentage; // a fixed percentage to check if the given flash loan strategy charges higher fees than we expect
    }

    /// @notice Vault Init configuration parameters
    struct VaultInit {
        VaultConfig vaultConfig; // vault configuration
        BorrowLimits borrowLimits; // borrow limits
        DefiProviders providers; // defi providers
    }

    /// @notice Vault Data parameters
    struct VaultData {
        VaultInit vaultInit; // vault init configuration
        LiquidatableConfig liquidatableConfig; // liquidatable configuration
        GroomableConfig groomableConfig; // groomable configuration
        SnapshotableConfig snapshotableConfig; // snapshotable configuration
    }
}
"
    },
    "contracts/interfaces/internal/strategy/swap/ISwapStrategyConfiguration.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "./ISwapStrategy.sol";

interface ISwapStrategyConfiguration {
    error SSC_SWAP_AMOUNT(uint256 actualAmount, uint256 expectedAmount);

    event UpdateSwapStrategy(address newSwapStrategy);

    function swapStrategy() external view returns (ISwapStrategy);

    function setSwapStrategy(address newSwapStrategy) external;
}
"
    },
    "node_modules/@openzeppelin/contracts/access/IAccessControl.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}
"
    },
    "contracts/interfaces/internal/tokens/ISupplyToken.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "./IDebtToken.sol";
import "./IInterestToken.sol";

/**
 * @author Altitude Protocol
 **/

interface ISupplyToken is IInterestToken {
    // Supply token Errors
    error ST_NOT_ENOUGH_BALANCE();
    error ST_NOT_ENOUGH_ALLOWANCE();

    function transferMax(address to) external returns (bool);

    function transferFromMax(address from, address to) external returns (bool);
}
"
    },
    "contracts/interfaces/internal/tokens/IDebtToken.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "./IInterestToken.sol";

/**
 * @author Altitude Protocol
 **/

interface IDebtToken is IInterestToken {
    // Debt token Errors
    error DT_APPROVAL_NOT_SUPPORTED();
    error DT_TRANSFER_NOT_SUPPORTED();
    error DT_ALLOWANCE_INCREASE_NOT_SUPPORTED();
    error DT_ALLOWANCE_DECREASE_NOT_SUPPORTED();

    function balanceOfDetails(address account) external view returns (uint256, uint256, uint256);
}
"
    },
    "contracts/interfaces/internal/misc/IBorrowVerifier.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

/**
 * @author Altitude Protocol
 **/

interface IBorrowVerifier {
    // Borrow Verifier Errors
    error BV_DEADLINE_PASSED();
    error BV_INVALID_SIGNATURE();
    error BV_ONLY_VAULT();
    error BV_INVALID_VAULT();

    function nonce(address) external returns (uint256);

    function verifyAndBurnNonce(
        uint256 amount,
        address onBehalfOf,
        address receiver,
        uint256 deadline,
        bytes calldata signature
    ) external;
}
"
    },
    "contracts/interfaces/internal/vault/extensions/groomable/IGroomableManager.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "../../../strategy/IFlashLoanCallback.sol";

/**
 * @author Altitude Protocol
 **/

interface IGroomableManager is IFlashLoanCallback {
    event RebalanceVaultLimit(bool shouldBorrow, uint256 calculatedAmount);
    event RebalanceVaultBorrow(uint256 amountToBorrow);
    event RebalanceVaultRepay(uint256 amountToRepay, uint256 amountWithdrawn);
    event MigrateLenderStrategy(address oldStrategy, address newStrategy);
    event MigrateFarmDispatcher(address oldFarmDispatcher, address newFarmDispatcher);

    // Groomable Manager Errors
    error GR_V1_MIGRATION_FEE_TOO_HIGH();
    error GR_V1_NOT_FLASH_LOAN_STRATEGY();
    error GR_V1_MIGRATION_OLD_SUPPLY_ERROR();
    error GR_V1_MIGRATION_OLD_BORROW_ERROR();
    error GR_V1_MIGRATION_NEW_SUPPLY_ERROR();
    error GR_V1_MIGRATION_NEW_BORROW_ERROR();
    error GR_V1_FARM_DISPATCHER_ALREADY_ACTIVE();
    error GR_V1_FARM_DISPATCHER_NOT_EMPTY();
    error GR_V1_LENDER_STRATEGY_ALREADY_ACTIVE();

    function migrateLender(address newStrategy) external;

    function migrateFarmDispatcher(address newFarmDispatcher) external;

    function rebalance() external;
}
"
    },
    "contracts/interfaces/internal/vault/extensions/snapshotable/ISnapshotableManager.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "../harvestable/IHarvestableManager.sol";
import "../supply-loss/ISupplyLossManager.sol";

/**
 * @author Altitude Protocol
 **/

interface ISnapshotableManager is IHarvestableManager, ISupplyLossManager {
    event UserCommit(
        address account,
        uint256 supplyIndex,
        uint256 supplyBalance,
        uint256 borrowIndex,
        uint256 borrowBalance,
        uint256 userHarvestUncommittedEarnings
    );
    event InjectSupply(uint256 actualInjected, uint256 amountToInject);

    function updatePosition(address account) external payable returns (uint256);

    function updatePositionTo(address account, uint256 snapshotId) external returns (uint256);

    function updatePositions(address[] calldata accounts) external returns (uint256);

    function injectSupply(uint256 targetTotalSupply, uint256 atIndex, address funder) external;
}
"
    },
    "contracts/interfaces/internal/vault/extensions/harvestable/IHarvestableVault.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "./IHarvestableManager.sol";
import "../../../../../libraries/types/HarvestTypes.sol";

/**
 * @author Altitude Protocol
 **/

interface IHarvestableVaultV1 is IHarvestableManager {
    function claimableRewards(address account) external view returns (uint256);

    function reserveAmount() external view returns (uint256);

    function getHarvest(uint256 id) external view returns (HarvestTypes.HarvestData memory);

    function getHarvestsCount() external view returns (uint256);

    function getUserHarvest(address user) external view returns (HarvestTypes.UserHarvestData memory);

    function getHarvestData()
        external
        view
        returns (uint256 realClaimableEarnings, uint256 realUncommittedEarnings, uint256 vaultReserve);
}
"
    },
    "contracts/interfaces/internal/vault/extensions/supply-loss/ISupplyLossVault.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "./ISupplyLossManager.sol";
import "../../../../../libraries/types/SupplyLossTypes.sol";

/**
 * @author Altitude Protocol
 **/

interface ISupplyLossVaultV1 is ISupplyLossManager {
    function getSupplyLossSnapshot(uint256 id) external view returns (SupplyLossTypes.SupplyLoss memory);
}
"
    },
    "contracts/interfaces/internal/vault/extensions/liquidatable/ILiquidatableManager.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

/**
 * @author Altitude Protocol
 **/

interface ILiquidatableManager {
    event LiquidateUser(address user, uint256 supplyTaken, uint256 borrowRepaid);

    event LiquidateUserDefault(address user, uint256 borrowRemaining);

    // Liquidation Errors
    error LQ_V1_MAX_BONUS_OUT_OF_RANGE();
    error LQ_V1_LIQUIDATION_CONSTRAINTS();
    error LQ_V1_INSUFFICIENT_REPAY_AMOUNT();
    error LQ_V1_MAX_POSITION_LIQUIDATION_OUT_OF_RANGE();

    function liquidateUsers(address[] calldata usersForLiquidation, uint256 repayAmountLimit) external;
}
"
    },
    "contracts/interfaces/internal/strategy/swap/ISwapStrategy.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "../../oracles/IPriceSource.sol";

/**
 * @author Altitude Protocol
 **/

interface ISwapStrategy {
    error SWAP_STRATEGY_UNKNOWN_PAIR();
    error SWAP_STRATEGY_SWAP_NOT_PROCEEDED();
    error SWAP_STRATEGY_INVALID_DESTINATION();
    error SWAP_STRATEGY_PRICE_SOURCE_GET_IN_BASE();
    error SWAP_STRATEGY_SET_SWAP_PAIR_INPUT_INVALID();
    error SWAP_STRATEGY_ROUTE_NOT_FOUND(address assetFrom, address assetTo);

    event PriceSourceUpdated(address newSource);

    function SLIPPAGE_BASE() external view returns (uint256);

    function swapRouter() external view returns (address);

    function priceSource() external view returns (IPriceSource);

    function setPriceSource(address newPriceSource) external;

    function getMinimumAmountOut(
        address assetFrom,
        address assetTo,
        uint256 baseAmount
    ) external view returns (uint256);

    function getMinimumAmountOut(
        address assetFrom,
        address assetTo,
        uint256 baseAmount,
        uint256 slippage
    ) external view returns (uint256);

    function getMaximumAmountIn(address assetFrom, address assetTo, uint256 amountOut) external view returns (uint256);

    function getMaximumAmountIn(
        address assetFrom,
        address assetTo,
        uint256 amountOut,
        uint256 slippage
    ) external view returns (uint256);

    function swapInBase(address assetFrom, address assetTo, uint256 amount) external returns (uint256);

    function swapOutBase(
        address assetFrom,
        address assetTo,
        uint256 amount,
        uint256 amountInMaximum
    ) external returns (uint256);

    function getAmountOut(
        address assetFrom,
        address assetTo,
        uint256 amountIn
    ) external view returns (uint256 amountOut);

    function getAmountIn(
        address assetFrom,
        address assetTo,
        uint256 amountOut
    ) external view returns (uint256 amountIn);
}
"
    },
    "contracts/interfaces/internal/tokens/IInterestToken.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";

/**
 * @author Altitude Protocol
 **/

interface IInterestToken is IERC20Upgradeable, IERC20MetadataUpgradeable {
    event UserSnapshot(address account, uint256 _interestIndex);

    // Interest Token Errors
    error IT_ONLY_VAULT();
    error IT_MINT_MORE_THAN_SIZE();
    error IT_INTEREST_INDEX_OUT_OF_RANGE();
    error IT_TRANSFER_BETWEEN_THE_SAME_ADDRESSES();

    function MATH_UNITS() external view returns (uint256);

    function vault() external view returns (address);

    function underlying() external view returns (address);

    function activeLenderStrategy() external view returns (address);

    function userIndex(address user) external view returns (uint256);

    function interestIndex() external view returns (uint256);

    function initialize(
        string memory name,
        string memory symbol,
        address vaultAddress,
        address underlyingAsset,
        address lenderStrategy,
        uint256 mathUnits
    ) external;

    function mint(address account, uint256 amount) external;

    function burn(address account, uint256 amount) external;

    function vaultTransfer(address owner, address to, uint256 amount) external returns (bool);

    function setActiveLenderStrategy(address newStrategy) external;

    function snapshotUser(address account) external returns (uint256, uint256);

    function snapshot() external;

    function calcNewIndex() external view returns (uint256 index);

    function calcIndex(uint256 balanceOld, uint256 balanceNew) external view returns (uint256);

    function balanceStored(address account) external view returns (uint256);

    function setInterestIndex(uint256 newIndex) external;

    function setBalance(address account, uint256 newBalance, uint256 newIndex) external;

    function storedTotalSupply() external view returns (uint256);

    function balanceOfAt(address account, uint256 snapshotId) external view returns (uint256);
}
"
    },
    "contracts/interfaces/internal/strategy/IFlashLoanCallback.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

/**
 * @author Altitude Protocol
 **/

interface IFlashLoanCallback {
    function flashLoanCallback(bytes calldata, uint256) external;
}
"
    },
    "contracts/interfaces/internal/vault/extensions/harvestable/IHarvestableManager.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

/**
 * @author Altitude Protocol
 **/

interface IHarvestableManager {
    event Harvested(
        uint256 harvestId,
        uint256 distributableProfit,
        uint256 vaultLoss,
        uint256 uncommittedLossPerc,
        uint256 claimableLossPerc
    );

    event ClaimedRewards(address indexed account, uint256 amountClaimed, uint256 debtRepayed);

    event InjectedBorrowAssets(uint256 amount);

    // Harvest Errors
    error HM_V1_BLOCK_ERROR();
    error HM_V1_INVALID_INJECT_AMOUNT();
    error HM_V1_HARVEST_ERROR();
    error HM_V1_PRICE_TOO_LOW();
    error HM_V1_INVALID_COMMIT();
    error HM_V1_CLAIM_REWARDS_ZERO();
    error HV_V1_HM_NO_ACTIVE_ASSETS();
    error HV_V1_RESERVE_FACTOR_OUT_OF_RANGE();
    error HM_V1_TOO_BIG_FARM_LOSS(uint256 farmRewardsLoss);
    error HM_V1_FARM_MODE_RESERVE_NOT_ENOUGH();

    function harvest(uint256 price) external;

    function withdrawReserve(address receiver, uint256 amount) external returns (uint256);

    function claimRewards(uint256 amountRequested) external returns (uint256);

    function injectBorrowAssets(uint256 amount) external;
}
"
    },
    "contracts/interfaces/internal/vault/extensions/supply-loss/ISupplyLossManager.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

/**
 * @author Altitude Protocol
 **/

interface ISupplyLossManager {
    event SupplyLossSnapshot(uint256 snapshotId);

    event WithdrawVaultBorrows(uint256 withdrawn, uint256 vaultBorrows);

    event InjectVaultWindfall(uint256 vaultWindfall, uint256 expectedAmountOut, uint256 amountOut, uint256 slippageFee);

    event RepayVaultRemaining(uint256 vaultBorrowsRemaining, uint256 maxBalance);

    function snapshotSupplyLoss() external;
}
"
    },
    "contracts/libraries/types/HarvestTypes.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "./CommonTypes.sol";

/**
 * @title HarvestTypes
 * @notice Harvest storage types
 * @author Altitude Labs
 **/

library HarvestTypes {
    /// @notice track the committable data for a user, detailing incremental adjustements to the user position
    struct UserCommit {
        uint256 blockNumber; // block number of the commit
        uint256 harvestId; // harvest id of the commit
        uint256 userClaimableEarnings; // user claimable earnings
        uint256 userHarvestJoiningBlock; // user harvest joining block
        uint256 userHarvestUncommittedEarnings; // user harvest uncommitted earnings
        uint256 vaultReserveUncommitted; // vault reserve uncommitted
        CommonTypes.UserPosition position; // user position
    }

    /// @notice track data for a single harvest, used for commit calculations
    struct HarvestData {
        uint256 harvestId; // harvest id
        uint256 farmEarnings; // farm earnings in the harvest
        uint256 vaultLoss; // farm loss applicable for the vault balance
        uint256 uncommittedLossPerc; // farm loss applicable in percentage for the uncommitted earnings
        uint256 claimableLossPerc; // farm loss applicable in percentage  for the claimable rewards
        uint256 activeAssetsThreshold; // active assets threshold for the harvest
        uint256 divertEarningsThreshold; // divert earnings threshold for the harvest
        uint256 vaultActiveAssets; // vault active assets
        uint256 price; // price for the harvest
        uint256 blockNumber; // block number for the harvest
    }

    /// @notice track data for a user's harvest
    struct UserHarvestData {
        uint256 harvestId; // harvest id
        uint256 harvestJoiningBlock; // harvest joining block
        uint256 claimableEarnings; // claimable earnings
        uint256 uncommittedEarnings; // uncommitted earnings (needed for partial commits)
        uint256 vaultReserveUncommitted; // vault reserve uncommitted (needed for partial commits)
    }

    /// @notice harvest storage for multiple harvests, used for commit calculations
    struct HarvestStorage {
        uint256 vaultReserve; // amount allocated to the vault reserve
        uint256 realClaimableEarnings; // total amount of known claimable earnings (users have committed)
        uint256 realUncommittedEarnings; // total amount of uncommitted earnings (prior to type allocation during commit)
        HarvestData[] harvests; // array of all harvests
        uint256 reserveFactor; // percentage of earnings to be allocated to the reserve
        mapping(address => UserHarvestData) userHarvest; // user => userHarvestData - harvest data for users
    }
}
"
    },
    "contracts/libraries/types/SupplyLossTypes.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

/**
 * @title SupplyLossTypes
 * @dev Input parameters for not having "Stack too deep"
 * @author Altitude Labs
 **/

library SupplyLossTypes {
    // @notice track data for a supply loss
    struct SupplyLoss {
        uint256 supplyLossAtSnapshot; // total reduction of supply, less fees
        uint256 supplyLossProfit; // interest earned on supply (if any, zero if supplyLossAtSnapshot > 0)
        uint256 borrowLossAtSnapshot; // total reduction of borrows
        uint256 supplyBalanceAtSnapshot; // vault total supplied at snapshot
        uint256 borrowBalanceAtSnapshot; // vault total user borrows at snapshot
        uint256 fee; // combination of liquidation penalty, slippage and deposit fees
        uint256 withdrawShortage; // vault farm balance less farm withdrawal amount (if any)
    }

    // @notice supply loss storage
    struct SupplyLossStorage {
        SupplyLoss[] supplyLosses; // array of all supply loss snapshots
    }
}
"
    },
    "contracts/interfaces/internal/oracles/IPriceSource.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;

/**
 * @author Altitude Protocol
 **/

interface IPriceSource {
    /// @return Price of 1 `fromAsset` in `toAsset`, using toAsset's decimal count
    function getInBase(address fromAsset, address toAsset) external view returns (uint256);

    /// @return Price of 1 `fromAsset` in USD, using 8 decimal count
    function getInUSD(address fromAsset) external view returns (uint256);
}
"
    },
    "node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20Upgradeable {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}
"
    },
    "node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20Upgradeable.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20MetadataUpgradeable is IERC20Upgradeable {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}
"
    },
    "contracts/libraries/types/CommonTypes.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

/**
 * @title CommonTypes
 * @dev Input parameters for not having "Stack too deep"
 * @author Altitude Labs
 **/

library CommonTypes {
    /// @notice struct for the supply and borrow position of a user
    struct UserPosition {
        uint256 supplyIndex; // supplyIndex for the user
        uint256 supplyBalance; // supplyBalance for the user
        uint256 borrowIndex; // borrowIndex for the user
        uint256 borrowBalance; // borrowBalance for the user
    }

    /// @notice defines the different types of snapshots
    enum SnapshotClass {
        Harvest,
        SupplyLoss
    }

    /// @notice struct for different commit types
    struct SnapshotType {
        uint256 id; // id of the snapshot
        uint256 kind; // kind of the snapshot, where 0 is harvest, 1 is supply loss
        uint256 supplyIndex; // supplyIndex for the snapshot
        uint256 borrowIndex; // borrowIndex for the snapshot
    }
}
"
    }
  },
  "settings": {
    "remappings": [
      "@chainlink/=node_modules/@chainlink/",
      "@eth-optimism/=node_modules/@pendle/core-v2/node_modules/@eth-optimism/",
      "@morpho-org/=node_modules/@morpho-org/",
      "@openzeppelin/=node_modules/@openzeppelin/",
      "@pendle/=node_modules/@pendle/",
      "@uniswap/=node_modules/@uniswap/",
      "base64-sol/=node_modules/base64-sol/",
      "forge-std/=lib/forge-std/src/",
      "hardhat/=node_modules/hardhat/"
    ],
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "metadata": {
      "useLiteralContent": false,
      "bytecodeHash": "ipfs",
      "appendCBOR": true
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "evmVersion": "cancun",
    "viaIR": false
  }
}}

Tags:
ERC20, Multisig, Mintable, Burnable, Swap, Upgradeable, Multi-Signature, Factory, Oracle|addr:0x5603578cad65ca5ccb9e3d1e8c2f346481ae768d|verified:true|block:23448087|tx:0x15a74f3165ecc3b241b22e83a4ed3605fadced1b9ffc6ebd20d14ceeeb11e822|first_check:1758901862

Submitted on: 2025-09-26 17:51:05

Comments

Log in to comment.

No comments yet.