Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 115 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim All Pendin... | 22464618 | 3 days ago | IN | 0 ETH | 0.0008657 | ||||
Invoke | 22444008 | 6 days ago | IN | 0 ETH | 0.00047449 | ||||
0x68747470 | 22413227 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22412841 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22412444 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22412279 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22411673 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22411306 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22410928 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22410558 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22410190 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22409819 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22409446 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22409077 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22408708 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22408333 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22407962 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22407593 | 11 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22407219 | 12 days ago | IN | 0 ETH | 0.00002384 | ||||
0x68747470 | 22406876 | 12 days ago | IN | 0 ETH | 0.00002366 | ||||
Swap To Ether | 22398567 | 13 days ago | IN | 0 ETH | 0.00183391 | ||||
Invoke | 22381526 | 15 days ago | IN | 0 ETH | 0.0005067 | ||||
Invoke | 22330192 | 22 days ago | IN | 0 ETH | 0.00064632 | ||||
Invoke | 22282814 | 29 days ago | IN | 0 ETH | 0.00068983 | ||||
Invoke | 22139743 | 49 days ago | IN | 0 ETH | 0.00056381 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
Transfer | 22478098 | 2 days ago | 0.00908177 ETH | ||||
Transfer | 22477774 | 2 days ago | 0.04456283 ETH | ||||
Transfer | 22477772 | 2 days ago | 0.04194149 ETH | ||||
Transfer | 22477585 | 2 days ago | 22.70443026 ETH | ||||
Transfer | 22477580 | 2 days ago | 0.21844526 ETH | ||||
Transfer | 22477578 | 2 days ago | 0.087451 ETH | ||||
Transfer | 22477572 | 2 days ago | 0.03933138 ETH | ||||
Transfer | 22477535 | 2 days ago | 0.04368587 ETH | ||||
Transfer | 22477525 | 2 days ago | 1.44173507 ETH | ||||
Transfer | 22477503 | 2 days ago | 544.90632631 ETH | ||||
Transfer | 22477490 | 2 days ago | 7.90206589 ETH | ||||
Transfer | 22477490 | 2 days ago | 181.6354421 ETH | ||||
Transfer | 22477449 | 2 days ago | 5.19043266 ETH | ||||
Transfer | 22477432 | 2 days ago | 0.17474013 ETH | ||||
Transfer | 22477428 | 2 days ago | 0.08298656 ETH | ||||
Transfer | 22477418 | 2 days ago | 0.09783821 ETH | ||||
Transfer | 22477405 | 2 days ago | 0.04367713 ETH | ||||
Transfer | 22477361 | 2 days ago | 0.08825166 ETH | ||||
Transfer | 22477334 | 2 days ago | 0.13225251 ETH | ||||
Transfer | 22477317 | 2 days ago | 0.0524417 ETH | ||||
Transfer | 22477303 | 2 days ago | 1.40459433 ETH | ||||
Transfer | 22477302 | 2 days ago | 0.24550989 ETH | ||||
Transfer | 22477215 | 2 days ago | 1.0482513 ETH | ||||
Transfer | 22477181 | 2 days ago | 43.69051068 ETH | ||||
Transfer | 22477153 | 2 days ago | 0.80847631 ETH |
Loading...
Loading
Contract Name:
EigenLSTRestaking
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 10 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {TransferHelper} from "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {EigenStrategy} from "../EigenStrategy.sol"; import {SwappingAggregator} from "../SwappingAggregator.sol"; import {IStrategyManager} from "../../interfaces/IStrategyManager.sol"; import {IDelegationManager} from "../../interfaces/IDelegationManager.sol"; import {IEigenStrategy} from "../../interfaces/IEigenStrategy.sol"; import {ILido} from "../../interfaces/ILido.sol"; import {ILidoWithdrawalQueue} from "../../interfaces/ILidoWithdrawalQueue.sol"; contract EigenLSTRestaking is EigenStrategy { using EnumerableSet for EnumerableSet.Bytes32Set; address public immutable tokenAddr; address public immutable strategyManager; address public immutable delegationManager; address public immutable eigenStrategy; address public immutable LidoWithdrawalQueue; address payable public immutable SWAPPING; address public referral; address public eigenOperator; bool public buyOnDex; bool public sellOnDex; bytes32[] public withdrawals; mapping(bytes32 => uint256) public withdrawingShares; EnumerableSet.Bytes32Set private withdrawalRootsSet; event Swap(address from, address to, uint256 sent, uint256 received); event DepositIntoStrategy(address strategy, address token, uint256 amount); event DelegateTo(address operator); event WithdrawalQueued(bytes32 withdrawalRoot); event WithdrawalCompleted( IDelegationManager.Withdrawal withdrawal, bytes32 root ); event SetEigenOperator(address oldOperator, address newOperator); event SetWithdrawQueueParams(uint256 length, uint256 amount); event SetRouter(bool buyOnDex, bool sellOnDex); event SetReferral(address oldAddr, address newAddr); event Invoked(address indexed targetAddress, uint256 value, bytes data); constructor( address payable _controller, address _tokenAddr, address _lidoWithdrawalQueue, address _strategyManager, address _delegationManager, address _eigenStrategy, address payable _swap, string memory _name ) EigenStrategy(_controller, _name) { require( _tokenAddr != address(0) && _lidoWithdrawalQueue != address(0) && _strategyManager != address(0) && _delegationManager != address(0) && _eigenStrategy != address(0) && _swap != address(0), "ZERO ADDRESS" ); tokenAddr = _tokenAddr; LidoWithdrawalQueue = _lidoWithdrawalQueue; strategyManager = _strategyManager; delegationManager = _delegationManager; eigenStrategy = _eigenStrategy; SWAPPING = _swap; } function deposit() public payable override onlyController notAtSameBlock { require(msg.value != 0, "zero value"); latestUpdateTime = block.timestamp; } function withdraw( uint256 _amount ) public override onlyController notAtSameBlock returns (uint256 actualAmount) { actualAmount = _withdraw(_amount); } function instantWithdraw( uint256 _amount ) public override onlyController returns (uint256 actualAmount) { actualAmount = _withdraw(_amount); } function _withdraw( uint256 _amount ) internal returns (uint256 actualAmount) { require(_amount != 0, "zero value"); require(_amount <= address(this).balance, "not enough"); actualAmount = _amount; TransferHelper.safeTransferETH(controller, actualAmount); latestUpdateTime = block.timestamp; } function clear() public override onlyController returns (uint256 amount) { uint256 balance = address(this).balance; if (balance != 0) { TransferHelper.safeTransferETH(controller, balance); amount = balance; } } function getAllValue() public override returns (uint256 value) { value = getInvestedValue(); } // TODO need testing function getInvestedValue() public override returns (uint256 value) { uint256 etherValue = address(this).balance; uint256 tokenValue = IERC20(tokenAddr).balanceOf(address(this)); (, uint256 claimableValue, uint256 pendingValue) = checkPendingAssets(); uint256 eigenValue = getRestakingValue(); uint256 unstakingValue = getUnstakingValue(); value = etherValue + tokenValue + claimableValue + pendingValue + eigenValue + unstakingValue; } function depositIntoStrategy( uint256 _amount ) external onlyOwner returns (uint256 shares) { TransferHelper.safeApprove(tokenAddr, strategyManager, _amount); shares = IStrategyManager(strategyManager).depositIntoStrategy( eigenStrategy, tokenAddr, _amount ); emit DepositIntoStrategy(eigenStrategy, tokenAddr, _amount); } function delegateTo( IDelegationManager.SignatureWithExpiry memory _approverSignatureAndExpiry, bytes32 _approverSalt ) external onlyOwner { IDelegationManager(delegationManager).delegateTo( eigenOperator, _approverSignatureAndExpiry, _approverSalt ); emit DelegateTo(eigenOperator); } function undelegate() external onlyOwner returns (bytes32[] memory withdrawalRoots) { require( IEigenStrategy(eigenStrategy).shares(address(this)) == 0, "active shares" ); withdrawalRoots = IDelegationManager(delegationManager).undelegate( address(this) ); } function queueWithdrawals( IDelegationManager.QueuedWithdrawalParams[] calldata _queuedWithdrawalParams ) external onlyOwner returns (bytes32[] memory withdrawalRoots) { require( _queuedWithdrawalParams.length == 1 && _queuedWithdrawalParams[0].shares.length == 1 && _queuedWithdrawalParams[0].strategies.length == 1, "invalid length" ); withdrawalRoots = IDelegationManager(delegationManager) .queueWithdrawals(_queuedWithdrawalParams); uint256 length = withdrawalRoots.length; require(length == 1, "invalid root length"); bytes32 root = withdrawalRoots[0]; withdrawalRootsSet.add(root); withdrawingShares[root] = _queuedWithdrawalParams[0].shares[0]; emit WithdrawalQueued(root); } function completeQueuedWithdrawal( IDelegationManager.Withdrawal calldata _withdrawal, IERC20[] calldata _tokens, uint256 _middlewareTimesIndex, bool _receiveAsTokens ) external onlyOwner { IDelegationManager(delegationManager).completeQueuedWithdrawal( _withdrawal, _tokens, _middlewareTimesIndex, _receiveAsTokens ); bytes32 root = calculateWithdrawalRoot(_withdrawal); withdrawingShares[root] = 0; withdrawalRootsSet.remove(root); emit WithdrawalCompleted(_withdrawal, root); } function swapToToken( uint256 _amount ) external onlyOwner returns (uint256 tokenAmount) { require(_amount != 0, "zero"); require(_amount <= address(this).balance, "exceed balance"); if (!buyOnDex) { tokenAmount = ILido(tokenAddr).submit{value: _amount}(referral); } else { tokenAmount = SwappingAggregator(SWAPPING).swap{value: _amount}( tokenAddr, _amount, false ); } emit Swap(address(0), tokenAddr, _amount, tokenAmount); } function swapToEther( uint256 _amount ) external onlyOwner returns (uint256 etherAmount) { IERC20 token = IERC20(tokenAddr); require(_amount != 0, "zero"); require(_amount <= token.balanceOf(address(this)), "exceed balance"); if (!sellOnDex) { token.approve(LidoWithdrawalQueue, _amount); ILidoWithdrawalQueue withdrawalQueue = ILidoWithdrawalQueue( LidoWithdrawalQueue ); uint256 maxAmountPerRequest = withdrawalQueue .MAX_STETH_WITHDRAWAL_AMOUNT(); uint256 minAmountPerRequest = withdrawalQueue .MIN_STETH_WITHDRAWAL_AMOUNT(); uint256[] memory amounts; if (_amount <= maxAmountPerRequest) { amounts = new uint256[](1); amounts[0] = _amount; } else { uint256 length = _amount / maxAmountPerRequest + 1; uint256 remainder = _amount % maxAmountPerRequest; if (remainder >= minAmountPerRequest) { amounts = new uint256[](length); amounts[length - 1] = remainder; } else { amounts = new uint256[](length - 1); } uint256 i; for (i; i < length - 1; i++) { amounts[i] = maxAmountPerRequest; } } uint256[] memory ids = withdrawalQueue.requestWithdrawals( amounts, address(this) ); require(ids.length != 0, "Lido request withdrawal error"); etherAmount = _amount; } else { TransferHelper.safeApprove(tokenAddr, SWAPPING, _amount); etherAmount = SwappingAggregator(SWAPPING).swap( tokenAddr, _amount, true ); } emit Swap(tokenAddr, address(0), _amount, etherAmount); } function setRouter(bool _buyOnDex, bool _sellOnDex) external onlyOwner { buyOnDex = _buyOnDex; sellOnDex = _sellOnDex; emit SetRouter(_buyOnDex, _sellOnDex); } function setEigenOperator(address _operator) external onlyOwner { require(_operator != address(0), "ZERO ADDR"); require( IDelegationManager(delegationManager).isOperator(_operator), "not operator" ); emit SetEigenOperator(eigenOperator, _operator); eigenOperator = _operator; } function setReferral(address _referral) external onlyOwner { require(_referral != address(0), "ZERO ADDR"); emit SetReferral(referral, _referral); referral = _referral; } function claimPendingAssets(uint256[] memory _ids) external onlyOwner { uint256 length = _ids.length; require(length != 0, "invalid length"); for (uint256 i; i < length; i++) { if (_ids[i] == 0) continue; ILidoWithdrawalQueue(LidoWithdrawalQueue).claimWithdrawal(_ids[i]); } } function claimAllPendingAssets() external onlyOwner { (uint256[] memory ids, , ) = checkPendingAssets(); uint256 length = ids.length; for (uint256 i; i < length; i++) { if (ids[i] == 0) continue; ILidoWithdrawalQueue(LidoWithdrawalQueue).claimWithdrawal(ids[i]); } } // TODO Gas consumption function checkPendingAssets() public returns ( uint256[] memory ids, uint256 totalClaimable, uint256 totalPending ) { ILidoWithdrawalQueue queue = ILidoWithdrawalQueue(LidoWithdrawalQueue); uint256[] memory allIds = queue.getWithdrawalRequests(address(this)); if (allIds.length == 0) { return (new uint256[](0), 0, 0); } ids = new uint256[](allIds.length); ILidoWithdrawalQueue.WithdrawalRequestStatus[] memory statuses = queue .getWithdrawalStatus(allIds); uint256 j; uint256 length = statuses.length; for (uint256 i; i < length; i++) { ILidoWithdrawalQueue.WithdrawalRequestStatus memory status = statuses[i]; if (status.isClaimed) { continue; } if (status.isFinalized) { ids[j++] = allIds[i]; totalClaimable = totalClaimable + status.amountOfStETH; } else { totalPending = totalPending + status.amountOfStETH; } } assembly { mstore(ids, j) } } function getRestakingValue() public view returns (uint256 value) { value = IEigenStrategy(eigenStrategy).userUnderlyingView(address(this)); } function getUnstakingValue() public view returns (uint256 value) { uint256 length = withdrawalRootsSet.length(); uint256 i; for (i; i < length; i++) { value += IEigenStrategy(eigenStrategy).sharesToUnderlyingView( withdrawingShares[withdrawalRootsSet.at(i)] ); } } function getWithdrawalRoots() public view returns (bytes32[] memory roots) { uint256 length = withdrawalRootsSet.length(); roots = new bytes32[](length); for (uint256 i; i < length; i++) { roots[i] = withdrawalRootsSet.at(i); } } function calculateWithdrawalRoot( IDelegationManager.Withdrawal memory withdrawal ) public pure returns (bytes32) { return keccak256(abi.encode(withdrawal)); } function invoke( address target, bytes memory data ) external onlyOwner returns (bytes memory result) { require(target != tokenAddr, "not permit"); bool success; (success, result) = target.call{value: 0}(data); if (!success) { // solhint-disable-next-line no-inline-assembly assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } emit Invoked(target, 0, data); } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {TransferHelper} from "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol"; import {ISwapRouter} from "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; import {IQuoter} from "@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IStableSwap} from "../interfaces/IStableSwap.sol"; import {IWETH9} from "../interfaces/IWETH9.sol"; contract SwappingAggregator is ReentrancyGuard { uint256 internal constant MULTIPLIER = 1e18; uint256 internal constant ONE_HUNDRED_PERCENT = 1e6; address internal immutable QUOTER = 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6; address internal immutable ROUTER = 0xE592427A0AEce92De3Edee1F18E0157C05861564; address internal immutable WETH9; address internal immutable CURVE_ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; mapping(address => address) public uniV3Pools; // token => pool mapping(address => address) public curvePools; mapping(address => uint8) public curvePoolType; // 0 - stableswap; 1 - two crypto swap mapping(address => uint256) public slippage; mapping(address => uint24) public fees; address public governance; event SetSlippage( address indexed token, uint256 oldSlippage, uint256 newSlippage ); event TransferGovernance(address oldAddr, address newAddr); modifier onlyGovernance() { require(governance == msg.sender, "not governace"); _; } enum DEX_TYPE { UNISWAPV3, CURVE } constructor( address _wETH, address[] memory _tokens, address[] memory _uniPools, address[] memory _curvePools, uint8[] memory _curvePoolTypes, uint256[] memory _slippages, uint24[] memory _fees ) { uint256 length = _tokens.length; require( length == _uniPools.length && length == _curvePools.length && length == _curvePoolTypes.length, "invalid length" ); require(_wETH != address(0), "ZERO ADDRESS"); for (uint256 i; i < length; i++) { require( _tokens[i] != address(0) && _uniPools[i] != address(0) && _curvePools[i] != address(0), "ZERO ADDRESS" ); uniV3Pools[_tokens[i]] = _uniPools[i]; curvePools[_tokens[i]] = _curvePools[i]; curvePoolType[_curvePools[i]] = _curvePoolTypes[i]; slippage[_tokens[i]] = _slippages[i]; fees[_tokens[i]] = _fees[i]; } governance = msg.sender; WETH9 = _wETH; } function swap( address _token, uint256 _amount, bool _isSell ) external payable returns (uint256 amount) { if ( uniV3Pools[_token] == address(0) && curvePools[_token] == address(0) ) { return 0; } (DEX_TYPE dex, uint256 expected) = getBestRouter( _token, _amount, _isSell ); if (!_isSell) { require(_amount == msg.value, "wrong value"); } if (expected == 0) { return 0; } if (dex == DEX_TYPE.UNISWAPV3) { amount = swapOnUniV3(_token, _amount, _isSell); } else { amount = swapOnCurve(_token, _amount, _isSell); } } function swapOnUniV3( address _token, uint256 _amount, bool _isSell ) internal nonReentrant returns (uint256 amount) { uint256 minReceived = calMinimumReceivedAmount( _amount, slippage[_token] ); address pool = uniV3Pools[_token]; if (_isSell) { TransferHelper.safeTransferFrom( _token, msg.sender, address(this), _amount ); TransferHelper.safeApprove(_token, ROUTER, _amount); ISwapRouter.ExactInputSingleParams memory params = ISwapRouter .ExactInputSingleParams({ tokenIn: _token, tokenOut: WETH9, fee: fees[_token], recipient: address(this), deadline: block.timestamp, amountIn: _amount, amountOutMinimum: minReceived, sqrtPriceLimitX96: 0 }); amount = ISwapRouter(ROUTER).exactInputSingle(params); IWETH9(WETH9).withdraw(amount); TransferHelper.safeTransferETH(msg.sender, address(this).balance); } else { IWETH9(WETH9).deposit{value: msg.value}(); TransferHelper.safeApprove( WETH9, ROUTER, IWETH9(WETH9).balanceOf(address(this)) ); ISwapRouter.ExactInputSingleParams memory params = ISwapRouter .ExactInputSingleParams({ tokenIn: WETH9, tokenOut: _token, fee: fees[_token], recipient: address(this), deadline: block.timestamp, amountIn: _amount, amountOutMinimum: minReceived, sqrtPriceLimitX96: 0 }); amount = ISwapRouter(ROUTER).exactInputSingle(params); TransferHelper.safeTransfer( _token, msg.sender, IERC20(_token).balanceOf(address(this)) ); } } function swapOnCurve( address _token, uint256 _amount, bool _isSell ) internal nonReentrant returns (uint256 amount) { uint256 minReceived = calMinimumReceivedAmount( _amount, slippage[_token] ); address pool = curvePools[_token]; (uint256 e, uint256 t, bool wrapped) = getCurveCoinIndex(_token); uint8 poolType = curvePoolType[pool]; if (_isSell) { TransferHelper.safeTransferFrom( _token, msg.sender, address(this), _amount ); TransferHelper.safeApprove(_token, pool, _amount); if (poolType == 0) { amount = IStableSwap(pool).exchange( int128(int256(t)), int128(int256(e)), _amount, minReceived ); } else { amount = IStableSwap(pool).exchange(t, e, _amount, minReceived); } if (wrapped) { IWETH9 weth = IWETH9(WETH9); weth.withdraw(weth.balanceOf(address(this))); } TransferHelper.safeTransferETH(msg.sender, address(this).balance); } else { if (poolType == 0) { if (!wrapped) { amount = IStableSwap(pool).exchange{value: _amount}( int128(int256(e)), int128(int256(t)), _amount, minReceived ); } else { IWETH9 weth = IWETH9(WETH9); weth.deposit{value: _amount}(); weth.approve(pool, _amount); amount = IStableSwap(pool).exchange( int128(int256(e)), int128(int256(t)), _amount, minReceived ); } } else { if (!wrapped) { amount = IStableSwap(pool).exchange{value: _amount}( e, t, _amount, minReceived ); } else { IWETH9 weth = IWETH9(WETH9); weth.deposit{value: _amount}(); weth.approve(pool, _amount); amount = IStableSwap(pool).exchange( e, t, _amount, minReceived ); } } TransferHelper.safeTransfer( _token, msg.sender, IERC20(_token).balanceOf(address(this)) ); } } function getBestRouter( address _token, uint256 _amount, bool _isSell ) public returns (DEX_TYPE dex, uint256 out) { uint256 uniV3Out = getUniV3Out(_token, _amount, _isSell); uint256 curveOut = getCurveOut(_token, _amount, _isSell); return uniV3Out > curveOut ? (DEX_TYPE.UNISWAPV3, uniV3Out) : (DEX_TYPE.CURVE, curveOut); } function getUniV3Out( address _token, uint256 _amount, bool _isSell ) public returns (uint256 out) { if (uniV3Pools[_token] == address(0)) { return 0; } if (_isSell) { out = IQuoter(QUOTER).quoteExactInputSingle( _token, WETH9, fees[_token], _amount, 0 ); } else { out = IQuoter(QUOTER).quoteExactInputSingle( WETH9, _token, fees[_token], _amount, 0 ); } } function getCurveOut( address _token, uint256 _amount, bool _isSell ) public returns (uint256 out) { address poolAddr = curvePools[_token]; if (poolAddr == address(0)) { return 0; } (uint256 e, uint256 t, ) = getCurveCoinIndex(_token); IStableSwap pool = IStableSwap(poolAddr); uint8 poolType = curvePoolType[poolAddr]; if (_isSell) { if (poolType == 0) { out = pool.get_dy( int128(int256(t)), int128(int256(e)), _amount ); } else { out = pool.get_dy(t, e, _amount); } } else { if (poolType == 0) { out = pool.get_dy( int128(int256(e)), int128(int256(t)), _amount ); } else { out = pool.get_dy(e, t, _amount); } } } function getCurveCoinIndex( address _token ) public view returns (uint256 i, uint256 j, bool wrapped) { // i for Ether, j for another token IStableSwap pool = IStableSwap(curvePools[_token]); if (pool.coins(0) == WETH9 || pool.coins(1) == WETH9) { wrapped = true; } if (pool.coins(0) == CURVE_ETH || pool.coins(0) == WETH9) { i = 0; j = 1; } else { i = 1; j = 0; } } function calMinimumReceivedAmount( uint256 _amount, uint256 _slippage ) internal view returns (uint256 amount) { amount = (_amount * _slippage) / ONE_HUNDRED_PERCENT; } function setSlippage( address _token, uint256 _slippage ) external onlyGovernance { emit SetSlippage(_token, slippage[_token], _slippage); slippage[_token] = _slippage; } function setUniRouter( address _token, address _uniPool, uint256 _slippage, uint24 _fee ) external onlyGovernance { require(_token != address(0), "ZERO ADDRESS"); uniV3Pools[_token] = _uniPool; slippage[_token] = _slippage; fees[_token] = _fee; } function setCurveRouter( address _token, address _curvePool, uint8 _curvePoolType, uint256 _slippage ) external onlyGovernance { require(_token != address(0), "ZERO ADDRESS"); curvePools[_token] = _curvePool; curvePoolType[_curvePool] = _curvePoolType; slippage[_token] = _slippage; } function setNewGovernance(address _governance) external onlyGovernance { emit TransferGovernance(governance, _governance); governance = _governance; } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {TransferHelper} from "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol"; import {Strategy} from "./Strategy.sol"; import {AssetsVault} from "../AssetsVault.sol"; contract StrategyController { using EnumerableSet for EnumerableSet.AddressSet; uint256 internal constant ONE_HUNDRED_PERCENT = 1e6; address public stoneVault; address payable public immutable assetsVault; EnumerableSet.AddressSet private strategies; mapping(address => uint256) public ratios; struct StrategyDiff { address strategy; bool isDeposit; uint256 amount; } modifier onlyVault() { require(stoneVault == msg.sender, "not vault"); _; } constructor( address payable _assetsVault, address[] memory _strategies, uint256[] memory _ratios ) { require(_assetsVault != address(0), "ZERO ADDRESS"); uint256 length = _strategies.length; for (uint256 i; i < length; i++) { require(_strategies[i] != address(0), "ZERO ADDRESS"); } stoneVault = msg.sender; assetsVault = _assetsVault; _initStrategies(_strategies, _ratios); } function forceWithdraw( uint256 _amount ) external onlyVault returns (uint256 actualAmount) { uint256 balanceBeforeRepay = address(this).balance; if (balanceBeforeRepay >= _amount) { _repayToVault(); actualAmount = _amount; } else { actualAmount = _forceWithdraw(_amount - balanceBeforeRepay) + balanceBeforeRepay; } } function setStrategies( address[] memory _strategies, uint256[] memory _ratios ) external onlyVault { _setStrategies(_strategies, _ratios); } function addStrategy(address _strategy) external onlyVault { require(!strategies.contains(_strategy), "already exist"); strategies.add(_strategy); } function rebaseStrategies( uint256 _in, uint256 _out ) external payable onlyVault { _rebase(_in, _out); } function destroyStrategy(address _strategy) external onlyVault { _destoryStrategy(_strategy); } function _rebase(uint256 _in, uint256 _out) internal { require(_in == 0 || _out == 0, "only deposit or withdraw"); if (_in != 0) { AssetsVault(assetsVault).withdraw(address(this), _in); } uint256 total = getAllStrategyValidValue(); if (total < _out) { total = 0; } else { total = total + _in - _out; } uint256 length = strategies.length(); StrategyDiff[] memory diffs = new StrategyDiff[](length); uint256 head; uint256 tail = length - 1; for (uint i; i < length; i++) { address strategy = strategies.at(i); if (ratios[strategy] == 0) { _clearStrategy(strategy, true); continue; } uint256 newPosition = (total * ratios[strategy]) / ONE_HUNDRED_PERCENT; uint256 position = getStrategyValidValue(strategy); if (newPosition < position) { diffs[head] = StrategyDiff( strategy, false, position - newPosition ); head++; } else if (newPosition > position) { diffs[tail] = StrategyDiff( strategy, true, newPosition - position ); if (tail != 0) { tail--; } } } length = diffs.length; for (uint256 i; i < length; i++) { StrategyDiff memory diff = diffs[i]; if (diff.amount == 0) { continue; } if (diff.isDeposit) { if (address(this).balance < diff.amount) { diff.amount = address(this).balance; } _depositToStrategy(diff.strategy, diff.amount); } else { _withdrawFromStrategy(diff.strategy, diff.amount); } } _repayToVault(); } function _repayToVault() internal { if (address(this).balance != 0) { TransferHelper.safeTransferETH(assetsVault, address(this).balance); } } function _depositToStrategy(address _strategy, uint256 _amount) internal { Strategy(_strategy).deposit{value: _amount}(); } function _withdrawFromStrategy( address _strategy, uint256 _amount ) internal { Strategy(_strategy).withdraw(_amount); } function _forceWithdraw( uint256 _amount ) internal returns (uint256 actualAmount) { uint256 length = strategies.length(); uint256 allRatios; for (uint i; i < length; i++) { address strategy = strategies.at(i); allRatios += ratios[strategy]; } for (uint i; i < length; i++) { address strategy = strategies.at(i); uint256 withAmount = (_amount * ratios[strategy]) / allRatios; if (withAmount != 0) { actualAmount = Strategy(strategy).instantWithdraw(withAmount) + actualAmount; } } _repayToVault(); } function getStrategyValue( address _strategy ) public returns (uint256 _value) { return Strategy(_strategy).getAllValue(); } function getStrategyValidValue( address _strategy ) public returns (uint256 _value) { return Strategy(_strategy).getInvestedValue(); } function getStrategyPendingValue( address _strategy ) public returns (uint256 _value) { return Strategy(_strategy).getPendingValue(); } function getAllStrategiesValue() public returns (uint256 _value) { uint256 length = strategies.length(); for (uint i; i < length; i++) { _value = _value + getStrategyValue(strategies.at(i)); } } function getAllStrategyValidValue() public returns (uint256 _value) { uint256 length = strategies.length(); for (uint i; i < length; i++) { _value = _value + getStrategyValidValue(strategies.at(i)); } } function getAllStrategyPendingValue() public returns (uint256 _value) { uint256 length = strategies.length(); for (uint i; i < length; i++) { _value = _value + getStrategyPendingValue(strategies.at(i)); } } function getStrategies() public view returns (address[] memory addrs, uint256[] memory portions) { uint256 length = strategies.length(); addrs = new address[](length); portions = new uint256[](length); for (uint256 i; i < length; i++) { address addr = strategies.at(i); addrs[i] = addr; portions[i] = ratios[addr]; } } function _initStrategies( address[] memory _strategies, uint256[] memory _ratios ) internal { require(_strategies.length == _ratios.length, "invalid length"); uint256 totalRatio; uint256 length = _strategies.length; for (uint i; i < length; i++) { strategies.add(_strategies[i]); ratios[_strategies[i]] = _ratios[i]; totalRatio = totalRatio + _ratios[i]; } require(totalRatio <= ONE_HUNDRED_PERCENT, "exceed 100%"); } function _setStrategies( address[] memory _strategies, uint256[] memory _ratios ) internal { uint256 length = _strategies.length; require(length == _ratios.length, "invalid length"); uint256 oldLength = strategies.length(); for (uint i; i < oldLength; i++) { ratios[strategies.at(i)] = 0; } uint256 totalRatio; for (uint i; i < length; i++) { require( Strategy(_strategies[i]).controller() == address(this), "controller mismatch" ); strategies.add(_strategies[i]); ratios[_strategies[i]] = _ratios[i]; totalRatio = totalRatio + _ratios[i]; } require(totalRatio <= ONE_HUNDRED_PERCENT, "exceed 100%"); } function clearStrategy(address _strategy) public onlyVault { _clearStrategy(_strategy, false); } function _clearStrategy(address _strategy, bool _isRebase) internal { Strategy(_strategy).clear(); if (!_isRebase) { _repayToVault(); } } function _destoryStrategy(address _strategy) internal { require(_couldDestroyStrategy(_strategy), "still active"); strategies.remove(_strategy); _repayToVault(); } function _couldDestroyStrategy( address _strategy ) internal returns (bool status) { return ratios[_strategy] == 0 && Strategy(_strategy).getAllValue() < 1e4; } function setNewVault(address _vault) external onlyVault { stoneVault = _vault; } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {StrategyController} from "../strategies/StrategyController.sol"; abstract contract Strategy { address payable public immutable controller; address public governance; uint256 public latestUpdateTime; uint256 public bufferTime = 12; string public name; modifier onlyGovernance() { require(governance == msg.sender, "not governace"); _; } modifier notAtSameBlock() { require( latestUpdateTime + bufferTime <= block.timestamp, "at the same block" ); _; } event TransferGovernance(address oldOwner, address newOwner); constructor(address payable _controller, string memory _name) { require(_controller != address(0), "ZERO ADDRESS"); governance = msg.sender; controller = _controller; name = _name; } modifier onlyController() { require(controller == msg.sender, "not controller"); _; } function deposit() public payable virtual onlyController notAtSameBlock {} function withdraw( uint256 _amount ) public virtual onlyController notAtSameBlock returns (uint256 actualAmount) {} function instantWithdraw( uint256 _amount ) public virtual onlyController notAtSameBlock returns (uint256 actualAmount) {} function clear() public virtual onlyController returns (uint256 amount) {} function execPendingRequest( uint256 _amount ) public virtual returns (uint256 amount) {} function getAllValue() public virtual returns (uint256 value) {} function getPendingValue() public virtual returns (uint256 value) {} function getInvestedValue() public virtual returns (uint256 value) {} function checkPendingStatus() public virtual returns (uint256 pending, uint256 executable) {} function setGovernance(address governance_) external onlyGovernance { emit TransferGovernance(governance, governance_); governance = governance_; } function setBufferTime(uint256 _time) external onlyGovernance { bufferTime = _time; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; import {StrategyController} from "../strategies/StrategyController.sol"; abstract contract EigenStrategy is Ownable2Step { address payable public immutable controller; uint256 public latestUpdateTime; uint256 public bufferTime = 12; string public name; modifier notAtSameBlock() { require( latestUpdateTime + bufferTime <= block.timestamp, "at the same block" ); _; } event TransferGovernance(address oldOwner, address newOwner); constructor(address payable _controller, string memory _name) { require(_controller != address(0), "ZERO ADDRESS"); controller = _controller; name = _name; } modifier onlyController() { require(controller == msg.sender, "not controller"); _; } function deposit() public payable virtual onlyController notAtSameBlock {} function withdraw( uint256 _amount ) public virtual onlyController notAtSameBlock returns (uint256 actualAmount) {} function instantWithdraw( uint256 _amount ) public virtual onlyController notAtSameBlock returns (uint256 actualAmount) {} function clear() public virtual onlyController returns (uint256 amount) {} function execPendingRequest( uint256 _amount ) public virtual returns (uint256 amount) {} function getAllValue() public virtual returns (uint256 value) {} function getPendingValue() public virtual returns (uint256 value) {} function getInvestedValue() public virtual returns (uint256 value) {} function checkPendingStatus() public virtual returns (uint256 pending, uint256 executable) {} function setBufferTime(uint256 _time) external onlyOwner { bufferTime = _time; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.21; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /// @title Interface for WETH9 interface IWETH9 is IERC20 { /// @notice Deposit ether to get wrapped ether function deposit() external payable; /// @notice Withdraw wrapped ether to get ether function withdraw(uint256) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; interface IStrategyManager { function depositIntoStrategy( address strategy, address token, uint256 amount ) external returns (uint256 shares); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; interface IStableSwap { function lp_token() external view returns (address); function coins(uint256 i) external view returns (address); function get_dy( int128 i, int128 j, uint256 dx ) external view returns (uint256); function get_dy( uint256 i, uint256 j, uint256 dx ) external view returns (uint256); function fee() external view returns (uint256); function admin_fee() external view returns (uint256); function calc_withdraw_one_coin( uint256 _token_amount, int128 i ) external view returns (uint256); function calc_token_amount( uint256[2] memory, bool ) external view returns (uint256); function remove_liquidity_imbalance( uint256[2] memory _amounts, uint256 _max_burn_amount ) external returns (uint256); function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 _min_amount ) external returns (uint256); function add_liquidity( uint256[2] memory amounts, uint256 min_mint_amount ) external payable returns (uint256); function exchange( int128 i, int128 j, uint256 dx, uint256 min_dy ) external payable returns (uint256); function exchange( uint256 i, uint256 j, uint256 dx, uint256 min_dy ) external payable returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; interface ILidoWithdrawalQueue { struct WithdrawalRequestStatus { /// @notice stETH token amount that was locked on withdrawal queue for this request uint256 amountOfStETH; /// @notice amount of stETH shares locked on withdrawal queue for this request uint256 amountOfShares; /// @notice address that can claim or transfer this request address owner; /// @notice timestamp of when the request was created, in seconds uint256 timestamp; /// @notice true, if request is finalized bool isFinalized; /// @notice true, if request is claimed. Request is claimable if (isFinalized && !isClaimed) bool isClaimed; } function MAX_STETH_WITHDRAWAL_AMOUNT() external view returns (uint256); function MIN_STETH_WITHDRAWAL_AMOUNT() external view returns (uint256); function getWithdrawalRequests( address _owner ) external view returns (uint256[] memory requestsIds); function getWithdrawalStatus( uint256[] calldata _requestIds ) external view returns (WithdrawalRequestStatus[] memory statuses); function requestWithdrawals( uint256[] calldata _amounts, address _owner ) external returns (uint256[] memory requestIds); function claimWithdrawals( uint256[] calldata _requestIds, uint256[] calldata _hints ) external; function claimWithdrawalsTo( uint256[] calldata _requestIds, uint256[] calldata _hints, address _recipient ) external; function claimWithdrawal(uint256 _requestId) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; interface ILido { function submit(address _referral) external payable returns (uint256); function balanceOf(address account) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; interface IEigenStrategy { function userUnderlyingView(address user) external view returns (uint256); function shares(address user) external view returns (uint256); function sharesToUnderlyingView( uint256 amountShares ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IDelegationManager { struct SignatureWithExpiry { bytes signature; uint256 expiry; } struct QueuedWithdrawalParams { address[] strategies; uint256[] shares; address withdrawer; } struct Withdrawal { address staker; address delegatedTo; address withdrawer; uint256 nonce; uint32 startBlock; address[] strategies; uint256[] shares; } event WithdrawalQueued(bytes32 withdrawalRoot, Withdrawal withdrawal); function delegateTo( address operator, SignatureWithExpiry memory approverSignatureAndExpiry, bytes32 approverSalt ) external; function undelegate( address staker ) external returns (bytes32[] memory withdrawalRoots); function queueWithdrawals( QueuedWithdrawalParams[] calldata queuedWithdrawalParams ) external returns (bytes32[] memory); function completeQueuedWithdrawal( Withdrawal calldata withdrawal, IERC20[] calldata tokens, uint256 middlewareTimesIndex, bool receiveAsTokens ) external; function isOperator(address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {TransferHelper} from "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol"; contract AssetsVault { address public stoneVault; address public strategyController; modifier onlyPermit() { require( stoneVault == msg.sender || strategyController == msg.sender, "not permit" ); _; } constructor(address _stoneVault, address _strategyController) { require( _stoneVault != address(0) && _strategyController != address(0), "ZERO ADDRESS" ); stoneVault = _stoneVault; strategyController = _strategyController; } function deposit() external payable { require(msg.value != 0, "too small"); } function withdraw(address _to, uint256 _amount) external onlyPermit { TransferHelper.safeTransferETH(_to, _amount); } function setNewVault(address _vault) external onlyPermit { stoneVault = _vault; } function getBalance() external view returns (uint256 amount) { amount = address(this).balance; } receive() external payable {} }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; library TransferHelper { /// @notice Transfers tokens from the targeted address to the given destination /// @notice Errors with 'STF' if transfer fails /// @param token The contract address of the token to be transferred /// @param from The originating address from which the tokens will be transferred /// @param to The destination address of the transfer /// @param value The amount to be transferred function safeTransferFrom( address token, address from, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); } /// @notice Transfers tokens from msg.sender to a recipient /// @dev Errors with ST if transfer fails /// @param token The contract address of the token which will be transferred /// @param to The recipient of the transfer /// @param value The value of the transfer function safeTransfer( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); } /// @notice Approves the stipulated contract to spend the given allowance in the given token /// @dev Errors with 'SA' if transfer fails /// @param token The contract address of the token to be approved /// @param to The target of the approval /// @param value The amount of the given token the target will be allowed to spend function safeApprove( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); } /// @notice Transfers ETH to the recipient address /// @dev Fails with `STE` /// @param to The destination of the transfer /// @param value The value to be transferred function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'STE'); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; /// @title Quoter Interface /// @notice Supports quoting the calculated amounts from exact input or exact output swaps /// @dev These functions are not marked view because they rely on calling non-view functions and reverting /// to compute the result. They are also not gas efficient and should not be called on-chain. interface IQuoter { /// @notice Returns the amount out received for a given exact input swap without executing the swap /// @param path The path of the swap, i.e. each token pair and the pool fee /// @param amountIn The amount of the first token to swap /// @return amountOut The amount of the last token that would be received function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut); /// @notice Returns the amount out received for a given exact input but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountIn The desired input amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// @return amountOut The amount of `tokenOut` that would be received function quoteExactInputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountOut); /// @notice Returns the amount in required for a given exact output swap without executing the swap /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order /// @param amountOut The amount of the last token to receive /// @return amountIn The amount of first token required to be paid function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn); /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountOut The desired output amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// @return amountIn The amount required as the input for the swap in order to receive `amountOut` function quoteExactOutputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountOut, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountIn); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; import "./Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 10 }, "evmVersion": "shanghai", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address payable","name":"_controller","type":"address"},{"internalType":"address","name":"_tokenAddr","type":"address"},{"internalType":"address","name":"_lidoWithdrawalQueue","type":"address"},{"internalType":"address","name":"_strategyManager","type":"address"},{"internalType":"address","name":"_delegationManager","type":"address"},{"internalType":"address","name":"_eigenStrategy","type":"address"},{"internalType":"address payable","name":"_swap","type":"address"},{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"DelegateTo","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositIntoStrategy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"targetAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"Invoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOperator","type":"address"},{"indexed":false,"internalType":"address","name":"newOperator","type":"address"}],"name":"SetEigenOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAddr","type":"address"},{"indexed":false,"internalType":"address","name":"newAddr","type":"address"}],"name":"SetReferral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"buyOnDex","type":"bool"},{"indexed":false,"internalType":"bool","name":"sellOnDex","type":"bool"}],"name":"SetRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"length","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SetWithdrawQueueParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"sent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"received","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"TransferGovernance","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"address","name":"delegatedTo","type":"address"},{"internalType":"address","name":"withdrawer","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"startBlock","type":"uint32"},{"internalType":"address[]","name":"strategies","type":"address[]"},{"internalType":"uint256[]","name":"shares","type":"uint256[]"}],"indexed":false,"internalType":"struct IDelegationManager.Withdrawal","name":"withdrawal","type":"tuple"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"WithdrawalCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"withdrawalRoot","type":"bytes32"}],"name":"WithdrawalQueued","type":"event"},{"inputs":[],"name":"LidoWithdrawalQueue","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SWAPPING","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bufferTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyOnDex","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"address","name":"delegatedTo","type":"address"},{"internalType":"address","name":"withdrawer","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"startBlock","type":"uint32"},{"internalType":"address[]","name":"strategies","type":"address[]"},{"internalType":"uint256[]","name":"shares","type":"uint256[]"}],"internalType":"struct IDelegationManager.Withdrawal","name":"withdrawal","type":"tuple"}],"name":"calculateWithdrawalRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"checkPendingAssets","outputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256","name":"totalClaimable","type":"uint256"},{"internalType":"uint256","name":"totalPending","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkPendingStatus","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"},{"internalType":"uint256","name":"executable","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAllPendingAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"claimPendingAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clear","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"address","name":"delegatedTo","type":"address"},{"internalType":"address","name":"withdrawer","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"startBlock","type":"uint32"},{"internalType":"address[]","name":"strategies","type":"address[]"},{"internalType":"uint256[]","name":"shares","type":"uint256[]"}],"internalType":"struct IDelegationManager.Withdrawal","name":"_withdrawal","type":"tuple"},{"internalType":"contract IERC20[]","name":"_tokens","type":"address[]"},{"internalType":"uint256","name":"_middlewareTimesIndex","type":"uint256"},{"internalType":"bool","name":"_receiveAsTokens","type":"bool"}],"name":"completeQueuedWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"expiry","type":"uint256"}],"internalType":"struct IDelegationManager.SignatureWithExpiry","name":"_approverSignatureAndExpiry","type":"tuple"},{"internalType":"bytes32","name":"_approverSalt","type":"bytes32"}],"name":"delegateTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delegationManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositIntoStrategy","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eigenOperator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eigenStrategy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"execPendingRequest","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllValue","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getInvestedValue","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPendingValue","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRestakingValue","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnstakingValue","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalRoots","outputs":[{"internalType":"bytes32[]","name":"roots","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"instantWithdraw","outputs":[{"internalType":"uint256","name":"actualAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"invoke","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"latestUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address[]","name":"strategies","type":"address[]"},{"internalType":"uint256[]","name":"shares","type":"uint256[]"},{"internalType":"address","name":"withdrawer","type":"address"}],"internalType":"struct IDelegationManager.QueuedWithdrawalParams[]","name":"_queuedWithdrawalParams","type":"tuple[]"}],"name":"queueWithdrawals","outputs":[{"internalType":"bytes32[]","name":"withdrawalRoots","type":"bytes32[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"referral","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sellOnDex","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_time","type":"uint256"}],"name":"setBufferTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setEigenOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_referral","type":"address"}],"name":"setReferral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_buyOnDex","type":"bool"},{"internalType":"bool","name":"_sellOnDex","type":"bool"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategyManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"swapToEther","outputs":[{"internalType":"uint256","name":"etherAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"swapToToken","outputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"undelegate","outputs":[{"internalType":"bytes32[]","name":"withdrawalRoots","type":"bytes32[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"actualAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawals","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"withdrawingShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
610160604052600c60035534801562000016575f80fd5b5060405162004098380380620040988339810160408190526200003991620001f3565b878162000046336200015d565b6001600160a01b038216620000785760405162461bcd60e51b81526004016200006f9062000356565b60405180910390fd5b6001600160a01b038216608052600462000093828262000408565b5050506001600160a01b03871615801590620000b757506001600160a01b03861615155b8015620000cc57506001600160a01b03851615155b8015620000e157506001600160a01b03841615155b8015620000f657506001600160a01b03831615155b80156200010b57506001600160a01b03821615155b6200012a5760405162461bcd60e51b81526004016200006f9062000356565b506001600160a01b0395861660a0529385166101205291841660c052831660e052821661010052166101405250620004d0565b600180546001600160a01b031916905562000178816200017b565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811462000178575f80fd5b634e487b7160e01b5f52604160045260245ffd5b5f805f805f805f80610100898b0312156200020c575f80fd5b88516200021981620001ca565b809850506020808a01516200022e81620001ca565b60408b01519098506200024181620001ca565b60608b01519097506200025481620001ca565b60808b01519096506200026781620001ca565b60a08b01519095506200027a81620001ca565b60c08b01519094506200028d81620001ca565b60e08b01519093506001600160401b0380821115620002aa575f80fd5b818c0191508c601f830112620002be575f80fd5b815181811115620002d357620002d3620001df565b604051601f8201601f19908116603f01168101908382118183101715620002fe57620002fe620001df565b816040528281528f8684870101111562000316575f80fd5b5f93505b828410156200033957848401860151818501870152928501926200031a565b5f8684830101528096505050505050509295985092959890939650565b6020808252600c908201526b5a45524f204144445245535360a01b604082015260600190565b600181811c908216806200039157607f821691505b602082108103620003b057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000403575f81815260208120601f850160051c81016020861015620003de5750805b601f850160051c820191505b81811015620003ff57828155600101620003ea565b5050505b505050565b81516001600160401b03811115620004245762000424620001df565b6200043c816200043584546200037c565b84620003b6565b602080601f83116001811462000472575f84156200045a5750858301515b5f19600386901b1c1916600185901b178555620003ff565b5f85815260208120601f198616915b82811015620004a25788860151825594840194600190910190840162000481565b5085821015620004c057878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e051610100516101205161014051613a6c6200062c5f395f818161058d01528181610f090152818161206a01526120a601525f818161026c01528181610b4101528181611ae901528181611c9c01528181611d0a01526124b701525f818161071d015281816114a90152818161155a015281816117140152818161231101526123a701525f81816107a1015281816109980152818161103c01528181611243015281816117dc01526121b501525f81816103f501528181611440015261147c01525f818161049901528181610e7201528181610f3801528181610fb9015281816113350152818161141f015281816114cb0152818161157b0152818161185f01528181611b9e01528181612049015281816120d3015261215301525f818161080701528181610d7b01528181611157015281816111a90152818161225e015281816125c501526126e00152613a6c5ff3fe60806040526004361061022f575f3560e01c80621a55971461023a57806304e7b5161461025b57806306fdde031461029b5780630dd8dd02146102bc5780631441a5a9146102e85780631aac030c146103075780631c2ca2fd146103285780632b26160e1461034b5780632e1a7d4d1461037657806331ff6d9d1461039557806334dfd55c146103b457806339b70e38146103e45780634f19c35f1461041757806352efea6e14610436578063597b36da1461044a5780635cc07076146104695780635fbe4d1d1461048857806360d7faed146104bb5780636c23ab4c146104da5780636f81a6b0146104ee578063715018a61461050d57806375421af3146105215780637654f7ab1461054057806379ba5097146105545780637f2207be146105685780638abd97fb1461057c5780638c9bd7c6146105af5780638da5cb5b146105cf578063924f4f6e146105e357806392ab89bb1461060257806394087747146106165780639bb66b28146106355780639e5914da14610654578063a7ea3b1114610673578063ad6a712514610692578063ba7b6703146106b1578063be8478f9146106c6578063ce9c79fb146106e5578063d0e30db014610704578063db4df7611461070c578063dd07d2881461073f578063ddcc3ded14610754578063df52b28714610768578063e30c39781461077c578063ea4d3c9b14610790578063eea94dab146107c3578063f2fde38b146107d7578063f77c4791146107f6578063fd92bff214610829575f80fd5b3661023657005b5f80fd5b348015610245575f80fd5b505f5b6040519081526020015b60405180910390f35b348015610266575f80fd5b5061028e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516102529190612a8e565b3480156102a6575f80fd5b506102af610848565b6040516102529190612aef565b3480156102c7575f80fd5b506102db6102d6366004612b48565b6108d4565b6040516102529190612b86565b3480156102f3575f80fd5b5060055461028e906001600160a01b031681565b348015610312575f80fd5b50610326610321366004612bc9565b610b2d565b005b348015610333575f80fd5b5061033c610b3a565b60405161025293929190612c19565b348015610356575f80fd5b50610248610365366004612bc9565b60086020525f908152604090205481565b348015610381575f80fd5b50610248610390366004612bc9565b610d78565b3480156103a0575f80fd5b506102486103af366004612bc9565b610dff565b3480156103bf575f80fd5b506006546103d490600160a01b900460ff1681565b6040519015158152602001610252565b3480156103ef575f80fd5b5061028e7f000000000000000000000000000000000000000000000000000000000000000081565b348015610422575f80fd5b50610326610431366004612c61565b610ff7565b348015610441575f80fd5b50610248611154565b348015610455575f80fd5b50610248610464366004612ec0565b6111d6565b348015610474575f80fd5b50610248610483366004612bc9565b611205565b348015610493575f80fd5b5061028e7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104c6575f80fd5b506103266104d5366004612f06565b611224565b3480156104e5575f80fd5b50610248611318565b3480156104f9575f80fd5b50610248610508366004612bc9565b611411565b348015610518575f80fd5b506103266115aa565b34801561052c575f80fd5b50604080515f808252602082015201610252565b34801561054b575f80fd5b506102486115bd565b34801561055f575f80fd5b506103266115cb565b348015610573575f80fd5b506102db611649565b348015610587575f80fd5b5061028e7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105ba575f80fd5b506006546103d490600160a81b900460ff1681565b3480156105da575f80fd5b5061028e6116e5565b3480156105ee575f80fd5b506102486105fd366004612bc9565b505f90565b34801561060d575f80fd5b506102db6116f3565b348015610621575f80fd5b5060065461028e906001600160a01b031681565b348015610640575f80fd5b506102af61064f366004612ff9565b611853565b34801561065f575f80fd5b5061032661066e366004612c61565b611980565b34801561067e575f80fd5b5061032661068d366004613045565b611a17565b34801561069d575f80fd5b506103266106ac36600461307c565b611a92565b3480156106bc575f80fd5b5061024860035481565b3480156106d1575f80fd5b506102486106e0366004612bc9565b611b93565b3480156106f0575f80fd5b506103266106ff3660046130ad565b612193565b61032661225c565b348015610717575f80fd5b5061028e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561074a575f80fd5b5061024860025481565b34801561075f575f80fd5b506102486122f8565b348015610773575f80fd5b50610248612385565b348015610787575f80fd5b5061028e612463565b34801561079b575f80fd5b5061028e7f000000000000000000000000000000000000000000000000000000000000000081565b3480156107ce575f80fd5b50610326612472565b3480156107e2575f80fd5b506103266107f1366004612c61565b61255c565b348015610801575f80fd5b5061028e7f000000000000000000000000000000000000000000000000000000000000000081565b348015610834575f80fd5b50610248610843366004612bc9565b6125c2565b6004805461085590613139565b80601f016020809104026020016040519081016040528092919081815260200182805461088190613139565b80156108cc5780601f106108a3576101008083540402835291602001916108cc565b820191905f5260205f20905b8154815290600101906020018083116108af57829003601f168201915b505050505081565b60606108de61260b565b600182148015610921575082825f8181106108fb576108fb613171565b905060200281019061090d9190613185565b61091b9060208101906131a3565b90506001145b801561095c575082825f81811061093a5761093a613171565b905060200281019061094c9190613185565b61095690806131a3565b90506001145b6109815760405162461bcd60e51b8152600401610978906131e8565b60405180910390fd5b6040516306ec6e8160e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630dd8dd02906109cf90869086906004016132c0565b5f604051808303815f875af11580156109ea573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610a119190810190613389565b805190915060018114610a5c5760405162461bcd60e51b81526020600482015260136024820152720d2dcecc2d8d2c840e4dedee840d8cadccee8d606b1b6044820152606401610978565b5f825f81518110610a6f57610a6f613171565b60200260200101519050610a8d81600961266a90919063ffffffff16565b5084845f818110610aa057610aa0613171565b9050602002810190610ab29190613185565b610ac09060208101906131a3565b5f818110610ad057610ad0613171565b9050602002013560085f8381526020019081526020015f20819055507f492bda9daea20b83c49f715949876cc4f0d2b23fc2603a6e086ba8452a80a63a81604051610b1d91815260200190565b60405180910390a1505092915050565b610b3561260b565b600355565b60605f805f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b0316637d031b65306040518263ffffffff1660e01b8152600401610b8f9190612a8e565b5f60405180830381865afa158015610ba9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610bd09190810190613389565b905080515f03610bf6575050604080515f80825260208201909252949093508392509050565b80516001600160401b03811115610c0f57610c0f612c7c565b604051908082528060200260200182016040528015610c38578160200160208202803683370190505b5094505f826001600160a01b031663b8c4b85a836040518263ffffffff1660e01b8152600401610c689190613414565b5f60405180830381865afa158015610c82573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ca99190810190613426565b80519091505f90815b81811015610d6a575f848281518110610ccd57610ccd613171565b602002602001015190508060a0015115610ce75750610d58565b806080015115610d4757858281518110610d0357610d03613171565b60200260200101518a8580610d179061352a565b965081518110610d2957610d29613171565b60209081029190910101528051610d40908a613542565b9850610d56565b8051610d539089613542565b97505b505b80610d628161352a565b915050610cb2565b508188525050505050909192565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610dc15760405162461bcd60e51b815260040161097890613555565b42600354600254610dd29190613542565b1115610df05760405162461bcd60e51b81526004016109789061357d565b610df98261267c565b92915050565b5f610e0861260b565b815f03610e275760405162461bcd60e51b8152600401610978906135a8565b47821115610e475760405162461bcd60e51b8152600401610978906135c6565b600654600160a01b900460ff16610ef25760055460405163a1903eab60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263a1903eab928692610eaa921690600401612a8e565b60206040518083038185885af1158015610ec6573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610eeb91906135ee565b9050610fa8565b60405163919722bb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063919722bb908490610f64907f00000000000000000000000000000000000000000000000000000000000000009083905f90600401613605565b60206040518083038185885af1158015610f80573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610fa591906135ee565b90505b5f80516020613a178339815191525f7f00000000000000000000000000000000000000000000000000000000000000008484604051610fea9493929190613628565b60405180910390a1919050565b610fff61260b565b6001600160a01b0381166110255760405162461bcd60e51b815260040161097890613651565b6040516336b87bd760e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636d70f7ae90611071908490600401612a8e565b602060405180830381865afa15801561108c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110b09190613674565b6110eb5760405162461bcd60e51b815260206004820152600c60248201526b3737ba1037b832b930ba37b960a11b6044820152606401610978565b6006546040517fd1141b3ae23758a51cb470527ddee6ed4146eccf6c201b1579fdd24b501b6b769161112a916001600160a01b0390911690849061368f565b60405180910390a1600680546001600160a01b0319166001600160a01b0392909216919091179055565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316331461119d5760405162461bcd60e51b815260040161097890613555565b4780156111d2576111ce7f00000000000000000000000000000000000000000000000000000000000000008261270e565b8091505b5090565b5f816040516020016111e891906136e0565b604051602081830303815290604052805190602001209050919050565b60078181548110611214575f80fd5b5f91825260209091200154905081565b61122c61260b565b6040516360d7faed60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906360d7faed906112809088908890889088908890600401613825565b5f604051808303815f87803b158015611297575f80fd5b505af11580156112a9573d5f803e3d5ffd5b505050505f6112bb8661046490613896565b5f8181526008602052604081205590506112d66009826127ad565b507fb04a02414a4ef8abdbc7835d387014794dc0e3e268f7eaf43dee3481db211b3086826040516113089291906138a1565b60405180910390a1505050505050565b6040516370a0823160e01b81525f90479082906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319061136a903090600401612a8e565b602060405180830381865afa158015611385573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113a991906135ee565b90505f806113b5610b3a565b92509250505f6113c36122f8565b90505f6113ce612385565b9050808284866113de898b613542565b6113e89190613542565b6113f29190613542565b6113fc9190613542565b6114069190613542565b965050505050505090565b5f61141a61260b565b6114657f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000846127b8565b6040516373d0285560e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e7a050aa906114f5907f0000000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000009087906004016138c2565b6020604051808303815f875af1158015611511573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061153591906135ee565b90507f46a80100e8cfe18c4729e50ad8704a292622bb8b711d9b6e915a1911f34920647f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000084604051610fea939291906138c2565b6115b261260b565b6115bb5f6128bd565b565b5f6115c6611318565b905090565b33806115d5612463565b6001600160a01b03161461163d5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610978565b611646816128bd565b50565b60605f61165660096128d6565b9050806001600160401b0381111561167057611670612c7c565b604051908082528060200260200182016040528015611699578160200160208202803683370190505b5091505f5b818110156116e0576116b16009826128df565b8382815181106116c3576116c3613171565b6020908102919091010152806116d88161352a565b91505061169e565b505090565b5f546001600160a01b031690565b60606116fd61260b565b60405163673e156160e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ce7c2ac290611749903090600401612a8e565b602060405180830381865afa158015611764573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061178891906135ee565b156117c55760405162461bcd60e51b815260206004820152600d60248201526c6163746976652073686172657360981b6044820152606401610978565b6040516336a2fa1960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063da8be86490611811903090600401612a8e565b5f604051808303815f875af115801561182c573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526115c69190810190613389565b606061185d61260b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036118cb5760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081c195c9b5a5d60b21b6044820152606401610978565b5f836001600160a01b03165f846040516118e591906138e6565b5f6040518083038185875af1925050503d805f811461191f576040519150601f19603f3d011682016040523d82523d5f602084013e611924565b606091505b509250905080611936573d5f803e3d5ffd5b836001600160a01b03167f8e084f4a28a6752a4c84a569571c55c88b5e8a28400d520311a3b501fc5e4c355f856040516119719291906138f7565b60405180910390a25092915050565b61198861260b565b6001600160a01b0381166119ae5760405162461bcd60e51b815260040161097890613651565b6005546040517f3576c10a3107273bc6535da3c7aef2a8fa869e980ce766193ce37d026d90fb37916119ed916001600160a01b0390911690849061368f565b60405180910390a1600580546001600160a01b0319166001600160a01b0392909216919091179055565b611a1f61260b565b6006805461ffff60a01b1916600160a01b84151590810260ff60a81b191691909117600160a81b841515908102919091179092556040805191825260208201929092527f01fbe4f77ca298ed7b6f81db870f0e0c2c385d1b17975407dff6f108ab321e8091015b60405180910390a15050565b611a9a61260b565b80515f819003611abc5760405162461bcd60e51b8152600401610978906131e8565b5f5b81811015611b8e57828181518110611ad857611ad8613171565b60200260200101515f0315611b7c577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f8444436848381518110611b2857611b28613171565b60200260200101516040518263ffffffff1660e01b8152600401611b4e91815260200190565b5f604051808303815f87803b158015611b65575f80fd5b505af1158015611b77573d5f803e3d5ffd5b505050505b80611b868161352a565b915050611abe565b505050565b5f611b9c61260b565b7f00000000000000000000000000000000000000000000000000000000000000005f839003611bdd5760405162461bcd60e51b8152600401610978906135a8565b6040516370a0823160e01b81526001600160a01b038216906370a0823190611c09903090600401612a8e565b602060405180830381865afa158015611c24573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c4891906135ee565b831115611c675760405162461bcd60e51b8152600401610978906135c6565b600654600160a81b900460ff166120445760405163095ea7b360e01b81526001600160a01b0382169063095ea7b390611cc6907f000000000000000000000000000000000000000000000000000000000000000090879060040161390f565b6020604051808303815f875af1158015611ce2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d069190613674565b505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663db2296cd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d68573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d8c91906135ee565b90505f826001600160a01b0316630d25a9576040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dcb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611def91906135ee565b90506060828711611e3e57604080516001808252818301909252906020808301908036833701905050905086815f81518110611e2d57611e2d613171565b602002602001018181525050611f73565b5f611e49848961393c565b611e54906001613542565b90505f611e61858a61394f565b9050838110611edc57816001600160401b03811115611e8257611e82612c7c565b604051908082528060200260200182016040528015611eab578160200160208202803683370190505b5092508083611ebb600185613962565b81518110611ecb57611ecb613171565b602002602001018181525050611f2b565b611ee7600183613962565b6001600160401b03811115611efe57611efe612c7c565b604051908082528060200260200182016040528015611f27578160200160208202803683370190505b5092505b5f5b611f38600184613962565b811015611f6f5785848281518110611f5257611f52613171565b602090810291909101015280611f678161352a565b915050611f2d565b5050505b604051636b34082160e11b81525f906001600160a01b0386169063d668104290611fa39085903090600401613975565b5f604051808303815f875af1158015611fbe573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611fe59190810190613389565b905080515f036120375760405162461bcd60e51b815260206004820152601d60248201527f4c69646f2072657175657374207769746864726177616c206572726f720000006044820152606401610978565b8796505050505050612143565b61208f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000856127b8565b60405163919722bb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063919722bb90612100907f0000000000000000000000000000000000000000000000000000000000000000908790600190600401613605565b6020604051808303815f875af115801561211c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214091906135ee565b91505b5f80516020613a178339815191527f00000000000000000000000000000000000000000000000000000000000000005f85856040516121859493929190613628565b60405180910390a150919050565b61219b61260b565b60065460405163eea9064b60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263eea9064b926121f29291909116908690869060040161399e565b5f604051808303815f87803b158015612209575f80fd5b505af115801561221b573d5f803e3d5ffd5b50506006546040517ffe4b2ef7c149e0cc043939d6adf86af0d16250c3fd818245a5896a9e8d71611d9350611a8692506001600160a01b0390911690612a8e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146122a45760405162461bcd60e51b815260040161097890613555565b426003546002546122b59190613542565b11156122d35760405162461bcd60e51b81526004016109789061357d565b345f036122f25760405162461bcd60e51b8152600401610978906139de565b42600255565b604051630aa794bf60e31b81525f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063553ca5f890612346903090600401612a8e565b602060405180830381865afa158015612361573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115c691906135ee565b5f8061239160096128d6565b90505f5b818110156116e0576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016637a8b263760085f6123da6009866128df565b81526020019081526020015f20546040518263ffffffff1660e01b815260040161240691815260200190565b602060405180830381865afa158015612421573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061244591906135ee565b61244f9084613542565b92508061245b8161352a565b915050612395565b6001546001600160a01b031690565b61247a61260b565b5f612483610b3a565b505080519091505f5b81811015611b8e578281815181106124a6576124a6613171565b60200260200101515f031561254a577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f84444368483815181106124f6576124f6613171565b60200260200101516040518263ffffffff1660e01b815260040161251c91815260200190565b5f604051808303815f87803b158015612533575f80fd5b505af1158015612545573d5f803e3d5ffd5b505050505b806125548161352a565b91505061248c565b61256461260b565b600180546001600160a01b0319166001600160a01b03831690811790915561258a6116e5565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610df05760405162461bcd60e51b815260040161097890613555565b336126146116e5565b6001600160a01b0316146115bb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610978565b5f61267583836128ea565b9392505050565b5f815f0361269c5760405162461bcd60e51b8152600401610978906139de565b478211156126d95760405162461bcd60e51b815260206004820152600a6024820152690dcdee840cadcdeeaced60b31b6044820152606401610978565b50806127057f00000000000000000000000000000000000000000000000000000000000000008261270e565b42600255919050565b604080515f808252602082019092526001600160a01b03841690839060405161273791906138e6565b5f6040518083038185875af1925050503d805f8114612771576040519150601f19603f3d011682016040523d82523d5f602084013e612776565b606091505b5050905080611b8e5760405162461bcd60e51b815260206004820152600360248201526253544560e81b6044820152606401610978565b5f6126758383612936565b5f80846001600160a01b031663095ea7b360e01b85856040516024016127df92919061390f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161281d91906138e6565b5f604051808303815f865af19150503d805f8114612856576040519150601f19603f3d011682016040523d82523d5f602084013e61285b565b606091505b50915091508180156128855750805115806128855750808060200190518101906128859190613674565b6128b65760405162461bcd60e51b8152602060048201526002602482015261534160f01b6044820152606401610978565b5050505050565b600180546001600160a01b031916905561164681612a19565b5f610df9825490565b5f6126758383612a68565b5f81815260018301602052604081205461292f57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610df9565b505f610df9565b5f8181526001830160205260408120548015612a10575f612958600183613962565b85549091505f9061296b90600190613962565b90508181146129ca575f865f01828154811061298957612989613171565b905f5260205f200154905080875f0184815481106129a9576129a9613171565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806129db576129db613a02565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610df9565b5f915050610df9565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f825f018281548110612a7d57612a7d613171565b905f5260205f200154905092915050565b6001600160a01b0391909116815260200190565b5f5b83811015612abc578181015183820152602001612aa4565b50505f910152565b5f8151808452612adb816020860160208601612aa2565b601f01601f19169290920160200192915050565b602081525f6126756020830184612ac4565b5f8083601f840112612b11575f80fd5b5081356001600160401b03811115612b27575f80fd5b6020830191508360208260051b8501011115612b41575f80fd5b9250929050565b5f8060208385031215612b59575f80fd5b82356001600160401b03811115612b6e575f80fd5b612b7a85828601612b01565b90969095509350505050565b602080825282518282018190525f9190848201906040850190845b81811015612bbd57835183529284019291840191600101612ba1565b50909695505050505050565b5f60208284031215612bd9575f80fd5b5035919050565b5f8151808452602080850194508084015f5b83811015612c0e57815187529582019590820190600101612bf2565b509495945050505050565b606081525f612c2b6060830186612be0565b60208301949094525060400152919050565b6001600160a01b0381168114611646575f80fd5b8035612c5c81612c3d565b919050565b5f60208284031215612c71575f80fd5b813561267581612c3d565b634e487b7160e01b5f52604160045260245ffd5b60405160e081016001600160401b0381118282101715612cb257612cb2612c7c565b60405290565b60405160c081016001600160401b0381118282101715612cb257612cb2612c7c565b604051601f8201601f191681016001600160401b0381118282101715612d0257612d02612c7c565b604052919050565b803563ffffffff81168114612c5c575f80fd5b5f6001600160401b03821115612d3557612d35612c7c565b5060051b60200190565b5f82601f830112612d4e575f80fd5b81356020612d63612d5e83612d1d565b612cda565b82815260059290921b84018101918181019086841115612d81575f80fd5b8286015b84811015612da5578035612d9881612c3d565b8352918301918301612d85565b509695505050505050565b5f82601f830112612dbf575f80fd5b81356020612dcf612d5e83612d1d565b82815260059290921b84018101918181019086841115612ded575f80fd5b8286015b84811015612da55780358352918301918301612df1565b5f60e08284031215612e18575f80fd5b612e20612c90565b9050612e2b82612c51565b8152612e3960208301612c51565b6020820152612e4a60408301612c51565b604082015260608201356060820152612e6560808301612d0a565b608082015260a08201356001600160401b0380821115612e83575f80fd5b612e8f85838601612d3f565b60a084015260c0840135915080821115612ea7575f80fd5b50612eb484828501612db0565b60c08301525092915050565b5f60208284031215612ed0575f80fd5b81356001600160401b03811115612ee5575f80fd5b612ef184828501612e08565b949350505050565b8015158114611646575f80fd5b5f805f805f60808688031215612f1a575f80fd5b85356001600160401b0380821115612f30575f80fd5b9087019060e0828a031215612f43575f80fd5b90955060208701359080821115612f58575f80fd5b50612f6588828901612b01565b909550935050604086013591506060860135612f8081612ef9565b809150509295509295909350565b5f82601f830112612f9d575f80fd5b81356001600160401b03811115612fb657612fb6612c7c565b612fc9601f8201601f1916602001612cda565b818152846020838601011115612fdd575f80fd5b816020850160208301375f918101602001919091529392505050565b5f806040838503121561300a575f80fd5b823561301581612c3d565b915060208301356001600160401b0381111561302f575f80fd5b61303b85828601612f8e565b9150509250929050565b5f8060408385031215613056575f80fd5b823561306181612ef9565b9150602083013561307181612ef9565b809150509250929050565b5f6020828403121561308c575f80fd5b81356001600160401b038111156130a1575f80fd5b612ef184828501612db0565b5f80604083850312156130be575f80fd5b82356001600160401b03808211156130d4575f80fd5b90840190604082870312156130e7575f80fd5b60405160408101818110838211171561310257613102612c7c565b604052823582811115613113575f80fd5b61311f88828601612f8e565b825250602092830135838201529694909101359450505050565b600181811c9082168061314d57607f821691505b60208210810361316b57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112613199575f80fd5b9190910192915050565b5f808335601e198436030181126131b8575f80fd5b8301803591506001600160401b038211156131d1575f80fd5b6020019150600581901b3603821315612b41575f80fd5b6020808252600e908201526d0d2dcecc2d8d2c840d8cadccee8d60931b604082015260600190565b5f808335601e19843603018112613225575f80fd5b83016020810192503590506001600160401b03811115613243575f80fd5b8060051b3603821315612b41575f80fd5b8183525f60208085019450825f5b85811015612c0e57813561327581612c3d565b6001600160a01b031687529582019590820190600101613262565b8183525f6001600160fb1b038311156132a7575f80fd5b8260051b80836020870137939093016020019392505050565b60208082528181018390525f906040808401600586901b850182018785805b8981101561337a57888403603f190185528235368c9003605e19018112613304578283fd5b8b0160606133128280613210565b8288526133228389018284613254565b9250505061333289830183613210565b8783038b890152613344838284613290565b9250505087820135915061335782612c3d565b6001600160a01b03919091169487019490945293860193918601916001016132df565b50919998505050505050505050565b5f602080838503121561339a575f80fd5b82516001600160401b038111156133af575f80fd5b8301601f810185136133bf575f80fd5b80516133cd612d5e82612d1d565b81815260059190911b820183019083810190878311156133eb575f80fd5b928401925b82841015613409578351825292840192908401906133f0565b979650505050505050565b602081525f6126756020830184612be0565b5f6020808385031215613437575f80fd5b82516001600160401b0381111561344c575f80fd5b8301601f8101851361345c575f80fd5b805161346a612d5e82612d1d565b81815260c09182028301840191848201919088841115613488575f80fd5b938501935b8385101561350a5780858a0312156134a4575f8081fd5b6134ac612cb8565b8551815286860151878201526040808701516134c781612c3d565b90820152606086810151908201526080808701516134e481612ef9565b9082015260a0868101516134f781612ef9565b908201528352938401939185019161348d565b50979650505050505050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161353b5761353b613516565b5060010190565b80820180821115610df957610df9613516565b6020808252600e908201526d3737ba1031b7b73a3937b63632b960911b604082015260600190565b6020808252601190820152706174207468652073616d6520626c6f636b60781b604082015260600190565b6020808252600490820152637a65726f60e01b604082015260600190565b6020808252600e908201526d6578636565642062616c616e636560901b604082015260600190565b5f602082840312156135fe575f80fd5b5051919050565b6001600160a01b0393909316835260208301919091521515604082015260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6020808252600990820152682d22a9279020a2222960b91b604082015260600190565b5f60208284031215613684575f80fd5b815161267581612ef9565b6001600160a01b0392831681529116602082015260400190565b5f8151808452602080850194508084015f5b83811015612c0e5781516001600160a01b0316875295820195908201906001016136bb565b602081525f60018060a01b038084511660208401528060208501511660408401528060408501511660608401525060608301516080830152608083015161372f60a084018263ffffffff169052565b5060a083015160e060c084015261374a6101008401826136a9565b905060c0840151601f198483030160e08501526137678282612be0565b95945050505050565b5f813561377c81612c3d565b6001600160a01b03908116845260208301359061379882612c3d565b90811660208501526040830135906137af82612c3d565b1660408401526060828101359084015263ffffffff6137d060808401612d0a565b1660808401526137e360a0830183613210565b60e060a08601526137f860e086018284613254565b91505061380860c0840184613210565b85830360c087015261381b838284613290565b9695505050505050565b608081525f6138376080830188613770565b828103602084810191909152868252879181015f5b8881101561387a57833561385f81612c3d565b6001600160a01b03168252928201929082019060010161384c565b5060408501969096525050509015156060909101529392505050565b5f610df93683612e08565b604081525f6138b36040830185613770565b90508260208301529392505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f8251613199818460208701612aa2565b828152604060208201525f612ef16040830184612ac4565b6001600160a01b03929092168252602082015260400190565b634e487b7160e01b5f52601260045260245ffd5b5f8261394a5761394a613928565b500490565b5f8261395d5761395d613928565b500690565b81810381811115610df957610df9613516565b604081525f6139876040830185612be0565b905060018060a01b03831660208301529392505050565b60018060a01b0384168152606060208201525f8351604060608401526139c760a0840182612ac4565b602095909501516080840152505060400152919050565b6020808252600a90820152697a65726f2076616c756560b01b604082015260600190565b634e487b7160e01b5f52603160045260245ffdfefa2dda1cc1b86e41239702756b13effbc1a092b5c57e3ad320fbe4f3b13fe235a264697066735822122063f84cdcac2d82a38b1893805dbca01e0cb6c41d2071b68d1b6b5794d5cc08d264736f6c63430008150033000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b2000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000889edc2edab5f40e902b864ad4d7ade8e412f9b1000000000000000000000000858646372cc42e1a627fce94aa7a7033e7cf075a00000000000000000000000039053d51b77dc0d36036fc1fcc8cb819df8ef37a00000000000000000000000093c4b944d05dfe6df7645a86cd2206016c51564d00000000000000000000000015469528c11e8ace863f3f9e5a8329216e33dd7d000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000144c53542052657374616b696e6728737445544829000000000000000000000000
Deployed Bytecode
0x60806040526004361061022f575f3560e01c80621a55971461023a57806304e7b5161461025b57806306fdde031461029b5780630dd8dd02146102bc5780631441a5a9146102e85780631aac030c146103075780631c2ca2fd146103285780632b26160e1461034b5780632e1a7d4d1461037657806331ff6d9d1461039557806334dfd55c146103b457806339b70e38146103e45780634f19c35f1461041757806352efea6e14610436578063597b36da1461044a5780635cc07076146104695780635fbe4d1d1461048857806360d7faed146104bb5780636c23ab4c146104da5780636f81a6b0146104ee578063715018a61461050d57806375421af3146105215780637654f7ab1461054057806379ba5097146105545780637f2207be146105685780638abd97fb1461057c5780638c9bd7c6146105af5780638da5cb5b146105cf578063924f4f6e146105e357806392ab89bb1461060257806394087747146106165780639bb66b28146106355780639e5914da14610654578063a7ea3b1114610673578063ad6a712514610692578063ba7b6703146106b1578063be8478f9146106c6578063ce9c79fb146106e5578063d0e30db014610704578063db4df7611461070c578063dd07d2881461073f578063ddcc3ded14610754578063df52b28714610768578063e30c39781461077c578063ea4d3c9b14610790578063eea94dab146107c3578063f2fde38b146107d7578063f77c4791146107f6578063fd92bff214610829575f80fd5b3661023657005b5f80fd5b348015610245575f80fd5b505f5b6040519081526020015b60405180910390f35b348015610266575f80fd5b5061028e7f000000000000000000000000889edc2edab5f40e902b864ad4d7ade8e412f9b181565b6040516102529190612a8e565b3480156102a6575f80fd5b506102af610848565b6040516102529190612aef565b3480156102c7575f80fd5b506102db6102d6366004612b48565b6108d4565b6040516102529190612b86565b3480156102f3575f80fd5b5060055461028e906001600160a01b031681565b348015610312575f80fd5b50610326610321366004612bc9565b610b2d565b005b348015610333575f80fd5b5061033c610b3a565b60405161025293929190612c19565b348015610356575f80fd5b50610248610365366004612bc9565b60086020525f908152604090205481565b348015610381575f80fd5b50610248610390366004612bc9565b610d78565b3480156103a0575f80fd5b506102486103af366004612bc9565b610dff565b3480156103bf575f80fd5b506006546103d490600160a01b900460ff1681565b6040519015158152602001610252565b3480156103ef575f80fd5b5061028e7f000000000000000000000000858646372cc42e1a627fce94aa7a7033e7cf075a81565b348015610422575f80fd5b50610326610431366004612c61565b610ff7565b348015610441575f80fd5b50610248611154565b348015610455575f80fd5b50610248610464366004612ec0565b6111d6565b348015610474575f80fd5b50610248610483366004612bc9565b611205565b348015610493575f80fd5b5061028e7f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe8481565b3480156104c6575f80fd5b506103266104d5366004612f06565b611224565b3480156104e5575f80fd5b50610248611318565b3480156104f9575f80fd5b50610248610508366004612bc9565b611411565b348015610518575f80fd5b506103266115aa565b34801561052c575f80fd5b50604080515f808252602082015201610252565b34801561054b575f80fd5b506102486115bd565b34801561055f575f80fd5b506103266115cb565b348015610573575f80fd5b506102db611649565b348015610587575f80fd5b5061028e7f00000000000000000000000015469528c11e8ace863f3f9e5a8329216e33dd7d81565b3480156105ba575f80fd5b506006546103d490600160a81b900460ff1681565b3480156105da575f80fd5b5061028e6116e5565b3480156105ee575f80fd5b506102486105fd366004612bc9565b505f90565b34801561060d575f80fd5b506102db6116f3565b348015610621575f80fd5b5060065461028e906001600160a01b031681565b348015610640575f80fd5b506102af61064f366004612ff9565b611853565b34801561065f575f80fd5b5061032661066e366004612c61565b611980565b34801561067e575f80fd5b5061032661068d366004613045565b611a17565b34801561069d575f80fd5b506103266106ac36600461307c565b611a92565b3480156106bc575f80fd5b5061024860035481565b3480156106d1575f80fd5b506102486106e0366004612bc9565b611b93565b3480156106f0575f80fd5b506103266106ff3660046130ad565b612193565b61032661225c565b348015610717575f80fd5b5061028e7f00000000000000000000000093c4b944d05dfe6df7645a86cd2206016c51564d81565b34801561074a575f80fd5b5061024860025481565b34801561075f575f80fd5b506102486122f8565b348015610773575f80fd5b50610248612385565b348015610787575f80fd5b5061028e612463565b34801561079b575f80fd5b5061028e7f00000000000000000000000039053d51b77dc0d36036fc1fcc8cb819df8ef37a81565b3480156107ce575f80fd5b50610326612472565b3480156107e2575f80fd5b506103266107f1366004612c61565b61255c565b348015610801575f80fd5b5061028e7f000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b281565b348015610834575f80fd5b50610248610843366004612bc9565b6125c2565b6004805461085590613139565b80601f016020809104026020016040519081016040528092919081815260200182805461088190613139565b80156108cc5780601f106108a3576101008083540402835291602001916108cc565b820191905f5260205f20905b8154815290600101906020018083116108af57829003601f168201915b505050505081565b60606108de61260b565b600182148015610921575082825f8181106108fb576108fb613171565b905060200281019061090d9190613185565b61091b9060208101906131a3565b90506001145b801561095c575082825f81811061093a5761093a613171565b905060200281019061094c9190613185565b61095690806131a3565b90506001145b6109815760405162461bcd60e51b8152600401610978906131e8565b60405180910390fd5b6040516306ec6e8160e11b81526001600160a01b037f00000000000000000000000039053d51b77dc0d36036fc1fcc8cb819df8ef37a1690630dd8dd02906109cf90869086906004016132c0565b5f604051808303815f875af11580156109ea573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610a119190810190613389565b805190915060018114610a5c5760405162461bcd60e51b81526020600482015260136024820152720d2dcecc2d8d2c840e4dedee840d8cadccee8d606b1b6044820152606401610978565b5f825f81518110610a6f57610a6f613171565b60200260200101519050610a8d81600961266a90919063ffffffff16565b5084845f818110610aa057610aa0613171565b9050602002810190610ab29190613185565b610ac09060208101906131a3565b5f818110610ad057610ad0613171565b9050602002013560085f8381526020019081526020015f20819055507f492bda9daea20b83c49f715949876cc4f0d2b23fc2603a6e086ba8452a80a63a81604051610b1d91815260200190565b60405180910390a1505092915050565b610b3561260b565b600355565b60605f805f7f000000000000000000000000889edc2edab5f40e902b864ad4d7ade8e412f9b190505f816001600160a01b0316637d031b65306040518263ffffffff1660e01b8152600401610b8f9190612a8e565b5f60405180830381865afa158015610ba9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610bd09190810190613389565b905080515f03610bf6575050604080515f80825260208201909252949093508392509050565b80516001600160401b03811115610c0f57610c0f612c7c565b604051908082528060200260200182016040528015610c38578160200160208202803683370190505b5094505f826001600160a01b031663b8c4b85a836040518263ffffffff1660e01b8152600401610c689190613414565b5f60405180830381865afa158015610c82573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ca99190810190613426565b80519091505f90815b81811015610d6a575f848281518110610ccd57610ccd613171565b602002602001015190508060a0015115610ce75750610d58565b806080015115610d4757858281518110610d0357610d03613171565b60200260200101518a8580610d179061352a565b965081518110610d2957610d29613171565b60209081029190910101528051610d40908a613542565b9850610d56565b8051610d539089613542565b97505b505b80610d628161352a565b915050610cb2565b508188525050505050909192565b5f7f000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b26001600160a01b03163314610dc15760405162461bcd60e51b815260040161097890613555565b42600354600254610dd29190613542565b1115610df05760405162461bcd60e51b81526004016109789061357d565b610df98261267c565b92915050565b5f610e0861260b565b815f03610e275760405162461bcd60e51b8152600401610978906135a8565b47821115610e475760405162461bcd60e51b8152600401610978906135c6565b600654600160a01b900460ff16610ef25760055460405163a1903eab60e01b81526001600160a01b037f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe8481169263a1903eab928692610eaa921690600401612a8e565b60206040518083038185885af1158015610ec6573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610eeb91906135ee565b9050610fa8565b60405163919722bb60e01b81526001600160a01b037f00000000000000000000000015469528c11e8ace863f3f9e5a8329216e33dd7d169063919722bb908490610f64907f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe849083905f90600401613605565b60206040518083038185885af1158015610f80573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610fa591906135ee565b90505b5f80516020613a178339815191525f7f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe848484604051610fea9493929190613628565b60405180910390a1919050565b610fff61260b565b6001600160a01b0381166110255760405162461bcd60e51b815260040161097890613651565b6040516336b87bd760e11b81526001600160a01b037f00000000000000000000000039053d51b77dc0d36036fc1fcc8cb819df8ef37a1690636d70f7ae90611071908490600401612a8e565b602060405180830381865afa15801561108c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110b09190613674565b6110eb5760405162461bcd60e51b815260206004820152600c60248201526b3737ba1037b832b930ba37b960a11b6044820152606401610978565b6006546040517fd1141b3ae23758a51cb470527ddee6ed4146eccf6c201b1579fdd24b501b6b769161112a916001600160a01b0390911690849061368f565b60405180910390a1600680546001600160a01b0319166001600160a01b0392909216919091179055565b5f7f000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b26001600160a01b0316331461119d5760405162461bcd60e51b815260040161097890613555565b4780156111d2576111ce7f000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b28261270e565b8091505b5090565b5f816040516020016111e891906136e0565b604051602081830303815290604052805190602001209050919050565b60078181548110611214575f80fd5b5f91825260209091200154905081565b61122c61260b565b6040516360d7faed60e01b81526001600160a01b037f00000000000000000000000039053d51b77dc0d36036fc1fcc8cb819df8ef37a16906360d7faed906112809088908890889088908890600401613825565b5f604051808303815f87803b158015611297575f80fd5b505af11580156112a9573d5f803e3d5ffd5b505050505f6112bb8661046490613896565b5f8181526008602052604081205590506112d66009826127ad565b507fb04a02414a4ef8abdbc7835d387014794dc0e3e268f7eaf43dee3481db211b3086826040516113089291906138a1565b60405180910390a1505050505050565b6040516370a0823160e01b81525f90479082906001600160a01b037f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe8416906370a082319061136a903090600401612a8e565b602060405180830381865afa158015611385573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113a991906135ee565b90505f806113b5610b3a565b92509250505f6113c36122f8565b90505f6113ce612385565b9050808284866113de898b613542565b6113e89190613542565b6113f29190613542565b6113fc9190613542565b6114069190613542565b965050505050505090565b5f61141a61260b565b6114657f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe847f000000000000000000000000858646372cc42e1a627fce94aa7a7033e7cf075a846127b8565b6040516373d0285560e11b81526001600160a01b037f000000000000000000000000858646372cc42e1a627fce94aa7a7033e7cf075a169063e7a050aa906114f5907f00000000000000000000000093c4b944d05dfe6df7645a86cd2206016c51564d907f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe849087906004016138c2565b6020604051808303815f875af1158015611511573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061153591906135ee565b90507f46a80100e8cfe18c4729e50ad8704a292622bb8b711d9b6e915a1911f34920647f00000000000000000000000093c4b944d05dfe6df7645a86cd2206016c51564d7f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe8484604051610fea939291906138c2565b6115b261260b565b6115bb5f6128bd565b565b5f6115c6611318565b905090565b33806115d5612463565b6001600160a01b03161461163d5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610978565b611646816128bd565b50565b60605f61165660096128d6565b9050806001600160401b0381111561167057611670612c7c565b604051908082528060200260200182016040528015611699578160200160208202803683370190505b5091505f5b818110156116e0576116b16009826128df565b8382815181106116c3576116c3613171565b6020908102919091010152806116d88161352a565b91505061169e565b505090565b5f546001600160a01b031690565b60606116fd61260b565b60405163673e156160e11b81526001600160a01b037f00000000000000000000000093c4b944d05dfe6df7645a86cd2206016c51564d169063ce7c2ac290611749903090600401612a8e565b602060405180830381865afa158015611764573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061178891906135ee565b156117c55760405162461bcd60e51b815260206004820152600d60248201526c6163746976652073686172657360981b6044820152606401610978565b6040516336a2fa1960e21b81526001600160a01b037f00000000000000000000000039053d51b77dc0d36036fc1fcc8cb819df8ef37a169063da8be86490611811903090600401612a8e565b5f604051808303815f875af115801561182c573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526115c69190810190613389565b606061185d61260b565b7f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b0316836001600160a01b0316036118cb5760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081c195c9b5a5d60b21b6044820152606401610978565b5f836001600160a01b03165f846040516118e591906138e6565b5f6040518083038185875af1925050503d805f811461191f576040519150601f19603f3d011682016040523d82523d5f602084013e611924565b606091505b509250905080611936573d5f803e3d5ffd5b836001600160a01b03167f8e084f4a28a6752a4c84a569571c55c88b5e8a28400d520311a3b501fc5e4c355f856040516119719291906138f7565b60405180910390a25092915050565b61198861260b565b6001600160a01b0381166119ae5760405162461bcd60e51b815260040161097890613651565b6005546040517f3576c10a3107273bc6535da3c7aef2a8fa869e980ce766193ce37d026d90fb37916119ed916001600160a01b0390911690849061368f565b60405180910390a1600580546001600160a01b0319166001600160a01b0392909216919091179055565b611a1f61260b565b6006805461ffff60a01b1916600160a01b84151590810260ff60a81b191691909117600160a81b841515908102919091179092556040805191825260208201929092527f01fbe4f77ca298ed7b6f81db870f0e0c2c385d1b17975407dff6f108ab321e8091015b60405180910390a15050565b611a9a61260b565b80515f819003611abc5760405162461bcd60e51b8152600401610978906131e8565b5f5b81811015611b8e57828181518110611ad857611ad8613171565b60200260200101515f0315611b7c577f000000000000000000000000889edc2edab5f40e902b864ad4d7ade8e412f9b16001600160a01b031663f8444436848381518110611b2857611b28613171565b60200260200101516040518263ffffffff1660e01b8152600401611b4e91815260200190565b5f604051808303815f87803b158015611b65575f80fd5b505af1158015611b77573d5f803e3d5ffd5b505050505b80611b868161352a565b915050611abe565b505050565b5f611b9c61260b565b7f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe845f839003611bdd5760405162461bcd60e51b8152600401610978906135a8565b6040516370a0823160e01b81526001600160a01b038216906370a0823190611c09903090600401612a8e565b602060405180830381865afa158015611c24573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c4891906135ee565b831115611c675760405162461bcd60e51b8152600401610978906135c6565b600654600160a81b900460ff166120445760405163095ea7b360e01b81526001600160a01b0382169063095ea7b390611cc6907f000000000000000000000000889edc2edab5f40e902b864ad4d7ade8e412f9b190879060040161390f565b6020604051808303815f875af1158015611ce2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d069190613674565b505f7f000000000000000000000000889edc2edab5f40e902b864ad4d7ade8e412f9b190505f816001600160a01b031663db2296cd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d68573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d8c91906135ee565b90505f826001600160a01b0316630d25a9576040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dcb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611def91906135ee565b90506060828711611e3e57604080516001808252818301909252906020808301908036833701905050905086815f81518110611e2d57611e2d613171565b602002602001018181525050611f73565b5f611e49848961393c565b611e54906001613542565b90505f611e61858a61394f565b9050838110611edc57816001600160401b03811115611e8257611e82612c7c565b604051908082528060200260200182016040528015611eab578160200160208202803683370190505b5092508083611ebb600185613962565b81518110611ecb57611ecb613171565b602002602001018181525050611f2b565b611ee7600183613962565b6001600160401b03811115611efe57611efe612c7c565b604051908082528060200260200182016040528015611f27578160200160208202803683370190505b5092505b5f5b611f38600184613962565b811015611f6f5785848281518110611f5257611f52613171565b602090810291909101015280611f678161352a565b915050611f2d565b5050505b604051636b34082160e11b81525f906001600160a01b0386169063d668104290611fa39085903090600401613975565b5f604051808303815f875af1158015611fbe573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611fe59190810190613389565b905080515f036120375760405162461bcd60e51b815260206004820152601d60248201527f4c69646f2072657175657374207769746864726177616c206572726f720000006044820152606401610978565b8796505050505050612143565b61208f7f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe847f00000000000000000000000015469528c11e8ace863f3f9e5a8329216e33dd7d856127b8565b60405163919722bb60e01b81526001600160a01b037f00000000000000000000000015469528c11e8ace863f3f9e5a8329216e33dd7d169063919722bb90612100907f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84908790600190600401613605565b6020604051808303815f875af115801561211c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214091906135ee565b91505b5f80516020613a178339815191527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe845f85856040516121859493929190613628565b60405180910390a150919050565b61219b61260b565b60065460405163eea9064b60e01b81526001600160a01b037f00000000000000000000000039053d51b77dc0d36036fc1fcc8cb819df8ef37a81169263eea9064b926121f29291909116908690869060040161399e565b5f604051808303815f87803b158015612209575f80fd5b505af115801561221b573d5f803e3d5ffd5b50506006546040517ffe4b2ef7c149e0cc043939d6adf86af0d16250c3fd818245a5896a9e8d71611d9350611a8692506001600160a01b0390911690612a8e565b7f000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b26001600160a01b031633146122a45760405162461bcd60e51b815260040161097890613555565b426003546002546122b59190613542565b11156122d35760405162461bcd60e51b81526004016109789061357d565b345f036122f25760405162461bcd60e51b8152600401610978906139de565b42600255565b604051630aa794bf60e31b81525f906001600160a01b037f00000000000000000000000093c4b944d05dfe6df7645a86cd2206016c51564d169063553ca5f890612346903090600401612a8e565b602060405180830381865afa158015612361573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115c691906135ee565b5f8061239160096128d6565b90505f5b818110156116e0576001600160a01b037f00000000000000000000000093c4b944d05dfe6df7645a86cd2206016c51564d16637a8b263760085f6123da6009866128df565b81526020019081526020015f20546040518263ffffffff1660e01b815260040161240691815260200190565b602060405180830381865afa158015612421573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061244591906135ee565b61244f9084613542565b92508061245b8161352a565b915050612395565b6001546001600160a01b031690565b61247a61260b565b5f612483610b3a565b505080519091505f5b81811015611b8e578281815181106124a6576124a6613171565b60200260200101515f031561254a577f000000000000000000000000889edc2edab5f40e902b864ad4d7ade8e412f9b16001600160a01b031663f84444368483815181106124f6576124f6613171565b60200260200101516040518263ffffffff1660e01b815260040161251c91815260200190565b5f604051808303815f87803b158015612533575f80fd5b505af1158015612545573d5f803e3d5ffd5b505050505b806125548161352a565b91505061248c565b61256461260b565b600180546001600160a01b0319166001600160a01b03831690811790915561258a6116e5565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f7f000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b26001600160a01b03163314610df05760405162461bcd60e51b815260040161097890613555565b336126146116e5565b6001600160a01b0316146115bb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610978565b5f61267583836128ea565b9392505050565b5f815f0361269c5760405162461bcd60e51b8152600401610978906139de565b478211156126d95760405162461bcd60e51b815260206004820152600a6024820152690dcdee840cadcdeeaced60b31b6044820152606401610978565b50806127057f000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b28261270e565b42600255919050565b604080515f808252602082019092526001600160a01b03841690839060405161273791906138e6565b5f6040518083038185875af1925050503d805f8114612771576040519150601f19603f3d011682016040523d82523d5f602084013e612776565b606091505b5050905080611b8e5760405162461bcd60e51b815260206004820152600360248201526253544560e81b6044820152606401610978565b5f6126758383612936565b5f80846001600160a01b031663095ea7b360e01b85856040516024016127df92919061390f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161281d91906138e6565b5f604051808303815f865af19150503d805f8114612856576040519150601f19603f3d011682016040523d82523d5f602084013e61285b565b606091505b50915091508180156128855750805115806128855750808060200190518101906128859190613674565b6128b65760405162461bcd60e51b8152602060048201526002602482015261534160f01b6044820152606401610978565b5050505050565b600180546001600160a01b031916905561164681612a19565b5f610df9825490565b5f6126758383612a68565b5f81815260018301602052604081205461292f57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610df9565b505f610df9565b5f8181526001830160205260408120548015612a10575f612958600183613962565b85549091505f9061296b90600190613962565b90508181146129ca575f865f01828154811061298957612989613171565b905f5260205f200154905080875f0184815481106129a9576129a9613171565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806129db576129db613a02565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610df9565b5f915050610df9565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f825f018281548110612a7d57612a7d613171565b905f5260205f200154905092915050565b6001600160a01b0391909116815260200190565b5f5b83811015612abc578181015183820152602001612aa4565b50505f910152565b5f8151808452612adb816020860160208601612aa2565b601f01601f19169290920160200192915050565b602081525f6126756020830184612ac4565b5f8083601f840112612b11575f80fd5b5081356001600160401b03811115612b27575f80fd5b6020830191508360208260051b8501011115612b41575f80fd5b9250929050565b5f8060208385031215612b59575f80fd5b82356001600160401b03811115612b6e575f80fd5b612b7a85828601612b01565b90969095509350505050565b602080825282518282018190525f9190848201906040850190845b81811015612bbd57835183529284019291840191600101612ba1565b50909695505050505050565b5f60208284031215612bd9575f80fd5b5035919050565b5f8151808452602080850194508084015f5b83811015612c0e57815187529582019590820190600101612bf2565b509495945050505050565b606081525f612c2b6060830186612be0565b60208301949094525060400152919050565b6001600160a01b0381168114611646575f80fd5b8035612c5c81612c3d565b919050565b5f60208284031215612c71575f80fd5b813561267581612c3d565b634e487b7160e01b5f52604160045260245ffd5b60405160e081016001600160401b0381118282101715612cb257612cb2612c7c565b60405290565b60405160c081016001600160401b0381118282101715612cb257612cb2612c7c565b604051601f8201601f191681016001600160401b0381118282101715612d0257612d02612c7c565b604052919050565b803563ffffffff81168114612c5c575f80fd5b5f6001600160401b03821115612d3557612d35612c7c565b5060051b60200190565b5f82601f830112612d4e575f80fd5b81356020612d63612d5e83612d1d565b612cda565b82815260059290921b84018101918181019086841115612d81575f80fd5b8286015b84811015612da5578035612d9881612c3d565b8352918301918301612d85565b509695505050505050565b5f82601f830112612dbf575f80fd5b81356020612dcf612d5e83612d1d565b82815260059290921b84018101918181019086841115612ded575f80fd5b8286015b84811015612da55780358352918301918301612df1565b5f60e08284031215612e18575f80fd5b612e20612c90565b9050612e2b82612c51565b8152612e3960208301612c51565b6020820152612e4a60408301612c51565b604082015260608201356060820152612e6560808301612d0a565b608082015260a08201356001600160401b0380821115612e83575f80fd5b612e8f85838601612d3f565b60a084015260c0840135915080821115612ea7575f80fd5b50612eb484828501612db0565b60c08301525092915050565b5f60208284031215612ed0575f80fd5b81356001600160401b03811115612ee5575f80fd5b612ef184828501612e08565b949350505050565b8015158114611646575f80fd5b5f805f805f60808688031215612f1a575f80fd5b85356001600160401b0380821115612f30575f80fd5b9087019060e0828a031215612f43575f80fd5b90955060208701359080821115612f58575f80fd5b50612f6588828901612b01565b909550935050604086013591506060860135612f8081612ef9565b809150509295509295909350565b5f82601f830112612f9d575f80fd5b81356001600160401b03811115612fb657612fb6612c7c565b612fc9601f8201601f1916602001612cda565b818152846020838601011115612fdd575f80fd5b816020850160208301375f918101602001919091529392505050565b5f806040838503121561300a575f80fd5b823561301581612c3d565b915060208301356001600160401b0381111561302f575f80fd5b61303b85828601612f8e565b9150509250929050565b5f8060408385031215613056575f80fd5b823561306181612ef9565b9150602083013561307181612ef9565b809150509250929050565b5f6020828403121561308c575f80fd5b81356001600160401b038111156130a1575f80fd5b612ef184828501612db0565b5f80604083850312156130be575f80fd5b82356001600160401b03808211156130d4575f80fd5b90840190604082870312156130e7575f80fd5b60405160408101818110838211171561310257613102612c7c565b604052823582811115613113575f80fd5b61311f88828601612f8e565b825250602092830135838201529694909101359450505050565b600181811c9082168061314d57607f821691505b60208210810361316b57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112613199575f80fd5b9190910192915050565b5f808335601e198436030181126131b8575f80fd5b8301803591506001600160401b038211156131d1575f80fd5b6020019150600581901b3603821315612b41575f80fd5b6020808252600e908201526d0d2dcecc2d8d2c840d8cadccee8d60931b604082015260600190565b5f808335601e19843603018112613225575f80fd5b83016020810192503590506001600160401b03811115613243575f80fd5b8060051b3603821315612b41575f80fd5b8183525f60208085019450825f5b85811015612c0e57813561327581612c3d565b6001600160a01b031687529582019590820190600101613262565b8183525f6001600160fb1b038311156132a7575f80fd5b8260051b80836020870137939093016020019392505050565b60208082528181018390525f906040808401600586901b850182018785805b8981101561337a57888403603f190185528235368c9003605e19018112613304578283fd5b8b0160606133128280613210565b8288526133228389018284613254565b9250505061333289830183613210565b8783038b890152613344838284613290565b9250505087820135915061335782612c3d565b6001600160a01b03919091169487019490945293860193918601916001016132df565b50919998505050505050505050565b5f602080838503121561339a575f80fd5b82516001600160401b038111156133af575f80fd5b8301601f810185136133bf575f80fd5b80516133cd612d5e82612d1d565b81815260059190911b820183019083810190878311156133eb575f80fd5b928401925b82841015613409578351825292840192908401906133f0565b979650505050505050565b602081525f6126756020830184612be0565b5f6020808385031215613437575f80fd5b82516001600160401b0381111561344c575f80fd5b8301601f8101851361345c575f80fd5b805161346a612d5e82612d1d565b81815260c09182028301840191848201919088841115613488575f80fd5b938501935b8385101561350a5780858a0312156134a4575f8081fd5b6134ac612cb8565b8551815286860151878201526040808701516134c781612c3d565b90820152606086810151908201526080808701516134e481612ef9565b9082015260a0868101516134f781612ef9565b908201528352938401939185019161348d565b50979650505050505050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161353b5761353b613516565b5060010190565b80820180821115610df957610df9613516565b6020808252600e908201526d3737ba1031b7b73a3937b63632b960911b604082015260600190565b6020808252601190820152706174207468652073616d6520626c6f636b60781b604082015260600190565b6020808252600490820152637a65726f60e01b604082015260600190565b6020808252600e908201526d6578636565642062616c616e636560901b604082015260600190565b5f602082840312156135fe575f80fd5b5051919050565b6001600160a01b0393909316835260208301919091521515604082015260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6020808252600990820152682d22a9279020a2222960b91b604082015260600190565b5f60208284031215613684575f80fd5b815161267581612ef9565b6001600160a01b0392831681529116602082015260400190565b5f8151808452602080850194508084015f5b83811015612c0e5781516001600160a01b0316875295820195908201906001016136bb565b602081525f60018060a01b038084511660208401528060208501511660408401528060408501511660608401525060608301516080830152608083015161372f60a084018263ffffffff169052565b5060a083015160e060c084015261374a6101008401826136a9565b905060c0840151601f198483030160e08501526137678282612be0565b95945050505050565b5f813561377c81612c3d565b6001600160a01b03908116845260208301359061379882612c3d565b90811660208501526040830135906137af82612c3d565b1660408401526060828101359084015263ffffffff6137d060808401612d0a565b1660808401526137e360a0830183613210565b60e060a08601526137f860e086018284613254565b91505061380860c0840184613210565b85830360c087015261381b838284613290565b9695505050505050565b608081525f6138376080830188613770565b828103602084810191909152868252879181015f5b8881101561387a57833561385f81612c3d565b6001600160a01b03168252928201929082019060010161384c565b5060408501969096525050509015156060909101529392505050565b5f610df93683612e08565b604081525f6138b36040830185613770565b90508260208301529392505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f8251613199818460208701612aa2565b828152604060208201525f612ef16040830184612ac4565b6001600160a01b03929092168252602082015260400190565b634e487b7160e01b5f52601260045260245ffd5b5f8261394a5761394a613928565b500490565b5f8261395d5761395d613928565b500690565b81810381811115610df957610df9613516565b604081525f6139876040830185612be0565b905060018060a01b03831660208301529392505050565b60018060a01b0384168152606060208201525f8351604060608401526139c760a0840182612ac4565b602095909501516080840152505060400152919050565b6020808252600a90820152697a65726f2076616c756560b01b604082015260600190565b634e487b7160e01b5f52603160045260245ffdfefa2dda1cc1b86e41239702756b13effbc1a092b5c57e3ad320fbe4f3b13fe235a264697066735822122063f84cdcac2d82a38b1893805dbca01e0cb6c41d2071b68d1b6b5794d5cc08d264736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b2000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000889edc2edab5f40e902b864ad4d7ade8e412f9b1000000000000000000000000858646372cc42e1a627fce94aa7a7033e7cf075a00000000000000000000000039053d51b77dc0d36036fc1fcc8cb819df8ef37a00000000000000000000000093c4b944d05dfe6df7645a86cd2206016c51564d00000000000000000000000015469528c11e8ace863f3f9e5a8329216e33dd7d000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000144c53542052657374616b696e6728737445544829000000000000000000000000
-----Decoded View---------------
Arg [0] : _controller (address): 0x396aBF9fF46E21694F4eF01ca77C6d7893A017B2
Arg [1] : _tokenAddr (address): 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84
Arg [2] : _lidoWithdrawalQueue (address): 0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1
Arg [3] : _strategyManager (address): 0x858646372CC42E1A627fcE94aa7A7033e7CF075A
Arg [4] : _delegationManager (address): 0x39053D51B77DC0d36036Fc1fCc8Cb819df8Ef37A
Arg [5] : _eigenStrategy (address): 0x93c4b944D05dfe6df7645A86cd2206016c51564D
Arg [6] : _swap (address): 0x15469528C11E8Ace863F3F9e5a8329216e33dD7d
Arg [7] : _name (string): LST Restaking(stETH)
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 000000000000000000000000396abf9ff46e21694f4ef01ca77c6d7893a017b2
Arg [1] : 000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84
Arg [2] : 000000000000000000000000889edc2edab5f40e902b864ad4d7ade8e412f9b1
Arg [3] : 000000000000000000000000858646372cc42e1a627fce94aa7a7033e7cf075a
Arg [4] : 00000000000000000000000039053d51b77dc0d36036fc1fcc8cb819df8ef37a
Arg [5] : 00000000000000000000000093c4b944d05dfe6df7645a86cd2206016c51564d
Arg [6] : 00000000000000000000000015469528c11e8ace863f3f9e5a8329216e33dd7d
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [9] : 4c53542052657374616b696e6728737445544829000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.