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/compressors/subcompressors/withdrawal/MellowWithdrawalSubcompressor.sol": {
"content": "// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundaiton, 2025.
pragma solidity ^0.8.23;
import {ICreditAccountV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditAccountV3.sol";
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
import {IWithdrawalSubcompressor} from "../../../interfaces/IWithdrawalSubcompressor.sol";
import {
WithdrawalOutput,
WithdrawableAsset,
RequestableWithdrawal,
ClaimableWithdrawal,
PendingWithdrawal,
WithdrawalLib
} from "../../../types/WithdrawalInfo.sol";
import {MultiCall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol";
import {MellowWithdrawalPhantomToken} from
"@gearbox-protocol/integrations-v3/contracts/helpers/mellow/MellowWithdrawalPhantomToken.sol";
import {
IMellowMultiVault,
IMellowWithdrawalQueue,
IEigenLayerWithdrawalQueue,
Subvault,
MellowProtocol
} from "@gearbox-protocol/integrations-v3/contracts/integrations/mellow/IMellowMultiVault.sol";
import {IMellowClaimerAdapter} from
"@gearbox-protocol/integrations-v3/contracts/interfaces/mellow/IMellowClaimerAdapter.sol";
import {IMellow4626VaultAdapter} from
"@gearbox-protocol/integrations-v3/contracts/interfaces/mellow/IMellow4626VaultAdapter.sol";
import {IERC4626Adapter} from "@gearbox-protocol/integrations-v3/contracts/interfaces/erc4626/IERC4626Adapter.sol";
import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol";
struct EpochData {
bool isClaimed;
uint256 sharesToClaim;
uint256 claimableAssets;
}
struct EigenLayerWithdrawal {
address staker;
address delegatedTo;
address withdrawer;
uint256 nonce;
uint32 startBlock;
address[] strategies;
uint256[] scaledShares;
}
interface ISymbioticSubvault {
function nextEpochStart() external view returns (uint256);
function epochDuration() external view returns (uint256);
function withdrawalsOf(uint256 epoch, address withdrawalQueue) external view returns (uint256);
}
interface IEigenLayerDelegation {
function minWithdrawalDelayBlocks() external view returns (uint256);
}
interface IEigenLayerWithdrawalQueueExt is IEigenLayerWithdrawalQueue {
function delegation() external view returns (address);
function latestWithdrawableBlock() external view returns (uint256);
function convertScaledSharesToShares(
EigenLayerWithdrawal memory withdrawal,
uint256 scaledShares,
uint256 totalScaledShares
) external view returns (uint256);
function getWithdrawalRequest(uint256 index, address account)
external
view
returns (
EigenLayerWithdrawal memory data,
bool isClaimed,
uint256 assets,
uint256 shares,
uint256 accountShares
);
function isolatedVault() external view returns (address);
function strategy() external view returns (address);
}
interface IEigenLayerIsolatedVault {
function sharesToUnderlyingView(address strategy, uint256 shares) external view returns (uint256);
}
interface ISymbioticWithdrawalQueue {
function getCurrentEpoch() external view returns (uint256);
function getAccountData(address account)
external
view
returns (uint256 sharesToClaimPrev, uint256 sharesToClaim, uint256 claimableAssets, uint256 claimEpoch);
function getEpochData(uint256 epoch) external view returns (EpochData memory);
}
interface IMellowMultiVaultExt is IMellowMultiVault {
function withdrawalStrategy() external view returns (address);
}
struct MellowWithdrawalAmounts {
uint256 subvaultIndex;
uint256 claimable;
uint256 pending;
uint256 staked;
}
interface IMellowWithdrawalStrategy {
function calculateWithdrawalAmounts(address multiVault, uint256 amount)
external
view
returns (MellowWithdrawalAmounts[] memory amounts);
}
contract MellowWithdrawalSubcompressor is IWithdrawalSubcompressor {
using WithdrawalLib for PendingWithdrawal[];
uint256 public constant version = 3_10;
bytes32 public constant contractType = "GLOBAL::MELLOW_WD_SC";
function getWithdrawableAssets(address, address token) external view returns (WithdrawableAsset[] memory) {
address multiVault = MellowWithdrawalPhantomToken(token).multiVault();
address asset = IERC4626(multiVault).asset();
WithdrawableAsset[] memory withdrawableAssets = new WithdrawableAsset[](1);
withdrawableAssets[0] = WithdrawableAsset(multiVault, token, asset, _getWithdrawalLength(multiVault));
return withdrawableAssets;
}
function getCurrentWithdrawals(address creditAccount, address token)
external
view
returns (ClaimableWithdrawal[] memory, PendingWithdrawal[] memory)
{
address multiVault = MellowWithdrawalPhantomToken(token).multiVault();
ClaimableWithdrawal[] memory claimableWithdrawals = new ClaimableWithdrawal[](1);
claimableWithdrawals[0] = _getClaimableWithdrawal(creditAccount, token, multiVault);
if (claimableWithdrawals[0].outputs.length == 0 || claimableWithdrawals[0].outputs[0].amount == 0) {
claimableWithdrawals = new ClaimableWithdrawal[](0);
}
PendingWithdrawal[] memory pendingWithdrawals = _getPendingWithdrawals(creditAccount, multiVault);
for (uint256 i = 0; i < pendingWithdrawals.length; ++i) {
pendingWithdrawals[i].withdrawalPhantomToken = token;
}
return (claimableWithdrawals, pendingWithdrawals);
}
function getWithdrawalRequestResult(address creditAccount, address token, address withdrawalToken, uint256 amount)
external
view
returns (RequestableWithdrawal memory requestableWithdrawal)
{
requestableWithdrawal.token = token;
requestableWithdrawal.amountIn = amount;
uint256 assets = IERC4626(token).convertToAssets(amount);
address withdrawalStrategy = IMellowMultiVaultExt(token).withdrawalStrategy();
MellowWithdrawalAmounts[] memory amounts =
IMellowWithdrawalStrategy(withdrawalStrategy).calculateWithdrawalAmounts(token, assets);
uint256 liquid = assets;
for (uint256 i = 0; i < amounts.length; ++i) {
Subvault memory subvault = IMellowMultiVault(token).subvaultAt(amounts[i].subvaultIndex);
if (subvault.protocol == MellowProtocol.SYMBIOTIC) {
liquid -= amounts[i].staked + amounts[i].pending;
} else if (subvault.protocol == MellowProtocol.EIGEN_LAYER) {
liquid -= amounts[i].staked + amounts[i].pending;
}
}
if (liquid < assets) {
requestableWithdrawal.outputs = new WithdrawalOutput[](2);
requestableWithdrawal.outputs[0] = WithdrawalOutput(IERC4626(token).asset(), false, liquid);
requestableWithdrawal.outputs[1] = WithdrawalOutput(withdrawalToken, true, assets - liquid);
} else {
requestableWithdrawal.outputs = new WithdrawalOutput[](1);
requestableWithdrawal.outputs[0] = WithdrawalOutput(IERC4626(token).asset(), false, assets);
}
requestableWithdrawal.requestCalls = new MultiCall[](2);
address creditManager = ICreditAccountV3(creditAccount).creditManager();
address vaultAdapter = ICreditManagerV3(creditManager).contractToAdapter(token);
requestableWithdrawal.requestCalls[0] = MultiCall({
target: vaultAdapter,
callData: abi.encodeCall(IERC4626Adapter.redeem, (amount, address(0), address(0)))
});
address claimer = MellowWithdrawalPhantomToken(withdrawalToken).claimer();
address claimerAdapter = ICreditManagerV3(creditManager).contractToAdapter(claimer);
(uint256[] memory subvaultIndices, uint256[][] memory withdrawalIndices) =
IMellowClaimerAdapter(claimerAdapter).getMultiVaultSubvaultIndices(token);
requestableWithdrawal.requestCalls[1] = MultiCall({
target: claimerAdapter,
callData: abi.encodeCall(IMellowClaimerAdapter.multiAccept, (token, subvaultIndices, withdrawalIndices))
});
requestableWithdrawal.claimableAt = block.timestamp + _getWithdrawalLength(token);
return requestableWithdrawal;
}
function _getPendingWithdrawals(address creditAccount, address multiVault)
internal
view
returns (PendingWithdrawal[] memory pendingWithdrawals)
{
address asset = IERC4626(multiVault).asset();
uint256 nSubvaults = IMellowMultiVault(multiVault).subvaultsCount();
for (uint256 i = 0; i < nSubvaults; ++i) {
Subvault memory subvault = IMellowMultiVault(multiVault).subvaultAt(i);
if (subvault.withdrawalQueue == address(0)) continue;
uint256 pendingAssets = IMellowWithdrawalQueue(subvault.withdrawalQueue).pendingAssetsOf(creditAccount);
if (pendingAssets > 0) {
pendingWithdrawals = pendingWithdrawals.concat(
_getSubvaultPendingWithdrawals(
creditAccount, multiVault, subvault.protocol, subvault.vault, subvault.withdrawalQueue, asset
)
);
}
}
return pendingWithdrawals;
}
function _getSubvaultPendingWithdrawals(
address creditAccount,
address multiVault,
MellowProtocol protocol,
address subvault,
address withdrawalQueue,
address asset
) internal view returns (PendingWithdrawal[] memory pendingWithdrawals) {
if (protocol == MellowProtocol.SYMBIOTIC) {
(uint256 sharesToClaimPrev, uint256 sharesToClaim,, uint256 claimEpoch) =
ISymbioticWithdrawalQueue(withdrawalQueue).getAccountData(creditAccount);
uint256 currentEpoch = ISymbioticWithdrawalQueue(withdrawalQueue).getCurrentEpoch();
if (claimEpoch < currentEpoch) {
return pendingWithdrawals;
} else if (claimEpoch == currentEpoch) {
pendingWithdrawals = new PendingWithdrawal[](1);
pendingWithdrawals[0].token = multiVault;
pendingWithdrawals[0].expectedOutputs = new WithdrawalOutput[](1);
uint256 expectedAmount =
_getSymbioticExpectedWithdrawal(subvault, withdrawalQueue, sharesToClaim, currentEpoch);
pendingWithdrawals[0].expectedOutputs[0] = WithdrawalOutput(asset, false, expectedAmount);
pendingWithdrawals[0].claimableAt = ISymbioticSubvault(subvault).nextEpochStart();
} else if (claimEpoch == currentEpoch + 1) {
pendingWithdrawals = new PendingWithdrawal[](2);
pendingWithdrawals[0].token = multiVault;
pendingWithdrawals[0].expectedOutputs = new WithdrawalOutput[](1);
uint256 expectedAmount =
_getSymbioticExpectedWithdrawal(subvault, withdrawalQueue, sharesToClaim, currentEpoch + 1);
pendingWithdrawals[0].expectedOutputs[0] = WithdrawalOutput(asset, false, expectedAmount);
pendingWithdrawals[0].claimableAt =
ISymbioticSubvault(subvault).nextEpochStart() + ISymbioticSubvault(subvault).epochDuration();
if (sharesToClaimPrev > 0) {
pendingWithdrawals[1].token = multiVault;
pendingWithdrawals[1].expectedOutputs = new WithdrawalOutput[](1);
expectedAmount =
_getSymbioticExpectedWithdrawal(subvault, withdrawalQueue, sharesToClaimPrev, currentEpoch);
pendingWithdrawals[1].expectedOutputs[0] = WithdrawalOutput(asset, false, expectedAmount);
pendingWithdrawals[1].claimableAt = ISymbioticSubvault(subvault).nextEpochStart();
}
}
}
if (protocol == MellowProtocol.EIGEN_LAYER) {
(, uint256[] memory withdrawals,) =
IEigenLayerWithdrawalQueueExt(withdrawalQueue).getAccountData(creditAccount, type(uint256).max, 0, 0, 0);
uint256 latestWithdrawableBlock = IEigenLayerWithdrawalQueueExt(withdrawalQueue).latestWithdrawableBlock();
pendingWithdrawals = new PendingWithdrawal[](withdrawals.length);
for (uint256 i = 0; i < withdrawals.length; ++i) {
(EigenLayerWithdrawal memory withdrawal,,, uint256 shares, uint256 accountShares) =
IEigenLayerWithdrawalQueueExt(withdrawalQueue).getWithdrawalRequest(withdrawals[i], creditAccount);
if (withdrawal.startBlock > latestWithdrawableBlock && accountShares > 0) {
pendingWithdrawals[i].token = multiVault;
pendingWithdrawals[i].expectedOutputs = new WithdrawalOutput[](1);
uint256 unscaledShares = IEigenLayerWithdrawalQueueExt(withdrawalQueue).convertScaledSharesToShares(
withdrawal, accountShares, shares
);
uint256 expectedAmount = IEigenLayerIsolatedVault(
IEigenLayerWithdrawalQueueExt(withdrawalQueue).isolatedVault()
).sharesToUnderlyingView(IEigenLayerWithdrawalQueueExt(withdrawalQueue).strategy(), unscaledShares);
pendingWithdrawals[i].expectedOutputs[0] = WithdrawalOutput(asset, false, expectedAmount);
pendingWithdrawals[i].claimableAt =
block.timestamp + 12 * (withdrawal.startBlock - latestWithdrawableBlock);
}
}
}
}
function _getClaimableWithdrawal(address creditAccount, address withdrawalToken, address multiVault)
internal
view
returns (ClaimableWithdrawal memory withdrawal)
{
address asset = IERC4626(multiVault).asset();
withdrawal.token = multiVault;
withdrawal.withdrawalPhantomToken = withdrawalToken;
withdrawal.outputs = new WithdrawalOutput[](1);
withdrawal.outputs[0] = WithdrawalOutput(asset, false, 0);
uint256 nSubvaults = IMellowMultiVault(multiVault).subvaultsCount();
for (uint256 i = 0; i < nSubvaults; ++i) {
Subvault memory subvault = IMellowMultiVault(multiVault).subvaultAt(i);
if (subvault.withdrawalQueue == address(0)) continue;
uint256 claimableAssets = IMellowWithdrawalQueue(subvault.withdrawalQueue).claimableAssetsOf(creditAccount);
withdrawal.outputs[0].amount += claimableAssets;
}
if (withdrawal.outputs[0].amount == 0) {
return withdrawal;
}
withdrawal.withdrawalTokenSpent = withdrawal.outputs[0].amount;
withdrawal.claimCalls = new MultiCall[](1);
address claimerAdapter;
{
address claimer = MellowWithdrawalPhantomToken(withdrawalToken).claimer();
address creditManager = ICreditAccountV3(creditAccount).creditManager();
claimerAdapter = ICreditManagerV3(creditManager).contractToAdapter(claimer);
}
(uint256[] memory subvaultIndices, uint256[][] memory withdrawalIndices) =
IMellowClaimerAdapter(claimerAdapter).getUserSubvaultIndices(multiVault, creditAccount);
withdrawal.claimCalls[0] = MultiCall(
address(claimerAdapter),
abi.encodeWithSelector(
IMellowClaimerAdapter.multiAcceptAndClaim.selector,
multiVault,
subvaultIndices,
withdrawalIndices,
creditAccount,
withdrawal.outputs[0].amount
)
);
return withdrawal;
}
function _getWithdrawalLength(address multiVault) internal view returns (uint256) {
uint256 withdrawalLength = 0;
uint256 nSubvaults = IMellowMultiVault(multiVault).subvaultsCount();
for (uint256 i = 0; i < nSubvaults; ++i) {
Subvault memory subvault = IMellowMultiVault(multiVault).subvaultAt(i);
if (subvault.protocol == MellowProtocol.SYMBIOTIC) {
uint256 symbioticWithdrawalLength = ISymbioticSubvault(subvault.vault).nextEpochStart()
+ ISymbioticSubvault(subvault.vault).epochDuration() - block.timestamp;
if (symbioticWithdrawalLength > withdrawalLength) {
withdrawalLength = symbioticWithdrawalLength;
}
}
if (subvault.protocol == MellowProtocol.EIGEN_LAYER) {
uint256 eigenLayerWithdrawalLength = IEigenLayerDelegation(
IEigenLayerWithdrawalQueueExt(subvault.withdrawalQueue).delegation()
).minWithdrawalDelayBlocks() * 12;
if (eigenLayerWithdrawalLength > withdrawalLength) {
withdrawalLength = eigenLayerWithdrawalLength;
}
}
}
return withdrawalLength;
}
function _getSymbioticExpectedWithdrawal(
address subvault,
address withdrawalQueue,
uint256 sharesToClaim,
uint256 epoch
) internal view returns (uint256) {
EpochData memory epochData = ISymbioticWithdrawalQueue(withdrawalQueue).getEpochData(epoch);
uint256 totalWithdrawals = ISymbioticSubvault(subvault).withdrawalsOf(epoch, withdrawalQueue);
return sharesToClaim * totalWithdrawals / epochData.sharesToClaim;
}
}
"
},
"lib/@gearbox-protocol/core-v3/contracts/interfaces/ICreditAccountV3.sol": {
"content": "// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
import {IVersion} from "./base/IVersion.sol";
/// @title Credit account V3 interface
interface ICreditAccountV3 is IVersion {
function factory() external view returns (address);
function creditManager() external view returns (address);
function safeTransfer(address token, address to, uint256 amount) external;
function execute(address target, bytes calldata data) external returns (bytes memory result);
function rescue(address target, bytes calldata data) external;
}
"
},
"lib/@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol": {
"content": "// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
import {IVersion} from "./base/IVersion.sol";
/// @notice Debt management type
/// - `INCREASE_DEBT` borrows additional funds from the pool, updates account's debt and cumulative interest index
/// - `DECREASE_DEBT` repays debt components (quota interest and fees -> base interest and fees -> debt principal)
/// and updates all corresponding state variables (base interest index, quota interest and fees, debt).
/// When repaying all the debt, ensures that account has no enabled quotas.
enum ManageDebtAction {
INCREASE_DEBT,
DECREASE_DEBT
}
/// @notice Collateral/debt calculation mode
/// - `GENERIC_PARAMS` returns generic data like account debt and cumulative indexes
/// - `DEBT_ONLY` is same as `GENERIC_PARAMS` but includes more detailed debt info, like accrued base/quota
/// interest and fees
/// - `FULL_COLLATERAL_CHECK_LAZY` checks whether account is sufficiently collateralized in a lazy fashion,
/// i.e. it stops iterating over collateral tokens once TWV reaches the desired target.
/// Since it may return underestimated TWV, it's only available for internal use.
/// - `DEBT_COLLATERAL` is same as `DEBT_ONLY` but also returns total value and total LT-weighted value of
/// account's tokens, this mode is used during account liquidation
/// - `DEBT_COLLATERAL_SAFE_PRICES` is same as `DEBT_COLLATERAL` but uses safe prices from price oracle
enum CollateralCalcTask {
GENERIC_PARAMS,
DEBT_ONLY,
FULL_COLLATERAL_CHECK_LAZY,
DEBT_COLLATERAL,
DEBT_COLLATERAL_SAFE_PRICES
}
struct CreditAccountInfo {
uint256 debt;
uint256 cumulativeIndexLastUpdate;
uint128 cumulativeQuotaInterest;
uint128 quotaFees;
uint256 enabledTokensMask;
uint16 flags;
uint64 lastDebtUpdate;
address borrower;
}
struct CollateralDebtData {
uint256 debt;
uint256 cumulativeIndexNow;
uint256 cumulativeIndexLastUpdate;
uint128 cumulativeQuotaInterest;
uint256 accruedInterest;
uint256 accruedFees;
uint256 totalDebtUSD;
uint256 totalValue;
uint256 totalValueUSD;
uint256 twvUSD;
uint256 enabledTokensMask;
uint256 quotedTokensMask;
address[] quotedTokens;
address _poolQuotaKeeper;
}
struct CollateralTokenData {
address token;
uint16 ltInitial;
uint16 ltFinal;
uint40 timestampRampStart;
uint24 rampDuration;
}
interface ICreditManagerV3Events {
/// @notice Emitted when new credit configurator is set
event SetCreditConfigurator(address indexed newConfigurator);
}
/// @title Credit manager V3 interface
interface ICreditManagerV3 is IVersion, ICreditManagerV3Events {
function pool() external view returns (address);
function underlying() external view returns (address);
function creditFacade() external view returns (address);
function creditConfigurator() external view returns (address);
function accountFactory() external view returns (address);
function name() external view returns (string memory);
// ------------------ //
// ACCOUNT MANAGEMENT //
// ------------------ //
function openCreditAccount(address onBehalfOf) external returns (address);
function closeCreditAccount(address creditAccount) external;
function liquidateCreditAccount(
address creditAccount,
CollateralDebtData calldata collateralDebtData,
address to,
bool isExpired
) external returns (uint256 remainingFunds, uint256 loss);
function manageDebt(address creditAccount, uint256 amount, uint256 enabledTokensMask, ManageDebtAction action)
external
returns (uint256 newDebt, uint256, uint256);
function addCollateral(address payer, address creditAccount, address token, uint256 amount)
external
returns (uint256);
function withdrawCollateral(address creditAccount, address token, uint256 amount, address to)
external
returns (uint256);
function externalCall(address creditAccount, address target, bytes calldata callData)
external
returns (bytes memory result);
function approveToken(address creditAccount, address token, address spender, uint256 amount) external;
// -------- //
// ADAPTERS //
// -------- //
function adapterToContract(address adapter) external view returns (address targetContract);
function contractToAdapter(address targetContract) external view returns (address adapter);
function execute(bytes calldata data) external returns (bytes memory result);
function approveCreditAccount(address token, uint256 amount) external;
function setActiveCreditAccount(address creditAccount) external;
function getActiveCreditAccountOrRevert() external view returns (address creditAccount);
// ----------------- //
// COLLATERAL CHECKS //
// ----------------- //
function priceOracle() external view returns (address);
function fullCollateralCheck(
address creditAccount,
uint256 enabledTokensMask,
uint256[] calldata collateralHints,
uint16 minHealthFactor,
bool useSafePrices
) external returns (uint256);
function isLiquidatable(address creditAccount, uint16 minHealthFactor) external view returns (bool);
function calcDebtAndCollateral(address creditAccount, CollateralCalcTask task)
external
view
returns (CollateralDebtData memory cdd);
// ------ //
// QUOTAS //
// ------ //
function poolQuotaKeeper() external view returns (address);
function quotedTokensMask() external view returns (uint256);
function updateQuota(address creditAccount, address token, int96 quotaChange, uint96 minQuota, uint96 maxQuota)
external
returns (uint256 tokensToEnable, uint256 tokensToDisable);
// --------------------- //
// CREDIT MANAGER PARAMS //
// --------------------- //
function maxEnabledTokens() external view returns (uint8);
function fees()
external
view
returns (
uint16 feeInterest,
uint16 feeLiquidation,
uint16 liquidationDiscount,
uint16 feeLiquidationExpired,
uint16 liquidationDiscountExpired
);
function collateralTokensCount() external view returns (uint8);
function getTokenMaskOrRevert(address token) external view returns (uint256 tokenMask);
function getTokenByMask(uint256 tokenMask) external view returns (address token);
function liquidationThresholds(address token) external view returns (uint16 lt);
function ltParams(address token)
external
view
returns (uint16 ltInitial, uint16 ltFinal, uint40 timestampRampStart, uint24 rampDuration);
function collateralTokenByMask(uint256 tokenMask)
external
view
returns (address token, uint16 liquidationThreshold);
// ------------ //
// ACCOUNT INFO //
// ------------ //
function creditAccountInfo(address creditAccount)
external
view
returns (
uint256 debt,
uint256 cumulativeIndexLastUpdate,
uint128 cumulativeQuotaInterest,
uint128 quotaFees,
uint256 enabledTokensMask,
uint16 flags,
uint64 lastDebtUpdate,
address borrower
);
function getBorrowerOrRevert(address creditAccount) external view returns (address borrower);
function flagsOf(address creditAccount) external view returns (uint16);
function setFlagFor(address creditAccount, uint16 flag, bool value) external;
function enabledTokensMaskOf(address creditAccount) external view returns (uint256);
function creditAccounts() external view returns (address[] memory);
function creditAccounts(uint256 offset, uint256 limit) external view returns (address[] memory);
function creditAccountsLen() external view returns (uint256);
// ------------- //
// CONFIGURATION //
// ------------- //
function addToken(address token) external;
function setCollateralTokenData(
address token,
uint16 ltInitial,
uint16 ltFinal,
uint40 timestampRampStart,
uint24 rampDuration
) external;
function setFees(
uint16 feeInterest,
uint16 feeLiquidation,
uint16 liquidationDiscount,
uint16 feeLiquidationExpired,
uint16 liquidationDiscountExpired
) external;
function setContractAllowance(address adapter, address targetContract) external;
function setCreditFacade(address creditFacade) external;
function setPriceOracle(address priceOracle) external;
function setCreditConfigurator(address creditConfigurator) external;
}
"
},
"contracts/interfaces/IWithdrawalSubcompressor.sol": {
"content": "// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2025.
pragma solidity ^0.8.23;
import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
import {
WithdrawableAsset,
RequestableWithdrawal,
ClaimableWithdrawal,
PendingWithdrawal
} from "../types/WithdrawalInfo.sol";
interface IWithdrawalSubcompressor is IVersion {
function getWithdrawableAssets(address creditManager, address token)
external
view
returns (WithdrawableAsset[] memory);
function getCurrentWithdrawals(address creditAccount, address token)
external
view
returns (ClaimableWithdrawal[] memory, PendingWithdrawal[] memory);
function getWithdrawalRequestResult(address creditAccount, address token, address withdrawalToken, uint256 amount)
external
view
returns (RequestableWithdrawal memory);
}
"
},
"contracts/types/WithdrawalInfo.sol": {
"content": "// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2025.
pragma solidity ^0.8.23;
import {MultiCall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol";
struct WithdrawalOutput {
address token;
bool isDelayed;
uint256 amount;
}
struct WithdrawableAsset {
address token;
address withdrawalPhantomToken;
address underlying;
uint256 withdrawalLength;
}
struct RequestableWithdrawal {
address token;
uint256 amountIn;
WithdrawalOutput[] outputs;
MultiCall[] requestCalls;
uint256 claimableAt;
}
struct ClaimableWithdrawal {
address token;
address withdrawalPhantomToken;
uint256 withdrawalTokenSpent;
WithdrawalOutput[] outputs;
MultiCall[] claimCalls;
}
struct PendingWithdrawal {
address token;
address withdrawalPhantomToken;
WithdrawalOutput[] expectedOutputs;
uint256 claimableAt;
}
library WithdrawalLib {
function push(WithdrawableAsset[] memory w, WithdrawableAsset memory asset)
internal
pure
returns (WithdrawableAsset[] memory)
{
WithdrawableAsset[] memory newWithdrawableAssets = new WithdrawableAsset[](w.length + 1);
for (uint256 i = 0; i < w.length; i++) {
newWithdrawableAssets[i] = w[i];
}
newWithdrawableAssets[w.length] = asset;
return newWithdrawableAssets;
}
function concat(WithdrawableAsset[] memory w0, WithdrawableAsset[] memory w1)
internal
pure
returns (WithdrawableAsset[] memory)
{
WithdrawableAsset[] memory newWithdrawableAssets = new WithdrawableAsset[](w0.length + w1.length);
for (uint256 i = 0; i < w0.length; i++) {
newWithdrawableAssets[i] = w0[i];
}
for (uint256 i = 0; i < w1.length; i++) {
newWithdrawableAssets[w0.length + i] = w1[i];
}
return newWithdrawableAssets;
}
function concat(RequestableWithdrawal[] memory w0, RequestableWithdrawal[] memory w1)
internal
pure
returns (RequestableWithdrawal[] memory)
{
RequestableWithdrawal[] memory withdrawals = new RequestableWithdrawal[](w0.length + w1.length);
for (uint256 i = 0; i < w0.length; i++) {
withdrawals[i] = w0[i];
}
for (uint256 i = 0; i < w1.length; i++) {
withdrawals[w0.length + i] = w1[i];
}
return withdrawals;
}
function push(ClaimableWithdrawal[] memory w, ClaimableWithdrawal memory withdrawal)
internal
pure
returns (ClaimableWithdrawal[] memory)
{
ClaimableWithdrawal[] memory newClaimableWithdrawals = new ClaimableWithdrawal[](w.length + 1);
for (uint256 i = 0; i < w.length; i++) {
newClaimableWithdrawals[i] = w[i];
}
newClaimableWithdrawals[w.length] = withdrawal;
return newClaimableWithdrawals;
}
function concat(ClaimableWithdrawal[] memory w0, ClaimableWithdrawal[] memory w1)
internal
pure
returns (ClaimableWithdrawal[] memory)
{
ClaimableWithdrawal[] memory withdrawals = new ClaimableWithdrawal[](w0.length + w1.length);
for (uint256 i = 0; i < w0.length; i++) {
withdrawals[i] = w0[i];
}
for (uint256 i = 0; i < w1.length; i++) {
withdrawals[w0.length + i] = w1[i];
}
return withdrawals;
}
function push(PendingWithdrawal[] memory w, PendingWithdrawal memory withdrawal)
internal
pure
returns (PendingWithdrawal[] memory)
{
PendingWithdrawal[] memory newPendingWithdrawals = new PendingWithdrawal[](w.length + 1);
for (uint256 i = 0; i < w.length; i++) {
newPendingWithdrawals[i] = w[i];
}
newPendingWithdrawals[w.length] = withdrawal;
return newPendingWithdrawals;
}
function concat(PendingWithdrawal[] memory w0, PendingWithdrawal[] memory w1)
internal
pure
returns (PendingWithdrawal[] memory)
{
PendingWithdrawal[] memory withdrawals = new PendingWithdrawal[](w0.length + w1.length);
for (uint256 i = 0; i < w0.length; i++) {
withdrawals[i] = w0[i];
}
for (uint256 i = 0; i < w1.length; i++) {
withdrawals[w0.length + i] = w1[i];
}
return withdrawals;
}
function filterEmpty(PendingWithdrawal[] memory pendingWithdrawals)
internal
pure
returns (PendingWithdrawal[] memory)
{
PendingWithdrawal[] memory filteredPendingWithdrawals = new PendingWithdrawal[](0);
for (uint256 i = 0; i < pendingWithdrawals.length; i++) {
if (pendingWithdrawals[i].expectedOutputs.length > 0) {
for (uint256 j = 0; j < pendingWithdrawals[i].expectedOutputs.length; j++) {
if (pendingWithdrawals[i].expectedOutputs[j].amount > 0) {
filteredPendingWithdrawals = push(filteredPendingWithdrawals, pendingWithdrawals[i]);
break;
}
}
}
}
return filteredPendingWithdrawals;
}
function filterEmpty(ClaimableWithdrawal[] memory claimableWithdrawals)
internal
pure
returns (ClaimableWithdrawal[] memory)
{
ClaimableWithdrawal[] memory filteredClaimableWithdrawals = new ClaimableWithdrawal[](0);
for (uint256 i = 0; i < claimableWithdrawals.length; i++) {
if (claimableWithdrawals[i].outputs.length > 0) {
for (uint256 j = 0; j < claimableWithdrawals[i].outputs.length; j++) {
if (claimableWithdrawals[i].outputs[j].amount > 0) {
filteredClaimableWithdrawals = push(filteredClaimableWithdrawals, claimableWithdrawals[i]);
break;
}
}
}
}
return filteredClaimableWithdrawals;
}
}
"
},
"lib/@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol": {
"content": "// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
import {AllowanceAction} from "./ICreditConfiguratorV3.sol";
import "./ICreditFacadeV3Multicall.sol";
import {IACLTrait} from "./base/IACLTrait.sol";
import {PriceUpdate} from "./base/IPriceFeedStore.sol";
import {IVersion} from "./base/IVersion.sol";
/// @notice Multicall element
/// @param target Call target, which is either credit facade or adapter
/// @param callData Call data
struct MultiCall {
address target;
bytes callData;
}
/// @notice Debt limits packed into a single slot
/// @param minDebt Minimum debt amount per credit account
/// @param maxDebt Maximum debt amount per credit account
struct DebtLimits {
uint128 minDebt;
uint128 maxDebt;
}
/// @notice Collateral check params
/// @param collateralHints Optional array of token masks to check first to reduce the amount of computation
/// when known subset of account's collateral tokens covers all the debt
/// @param minHealthFactor Min account's health factor in bps in order not to revert
struct FullCheckParams {
uint256[] collateralHints;
uint16 minHealthFactor;
}
interface ICreditFacadeV3Events {
/// @notice Emitted when a new credit account is opened
event OpenCreditAccount(
address indexed creditAccount, address indexed onBehalfOf, address indexed caller, uint256 referralCode
);
/// @notice Emitted when account is closed
event CloseCreditAccount(address indexed creditAccount, address indexed borrower);
/// @notice Emitted when account is liquidated
event LiquidateCreditAccount(
address indexed creditAccount, address indexed liquidator, address to, uint256 remainingFunds
);
/// @notice Emitted when account is partially liquidated
event PartiallyLiquidateCreditAccount(
address indexed creditAccount,
address indexed token,
address indexed liquidator,
uint256 repaidDebt,
uint256 seizedCollateral,
uint256 fee
);
/// @notice Emitted when collateral is added to account
event AddCollateral(address indexed creditAccount, address indexed token, uint256 amount);
/// @notice Emitted when collateral is withdrawn from account
event WithdrawCollateral(address indexed creditAccount, address indexed token, uint256 amount, address to);
/// @notice Emitted when a multicall is started
event StartMultiCall(address indexed creditAccount, address indexed caller);
/// @notice Emitted when phantom token is withdrawn by account
event WithdrawPhantomToken(address indexed creditAccount, address indexed token, uint256 amount);
/// @notice Emitted when a call from account to an external contract is made during a multicall
event Execute(address indexed creditAccount, address indexed targetContract);
/// @notice Emitted when a multicall is finished
event FinishMultiCall();
}
/// @title Credit facade V3 interface
interface ICreditFacadeV3 is IVersion, IACLTrait, ICreditFacadeV3Events {
function creditManager() external view returns (address);
function underlying() external view returns (address);
function treasury() external view returns (address);
function priceFeedStore() external view returns (address);
function degenNFT() external view returns (address);
function weth() external view returns (address);
function botList() external view returns (address);
function maxDebtPerBlockMultiplier() external view returns (uint8);
function maxQuotaMultiplier() external view returns (uint256);
function expirable() external view returns (bool);
function expirationDate() external view returns (uint40);
function debtLimits() external view returns (uint128 minDebt, uint128 maxDebt);
function lossPolicy() external view returns (address);
function forbiddenTokenMask() external view returns (uint256);
// ------------------ //
// ACCOUNT MANAGEMENT //
// ------------------ //
function openCreditAccount(address onBehalfOf, MultiCall[] calldata calls, uint256 referralCode)
external
payable
returns (address creditAccount);
function closeCreditAccount(address creditAccount, MultiCall[] calldata calls) external payable;
function liquidateCreditAccount(
address creditAccount,
address to,
MultiCall[] calldata calls,
bytes memory lossPolicyData
) external;
function liquidateCreditAccount(address creditAccount, address to, MultiCall[] calldata calls) external;
function partiallyLiquidateCreditAccount(
address creditAccount,
address token,
uint256 repaidAmount,
uint256 minSeizedAmount,
address to,
PriceUpdate[] calldata priceUpdates
) external returns (uint256 seizedAmount);
function multicall(address creditAccount, MultiCall[] calldata calls) external payable;
function botMulticall(address creditAccount, MultiCall[] calldata calls) external;
// ------------- //
// CONFIGURATION //
// ------------- //
function setExpirationDate(uint40 newExpirationDate) external;
function setDebtLimits(uint128 newMinDebt, uint128 newMaxDebt, uint8 newMaxDebtPerBlockMultiplier) external;
function setLossPolicy(address newLossPolicy) external;
function setTokenAllowance(address token, AllowanceAction allowance) external;
function pause() external;
function unpause() external;
}
"
},
"lib/@gearbox-protocol/integrations-v3/contracts/helpers/mellow/MellowWithdrawalPhantomToken.sol": {
"content": "// SPDX-License-Identifier: GPL-2.0-or-later
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.23;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import {IMellowMultiVault, IMellowWithdrawalQueue, Subvault} from "../../integrations/mellow/IMellowMultiVault.sol";
import {PhantomERC20} from "../PhantomERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {MultiCall} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditFacadeV3.sol";
import {IPhantomToken} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IPhantomToken.sol";
/// @title MellowLRT withdrawal phantom token
/// @notice Phantom ERC-20 token that represents the balance of the pending and claimable withdrawals in Mellow vaults
contract MellowWithdrawalPhantomToken is PhantomERC20, Ownable, IPhantomToken {
event SetClaimer(address indexed claimer);
error SubvaultClaimerMismatchException();
bytes32 public constant override contractType = "PHANTOM_TOKEN::MELLOW_WITHDRAWAL";
uint256 public constant override version = 3_11;
address public immutable multiVault;
address public claimer;
/// @notice Constructor
/// @param _ioProxy The address of the Instance Owner proxy
/// @param _multiVault The MultiVault where the pending assets are tracked
/// @param _claimer The address of the initial Claimer contract
constructor(address _ioProxy, address _multiVault, address _claimer)
PhantomERC20(
IERC4626(_multiVault).asset(),
string.concat("Mellow withdrawn ", IERC20Metadata(IERC4626(_multiVault).asset()).name()),
string.concat("wd", IERC20Metadata(IERC4626(_multiVault).asset()).symbol()),
IERC20Metadata(IERC4626(_multiVault).asset()).decimals()
)
{
_transferOwnership(_ioProxy);
multiVault = _multiVault;
claimer = _claimer;
}
/// @notice Returns the amount of assets pending/claimable for withdrawal
/// @param account The account for which the calculation is performed
function balanceOf(address account) public view returns (uint256 balance) {
uint256 nSubvaults = IMellowMultiVault(multiVault).subvaultsCount();
for (uint256 i = 0; i < nSubvaults; ++i) {
Subvault memory subvault = IMellowMultiVault(multiVault).subvaultAt(i);
if (subvault.withdrawalQueue == address(0)) continue;
balance += IMellowWithdrawalQueue(subvault.withdrawalQueue).pendingAssetsOf(account)
+ IMellowWithdrawalQueue(subvault.withdrawalQueue).claimableAssetsOf(account);
}
}
/// @notice Returns phantom token's target contract and underlying
function getPhantomTokenInfo() external view override returns (address, address) {
return (claimer, underlying);
}
function serialize() external view override returns (bytes memory) {
return abi.encode(claimer, underlying);
}
/// @notice Sets the address of the Claimer contract
function setClaimer(address _claimer) external onlyOwner {
if (_claimer != claimer) {
uint256 nSubvaults = IMellowMultiVault(multiVault).subvaultsCount();
for (uint256 i = 0; i < nSubvaults; ++i) {
Subvault memory subvault = IMellowMultiVault(multiVault).subvaultAt(i);
if (subvault.withdrawalQueue == address(0)) continue;
address queueClaimer = IMellowWithdrawalQueue(subvault.withdrawalQueue).claimer();
if (queueClaimer != _claimer) revert SubvaultClaimerMismatchException();
}
claimer = _claimer;
emit SetClaimer(_claimer);
}
}
}
"
},
"lib/@gearbox-protocol/integrations-v3/contracts/integrations/mellow/IMellowMultiVault.sol": {
"content": "// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;
enum MellowProtocol {
SYMBIOTIC,
EIGEN_LAYER,
ERC4626
}
struct Subvault {
MellowProtocol protocol;
address vault;
address withdrawalQueue;
}
interface IMellowMultiVault {
function asset() external view returns (address);
function withdrawalQueue() external view returns (address);
function subvaultsCount() external view returns (uint256);
function subvaultAt(uint256 index) external view returns (Subvault memory);
function depositWhitelist() external view returns (bool);
}
interface IMellowWithdrawalQueue {
function pendingAssetsOf(address account) external view returns (uint256);
function claimableAssetsOf(address account) external view returns (uint256);
function claimer() external view returns (address);
}
interface IEigenLayerWithdrawalQueue {
function getAccountData(
address account,
uint256 withdrawalsLimit,
uint256 withdrawalsOffset,
uint256 transferredWithdrawalsLimit,
uint256 transferredWithdrawalsOffset
)
external
view
returns (uint256 claimableAssets, uint256[] memory withdrawals, uint256[] memory transferredWithdrawals);
}
"
},
"lib/@gearbox-protocol/integrations-v3/contracts/interfaces/mellow/IMellowClaimerAdapter.sol": {
"content": "// SPDX-License-Identifier: GPL-2.0-or-later
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.23;
import {IPhantomTokenAdapter} from "../IPhantomTokenAdapter.sol";
struct MellowMultiVaultStatus {
address multiVault;
address stakedPhantomToken;
bool allowed;
}
interface IMellowClaimerAdapterEvents {
event SetMultiVaultStatus(address indexed multiVault, bool allowed);
}
interface IMellowClaimerAdapterExceptions {
/// @notice Error thrown when the actually claimed amount is less than the requested amount
error InsufficientClaimedException();
/// @notice Thrown when the staked phantom token field does not match the multivault
error InvalidMultiVaultException();
/// @notice Thrown when the staked phantom token added with the vault has incorrect parameters
error InvalidStakedPhantomTokenException();
/// @notice Thrown when the multivault is not allowed
error MultiVaultNotAllowedException();
}
/// @title Mellow ERC4626 Vault adapter interface
/// @notice Interface for the adapter to interact with Mellow's ERC4626 vaults
interface IMellowClaimerAdapter is
IPhantomTokenAdapter,
IMellowClaimerAdapterExceptions,
IMellowClaimerAdapterEvents
{
function multiAccept(address multiVault, uint256[] calldata subvaultIndices, uint256[][] calldata indices)
external
returns (bool);
function multiAcceptAndClaim(
address multiVault,
uint256[] calldata subvaultIndices,
uint256[][] calldata indices,
address,
uint256 maxAssets
) external returns (bool);
function getMultiVaultSubvaultIndices(address multiVault)
external
view
returns (uint256[] memory subvaultIndices, uint256[][] memory withdrawalIndices);
function getUserSubvaultIndices(address multiVault, address user)
external
view
returns (uint256[] memory subvaultIndices, uint256[][] memory withdrawalIndices);
function allowedMultiVaults() external view returns (address[] memory);
function setMultiVaultStatusBatch(MellowMultiVaultStatus[] calldata multivaults) external;
}
"
},
"lib/@gearbox-protocol/integrations-v3/contracts/interfaces/mellow/IMellow4626VaultAdapter.sol": {
"content": "// SPDX-License-Identifier: GPL-2.0-or-later
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.23;
import {IERC4626Adapter} from "../erc4626/IERC4626Adapter.sol";
/// @title Mellow ERC4626 Vault adapter interface
/// @notice Interface for the adapter to interact with Mellow's ERC4626 vaults
interface IMellow4626VaultAdapter is IERC4626Adapter {
/// @notice Thrown when the multivault in the staked phantom token does not match the one in the adapter
error InvalidMultiVaultException();
}
"
},
"lib/@gearbox-protocol/integrations-v3/contracts/interfaces/erc4626/IERC4626Adapter.sol": {
"content": "// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.23;
import {IAdapter} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IAdapter.sol";
interface IERC4626Adapter is IAdapter {
function asset() external view returns (address);
function vault() external view returns (address);
function deposit(uint256 assets, address) external returns (bool useSafePrices);
function depositDiff(uint256 leftoverAmount) external returns (bool useSafePrices);
function mint(uint256 shares, address) external returns (bool useSafePrices);
function withdraw(uint256 assets, address, address) external returns (bool useSafePrices);
function redeem(uint256 shares, address, address) external returns (bool useSafePrices);
function redeemDiff(uint256 leftoverAmount) external returns (bool useSafePrices);
}
"
},
"lib/@openzeppelin/contracts/interfaces/IERC4626.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4626.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20.sol";
import "../token/ERC20/extensions/IERC20Metadata.sol";
/**
* @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in
* https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].
*
* _Available since v4.7._
*/
interface IERC4626 is IERC20, IERC20Metadata {
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
/**
* @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
*
* - MUST be an ERC-20 token contract.
* - MUST NOT revert.
*/
function asset() external view returns (address assetTokenAddress);
/**
* @dev Returns the total amount of the underlying asset that is “managed” by Vault.
*
* - SHOULD include any compounding that occurs from yield.
* - MUST be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT revert.
*/
function totalAssets() external view returns (uint256 totalManagedAssets);
/**
* @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToShares(uint256 assets) external view returns (uint256 shares);
/**
* @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToAssets(uint256 shares) external view returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
* through a deposit call.
*
* - MUST return a limited value if receiver is subject to some deposit limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
* - MUST NOT revert.
*/
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
* call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
* in the same transaction.
* - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
* deposit would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewDeposit(uint256 assets) external view returns (uint256 shares);
/**
* @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* deposit execution, and are accounted for during deposit.
* - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
* - MUST return a limited value if receiver is subject to some mint limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
* - MUST NOT revert.
*/
function maxMint(address receiver) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
* in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
* same transaction.
* - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
* would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by minting.
*/
function previewMint(uint256 shares) external view returns (uint256 assets);
/**
* @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
* execution, and are accounted for during mint.
* - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function mint(uint256 shares, address receiver) external returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
* Vault, through a withdraw call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
* call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
* called
* in the same transaction.
* - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
* the withdrawal would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
/**
* @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* withdraw execution, and are accounted for during withdraw.
* - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
* through a redeem call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxRedeem(address owner) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
* in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
* same transaction.
* - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
* redemption would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by redeeming.
*/
function previewRedeem(uint256 shares) external view returns (uint256 assets);
/**
* @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* redeem execution, and are accounted for during redeem.
* - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}
"
},
"lib/@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol": {
"content": "// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
/// @title Version interface
/// @notice Defines contract version and type
interface IVersion {
/// @notice Contract version
function version() external view returns (uint256);
/// @notice Contract type
function contractType() external view returns (bytes32);
}
"
},
"lib/@gearbox-protocol/core-v3/contracts/interfaces/ICreditConfiguratorV3.sol": {
"content": "// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
import {IACLTrait} from "./base/IACLTrait.sol";
import {IVersion} from "./base/IVersion.sol";
enum AllowanceAction {
FORBID,
ALLOW
}
interface ICreditConfiguratorV3Events {
// ------ //
// TOKENS //
// ------ //
/// @notice Emitted when a token is made recognizable as collateral in the credit manager
event AddCollateralToken(address indexed token);
/// @notice Emitted when a new collateral token liquidation threshold is set
event SetTokenLiquidationThreshold(address indexed token, uint16 liquidationThreshold);
/// @notice Emitted when a collateral token liquidation th
Submitted on: 2025-10-07 11:31:09
Comments
Log in to comment.
No comments yet.