Diff
checker
テキスト
テキスト
画像
ドキュメント
Excel
フォルダ
Legal
Enterprise
デスクトップ
料金
ログイン
Diffchecker デスクトップのダウンロード
テキスト比較
2 つのテキスト ファイルの違いを見つける
ツール
履歴
表示
レイアウト
分割
統合
ライブエディター
空白の変更を非表示
未変更行を折りたたむ
折り返しなし
比較精度
スマート
構文
なし
外観を変更
処理
無視
テキスト変換
最初の差分へ移動
入力を編集
Diffchecker Desktop
Diffcheckerを実行する最も安全な方法。Diffchecker Desktopアプリを入手:あなたの差分はコンピューターから出ることはありません!
Desktopを入手
LrtUnstackingVault
作成日
10 か月前
差分は期限切れになりません
クリア
エクスポート
共有
説明
29 削除
行
合計
削除
文字
合計
削除
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
287 行
すべてコピー
6 追加
行
合計
追加
文字
合計
追加
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
265 行
すべてコピー
// SPDX-License-Identifier: BUSL-1.1
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.27;
pragma solidity 0.8.27;
import { UtilLib } from "./utils/UtilLib.sol";
import { UtilLib } from "./utils/UtilLib.sol";
import { LRTConstants } from "./utils/LRTConstants.sol";
import { LRTConstants } from "./utils/LRTConstants.sol";
import { LRTConfigRoleChecker, ILRTConfig } from "./utils/LRTConfigRoleChecker.sol";
import { LRTConfigRoleChecker, ILRTConfig } from "./utils/LRTConfigRoleChecker.sol";
import { INodeDelegator } from "./interfaces/INodeDelegator.sol";
import { INodeDelegator } from "./interfaces/INodeDelegator.sol";
import { IStrategy } from "./external/eigenlayer/interfaces/IStrategy.sol";
import { IStrategy } from "./external/eigenlayer/interfaces/IStrategy.sol";
import { ILRTWithdrawalManager } from "./interfaces/ILRTWithdrawalManager.sol";
import { ILRTWithdrawalManager } from "./interfaces/ILRTWithdrawalManager.sol";
import { ILRTUnstakingVault } from "./interfaces/ILRTUnstakingVault.sol";
import { ILRTUnstakingVault } from "./interfaces/ILRTUnstakingVault.sol";
import { IStrategyManager } from "./external/eigenlayer/interfaces/IStrategyManager.sol";
import { IStrategyManager } from "./external/eigenlayer/interfaces/IStrategyManager.sol";
import { ILRTDepositPool } from "./interfaces/ILRTDepositPool.sol";
import { ILRTDepositPool } from "./interfaces/ILRTDepositPool.sol";
import { IDelegationManager } from "./external/eigenlayer/interfaces/IDelegationManager.sol";
import { IDelegationManager } from "./external/eigenlayer/interfaces/IDelegationManager.sol";
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {
import {
ReentrancyGuardUpgradeable
ReentrancyGuardUpgradeable
} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { SlashingLib } from "./external/eigenlayer/libraries/SlashingLib.sol";
import { SlashingLib } from "./external/eigenlayer/libraries/SlashingLib.sol";
/// @title LRTUnstakingVault Contract
/// @title LRTUnstakingVault Contract
/// @notice The contract that handles the unstaking of assets
/// @notice The contract that handles the unstaking of assets
contract LRTUnstakingVault is
contract LRTUnstakingVault is
ILRTUnstakingVault,
ILRTUnstakingVault,
LRTConfigRoleChecker,
LRTConfigRoleChecker,
PausableUpgradeable,
PausableUpgradeable,
ReentrancyGuardUpgradeable
ReentrancyGuardUpgradeable
{
{
using SafeERC20 for IERC20;
using SafeERC20 for IERC20;
using SlashingLib for *;
using SlashingLib for *;
using LRTConstants for ILRTConfig;
using LRTConstants for ILRTConfig;
コピー
コピー済み
コピー
コピー済み
// NOTE: For legacy withdrawal support, this can be made private after all pre slashing withdrawals are processed
mapping(address asset => uint256)
private __deprecated_
sharesUnstaking;
// (asset => 0)
mapping(address asset => uint256)
public
sharesUnstaking;
mapping(bytes32 => bool) public trackedWithdrawal;
mapping(bytes32 => bool) public trackedWithdrawal;
uint256 public uncompletedWithdrawalCount;
uint256 public uncompletedWithdrawalCount;
uint256 public maxUncompletedWithdrawalCount;
uint256 public maxUncompletedWithdrawalCount;
// Portion of the vault reserved for servicing queued withdrawals; unavailable for instant withdrawals.
// Portion of the vault reserved for servicing queued withdrawals; unavailable for instant withdrawals.
mapping(address asset => uint256 buffer) public queuedWithdrawalsBuffer;
mapping(address asset => uint256 buffer) public queuedWithdrawalsBuffer;
modifier onlyLRTNodeDelegator() {
modifier onlyLRTNodeDelegator() {
ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL));
ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL));
if (lrtDepositPool.isNodeDelegator(msg.sender) != 1) {
if (lrtDepositPool.isNodeDelegator(msg.sender) != 1) {
revert CallerNotLRTNodeDelegator();
revert CallerNotLRTNodeDelegator();
}
}
_;
_;
}
}
modifier onlyLRTWithdrawalManager() {
modifier onlyLRTWithdrawalManager() {
if (msg.sender != lrtConfig.withdrawManager()) {
if (msg.sender != lrtConfig.withdrawManager()) {
revert CallerNotLRTWithdrawalManager();
revert CallerNotLRTWithdrawalManager();
}
}
_;
_;
}
}
/// @custom:oz-upgrades-unsafe-allow constructor
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
constructor() {
_disableInitializers();
_disableInitializers();
}
}
/// @dev Initializes the contract
/// @dev Initializes the contract
/// @param lrtConfigAddr LRT config address
/// @param lrtConfigAddr LRT config address
function initialize(address lrtConfigAddr) external initializer {
function initialize(address lrtConfigAddr) external initializer {
UtilLib.checkNonZeroAddress(lrtConfigAddr);
UtilLib.checkNonZeroAddress(lrtConfigAddr);
__Pausable_init();
__Pausable_init();
__ReentrancyGuard_init();
__ReentrancyGuard_init();
lrtConfig = ILRTConfig(lrtConfigAddr);
lrtConfig = ILRTConfig(lrtConfigAddr);
emit UpdatedLRTConfig(lrtConfigAddr);
emit UpdatedLRTConfig(lrtConfigAddr);
}
}
/*//////////////////////////////////////////////////////////////
/*//////////////////////////////////////////////////////////////
receive functions
receive functions
//////////////////////////////////////////////////////////////*/
//////////////////////////////////////////////////////////////*/
receive() external payable {
receive() external payable {
emit EthReceived(msg.sender, msg.value);
emit EthReceived(msg.sender, msg.value);
}
}
/// @dev receive from LRTDepositPool
/// @dev receive from LRTDepositPool
function receiveFromLRTDepositPool() external payable { }
function receiveFromLRTDepositPool() external payable { }
/// @dev receive from NodeDelegator
/// @dev receive from NodeDelegator
function receiveFromNodeDelegator() external payable { }
function receiveFromNodeDelegator() external payable { }
/*//////////////////////////////////////////////////////////////
/*//////////////////////////////////////////////////////////////
write functions
write functions
//////////////////////////////////////////////////////////////*/
//////////////////////////////////////////////////////////////*/
/// @notice This is used by withdrawal manager when unlocking assets. The unlocked assets are pulled from the vault
/// @notice This is used by withdrawal manager when unlocking assets. The unlocked assets are pulled from the vault
/// and used to pay the user.
/// and used to pay the user.
/// @param asset The asset address.
/// @param asset The asset address.
/// @param amount The amount of asset to redeem.
/// @param amount The amount of asset to redeem.
function redeem(address asset, uint256 amount) external nonReentrant onlyLRTWithdrawalManager {
function redeem(address asset, uint256 amount) external nonReentrant onlyLRTWithdrawalManager {
if (asset == LRTConstants.ETH_TOKEN) {
if (asset == LRTConstants.ETH_TOKEN) {
保存された差分
原文
ファイルを開く
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.27; import { UtilLib } from "./utils/UtilLib.sol"; import { LRTConstants } from "./utils/LRTConstants.sol"; import { LRTConfigRoleChecker, ILRTConfig } from "./utils/LRTConfigRoleChecker.sol"; import { INodeDelegator } from "./interfaces/INodeDelegator.sol"; import { IStrategy } from "./external/eigenlayer/interfaces/IStrategy.sol"; import { ILRTWithdrawalManager } from "./interfaces/ILRTWithdrawalManager.sol"; import { ILRTUnstakingVault } from "./interfaces/ILRTUnstakingVault.sol"; import { IStrategyManager } from "./external/eigenlayer/interfaces/IStrategyManager.sol"; import { ILRTDepositPool } from "./interfaces/ILRTDepositPool.sol"; import { IDelegationManager } from "./external/eigenlayer/interfaces/IDelegationManager.sol"; import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol"; import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { SlashingLib } from "./external/eigenlayer/libraries/SlashingLib.sol"; /// @title LRTUnstakingVault Contract /// @notice The contract that handles the unstaking of assets contract LRTUnstakingVault is ILRTUnstakingVault, LRTConfigRoleChecker, PausableUpgradeable, ReentrancyGuardUpgradeable { using SafeERC20 for IERC20; using SlashingLib for *; using LRTConstants for ILRTConfig; // NOTE: For legacy withdrawal support, this can be made private after all pre slashing withdrawals are processed // (asset => 0) mapping(address asset => uint256) public sharesUnstaking; mapping(bytes32 => bool) public trackedWithdrawal; uint256 public uncompletedWithdrawalCount; uint256 public maxUncompletedWithdrawalCount; // Portion of the vault reserved for servicing queued withdrawals; unavailable for instant withdrawals. mapping(address asset => uint256 buffer) public queuedWithdrawalsBuffer; modifier onlyLRTNodeDelegator() { ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL)); if (lrtDepositPool.isNodeDelegator(msg.sender) != 1) { revert CallerNotLRTNodeDelegator(); } _; } modifier onlyLRTWithdrawalManager() { if (msg.sender != lrtConfig.withdrawManager()) { revert CallerNotLRTWithdrawalManager(); } _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /// @dev Initializes the contract /// @param lrtConfigAddr LRT config address function initialize(address lrtConfigAddr) external initializer { UtilLib.checkNonZeroAddress(lrtConfigAddr); __Pausable_init(); __ReentrancyGuard_init(); lrtConfig = ILRTConfig(lrtConfigAddr); emit UpdatedLRTConfig(lrtConfigAddr); } /*////////////////////////////////////////////////////////////// receive functions //////////////////////////////////////////////////////////////*/ receive() external payable { emit EthReceived(msg.sender, msg.value); } /// @dev receive from LRTDepositPool function receiveFromLRTDepositPool() external payable { } /// @dev receive from NodeDelegator function receiveFromNodeDelegator() external payable { } /*////////////////////////////////////////////////////////////// write functions //////////////////////////////////////////////////////////////*/ /// @notice This is used by withdrawal manager when unlocking assets. The unlocked assets are pulled from the vault /// and used to pay the user. /// @param asset The asset address. /// @param amount The amount of asset to redeem. function redeem(address asset, uint256 amount) external nonReentrant onlyLRTWithdrawalManager { if (asset == LRTConstants.ETH_TOKEN) { ILRTWithdrawalManager(msg.sender).receiveFromLRTUnstakingVault{ value: amount }(); } else { IERC20(asset).safeTransfer(msg.sender, amount); } } /// @notice transfers asset lying in this LRTUnstakingVault to node delegator contract /// @dev only callable by LRT Operator /// @param ndcIndex Index of NodeDelegator contract address in nodeDelegatorQueue /// @param asset Asset address /// @param amount Asset amount to transfer function transferAssetToNodeDelegator( uint256 ndcIndex, address asset, uint256 amount ) external nonReentrant onlyLRTOperator onlySupportedAsset(asset) { ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.depositPool()); address[] memory nodeDelegatorQueue = lrtDepositPool.getNodeDelegatorQueue(); address nodeDelegator = nodeDelegatorQueue[ndcIndex]; IERC20(asset).safeTransfer(nodeDelegator, amount); } /// @notice transfers ETH lying in this LRTUnstakingVault to node delegator contract /// @dev only callable by LRT Operator /// @param ndcIndex Index of NodeDelegator contract address in nodeDelegatorQueue /// @param amount ETH amount to transfer function transferETHToNodeDelegator( uint256 ndcIndex, uint256 amount ) external nonReentrant onlyLRTOperator onlySupportedAsset(LRTConstants.ETH_TOKEN) { ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.depositPool()); address[] memory nodeDelegatorQueue = lrtDepositPool.getNodeDelegatorQueue(); address nodeDelegator = nodeDelegatorQueue[ndcIndex]; INodeDelegator(nodeDelegator).sendETHFromUnstakingVaultToNDC{ value: amount }(); emit EthTransferred(nodeDelegator, amount); } /// @notice Reduce shares that are in unstaking process. /// @param asset The asset address. /// @param amount The amount of shares to reduce. /// @dev This function is only callable by the NodeDelegator contracts during the unstaking process. function reduceSharesUnstaking(address asset, uint256 amount) external onlyLRTNodeDelegator { sharesUnstaking[asset] -= amount; } /// @notice Set the max number of uncompleted withdrawals. /// @param _maxUncompletedWithdrawalCount The max number of uncompleted withdrawals. function setMaxUncompletedWithdrawalCount(uint256 _maxUncompletedWithdrawalCount) external onlyLRTManager { // 120 is the max number of uncompleted withdrawals that allows us to still perform update rsETH price // Need buffer for theoretical operator forced undelegations (ndc count * asset count = 15) if (_maxUncompletedWithdrawalCount > 80) { revert MaxUncompletedWithdrawalCountTooHigh(); } maxUncompletedWithdrawalCount = _maxUncompletedWithdrawalCount; emit MaxUncompletedWithdrawalCountSet(_maxUncompletedWithdrawalCount); } /// @notice Set the uncompleted withdrawal count. /// @notice Can be used on forced undelegations. /// @dev only callable by LRT Manager function setUncompletedWithdrawalCount() external onlyLRTManager { ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL)); IDelegationManager delegationManager = IDelegationManager(lrtConfig.getContract(LRTConstants.EIGEN_DELEGATION_MANAGER)); address[] memory nodeDelegatorQueue = lrtDepositPool.getNodeDelegatorQueue(); uint256 totalQueued; for (uint256 i = 0; i < nodeDelegatorQueue.length; i++) { address nodeDelegator = nodeDelegatorQueue[i]; (IDelegationManager.Withdrawal[] memory queuedWithdrawals,) = delegationManager.getQueuedWithdrawals(nodeDelegator); totalQueued += queuedWithdrawals.length; } uncompletedWithdrawalCount = totalQueued; emit UncompletedWithdrawalCountSet(totalQueued); } /// @notice Increase the number of uncompleted withdrawals. /// @dev This function is only callable by the NodeDelegator contracts during the unstaking process. function increaseUncompletedWithdrawalCount() external onlyLRTNodeDelegator { uncompletedWithdrawalCount++; } /// @notice Decrease the number of uncompleted withdrawals. /// @dev This function is only callable by the NodeDelegator contracts during the unstaking process. function decreaseUncompletedWithdrawalCount() external onlyLRTNodeDelegator { if (uncompletedWithdrawalCount > 0) { uncompletedWithdrawalCount--; } } /// @notice Set the reserved buffer for queued withdrawals for an asset. /// @param asset The asset address. /// @param buffer The reserved amount for queued withdrawals. function setQueuedWithdrawalsBuffer( address asset, uint256 buffer ) external onlyLRTOperator onlySupportedAsset(asset) { queuedWithdrawalsBuffer[asset] = buffer; emit QueuedWithdrawalsBufferUpdated(asset, buffer); } /*////////////////////////////////////////////////////////////// view functions //////////////////////////////////////////////////////////////*/ // NOTE: For legacy el withdrawal support, this can be removed after all pre slashing withdrawals are processed /// @notice Returns the total asset amount in unstaking process. /// @param asset The asset address. /// @return The total asset amount in unstaking process. function getAssetsUnstaking(address asset) external view onlySupportedAsset(asset) returns (uint256) { if (asset == LRTConstants.ETH_TOKEN) { return sharesUnstaking[asset]; } IStrategy strategy = IStrategy(lrtConfig.assetStrategy(asset)); return strategy.sharesToUnderlyingView(sharesUnstaking[asset]); } /// @notice Returns the the vaults balance of the asset. /// @param asset The asset address. /// @return The balance of the asset. function balanceOf(address asset) public view returns (uint256) { if (asset == LRTConstants.ETH_TOKEN) { return address(this).balance; } else { return IERC20(asset).balanceOf(address(this)); } } /// @notice Returns the amount of the asset available for instant withdrawal. /// @param asset The asset address. /// @return availableAmount The amount of the asset available for instant withdrawal. function getAssetsAvailableForInstantWithdrawal(address asset) external view onlySupportedAsset(asset) returns (uint256 availableAmount) { uint256 vaultBalance = balanceOf(asset); uint256 reservedBuffer = queuedWithdrawalsBuffer[asset]; availableAmount = reservedBuffer >= vaultBalance ? 0 : vaultBalance - reservedBuffer; } /// @notice Fetches balance of all assets staked in eigen layer through this contract /// @param staker the staker address /// @return assets the assets that the node delegator has deposited into strategies /// @return assetBalances the balances of the assets that the node delegator has deposited into strategies function getStakedAssetBalances(address staker) external view override returns (address[] memory assets, uint256[] memory assetBalances) { (IStrategy[] memory strategies,) = IStrategyManager(lrtConfig.strategyManager()).getDeposits(staker); uint256 strategiesLength = strategies.length; assets = new address[](strategiesLength); assetBalances = new uint256[](strategiesLength); for (uint256 i = 0; i < strategiesLength;) { assets[i] = address(IStrategy(strategies[i]).underlyingToken()); assetBalances[i] = IStrategy(strategies[i]).userUnderlyingView(staker); unchecked { ++i; } } } }
変更されたテキスト
ファイルを開く
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.27; import { UtilLib } from "./utils/UtilLib.sol"; import { LRTConstants } from "./utils/LRTConstants.sol"; import { LRTConfigRoleChecker, ILRTConfig } from "./utils/LRTConfigRoleChecker.sol"; import { INodeDelegator } from "./interfaces/INodeDelegator.sol"; import { IStrategy } from "./external/eigenlayer/interfaces/IStrategy.sol"; import { ILRTWithdrawalManager } from "./interfaces/ILRTWithdrawalManager.sol"; import { ILRTUnstakingVault } from "./interfaces/ILRTUnstakingVault.sol"; import { IStrategyManager } from "./external/eigenlayer/interfaces/IStrategyManager.sol"; import { ILRTDepositPool } from "./interfaces/ILRTDepositPool.sol"; import { IDelegationManager } from "./external/eigenlayer/interfaces/IDelegationManager.sol"; import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol"; import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { SlashingLib } from "./external/eigenlayer/libraries/SlashingLib.sol"; /// @title LRTUnstakingVault Contract /// @notice The contract that handles the unstaking of assets contract LRTUnstakingVault is ILRTUnstakingVault, LRTConfigRoleChecker, PausableUpgradeable, ReentrancyGuardUpgradeable { using SafeERC20 for IERC20; using SlashingLib for *; using LRTConstants for ILRTConfig; mapping(address asset => uint256) private __deprecated_sharesUnstaking; mapping(bytes32 => bool) public trackedWithdrawal; uint256 public uncompletedWithdrawalCount; uint256 public maxUncompletedWithdrawalCount; // Portion of the vault reserved for servicing queued withdrawals; unavailable for instant withdrawals. mapping(address asset => uint256 buffer) public queuedWithdrawalsBuffer; modifier onlyLRTNodeDelegator() { ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL)); if (lrtDepositPool.isNodeDelegator(msg.sender) != 1) { revert CallerNotLRTNodeDelegator(); } _; } modifier onlyLRTWithdrawalManager() { if (msg.sender != lrtConfig.withdrawManager()) { revert CallerNotLRTWithdrawalManager(); } _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /// @dev Initializes the contract /// @param lrtConfigAddr LRT config address function initialize(address lrtConfigAddr) external initializer { UtilLib.checkNonZeroAddress(lrtConfigAddr); __Pausable_init(); __ReentrancyGuard_init(); lrtConfig = ILRTConfig(lrtConfigAddr); emit UpdatedLRTConfig(lrtConfigAddr); } /*////////////////////////////////////////////////////////////// receive functions //////////////////////////////////////////////////////////////*/ receive() external payable { emit EthReceived(msg.sender, msg.value); } /// @dev receive from LRTDepositPool function receiveFromLRTDepositPool() external payable { } /// @dev receive from NodeDelegator function receiveFromNodeDelegator() external payable { } /*////////////////////////////////////////////////////////////// write functions //////////////////////////////////////////////////////////////*/ /// @notice This is used by withdrawal manager when unlocking assets. The unlocked assets are pulled from the vault /// and used to pay the user. /// @param asset The asset address. /// @param amount The amount of asset to redeem. function redeem(address asset, uint256 amount) external nonReentrant onlyLRTWithdrawalManager { if (asset == LRTConstants.ETH_TOKEN) { ILRTWithdrawalManager(msg.sender).receiveFromLRTUnstakingVault{ value: amount }(); } else { IERC20(asset).safeTransfer(msg.sender, amount); } } /// @notice transfers asset lying in this LRTUnstakingVault to node delegator contract /// @dev only callable by Asset Transfer Role /// @param ndcIndex Index of NodeDelegator contract address in nodeDelegatorQueue /// @param asset Asset address /// @param amount Asset amount to transfer function transferAssetToNodeDelegator( uint256 ndcIndex, address asset, uint256 amount ) external nonReentrant onlyAssetTransferRole onlySupportedAsset(asset) { ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.depositPool()); address[] memory nodeDelegatorQueue = lrtDepositPool.getNodeDelegatorQueue(); address nodeDelegator = nodeDelegatorQueue[ndcIndex]; IERC20(asset).safeTransfer(nodeDelegator, amount); } /// @notice transfers ETH lying in this LRTUnstakingVault to node delegator contract /// @dev only callable by Asset Transfer Role /// @param ndcIndex Index of NodeDelegator contract address in nodeDelegatorQueue /// @param amount ETH amount to transfer function transferETHToNodeDelegator( uint256 ndcIndex, uint256 amount ) external nonReentrant onlyAssetTransferRole onlySupportedAsset(LRTConstants.ETH_TOKEN) { ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.depositPool()); address[] memory nodeDelegatorQueue = lrtDepositPool.getNodeDelegatorQueue(); address nodeDelegator = nodeDelegatorQueue[ndcIndex]; INodeDelegator(nodeDelegator).sendETHFromUnstakingVaultToNDC{ value: amount }(); emit EthTransferred(nodeDelegator, amount); } /// @notice Set the max number of uncompleted withdrawals. /// @param _maxUncompletedWithdrawalCount The max number of uncompleted withdrawals. function setMaxUncompletedWithdrawalCount(uint256 _maxUncompletedWithdrawalCount) external onlyLRTManager { // 120 is the max number of uncompleted withdrawals that allows us to still perform update rsETH price // Need buffer for theoretical operator forced undelegations (ndc count * asset count = 15) if (_maxUncompletedWithdrawalCount > 80) { revert MaxUncompletedWithdrawalCountTooHigh(); } maxUncompletedWithdrawalCount = _maxUncompletedWithdrawalCount; emit MaxUncompletedWithdrawalCountSet(_maxUncompletedWithdrawalCount); } /// @notice Set the uncompleted withdrawal count. /// @notice Can be used on forced undelegations. /// @dev only callable by LRT Manager function setUncompletedWithdrawalCount() external onlyLRTManager { ILRTDepositPool lrtDepositPool = ILRTDepositPool(lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL)); IDelegationManager delegationManager = IDelegationManager(lrtConfig.getContract(LRTConstants.EIGEN_DELEGATION_MANAGER)); address[] memory nodeDelegatorQueue = lrtDepositPool.getNodeDelegatorQueue(); uint256 totalQueued; for (uint256 i = 0; i < nodeDelegatorQueue.length; i++) { address nodeDelegator = nodeDelegatorQueue[i]; (IDelegationManager.Withdrawal[] memory queuedWithdrawals,) = delegationManager.getQueuedWithdrawals(nodeDelegator); totalQueued += queuedWithdrawals.length; } uncompletedWithdrawalCount = totalQueued; emit UncompletedWithdrawalCountSet(totalQueued); } /// @notice Increase the number of uncompleted withdrawals. /// @dev This function is only callable by the NodeDelegator contracts during the unstaking process. function increaseUncompletedWithdrawalCount() external onlyLRTNodeDelegator { uncompletedWithdrawalCount++; } /// @notice Decrease the number of uncompleted withdrawals. /// @dev This function is only callable by the NodeDelegator contracts during the unstaking process. function decreaseUncompletedWithdrawalCount() external onlyLRTNodeDelegator { if (uncompletedWithdrawalCount > 0) { uncompletedWithdrawalCount--; } } /// @notice Set the reserved buffer for queued withdrawals for an asset. /// @param asset The asset address. /// @param buffer The reserved amount for queued withdrawals. function setQueuedWithdrawalsBuffer( address asset, uint256 buffer ) external onlyLRTOperator onlySupportedAsset(asset) { queuedWithdrawalsBuffer[asset] = buffer; emit QueuedWithdrawalsBufferUpdated(asset, buffer); } /*////////////////////////////////////////////////////////////// view functions //////////////////////////////////////////////////////////////*/ /// @notice Returns the the vaults balance of the asset. /// @param asset The asset address. /// @return The balance of the asset. function balanceOf(address asset) public view returns (uint256) { if (asset == LRTConstants.ETH_TOKEN) { return address(this).balance; } else { return IERC20(asset).balanceOf(address(this)); } } /// @notice Returns the amount of the asset available for instant withdrawal. /// @param asset The asset address. /// @return availableAmount The amount of the asset available for instant withdrawal. function getAssetsAvailableForInstantWithdrawal(address asset) external view onlySupportedAsset(asset) returns (uint256 availableAmount) { uint256 vaultBalance = balanceOf(asset); uint256 reservedBuffer = queuedWithdrawalsBuffer[asset]; availableAmount = reservedBuffer >= vaultBalance ? 0 : vaultBalance - reservedBuffer; } /// @notice Fetches balance of all assets staked in eigen layer through this contract /// @param staker the staker address /// @return assets the assets that the node delegator has deposited into strategies /// @return assetBalances the balances of the assets that the node delegator has deposited into strategies function getStakedAssetBalances(address staker) external view override returns (address[] memory assets, uint256[] memory assetBalances) { (IStrategy[] memory strategies,) = IStrategyManager(lrtConfig.strategyManager()).getDeposits(staker); uint256 strategiesLength = strategies.length; assets = new address[](strategiesLength); assetBalances = new uint256[](strategiesLength); for (uint256 i = 0; i < strategiesLength;) { assets[i] = address(IStrategy(strategies[i]).underlyingToken()); assetBalances[i] = IStrategy(strategies[i]).userUnderlyingView(staker); unchecked { ++i; } } } }
違いを見つける