Diff
checker
टेक्स्ट
टेक्स्ट
छवियां
दस्तावेज़
Excel
फ़ोल्डर्स
Legal
Enterprise
डेस्कटॉप
मूल्य
साइन इन करें
Diffchecker डेस्कटॉप डाउनलोड करें
टेक्स्ट की तुलना करें
दो टेक्स्ट फ़ाइलों के बीच अंतर ढूंढें
उपकरण
इतिहास
प्रदर्शन
लेआउट
विभाजित
संयुक्त
रियल-टाइम एडिटर
रिक्त स्थान छिपाएँ
अपरिवर्तित संक्षिप्त करें
लाइन रैप बंद
परिवर्तन हाइलाइट करें
स्मार्ट
सिंटैक्स
कोई नहीं
दिखावट बदलें
प्रोसेसिंग
अनदेखा करें
टेक्स्ट बदलें
पहले अंतर पर जाएँ
इनपुट संपादित करें
Diffchecker Desktop
Diffchecker चलाने का सबसे सुरक्षित तरीका। Diffchecker Desktop ऐप पाएं: आपके diffs कभी आपके कंप्यूटर से बाहर नहीं जाते!
Desktop पाएं
LRTConverter
बनाया गया
10 माह पहले
Diff कभी समाप्त नहीं होता
साफ़
निर्यात करें
शेयर करें
समझाएं
4 हटाए गए
लाइनें
कुल
हटाया गया
अक्षर
कुल
हटाया गया
इस सुविधा का उपयोग जारी रखने के लिए, अपग्रेड करें
Diff
checker
Pro
मूल्य देखें
271 लाइनें
सभी को कॉपी करें
7 जोड़े गए
लाइनें
कुल
जोड़ा गया
अक्षर
कुल
जोड़ा गया
इस सुविधा का उपयोग जारी रखने के लिए, अपग्रेड करें
Diff
checker
Pro
मूल्य देखें
272 लाइनें
सभी को कॉपी करें
// SPDX-License-Identifier: BUSL-1.1
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.27;
pragma solidity 0.8.27;
import { LRTConstants } from "./utils/LRTConstants.sol";
import { LRTConstants } from "./utils/LRTConstants.sol";
import { UtilLib } from "./utils/UtilLib.sol";
import { UtilLib } from "./utils/UtilLib.sol";
import { LRTConfigRoleChecker, ILRTConfig } from "./utils/LRTConfigRoleChecker.sol";
import { LRTConfigRoleChecker, ILRTConfig } from "./utils/LRTConfigRoleChecker.sol";
import { ILRTDepositPool } from "./interfaces/ILRTDepositPool.sol";
import { ILRTDepositPool } from "./interfaces/ILRTDepositPool.sol";
import { ILRTOracle } from "./interfaces/ILRTOracle.sol";
import { ILRTOracle } from "./interfaces/ILRTOracle.sol";
import { ILRTConverter } from "./interfaces/ILRTConverter.sol";
import { ILRTConverter } from "./interfaces/ILRTConverter.sol";
import { ILRTWithdrawalManager } from "./interfaces/ILRTWithdrawalManager.sol";
import { ILRTWithdrawalManager } from "./interfaces/ILRTWithdrawalManager.sol";
import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.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 { UnstakeStETH } from "./unstaking-adapters/UnstakeStETH.sol";
import { UnstakeStETH } from "./unstaking-adapters/UnstakeStETH.sol";
/// @dev Legacy unstaking adapters for swETH are kept for upgrade compatibility
/// @dev Legacy unstaking adapters for swETH are kept for upgrade compatibility
import { UnstakeSwETH } from "./unstaking-adapters/UnstakeSwETH.sol";
import { UnstakeSwETH } from "./unstaking-adapters/UnstakeSwETH.sol";
/// @title LRTConverter - Unstakes LSTs to ETH and swaps ETH to LSTs
/// @title LRTConverter - Unstakes LSTs to ETH and swaps ETH to LSTs
/// @notice This contract is responsible for unstaking LSTs to ETH and swapping ETH to LSTs
/// @notice This contract is responsible for unstaking LSTs to ETH and swapping ETH to LSTs
contract LRTConverter is
contract LRTConverter is
ILRTConverter,
ILRTConverter,
LRTConfigRoleChecker,
LRTConfigRoleChecker,
ReentrancyGuardUpgradeable,
ReentrancyGuardUpgradeable,
UnstakeSwETH,
UnstakeSwETH,
UnstakeStETH,
UnstakeStETH,
IERC721Receiver
IERC721Receiver
{
{
using SafeERC20 for IERC20;
using SafeERC20 for IERC20;
mapping(bytes32 => bool) public _legacyProcessedWithdrawalRoots;
mapping(bytes32 => bool) public _legacyProcessedWithdrawalRoots;
mapping(address => bool) public _legacyConvertibleAssets;
mapping(address => bool) public _legacyConvertibleAssets;
mapping(address => uint256) public _legacyConversionLimit;
mapping(address => uint256) public _legacyConversionLimit;
// needs to be added to total assets in protocol
// needs to be added to total assets in protocol
uint256 public ethValueInWithdrawal;
uint256 public ethValueInWithdrawal;
mapping(address => bool) private whitelistedUsers;
mapping(address => bool) private whitelistedUsers;
uint256 public whitelistedUnstakeAllowance;
uint256 public whitelistedUnstakeAllowance;
modifier onlyWhitelistedUser() {
modifier onlyWhitelistedUser() {
if (!isUserWhitelisted(msg.sender)) {
if (!isUserWhitelisted(msg.sender)) {
revert UserNotWhitelisted();
revert UserNotWhitelisted();
}
}
_;
_;
}
}
/// @dev Modifier to enforce unstaking limits and update counters
/// @dev Modifier to enforce unstaking limits and update counters
/// @param amountToUnstake Amount of stETH to unstake
/// @param amountToUnstake Amount of stETH to unstake
modifier withinUnstakeLimits(uint256 amountToUnstake) {
modifier withinUnstakeLimits(uint256 amountToUnstake) {
if (amountToUnstake == 0) {
if (amountToUnstake == 0) {
revert InvalidAmount();
revert InvalidAmount();
}
}
uint256 availableActiveETHWithdrawals = _getActiveETHUserWithdrawals();
uint256 availableActiveETHWithdrawals = _getActiveETHUserWithdrawals();
if (amountToUnstake > whitelistedUnstakeAllowance + availableActiveETHWithdrawals) {
if (amountToUnstake > whitelistedUnstakeAllowance + availableActiveETHWithdrawals) {
revert UnstakeLimitExceeded();
revert UnstakeLimitExceeded();
}
}
// Consume intended withdrawal limit
// Consume intended withdrawal limit
if (whitelistedUnstakeAllowance > 0) {
if (whitelistedUnstakeAllowance > 0) {
uint256 whitelistedAmountConsumed =
uint256 whitelistedAmountConsumed =
amountToUnstake > whitelistedUnstakeAllowance ? whitelistedUnstakeAllowance : amountToUnstake;
amountToUnstake > whitelistedUnstakeAllowance ? whitelistedUnstakeAllowance : amountToUnstake;
whitelistedUnstakeAllowance -= whitelistedAmountConsumed;
whitelistedUnstakeAllowance -= whitelistedAmountConsumed;
}
}
_;
_;
}
}
/// @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);
__ReentrancyGuard_init();
__ReentrancyGuard_init();
lrtConfig = ILRTConfig(lrtConfigAddr);
lrtConfig = ILRTConfig(lrtConfigAddr);
emit UpdatedLRTConfig(lrtConfigAddr);
emit UpdatedLRTConfig(lrtConfigAddr);
}
}
/// @dev Initializes the contract
/// @dev Initializes the contract
/// @param _withdrawalQueueAddress Address of withdrawal queue (stETH)
/// @param _withdrawalQueueAddress Address of withdrawal queue (stETH)
/// @param _stETHAddress Address of stETH
/// @param _stETHAddress Address of stETH
/// @param _swEXITAddress Address of swEXIT (swETH)
/// @param _swEXITAddress Address of swEXIT (swETH)
/// @param _swETHAddress Address of swETH
/// @param _swETHAddress Address of swETH
function initialize2(
function initialize2(
address _withdrawalQueueAddress,
address _withdrawalQueueAddress,
address _stETHAddress,
address _stETHAddress,
सेव किए गए Diffs
ऑरिजनल टेक्स्ट
फ़ाइल खोलें
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.27; import { LRTConstants } from "./utils/LRTConstants.sol"; import { UtilLib } from "./utils/UtilLib.sol"; import { LRTConfigRoleChecker, ILRTConfig } from "./utils/LRTConfigRoleChecker.sol"; import { ILRTDepositPool } from "./interfaces/ILRTDepositPool.sol"; import { ILRTOracle } from "./interfaces/ILRTOracle.sol"; import { ILRTConverter } from "./interfaces/ILRTConverter.sol"; import { ILRTWithdrawalManager } from "./interfaces/ILRTWithdrawalManager.sol"; import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { UnstakeStETH } from "./unstaking-adapters/UnstakeStETH.sol"; /// @dev Legacy unstaking adapters for swETH are kept for upgrade compatibility import { UnstakeSwETH } from "./unstaking-adapters/UnstakeSwETH.sol"; /// @title LRTConverter - Unstakes LSTs to ETH and swaps ETH to LSTs /// @notice This contract is responsible for unstaking LSTs to ETH and swapping ETH to LSTs contract LRTConverter is ILRTConverter, LRTConfigRoleChecker, ReentrancyGuardUpgradeable, UnstakeSwETH, UnstakeStETH, IERC721Receiver { using SafeERC20 for IERC20; mapping(bytes32 => bool) public _legacyProcessedWithdrawalRoots; mapping(address => bool) public _legacyConvertibleAssets; mapping(address => uint256) public _legacyConversionLimit; // needs to be added to total assets in protocol uint256 public ethValueInWithdrawal; mapping(address => bool) private whitelistedUsers; uint256 public whitelistedUnstakeAllowance; modifier onlyWhitelistedUser() { if (!isUserWhitelisted(msg.sender)) { revert UserNotWhitelisted(); } _; } /// @dev Modifier to enforce unstaking limits and update counters /// @param amountToUnstake Amount of stETH to unstake modifier withinUnstakeLimits(uint256 amountToUnstake) { if (amountToUnstake == 0) { revert InvalidAmount(); } uint256 availableActiveETHWithdrawals = _getActiveETHUserWithdrawals(); if (amountToUnstake > whitelistedUnstakeAllowance + availableActiveETHWithdrawals) { revert UnstakeLimitExceeded(); } // Consume intended withdrawal limit if (whitelistedUnstakeAllowance > 0) { uint256 whitelistedAmountConsumed = amountToUnstake > whitelistedUnstakeAllowance ? whitelistedUnstakeAllowance : amountToUnstake; whitelistedUnstakeAllowance -= whitelistedAmountConsumed; } _; } /// @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); __ReentrancyGuard_init(); lrtConfig = ILRTConfig(lrtConfigAddr); emit UpdatedLRTConfig(lrtConfigAddr); } /// @dev Initializes the contract /// @param _withdrawalQueueAddress Address of withdrawal queue (stETH) /// @param _stETHAddress Address of stETH /// @param _swEXITAddress Address of swEXIT (swETH) /// @param _swETHAddress Address of swETH function initialize2( address _withdrawalQueueAddress, address _stETHAddress, address _swEXITAddress, address _swETHAddress ) external reinitializer(2) onlyLRTAdmin { __ReentrancyGuard_init(); __initializeSwETH(_swEXITAddress, _swETHAddress); __initializeStETH(_withdrawalQueueAddress, _stETHAddress); } function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) { return this.onERC721Received.selector; } /// @dev fallback to receive funds receive() external payable { } /*//////////////////////////////////////////////////////////// write interactions //////////////////////////////////////////////////////////////*/ /// @notice send asset from deposit pool to LRTConverter /// @dev Only callable by LRT Operator and asset need to be approved /// @param _asset Asset address to send /// @param _amount Asset amount to send function transferAssetFromDepositPool( address _asset, uint256 _amount ) external onlySupportedERC20Token(_asset) onlyLRTOperator { address lrtDepositPoolAddress = lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL); address lrtOracleAddress = lrtConfig.getContract(LRTConstants.LRT_ORACLE); ILRTOracle lrtOracle = ILRTOracle(lrtOracleAddress); ethValueInWithdrawal += (_amount * lrtOracle.getAssetPrice(_asset)) / 1e18; IERC20(_asset).safeTransferFrom(lrtDepositPoolAddress, address(this), _amount); } /// @notice send asset from LRTConverter to deposit pool /// @dev Only callable by LRT Operator and asset need to be approved /// @param _asset Asset address to send /// @param _amount Asset amount to send function transferAssetToDepositPool( address _asset, uint256 _amount ) external onlySupportedERC20Token(_asset) onlyLRTOperator { address lrtDepositPoolAddress = lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL); address lrtOracleAddress = lrtConfig.getContract(LRTConstants.LRT_ORACLE); ILRTOracle lrtOracle = ILRTOracle(lrtOracleAddress); uint256 assetValue = (_amount * lrtOracle.getAssetPrice(_asset)) / 1e18; // Set to 0 if assetValue exceeds ethValueInWithdrawal, otherwise subtract assetValue ethValueInWithdrawal = ethValueInWithdrawal > assetValue ? ethValueInWithdrawal - assetValue : 0; IERC20(_asset).safeTransfer(lrtDepositPoolAddress, _amount); } /// @notice raises a unstake request for steth on lido /// @param amountToUnstake Amount of stETH to unstake function unstakeStEth(uint256 amountToUnstake) external nonReentrant onlyLRTOperator withinUnstakeLimits(amountToUnstake) { _unstakeStEth(amountToUnstake); } /// @notice claim eth from lido for steth and sends to deposit pool function claimStEth(uint256 _requestId, uint256 _hint) external nonReentrant onlyLRTOperator { _claimStEth(_requestId, _hint); _sendEthToDepositPool(address(this).balance); } /// @notice raises a unstake request for sweth on swell function unstakeSwEth(uint256 amountToUnstake) external nonReentrant onlyLRTOperator { _unstakeSwEth(amountToUnstake); } /// @notice claim eth from sweth from swell for sweth and sends to deposit pool function claimSwEth(uint256 _tokenId) external nonReentrant onlyLRTOperator { _claimSwEth(_tokenId); _sendEthToDepositPool(address(this).balance); } /// @notice Add or remove a user from the whitelist /// @param user User address /// @param whitelisted Whether to whitelist or remove from whitelist function setUserWhitelisted(address user, bool whitelisted) external onlyLRTManager { whitelistedUsers[user] = whitelisted; emit UserWhitelisted(user, whitelisted); } /// @notice Batch add or remove users from the whitelist /// @param users Array of user addresses /// @param whitelisted Whether to whitelist or remove from whitelist function batchSetUserWhitelisted(address[] calldata users, bool whitelisted) external onlyLRTManager { for (uint256 i = 0; i < users.length; i++) { whitelistedUsers[users[i]] = whitelisted; emit UserWhitelisted(users[i], whitelisted); } } /// @notice Declare withdrawal intent (only whitelisted users) /// @param amount Amount of stETH to declare for withdrawal function declareWithdrawalIntent(uint256 amount) external nonReentrant onlyWhitelistedUser { if (amount == 0) { revert InvalidAmount(); } uint256 maxWhitelistedAllowance = 1_000_000_000 ether; if (whitelistedUnstakeAllowance + amount > maxWhitelistedAllowance) { revert WhitelistedAllowanceExceeded(); } whitelistedUnstakeAllowance = whitelistedUnstakeAllowance + amount; emit WithdrawalIntentDeclared(msg.sender, amount); } /*//////////////////////////////////////////////////////////// view functions //////////////////////////////////////////////////////////////*/ /// @notice Get the current unstaking limits and usage /// @return whitelistedAllowance Current whitelisted unstake allowance /// @return activeETHWithdrawals Current active ETH withdrawals function getUnstakeLimits() external view returns (uint256 whitelistedAllowance, uint256 activeETHWithdrawals) { whitelistedAllowance = whitelistedUnstakeAllowance; activeETHWithdrawals = _getActiveETHUserWithdrawals(); } /// @notice Check if a user is whitelisted /// @param user User address to check /// @return True if user is whitelisted function isUserWhitelisted(address user) public view returns (bool) { return whitelistedUsers[user]; } /*//////////////////////////////////////////////////////////// internal functions //////////////////////////////////////////////////////////////*/ function _sendEthToDepositPool(uint256 _amount) internal { address lrtDepositPoolAddress = lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL); if (ethValueInWithdrawal > _amount) { ethValueInWithdrawal -= _amount; } else { ethValueInWithdrawal = 0; } // Send eth to deposit pool ILRTDepositPool(lrtDepositPoolAddress).receiveFromLRTConverter{ value: _amount }(); emit EthTransferred(lrtDepositPoolAddress, _amount); } /// @dev Get active user ETH withdrawals from LRTWithdrawalManager function _getActiveETHUserWithdrawals() internal view returns (uint256 activeETHWithdrawals) { ILRTWithdrawalManager lrtWithdrawalManager = ILRTWithdrawalManager(lrtConfig.getContract(LRTConstants.LRT_WITHDRAW_MANAGER)); activeETHWithdrawals = lrtWithdrawalManager.assetsCommitted(LRTConstants.ETH_TOKEN); } }
परिवर्तित टेक्स्ट
फ़ाइल खोलें
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.27; import { LRTConstants } from "./utils/LRTConstants.sol"; import { UtilLib } from "./utils/UtilLib.sol"; import { LRTConfigRoleChecker, ILRTConfig } from "./utils/LRTConfigRoleChecker.sol"; import { ILRTDepositPool } from "./interfaces/ILRTDepositPool.sol"; import { ILRTOracle } from "./interfaces/ILRTOracle.sol"; import { ILRTConverter } from "./interfaces/ILRTConverter.sol"; import { ILRTWithdrawalManager } from "./interfaces/ILRTWithdrawalManager.sol"; import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { UnstakeStETH } from "./unstaking-adapters/UnstakeStETH.sol"; /// @dev Legacy unstaking adapters for swETH are kept for upgrade compatibility import { UnstakeSwETH } from "./unstaking-adapters/UnstakeSwETH.sol"; /// @title LRTConverter - Unstakes LSTs to ETH and swaps ETH to LSTs /// @notice This contract is responsible for unstaking LSTs to ETH and swapping ETH to LSTs contract LRTConverter is ILRTConverter, LRTConfigRoleChecker, ReentrancyGuardUpgradeable, UnstakeSwETH, UnstakeStETH, IERC721Receiver { using SafeERC20 for IERC20; mapping(bytes32 => bool) public _legacyProcessedWithdrawalRoots; mapping(address => bool) public _legacyConvertibleAssets; mapping(address => uint256) public _legacyConversionLimit; // needs to be added to total assets in protocol uint256 public ethValueInWithdrawal; mapping(address => bool) private whitelistedUsers; uint256 public whitelistedUnstakeAllowance; modifier onlyWhitelistedUser() { if (!isUserWhitelisted(msg.sender)) { revert UserNotWhitelisted(); } _; } /// @dev Modifier to enforce unstaking limits and update counters /// @param amountToUnstake Amount of stETH to unstake modifier withinUnstakeLimits(uint256 amountToUnstake) { if (amountToUnstake == 0) { revert InvalidAmount(); } uint256 availableActiveETHWithdrawals = _getActiveETHUserWithdrawals(); if (amountToUnstake > whitelistedUnstakeAllowance + availableActiveETHWithdrawals) { revert UnstakeLimitExceeded(); } // Consume intended withdrawal limit if (whitelistedUnstakeAllowance > 0) { uint256 whitelistedAmountConsumed = amountToUnstake > whitelistedUnstakeAllowance ? whitelistedUnstakeAllowance : amountToUnstake; whitelistedUnstakeAllowance -= whitelistedAmountConsumed; } _; } /// @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); __ReentrancyGuard_init(); lrtConfig = ILRTConfig(lrtConfigAddr); emit UpdatedLRTConfig(lrtConfigAddr); } /// @dev Initializes the contract /// @param _withdrawalQueueAddress Address of withdrawal queue (stETH) /// @param _stETHAddress Address of stETH /// @param _swEXITAddress Address of swEXIT (swETH) /// @param _swETHAddress Address of swETH function initialize2( address _withdrawalQueueAddress, address _stETHAddress, address _swEXITAddress, address _swETHAddress ) external reinitializer(2) onlyLRTAdmin { __ReentrancyGuard_init(); __initializeSwETH(_swEXITAddress, _swETHAddress); __initializeStETH(_withdrawalQueueAddress, _stETHAddress); } function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) { return this.onERC721Received.selector; } /// @dev fallback to receive funds receive() external payable { } /*//////////////////////////////////////////////////////////// write interactions //////////////////////////////////////////////////////////////*/ /// @notice send asset from deposit pool to LRTConverter /// @dev Only callable by Asset Transfer Role and asset needs to be approved /// @param _asset Asset address to send /// @param _amount Asset amount to send function transferAssetFromDepositPool( address _asset, uint256 _amount ) external onlySupportedERC20Token(_asset) onlyAssetTransferRole { address lrtDepositPoolAddress = lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL); address lrtOracleAddress = lrtConfig.getContract(LRTConstants.LRT_ORACLE); ILRTOracle lrtOracle = ILRTOracle(lrtOracleAddress); ethValueInWithdrawal += (_amount * lrtOracle.getAssetPrice(_asset)) / 1e18; IERC20(_asset).safeTransferFrom(lrtDepositPoolAddress, address(this), _amount); } /// @notice send asset from LRTConverter to deposit pool /// @dev Only callable by Asset Transfer Role and asset needs to be approved /// @param _asset Asset address to send /// @param _amount Asset amount to send function transferAssetToDepositPool( address _asset, uint256 _amount ) external onlySupportedERC20Token(_asset) onlyAssetTransferRole { address lrtDepositPoolAddress = lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL); address lrtOracleAddress = lrtConfig.getContract(LRTConstants.LRT_ORACLE); ILRTOracle lrtOracle = ILRTOracle(lrtOracleAddress); uint256 assetValue = (_amount * lrtOracle.getAssetPrice(_asset)) / 1e18; // Set to 0 if assetValue exceeds ethValueInWithdrawal, otherwise subtract assetValue ethValueInWithdrawal = ethValueInWithdrawal > assetValue ? ethValueInWithdrawal - assetValue : 0; IERC20(_asset).safeTransfer(lrtDepositPoolAddress, _amount); } /// @notice raises a unstake request for steth on lido /// @param amountToUnstake Amount of stETH to unstake function unstakeStEth(uint256 amountToUnstake) external nonReentrant onlyLRTOperator withinUnstakeLimits(amountToUnstake) { _unstakeStEth(amountToUnstake); } /// @notice claim eth from lido for steth and sends to deposit pool function claimStEth(uint256 _requestId, uint256 _hint) external nonReentrant onlyLRTOperator { _claimStEth(_requestId, _hint); _sendEthToDepositPool(address(this).balance); } /// @notice raises a unstake request for sweth on swell function unstakeSwEth(uint256 amountToUnstake) external nonReentrant onlyLRTOperator { _unstakeSwEth(amountToUnstake); } /// @notice claim eth from sweth from swell for sweth and sends to deposit pool function claimSwEth(uint256 _tokenId) external nonReentrant onlyLRTOperator { _claimSwEth(_tokenId); _sendEthToDepositPool(address(this).balance); } /// @notice Add or remove a user from the whitelist /// @param user User address /// @param whitelisted Whether to whitelist or remove from whitelist function setUserWhitelisted(address user, bool whitelisted) external onlyLRTManager { whitelistedUsers[user] = whitelisted; emit UserWhitelisted(user, whitelisted); } /// @notice Batch add or remove users from the whitelist /// @param users Array of user addresses /// @param whitelisted Whether to whitelist or remove from whitelist function batchSetUserWhitelisted(address[] calldata users, bool whitelisted) external onlyLRTManager { for (uint256 i = 0; i < users.length; i++) { whitelistedUsers[users[i]] = whitelisted; emit UserWhitelisted(users[i], whitelisted); } } /// @notice Declare withdrawal intent (only whitelisted users) /// @param amount Amount of stETH to declare for withdrawal function declareWithdrawalIntent(uint256 amount) external nonReentrant onlyWhitelistedUser { if (amount == 0) { revert InvalidAmount(); } uint256 maxWhitelistedAllowance = 1_000_000_000 ether; if (whitelistedUnstakeAllowance + amount > maxWhitelistedAllowance) { revert WhitelistedAllowanceExceeded(); } whitelistedUnstakeAllowance = whitelistedUnstakeAllowance + amount; emit WithdrawalIntentDeclared(msg.sender, amount); } /*//////////////////////////////////////////////////////////// view functions //////////////////////////////////////////////////////////////*/ /// @notice Get the current unstaking limits and usage /// @return whitelistedAllowance Current whitelisted unstake allowance /// @return activeETHWithdrawals Current active ETH withdrawals function getUnstakeLimits() external view returns (uint256 whitelistedAllowance, uint256 activeETHWithdrawals) { whitelistedAllowance = whitelistedUnstakeAllowance; activeETHWithdrawals = _getActiveETHUserWithdrawals(); } /// @notice Check if a user is whitelisted /// @param user User address to check /// @return True if user is whitelisted function isUserWhitelisted(address user) public view returns (bool) { return whitelistedUsers[user]; } /*//////////////////////////////////////////////////////////// internal functions //////////////////////////////////////////////////////////////*/ function _sendEthToDepositPool(uint256 _amount) internal { address lrtDepositPoolAddress = lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL); if (ethValueInWithdrawal > _amount) { ethValueInWithdrawal -= _amount; } else { ethValueInWithdrawal = 0; } // Send eth to deposit pool ILRTDepositPool(lrtDepositPoolAddress).receiveFromLRTConverter{ value: _amount }(); emit EthTransferred(lrtDepositPoolAddress, _amount); } /// @dev Get active user ETH withdrawals from LRTWithdrawalManager function _getActiveETHUserWithdrawals() internal view returns (uint256 activeETHWithdrawals) { ILRTWithdrawalManager lrtWithdrawalManager = ILRTWithdrawalManager(lrtConfig.getContract(LRTConstants.LRT_WITHDRAW_MANAGER)); activeETHWithdrawals = lrtWithdrawalManager.assetsCommitted(LRTConstants.ETH_TOKEN); } }
अंतर खोजें