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;
/**
* @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_);
}
function rebalance() external override {
if (!canRebalance()) {
revert RIC_CAN_NOT_REBALANCE();
}
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) {
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) {
return true;
}
if (threshold > maxThreshold) {
if (
IFarmDispatcher(activeFarmStrategy).balance() > 0 &&
IVaultCoreV1(vault).debtToken().balanceOf(address(vault)) > 0
) {
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_);
// 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 currentThreshold() external view returns (uint256);
function canRebalance() external view returns (bool);
function setDeviation(uint256 minDeviation_, uint256 maxDeviation_) 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
}
}}
Submitted on: 2025-09-26 15:09:31
Comments
Log in to comment.
No comments yet.