Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
RiverV1
Compiler Version
v0.8.10+commit.fc410830
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "./interfaces/IAllowlist.1.sol"; import "./interfaces/IOperatorRegistry.1.sol"; import "./interfaces/IRiver.1.sol"; import "./interfaces/IWithdraw.1.sol"; import "./interfaces/IELFeeRecipient.1.sol"; import "./interfaces/ICoverageFund.1.sol"; import "./components/ConsensusLayerDepositManager.1.sol"; import "./components/UserDepositManager.1.sol"; import "./components/SharesManager.1.sol"; import "./components/OracleManager.1.sol"; import "./Initializable.sol"; import "./Administrable.sol"; import "./libraries/LibAllowlistMasks.sol"; import "./state/river/AllowlistAddress.sol"; import "./state/river/RedeemManagerAddress.sol"; import "./state/river/OperatorsRegistryAddress.sol"; import "./state/river/CollectorAddress.sol"; import "./state/river/ELFeeRecipientAddress.sol"; import "./state/river/CoverageFundAddress.sol"; import "./state/river/BalanceToRedeem.sol"; import "./state/river/GlobalFee.sol"; import "./state/river/MetadataURI.sol"; import "./state/river/LastConsensusLayerReport.sol"; /// @title River (v1) /// @author Kiln /// @notice This contract merges all the manager contracts and implements all the virtual methods stitching all components together contract RiverV1 is ConsensusLayerDepositManagerV1, UserDepositManagerV1, SharesManagerV1, OracleManagerV1, Initializable, Administrable, IRiverV1 { /// @inheritdoc IRiverV1 function initRiverV1( address _depositContractAddress, address _elFeeRecipientAddress, bytes32 _withdrawalCredentials, address _oracleAddress, address _systemAdministratorAddress, address _allowlistAddress, address _operatorRegistryAddress, address _collectorAddress, uint256 _globalFee ) external init(0) { _setAdmin(_systemAdministratorAddress); CollectorAddress.set(_collectorAddress); emit SetCollector(_collectorAddress); GlobalFee.set(_globalFee); emit SetGlobalFee(_globalFee); ELFeeRecipientAddress.set(_elFeeRecipientAddress); emit SetELFeeRecipient(_elFeeRecipientAddress); AllowlistAddress.set(_allowlistAddress); emit SetAllowlist(_allowlistAddress); OperatorsRegistryAddress.set(_operatorRegistryAddress); emit SetOperatorsRegistry(_operatorRegistryAddress); ConsensusLayerDepositManagerV1.initConsensusLayerDepositManagerV1( _depositContractAddress, _withdrawalCredentials ); OracleManagerV1.initOracleManagerV1(_oracleAddress); } /// @inheritdoc IRiverV1 function initRiverV1_1( address _redeemManager, uint64 _epochsPerFrame, uint64 _slotsPerEpoch, uint64 _secondsPerSlot, uint64 _genesisTime, uint64 _epochsToAssumedFinality, uint256 _annualAprUpperBound, uint256 _relativeLowerBound, uint128 _minDailyNetCommittableAmount_, uint128 _maxDailyRelativeCommittableAmount_ ) external init(1) { RedeemManagerAddress.set(_redeemManager); emit SetRedeemManager(_redeemManager); _setDailyCommittableLimits( DailyCommittableLimits.DailyCommittableLimitsStruct({ minDailyNetCommittableAmount: _minDailyNetCommittableAmount_, maxDailyRelativeCommittableAmount: _maxDailyRelativeCommittableAmount_ }) ); initOracleManagerV1_1( _epochsPerFrame, _slotsPerEpoch, _secondsPerSlot, _genesisTime, _epochsToAssumedFinality, _annualAprUpperBound, _relativeLowerBound ); _approve(address(this), _redeemManager, type(uint256).max); } /// @inheritdoc IRiverV1 function getGlobalFee() external view returns (uint256) { return GlobalFee.get(); } /// @inheritdoc IRiverV1 function getAllowlist() external view returns (address) { return AllowlistAddress.get(); } /// @inheritdoc IRiverV1 function getCollector() external view returns (address) { return CollectorAddress.get(); } /// @inheritdoc IRiverV1 function getELFeeRecipient() external view returns (address) { return ELFeeRecipientAddress.get(); } /// @inheritdoc IRiverV1 function getCoverageFund() external view returns (address) { return CoverageFundAddress.get(); } /// @inheritdoc IRiverV1 function getRedeemManager() external view returns (address) { return RedeemManagerAddress.get(); } /// @inheritdoc IRiverV1 function getMetadataURI() external view returns (string memory) { return MetadataURI.get(); } /// @inheritdoc IRiverV1 function getDailyCommittableLimits() external view returns (DailyCommittableLimits.DailyCommittableLimitsStruct memory) { return DailyCommittableLimits.get(); } /// @inheritdoc IRiverV1 function setDailyCommittableLimits(DailyCommittableLimits.DailyCommittableLimitsStruct memory _dcl) external onlyAdmin { _setDailyCommittableLimits(_dcl); } /// @inheritdoc IRiverV1 function getBalanceToRedeem() external view returns (uint256) { return BalanceToRedeem.get(); } /// @inheritdoc IRiverV1 function resolveRedeemRequests(uint32[] calldata _redeemRequestIds) external view returns (int64[] memory withdrawalEventIds) { return IRedeemManagerV1(RedeemManagerAddress.get()).resolveRedeemRequests(_redeemRequestIds); } /// @inheritdoc IRiverV1 function requestRedeem(uint256 _lsETHAmount, address _recipient) external returns (uint32 _redeemRequestId) { IAllowlistV1(AllowlistAddress.get()).onlyAllowed(msg.sender, LibAllowlistMasks.REDEEM_MASK); _transfer(msg.sender, address(this), _lsETHAmount); return IRedeemManagerV1(RedeemManagerAddress.get()).requestRedeem(_lsETHAmount, _recipient); } /// @inheritdoc IRiverV1 function claimRedeemRequests(uint32[] calldata _redeemRequestIds, uint32[] calldata _withdrawalEventIds) external returns (uint8[] memory claimStatuses) { return IRedeemManagerV1(RedeemManagerAddress.get()).claimRedeemRequests( _redeemRequestIds, _withdrawalEventIds, true, type(uint16).max ); } /// @inheritdoc IRiverV1 function setGlobalFee(uint256 _newFee) external onlyAdmin { GlobalFee.set(_newFee); emit SetGlobalFee(_newFee); } /// @inheritdoc IRiverV1 function setAllowlist(address _newAllowlist) external onlyAdmin { AllowlistAddress.set(_newAllowlist); emit SetAllowlist(_newAllowlist); } /// @inheritdoc IRiverV1 function setCollector(address _newCollector) external onlyAdmin { CollectorAddress.set(_newCollector); emit SetCollector(_newCollector); } /// @inheritdoc IRiverV1 function setELFeeRecipient(address _newELFeeRecipient) external onlyAdmin { ELFeeRecipientAddress.set(_newELFeeRecipient); emit SetELFeeRecipient(_newELFeeRecipient); } /// @inheritdoc IRiverV1 function setCoverageFund(address _newCoverageFund) external onlyAdmin { CoverageFundAddress.set(_newCoverageFund); emit SetCoverageFund(_newCoverageFund); } /// @inheritdoc IRiverV1 function setMetadataURI(string memory _metadataURI) external onlyAdmin { LibSanitize._notEmptyString(_metadataURI); MetadataURI.set(_metadataURI); emit SetMetadataURI(_metadataURI); } /// @inheritdoc IRiverV1 function getOperatorsRegistry() external view returns (address) { return OperatorsRegistryAddress.get(); } /// @inheritdoc IRiverV1 function sendELFees() external payable { if (msg.sender != ELFeeRecipientAddress.get()) { revert LibErrors.Unauthorized(msg.sender); } } /// @inheritdoc IRiverV1 function sendCLFunds() external payable { if (msg.sender != WithdrawalCredentials.getAddress()) { revert LibErrors.Unauthorized(msg.sender); } } /// @inheritdoc IRiverV1 function sendCoverageFunds() external payable { if (msg.sender != CoverageFundAddress.get()) { revert LibErrors.Unauthorized(msg.sender); } } /// @inheritdoc IRiverV1 function sendRedeemManagerExceedingFunds() external payable { if (msg.sender != RedeemManagerAddress.get()) { revert LibErrors.Unauthorized(msg.sender); } } /// @notice Overridden handler to pass the system admin inside components /// @return The address of the admin function _getRiverAdmin() internal view override(OracleManagerV1, ConsensusLayerDepositManagerV1) returns (address) { return Administrable._getAdmin(); } /// @notice Overridden handler called whenever a token transfer is triggered /// @param _from Token sender /// @param _to Token receiver function _onTransfer(address _from, address _to) internal view override { IAllowlistV1 allowlist = IAllowlistV1(AllowlistAddress.get()); if (allowlist.isDenied(_from)) { revert Denied(_from); } if (allowlist.isDenied(_to)) { revert Denied(_to); } } /// @notice Overridden handler called whenever a user deposits ETH to the system. Mints the adequate amount of shares. /// @param _depositor User address that made the deposit /// @param _amount Amount of ETH deposited function _onDeposit(address _depositor, address _recipient, uint256 _amount) internal override { uint256 mintedShares = SharesManagerV1._mintShares(_depositor, _amount); IAllowlistV1 allowlist = IAllowlistV1(AllowlistAddress.get()); if (_depositor == _recipient) { allowlist.onlyAllowed(_depositor, LibAllowlistMasks.DEPOSIT_MASK); // this call reverts if unauthorized or denied } else { allowlist.onlyAllowed(_depositor, LibAllowlistMasks.DEPOSIT_MASK); // this call reverts if unauthorized or denied if (allowlist.isDenied(_recipient)) { revert Denied(_recipient); } _transfer(_depositor, _recipient, mintedShares); } } /// @notice Overridden handler called whenever a deposit to the consensus layer is made. Should retrieve _requestedAmount or lower keys /// @param _requestedAmount Amount of keys required. Contract is expected to send _requestedAmount or lower. /// @return publicKeys Array of fundable public keys /// @return signatures Array of signatures linked to the public keys function _getNextValidators(uint256 _requestedAmount) internal override returns (bytes[] memory publicKeys, bytes[] memory signatures) { return IOperatorsRegistryV1(OperatorsRegistryAddress.get()).pickNextValidatorsToDeposit(_requestedAmount); } /// @notice Overridden handler to pull funds from the execution layer fee recipient to River and return the delta in the balance /// @param _max The maximum amount to pull from the execution layer fee recipient /// @return The amount pulled from the execution layer fee recipient function _pullELFees(uint256 _max) internal override returns (uint256) { address elFeeRecipient = ELFeeRecipientAddress.get(); uint256 initialBalance = address(this).balance; IELFeeRecipientV1(payable(elFeeRecipient)).pullELFees(_max); uint256 collectedELFees = address(this).balance - initialBalance; if (collectedELFees > 0) { _setBalanceToDeposit(BalanceToDeposit.get() + collectedELFees); } emit PulledELFees(collectedELFees); return collectedELFees; } /// @notice Overridden handler to pull funds from the coverage fund to River and return the delta in the balance /// @param _max The maximum amount to pull from the coverage fund /// @return The amount pulled from the coverage fund function _pullCoverageFunds(uint256 _max) internal override returns (uint256) { address coverageFund = CoverageFundAddress.get(); if (coverageFund == address(0)) { return 0; } uint256 initialBalance = address(this).balance; ICoverageFundV1(payable(coverageFund)).pullCoverageFunds(_max); uint256 collectedCoverageFunds = address(this).balance - initialBalance; if (collectedCoverageFunds > 0) { _setBalanceToDeposit(BalanceToDeposit.get() + collectedCoverageFunds); } emit PulledCoverageFunds(collectedCoverageFunds); return collectedCoverageFunds; } /// @notice Overridden handler called whenever the balance of ETH handled by the system increases. Computes the fees paid to the collector /// @param _amount Additional ETH received function _onEarnings(uint256 _amount) internal override { uint256 oldTotalSupply = _totalSupply(); if (oldTotalSupply == 0) { revert ZeroMintedShares(); } uint256 newTotalBalance = _assetBalance(); uint256 globalFee = GlobalFee.get(); uint256 numerator = _amount * oldTotalSupply * globalFee; uint256 denominator = (newTotalBalance * LibBasisPoints.BASIS_POINTS_MAX) - (_amount * globalFee); uint256 sharesToMint = denominator == 0 ? 0 : (numerator / denominator); if (sharesToMint > 0) { address collector = CollectorAddress.get(); _mintRawShares(collector, sharesToMint); uint256 newTotalSupply = _totalSupply(); uint256 oldTotalBalance = newTotalBalance - _amount; emit RewardsEarned(collector, oldTotalBalance, oldTotalSupply, newTotalBalance, newTotalSupply); } } /// @notice Overridden handler called whenever the total balance of ETH is requested /// @return The current total asset balance managed by River function _assetBalance() internal view override(SharesManagerV1, OracleManagerV1) returns (uint256) { IOracleManagerV1.StoredConsensusLayerReport storage storedReport = LastConsensusLayerReport.get(); uint256 clValidatorCount = storedReport.validatorsCount; uint256 depositedValidatorCount = DepositedValidatorCount.get(); if (clValidatorCount < depositedValidatorCount) { return storedReport.validatorsBalance + BalanceToDeposit.get() + CommittedBalance.get() + BalanceToRedeem.get() + (depositedValidatorCount - clValidatorCount) * ConsensusLayerDepositManagerV1.DEPOSIT_SIZE; } else { return storedReport.validatorsBalance + BalanceToDeposit.get() + CommittedBalance.get() + BalanceToRedeem.get(); } } /// @notice Internal utility to set the daily committable limits /// @param _dcl The new daily committable limits function _setDailyCommittableLimits(DailyCommittableLimits.DailyCommittableLimitsStruct memory _dcl) internal { DailyCommittableLimits.set(_dcl); emit SetMaxDailyCommittableAmounts(_dcl.minDailyNetCommittableAmount, _dcl.maxDailyRelativeCommittableAmount); } /// @notice Sets the balance to deposit, but not yet committed /// @param _newBalanceToDeposit The new balance to deposit value function _setBalanceToDeposit(uint256 _newBalanceToDeposit) internal override(UserDepositManagerV1) { emit SetBalanceToDeposit(BalanceToDeposit.get(), _newBalanceToDeposit); BalanceToDeposit.set(_newBalanceToDeposit); } /// @notice Sets the balance to redeem, to be used to satisfy redeem requests on the redeem manager /// @param _newBalanceToRedeem The new balance to redeem value function _setBalanceToRedeem(uint256 _newBalanceToRedeem) internal { emit SetBalanceToRedeem(BalanceToRedeem.get(), _newBalanceToRedeem); BalanceToRedeem.set(_newBalanceToRedeem); } /// @notice Sets the committed balance, ready to be deposited to the consensus layer /// @param _newCommittedBalance The new committed balance value function _setCommittedBalance(uint256 _newCommittedBalance) internal override(ConsensusLayerDepositManagerV1) { emit SetBalanceCommittedToDeposit(CommittedBalance.get(), _newCommittedBalance); CommittedBalance.set(_newCommittedBalance); } /// @notice Pulls funds from the Withdraw contract, and adds funds to deposit and redeem balances /// @param _skimmedEthAmount The new amount of skimmed eth to pull /// @param _exitedEthAmount The new amount of exited eth to pull function _pullCLFunds(uint256 _skimmedEthAmount, uint256 _exitedEthAmount) internal override { uint256 currentBalance = address(this).balance; uint256 totalAmountToPull = _skimmedEthAmount + _exitedEthAmount; IWithdrawV1(WithdrawalCredentials.getAddress()).pullEth(totalAmountToPull); uint256 collectedCLFunds = address(this).balance - currentBalance; if (collectedCLFunds != _skimmedEthAmount + _exitedEthAmount) { revert InvalidPulledClFundsAmount(_skimmedEthAmount + _exitedEthAmount, collectedCLFunds); } if (_skimmedEthAmount > 0) { _setBalanceToDeposit(BalanceToDeposit.get() + _skimmedEthAmount); } if (_exitedEthAmount > 0) { _setBalanceToRedeem(BalanceToRedeem.get() + _exitedEthAmount); } emit PulledCLFunds(_skimmedEthAmount, _exitedEthAmount); } /// @notice Pulls funds from the redeem manager exceeding eth buffer /// @param _max The maximum amount to pull function _pullRedeemManagerExceedingEth(uint256 _max) internal override returns (uint256) { uint256 currentBalance = address(this).balance; IRedeemManagerV1(RedeemManagerAddress.get()).pullExceedingEth(_max); uint256 collectedExceedingEth = address(this).balance - currentBalance; if (collectedExceedingEth > 0) { _setBalanceToDeposit(BalanceToDeposit.get() + collectedExceedingEth); } emit PulledRedeemManagerExceedingEth(collectedExceedingEth); return collectedExceedingEth; } /// @notice Use the balance to redeem to report a withdrawal event on the redeem manager function _reportWithdrawToRedeemManager() internal override { IRedeemManagerV1 redeemManager_ = IRedeemManagerV1(RedeemManagerAddress.get()); uint256 underlyingAssetBalance = _assetBalance(); uint256 totalSupply = _totalSupply(); if (underlyingAssetBalance > 0 && totalSupply > 0) { // we compute the redeem manager demands in eth and lsEth based on current conversion rate uint256 redeemManagerDemand = redeemManager_.getRedeemDemand(); uint256 suppliedRedeemManagerDemand = redeemManagerDemand; uint256 suppliedRedeemManagerDemandInEth = _balanceFromShares(suppliedRedeemManagerDemand); uint256 availableBalanceToRedeem = BalanceToRedeem.get(); // if demand is higher than available eth, we update demand values to use the available eth if (suppliedRedeemManagerDemandInEth > availableBalanceToRedeem) { suppliedRedeemManagerDemandInEth = availableBalanceToRedeem; suppliedRedeemManagerDemand = _sharesFromBalance(suppliedRedeemManagerDemandInEth); } emit ReportedRedeemManager( redeemManagerDemand, suppliedRedeemManagerDemand, suppliedRedeemManagerDemandInEth ); if (suppliedRedeemManagerDemandInEth > 0) { // the available balance to redeem is updated _setBalanceToRedeem(availableBalanceToRedeem - suppliedRedeemManagerDemandInEth); // we burn the shares of the redeem manager associated with the amount of eth provided _burnRawShares(address(redeemManager_), suppliedRedeemManagerDemand); // perform a report withdraw call to the redeem manager redeemManager_.reportWithdraw{value: suppliedRedeemManagerDemandInEth}(suppliedRedeemManagerDemand); } } } /// @notice Requests exits of validators after possibly rebalancing deposit and redeem balances /// @param _exitingBalance The currently exiting funds, soon to be received on the execution layer /// @param _depositToRedeemRebalancingAllowed True if rebalancing from deposit to redeem is allowed function _requestExitsBasedOnRedeemDemandAfterRebalancings( uint256 _exitingBalance, uint32[] memory _stoppedValidatorCounts, bool _depositToRedeemRebalancingAllowed, bool _slashingContainmentModeEnabled ) internal override { IOperatorsRegistryV1(OperatorsRegistryAddress.get()).reportStoppedValidatorCounts( _stoppedValidatorCounts, DepositedValidatorCount.get() ); if (_slashingContainmentModeEnabled) { return; } uint256 totalSupply = _totalSupply(); if (totalSupply > 0) { uint256 availableBalanceToRedeem = BalanceToRedeem.get(); uint256 availableBalanceToDeposit = BalanceToDeposit.get(); uint256 redeemManagerDemandInEth = _balanceFromShares(IRedeemManagerV1(RedeemManagerAddress.get()).getRedeemDemand()); // if after all rebalancings, the redeem manager demand is still higher than the balance to redeem and exiting eth, we compute // the amount of validators to exit in order to cover the remaining demand if (availableBalanceToRedeem + _exitingBalance < redeemManagerDemandInEth) { // if reblancing is enabled and the redeem manager demand is higher than exiting eth, we add eth for deposit buffer to redeem buffer if (_depositToRedeemRebalancingAllowed && availableBalanceToDeposit > 0) { uint256 rebalancingAmount = LibUint256.min( availableBalanceToDeposit, redeemManagerDemandInEth - _exitingBalance - availableBalanceToRedeem ); if (rebalancingAmount > 0) { availableBalanceToRedeem += rebalancingAmount; _setBalanceToRedeem(availableBalanceToRedeem); _setBalanceToDeposit(availableBalanceToDeposit - rebalancingAmount); } } IOperatorsRegistryV1 or = IOperatorsRegistryV1(OperatorsRegistryAddress.get()); (uint256 totalStoppedValidatorCount, uint256 totalRequestedExitsCount) = or.getStoppedAndRequestedExitCounts(); // what we are calling pre-exiting balance is the amount of eth that should soon enter the exiting balance // because exit requests have been made and operators might have a lag to process them // we take them into account to not exit too many validators uint256 preExitingBalance = ( totalRequestedExitsCount > totalStoppedValidatorCount ? (totalRequestedExitsCount - totalStoppedValidatorCount) : 0 ) * DEPOSIT_SIZE; if (availableBalanceToRedeem + _exitingBalance + preExitingBalance < redeemManagerDemandInEth) { uint256 validatorCountToExit = LibUint256.ceil( redeemManagerDemandInEth - (availableBalanceToRedeem + _exitingBalance + preExitingBalance), DEPOSIT_SIZE ); or.demandValidatorExits(validatorCountToExit, DepositedValidatorCount.get()); } } } } /// @notice Skims the redeem balance and sends remaining funds to the deposit balance function _skimExcessBalanceToRedeem() internal override { uint256 availableBalanceToRedeem = BalanceToRedeem.get(); // if the available balance to redeem is not 0, it means that all the redeem requests are fulfilled, we should redirect funds for deposits if (availableBalanceToRedeem > 0) { _setBalanceToDeposit(BalanceToDeposit.get() + availableBalanceToRedeem); _setBalanceToRedeem(0); } } /// @notice Commits the deposit balance up to the allowed daily limit /// @notice Committed funds are funds waiting to be deposited but that cannot be used to fund the redeem manager anymore /// @notice This two step process is required to prevent possible out of gas issues we would have from actually funding the validators at this point /// @param _period The period between current and last report function _commitBalanceToDeposit(uint256 _period) internal override { uint256 underlyingAssetBalance = _assetBalance(); uint256 currentBalanceToDeposit = BalanceToDeposit.get(); DailyCommittableLimits.DailyCommittableLimitsStruct memory dcl = DailyCommittableLimits.get(); // we compute the max daily committable amount by taking the asset balance without the balance to deposit into account // this value is the daily maximum amount we can commit for deposits // we take the maximum value between a net amount and an amount relative to the asset balance // this ensures that the amount we can commit is not too low in the beginning and that it is not too high when volumes grow // the relative amount is computed from the committed and activated funds (on the CL or committed to be on the CL soon) and not // the deposit balance // this value is computed by subtracting the current balance to deposit from the underlying asset balance uint256 currentMaxDailyCommittableAmount = LibUint256.max( dcl.minDailyNetCommittableAmount, (uint256(dcl.maxDailyRelativeCommittableAmount) * (underlyingAssetBalance - currentBalanceToDeposit)) / LibBasisPoints.BASIS_POINTS_MAX ); // we adapt the value for the reporting period by using the asset balance as upper bound uint256 currentMaxCommittableAmount = LibUint256.min((currentMaxDailyCommittableAmount * _period) / 1 days, currentBalanceToDeposit); if (currentMaxCommittableAmount > 0) { _setCommittedBalance(CommittedBalance.get() + currentMaxCommittableAmount); _setBalanceToDeposit(currentBalanceToDeposit - currentMaxCommittableAmount); } } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "./interfaces/IAdministrable.sol"; import "./libraries/LibAdministrable.sol"; import "./libraries/LibSanitize.sol"; /// @title Administrable /// @author Kiln /// @notice This contract handles the administration of the contracts abstract contract Administrable is IAdministrable { /// @notice Prevents unauthorized calls modifier onlyAdmin() { if (msg.sender != LibAdministrable._getAdmin()) { revert LibErrors.Unauthorized(msg.sender); } _; } /// @notice Prevents unauthorized calls modifier onlyPendingAdmin() { if (msg.sender != LibAdministrable._getPendingAdmin()) { revert LibErrors.Unauthorized(msg.sender); } _; } /// @inheritdoc IAdministrable function getAdmin() external view returns (address) { return LibAdministrable._getAdmin(); } /// @inheritdoc IAdministrable function getPendingAdmin() external view returns (address) { return LibAdministrable._getPendingAdmin(); } /// @inheritdoc IAdministrable function proposeAdmin(address _newAdmin) external onlyAdmin { _setPendingAdmin(_newAdmin); } /// @inheritdoc IAdministrable function acceptAdmin() external onlyPendingAdmin { _setAdmin(LibAdministrable._getPendingAdmin()); _setPendingAdmin(address(0)); } /// @notice Internal utility to set the admin address /// @param _admin Address to set as admin function _setAdmin(address _admin) internal { LibSanitize._notZeroAddress(_admin); LibAdministrable._setAdmin(_admin); emit SetAdmin(_admin); } /// @notice Internal utility to set the pending admin address /// @param _pendingAdmin Address to set as pending admin function _setPendingAdmin(address _pendingAdmin) internal { LibAdministrable._setPendingAdmin(_pendingAdmin); emit SetPendingAdmin(_pendingAdmin); } /// @notice Internal utility to retrieve the address of the current admin /// @return The address of admin function _getAdmin() internal view returns (address) { return LibAdministrable._getAdmin(); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "./state/shared/Version.sol"; /// @title Initializable /// @author Kiln /// @notice This contract ensures that initializers are called only once per version contract Initializable { /// @notice Disable initialization on implementations constructor() { Version.set(type(uint256).max); emit Initialize(type(uint256).max, msg.data); } /// @notice An error occured during the initialization /// @param version The version that was attempting to be initialized /// @param expectedVersion The version that was expected error InvalidInitialization(uint256 version, uint256 expectedVersion); /// @notice Emitted when the contract is properly initialized /// @param version New version of the contracts /// @param cdata Complete calldata that was used during the initialization event Initialize(uint256 version, bytes cdata); /// @notice Use this modifier on initializers along with a hard-coded version number /// @param _version Version to initialize modifier init(uint256 _version) { if (_version != Version.get()) { revert InvalidInitialization(_version, Version.get()); } Version.set(_version + 1); // prevents reentrency on the called method _; emit Initialize(_version, msg.data); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../interfaces/components/IConsensusLayerDepositManager.1.sol"; import "../interfaces/IDepositContract.sol"; import "../libraries/LibBytes.sol"; import "../libraries/LibUint256.sol"; import "../state/river/DepositContractAddress.sol"; import "../state/river/WithdrawalCredentials.sol"; import "../state/river/DepositedValidatorCount.sol"; import "../state/river/BalanceToDeposit.sol"; import "../state/river/CommittedBalance.sol"; /// @title Consensus Layer Deposit Manager (v1) /// @author Kiln /// @notice This contract handles the interactions with the official deposit contract, funding all validators /// @notice Whenever a deposit to the consensus layer is requested, this contract computed the amount of keys /// @notice that could be deposited depending on the amount available in the contract. It then tries to retrieve /// @notice validator keys by calling its internal virtual method _getNextValidators. This method should be /// @notice overridden by the implementing contract to provide [0; _keyCount] keys when invoked. abstract contract ConsensusLayerDepositManagerV1 is IConsensusLayerDepositManagerV1 { /// @notice Size of a BLS Public key in bytes uint256 public constant PUBLIC_KEY_LENGTH = 48; /// @notice Size of a BLS Signature in bytes uint256 public constant SIGNATURE_LENGTH = 96; /// @notice Size of a deposit in ETH uint256 public constant DEPOSIT_SIZE = 32 ether; /// @notice Handler called to retrieve the internal River admin address /// @dev Must be Overridden function _getRiverAdmin() internal view virtual returns (address); /// @notice Handler called to change the committed balance to deposit /// @param newCommittedBalance The new committed balance value function _setCommittedBalance(uint256 newCommittedBalance) internal virtual; /// @notice Internal helper to retrieve validator keys ready to be funded /// @dev Must be overridden /// @param _keyCount The amount of keys (or less) to return. function _getNextValidators(uint256 _keyCount) internal virtual returns (bytes[] memory publicKeys, bytes[] memory signatures); /// @notice Initializer to set the deposit contract address and the withdrawal credentials to use /// @param _depositContractAddress The address of the deposit contract /// @param _withdrawalCredentials The withdrawal credentials to apply to all deposits function initConsensusLayerDepositManagerV1(address _depositContractAddress, bytes32 _withdrawalCredentials) internal { DepositContractAddress.set(_depositContractAddress); emit SetDepositContractAddress(_depositContractAddress); WithdrawalCredentials.set(_withdrawalCredentials); emit SetWithdrawalCredentials(_withdrawalCredentials); } /// @inheritdoc IConsensusLayerDepositManagerV1 function getCommittedBalance() external view returns (uint256) { return CommittedBalance.get(); } /// @inheritdoc IConsensusLayerDepositManagerV1 function getBalanceToDeposit() external view returns (uint256) { return BalanceToDeposit.get(); } /// @inheritdoc IConsensusLayerDepositManagerV1 function getWithdrawalCredentials() external view returns (bytes32) { return WithdrawalCredentials.get(); } /// @inheritdoc IConsensusLayerDepositManagerV1 function getDepositedValidatorCount() external view returns (uint256) { return DepositedValidatorCount.get(); } /// @inheritdoc IConsensusLayerDepositManagerV1 function depositToConsensusLayer(uint256 _maxCount) external { uint256 committedBalance = CommittedBalance.get(); uint256 keyToDepositCount = LibUint256.min(committedBalance / DEPOSIT_SIZE, _maxCount); if (keyToDepositCount == 0) { revert NotEnoughFunds(); } // it's up to the internal overriden _getNextValidators method to provide two array of the same // size for the publicKeys and the signatures (bytes[] memory publicKeys, bytes[] memory signatures) = _getNextValidators(keyToDepositCount); uint256 receivedPublicKeyCount = publicKeys.length; if (receivedPublicKeyCount == 0) { revert NoAvailableValidatorKeys(); } if (receivedPublicKeyCount > keyToDepositCount) { revert InvalidPublicKeyCount(); } bytes32 withdrawalCredentials = WithdrawalCredentials.get(); if (withdrawalCredentials == 0) { revert InvalidWithdrawalCredentials(); } for (uint256 idx = 0; idx < receivedPublicKeyCount;) { _depositValidator(publicKeys[idx], signatures[idx], withdrawalCredentials); unchecked { ++idx; } } _setCommittedBalance(committedBalance - DEPOSIT_SIZE * receivedPublicKeyCount); uint256 currentDepositedValidatorCount = DepositedValidatorCount.get(); DepositedValidatorCount.set(currentDepositedValidatorCount + receivedPublicKeyCount); emit SetDepositedValidatorCount( currentDepositedValidatorCount, currentDepositedValidatorCount + receivedPublicKeyCount ); } /// @notice Deposits 32 ETH to the official Deposit contract /// @param _publicKey The public key of the validator /// @param _signature The signature provided by the operator /// @param _withdrawalCredentials The withdrawal credentials provided by River function _depositValidator(bytes memory _publicKey, bytes memory _signature, bytes32 _withdrawalCredentials) internal { if (_publicKey.length != PUBLIC_KEY_LENGTH) { revert InconsistentPublicKeys(); } if (_signature.length != SIGNATURE_LENGTH) { revert InconsistentSignatures(); } uint256 value = DEPOSIT_SIZE; uint256 depositAmount = value / 1 gwei; bytes32 pubkeyRoot = sha256(bytes.concat(_publicKey, bytes16(0))); bytes32 signatureRoot = sha256( bytes.concat( sha256(LibBytes.slice(_signature, 0, 64)), sha256(bytes.concat(LibBytes.slice(_signature, 64, SIGNATURE_LENGTH - 64), bytes32(0))) ) ); bytes32 depositDataRoot = sha256( bytes.concat( sha256(bytes.concat(pubkeyRoot, _withdrawalCredentials)), sha256(bytes.concat(bytes32(LibUint256.toLittleEndian64(depositAmount)), signatureRoot)) ) ); uint256 targetBalance = address(this).balance - value; IDepositContract(DepositContractAddress.get()).deposit{value: value}( _publicKey, abi.encodePacked(_withdrawalCredentials), _signature, depositDataRoot ); if (address(this).balance != targetBalance) { revert ErrorOnDeposit(); } } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../interfaces/components/IOracleManager.1.sol"; import "../interfaces/IRedeemManager.1.sol"; import "../libraries/LibUint256.sol"; import "../state/river/LastConsensusLayerReport.sol"; import "../state/river/OracleAddress.sol"; import "../state/river/CLValidatorTotalBalance.sol"; import "../state/river/CLValidatorCount.sol"; import "../state/river/DepositedValidatorCount.sol"; import "../state/river/LastOracleRoundId.sol"; /// @title Oracle Manager (v1) /// @author Kiln /// @notice This contract handles the inputs provided by the oracle /// @notice The Oracle contract is plugged to this contract and is in charge of pushing /// @notice data whenever a new report has been deemed valid. The report consists in two /// @notice values: the sum of all balances of all deposited validators and the count of /// @notice validators that have been activated on the consensus layer. abstract contract OracleManagerV1 is IOracleManagerV1 { uint256 internal constant ONE_YEAR = 365 days; /// @notice Size of a deposit in ETH uint256 public constant _DEPOSIT_SIZE = 32 ether; /// @notice Handler called if the delta between the last and new validator balance sum is positive /// @dev Must be overridden /// @param _profits The positive increase in the validator balance sum (staking rewards) function _onEarnings(uint256 _profits) internal virtual; /// @notice Handler called to pull the Execution layer fees from the recipient /// @dev Must be overridden /// @param _max The maximum amount to pull inside the system /// @return The amount pulled inside the system function _pullELFees(uint256 _max) internal virtual returns (uint256); /// @notice Handler called to pull the coverage funds /// @dev Must be overridden /// @param _max The maximum amount to pull inside the system /// @return The amount pulled inside the system function _pullCoverageFunds(uint256 _max) internal virtual returns (uint256); /// @notice Handler called to retrieve the system administrator address /// @dev Must be overridden /// @return The system administrator address function _getRiverAdmin() internal view virtual returns (address); /// @notice Overridden handler called whenever the total balance of ETH is requested /// @return The current total asset balance managed by River function _assetBalance() internal view virtual returns (uint256); /// @notice Pulls funds from the Withdraw contract, and adds funds to deposit and redeem balances /// @param _skimmedEthAmount The new amount of skimmed eth to pull /// @param _exitedEthAmount The new amount of exited eth to pull function _pullCLFunds(uint256 _skimmedEthAmount, uint256 _exitedEthAmount) internal virtual; /// @notice Pulls funds from the redeem manager exceeding eth buffer /// @param _max The maximum amount to pull /// @return The amount pulled function _pullRedeemManagerExceedingEth(uint256 _max) internal virtual returns (uint256); /// @notice Use the balance to redeem to report a withdrawal event on the redeem manager function _reportWithdrawToRedeemManager() internal virtual; /// @notice Requests exits of validators after possibly rebalancing deposit and redeem balances /// @param _exitingBalance The currently exiting funds, soon to be received on the execution layer /// @param _depositToRedeemRebalancingAllowed True if rebalancing from deposit to redeem is allowed function _requestExitsBasedOnRedeemDemandAfterRebalancings( uint256 _exitingBalance, uint32[] memory _stoppedValidatorCounts, bool _depositToRedeemRebalancingAllowed, bool _slashingContainmentModeEnabled ) internal virtual; /// @notice Skims the redeem balance and sends remaining funds to the deposit balance function _skimExcessBalanceToRedeem() internal virtual; /// @notice Commits the deposit balance up to the allowed daily limit /// @param _period The period between current and last report function _commitBalanceToDeposit(uint256 _period) internal virtual; /// @notice Prevents unauthorized calls modifier onlyAdmin_OMV1() { if (msg.sender != _getRiverAdmin()) { revert LibErrors.Unauthorized(msg.sender); } _; } /// @notice Set the initial oracle address /// @param _oracle Address of the oracle function initOracleManagerV1(address _oracle) internal { OracleAddress.set(_oracle); emit SetOracle(_oracle); } /// @notice Initializes version 1.1 of the oracle manager /// @param _epochsPerFrame The amounts of epochs in a frame /// @param _slotsPerEpoch The slots inside an epoch /// @param _secondsPerSlot The seconds inside a slot /// @param _genesisTime The genesis timestamp /// @param _epochsToAssumedFinality The number of epochs before an epoch is considered final on-chain /// @param _annualAprUpperBound The reporting upper bound /// @param _relativeLowerBound The reporting lower bound function initOracleManagerV1_1( uint64 _epochsPerFrame, uint64 _slotsPerEpoch, uint64 _secondsPerSlot, uint64 _genesisTime, uint64 _epochsToAssumedFinality, uint256 _annualAprUpperBound, uint256 _relativeLowerBound ) internal { CLSpec.set( CLSpec.CLSpecStruct({ epochsPerFrame: _epochsPerFrame, slotsPerEpoch: _slotsPerEpoch, secondsPerSlot: _secondsPerSlot, genesisTime: _genesisTime, epochsToAssumedFinality: _epochsToAssumedFinality }) ); emit SetSpec(_epochsPerFrame, _slotsPerEpoch, _secondsPerSlot, _genesisTime, _epochsToAssumedFinality); ReportBounds.set( ReportBounds.ReportBoundsStruct({ annualAprUpperBound: _annualAprUpperBound, relativeLowerBound: _relativeLowerBound }) ); emit SetBounds(_annualAprUpperBound, _relativeLowerBound); IOracleManagerV1.StoredConsensusLayerReport memory storedReport; storedReport.epoch = uint256(LastOracleRoundId.get()); storedReport.validatorsBalance = CLValidatorTotalBalance.get(); storedReport.validatorsSkimmedBalance = 0; storedReport.validatorsExitedBalance = 0; storedReport.validatorsExitingBalance = 0; storedReport.validatorsCount = uint32(CLValidatorCount.get()); storedReport.rebalanceDepositToRedeemMode = false; storedReport.slashingContainmentMode = false; LastConsensusLayerReport.set(storedReport); } /// @inheritdoc IOracleManagerV1 function getOracle() external view returns (address) { return OracleAddress.get(); } /// @inheritdoc IOracleManagerV1 function getCLValidatorTotalBalance() external view returns (uint256) { return LastConsensusLayerReport.get().validatorsBalance; } /// @inheritdoc IOracleManagerV1 function getCLValidatorCount() external view returns (uint256) { return LastConsensusLayerReport.get().validatorsCount; } /// @inheritdoc IOracleManagerV1 function getExpectedEpochId() external view returns (uint256) { CLSpec.CLSpecStruct memory cls = CLSpec.get(); uint256 currentEpoch = _currentEpoch(cls); return LibUint256.max( LastConsensusLayerReport.get().epoch + cls.epochsPerFrame, currentEpoch - (currentEpoch % cls.epochsPerFrame) ); } /// @inheritdoc IOracleManagerV1 function isValidEpoch(uint256 _epoch) external view returns (bool) { return _isValidEpoch(CLSpec.get(), _epoch); } /// @inheritdoc IOracleManagerV1 function getTime() external view returns (uint256) { return block.timestamp; } /// @inheritdoc IOracleManagerV1 function getLastCompletedEpochId() external view returns (uint256) { return LastConsensusLayerReport.get().epoch; } /// @inheritdoc IOracleManagerV1 function getCurrentEpochId() external view returns (uint256) { return _currentEpoch(CLSpec.get()); } /// @inheritdoc IOracleManagerV1 function getCLSpec() external view returns (CLSpec.CLSpecStruct memory) { return CLSpec.get(); } /// @inheritdoc IOracleManagerV1 function getCurrentFrame() external view returns (uint256 _startEpochId, uint256 _startTime, uint256 _endTime) { CLSpec.CLSpecStruct memory cls = CLSpec.get(); uint256 currentEpoch = _currentEpoch(cls); _startEpochId = currentEpoch - (currentEpoch % cls.epochsPerFrame); _startTime = _startEpochId * cls.slotsPerEpoch * cls.secondsPerSlot; _endTime = (_startEpochId + cls.epochsPerFrame) * cls.slotsPerEpoch * cls.secondsPerSlot - 1; } /// @inheritdoc IOracleManagerV1 function getFrameFirstEpochId(uint256 _epochId) external view returns (uint256) { return _epochId - (_epochId % CLSpec.get().epochsPerFrame); } /// @inheritdoc IOracleManagerV1 function getReportBounds() external view returns (ReportBounds.ReportBoundsStruct memory) { return ReportBounds.get(); } /// @inheritdoc IOracleManagerV1 function getLastConsensusLayerReport() external view returns (IOracleManagerV1.StoredConsensusLayerReport memory) { return LastConsensusLayerReport.get(); } /// @inheritdoc IOracleManagerV1 function setOracle(address _oracleAddress) external onlyAdmin_OMV1 { OracleAddress.set(_oracleAddress); emit SetOracle(_oracleAddress); } /// @inheritdoc IOracleManagerV1 function setCLSpec(CLSpec.CLSpecStruct calldata _newValue) external onlyAdmin_OMV1 { CLSpec.set(_newValue); emit SetSpec( _newValue.epochsPerFrame, _newValue.slotsPerEpoch, _newValue.secondsPerSlot, _newValue.genesisTime, _newValue.epochsToAssumedFinality ); } /// @inheritdoc IOracleManagerV1 function setReportBounds(ReportBounds.ReportBoundsStruct calldata _newValue) external onlyAdmin_OMV1 { ReportBounds.set(_newValue); emit SetBounds(_newValue.annualAprUpperBound, _newValue.relativeLowerBound); } /// @notice Structure holding internal variables used during reporting struct ConsensusLayerDataReportingVariables { uint256 preReportUnderlyingBalance; uint256 postReportUnderlyingBalance; uint256 lastReportExitedBalance; uint256 lastReportSkimmedBalance; uint256 exitedAmountIncrease; uint256 skimmedAmountIncrease; uint256 timeElapsedSinceLastReport; uint256 availableAmountToUpperBound; uint256 redeemManagerDemand; ConsensusLayerDataReportingTrace trace; } /// @inheritdoc IOracleManagerV1 function setConsensusLayerData(IOracleManagerV1.ConsensusLayerReport calldata _report) external { // only the oracle is allowed to call this endpoint if (msg.sender != OracleAddress.get()) { revert LibErrors.Unauthorized(msg.sender); } CLSpec.CLSpecStruct memory cls = CLSpec.get(); // we start by verifying that the reported epoch is valid based on the consensus layer spec if (!_isValidEpoch(cls, _report.epoch)) { revert InvalidEpoch(_report.epoch); } ConsensusLayerDataReportingVariables memory vars; { IOracleManagerV1.StoredConsensusLayerReport storage lastStoredReport = LastConsensusLayerReport.get(); vars.lastReportExitedBalance = lastStoredReport.validatorsExitedBalance; // we ensure that the reported total exited balance is not decreasing if (_report.validatorsExitedBalance < vars.lastReportExitedBalance) { revert InvalidDecreasingValidatorsExitedBalance( vars.lastReportExitedBalance, _report.validatorsExitedBalance ); } // we compute the exited amount increase by taking the delta between reports vars.exitedAmountIncrease = _report.validatorsExitedBalance - vars.lastReportExitedBalance; vars.lastReportSkimmedBalance = lastStoredReport.validatorsSkimmedBalance; // we ensure that the reported total skimmed balance is not decreasing if (_report.validatorsSkimmedBalance < vars.lastReportSkimmedBalance) { revert InvalidDecreasingValidatorsSkimmedBalance( vars.lastReportSkimmedBalance, _report.validatorsSkimmedBalance ); } // we ensure that the reported validator count is not decreasing if ( _report.validatorsCount > DepositedValidatorCount.get() || _report.validatorsCount < lastStoredReport.validatorsCount ) { revert InvalidValidatorCountReport( _report.validatorsCount, DepositedValidatorCount.get(), lastStoredReport.validatorsCount ); } // we compute the new skimmed amount by taking the delta between reports vars.skimmedAmountIncrease = _report.validatorsSkimmedBalance - vars.lastReportSkimmedBalance; vars.timeElapsedSinceLastReport = _timeBetweenEpochs(cls, lastStoredReport.epoch, _report.epoch); } // we retrieve the current total underlying balance before any reporting data is applied to the system vars.preReportUnderlyingBalance = _assetBalance(); // if we have new exited / skimmed eth available, we pull funds from the consensus layer recipient if (vars.exitedAmountIncrease + vars.skimmedAmountIncrease > 0) { // this method pulls and updates ethToDeposit / ethToRedeem accordingly _pullCLFunds(vars.skimmedAmountIncrease, vars.exitedAmountIncrease); } { // we update the system parameters, this will have an impact on how the total underlying balance is computed IOracleManagerV1.StoredConsensusLayerReport memory storedReport; storedReport.epoch = _report.epoch; storedReport.validatorsBalance = _report.validatorsBalance; storedReport.validatorsSkimmedBalance = _report.validatorsSkimmedBalance; storedReport.validatorsExitedBalance = _report.validatorsExitedBalance; storedReport.validatorsExitingBalance = _report.validatorsExitingBalance; storedReport.validatorsCount = _report.validatorsCount; storedReport.rebalanceDepositToRedeemMode = _report.rebalanceDepositToRedeemMode; storedReport.slashingContainmentMode = _report.slashingContainmentMode; LastConsensusLayerReport.set(storedReport); } ReportBounds.ReportBoundsStruct memory rb = ReportBounds.get(); // we compute the maximum allowed increase in balance based on the pre report value uint256 maxIncrease = _maxIncrease(rb, vars.preReportUnderlyingBalance, vars.timeElapsedSinceLastReport); // we retrieve the new total underlying balance after system parameters are changed vars.postReportUnderlyingBalance = _assetBalance(); // we can now compute the earned rewards from the consensus layer balances // in order to properly account for the balance increase, we compare the sums of current balances, skimmed balance and exited balances // we also synthetically increase the current balance by 32 eth per new activated validator, this way we have no discrepency due // to currently activating funds that were not yet accounted in the consensus layer balances if (vars.postReportUnderlyingBalance >= vars.preReportUnderlyingBalance) { // if this happens, we revert and the reporting process is cancelled if (vars.postReportUnderlyingBalance > vars.preReportUnderlyingBalance + maxIncrease) { revert TotalValidatorBalanceIncreaseOutOfBound( vars.preReportUnderlyingBalance, vars.postReportUnderlyingBalance, vars.timeElapsedSinceLastReport, rb.annualAprUpperBound ); } // we update the rewards based on the balance delta vars.trace.rewards = vars.postReportUnderlyingBalance - vars.preReportUnderlyingBalance; // we update the available amount to upper bound (the amount of eth we can still pull and stay below the upper reporting bound) vars.availableAmountToUpperBound = maxIncrease - vars.trace.rewards; } else { // otherwise if the balance has decreased, we verify that we are not exceeding the lower reporting bound // we compute the maximum allowed decrease in balance uint256 maxDecrease = _maxDecrease(rb, vars.preReportUnderlyingBalance); // we verify that the bound is not crossed if ( vars.postReportUnderlyingBalance < vars.preReportUnderlyingBalance - LibUint256.min(maxDecrease, vars.preReportUnderlyingBalance) ) { revert TotalValidatorBalanceDecreaseOutOfBound( vars.preReportUnderlyingBalance, vars.postReportUnderlyingBalance, vars.timeElapsedSinceLastReport, rb.relativeLowerBound ); } // we update the available amount to upper bound to be equal to the maximum allowed increase plus the negative delta due to the loss vars.availableAmountToUpperBound = maxIncrease + (vars.preReportUnderlyingBalance - vars.postReportUnderlyingBalance); } // if we have available amount to upper bound after the reporting values are applied if (vars.availableAmountToUpperBound > 0) { // we pull the funds from the execution layer fee recipient vars.trace.pulledELFees = _pullELFees(vars.availableAmountToUpperBound); // we update the rewards vars.trace.rewards += vars.trace.pulledELFees; // we update the available amount accordingly vars.availableAmountToUpperBound -= vars.trace.pulledELFees; } // if we have available amount to upper bound after the execution layer fees are pulled if (vars.availableAmountToUpperBound > 0) { // we pull the funds from the exceeding eth buffer of the redeem manager vars.trace.pulledRedeemManagerExceedingEthBuffer = _pullRedeemManagerExceedingEth(vars.availableAmountToUpperBound); // we update the available amount accordingly vars.availableAmountToUpperBound -= vars.trace.pulledRedeemManagerExceedingEthBuffer; } // if we have available amount to upper bound after pulling the exceeding eth buffer, we attempt to pull coverage funds if (vars.availableAmountToUpperBound > 0) { // we pull the funds from the coverage recipient vars.trace.pulledCoverageFunds = _pullCoverageFunds(vars.availableAmountToUpperBound); // we do not update the rewards as coverage is not considered rewards // we do not update the available amount as there are no more pulling actions to perform afterwards } // if our rewards are not null, we dispatch the fee to the collector if (vars.trace.rewards > 0) { _onEarnings(vars.trace.rewards); } _requestExitsBasedOnRedeemDemandAfterRebalancings( _report.validatorsExitingBalance, _report.stoppedValidatorCountPerOperator, _report.rebalanceDepositToRedeemMode, _report.slashingContainmentMode ); // we use the updated balanceToRedeem value to report a withdraw event on the redeem manager _reportWithdrawToRedeemManager(); // if funds are left in the balance to redeem, we move them to the deposit balance _skimExcessBalanceToRedeem(); // we update the committable amount based on daily maximum allowed _commitBalanceToDeposit(vars.timeElapsedSinceLastReport); // we emit a summary event with all the reporting details emit ProcessedConsensusLayerReport(_report, vars.trace); } /// @notice Retrieve the current epoch based on the current timestamp /// @param _cls The consensus layer spec struct /// @return The current epoch function _currentEpoch(CLSpec.CLSpecStruct memory _cls) internal view returns (uint256) { return ((block.timestamp - _cls.genesisTime) / _cls.secondsPerSlot) / _cls.slotsPerEpoch; } /// @notice Verifies if the given epoch is valid /// @param _cls The consensus layer spec struct /// @param _epoch The epoch to verify /// @return True if valid function _isValidEpoch(CLSpec.CLSpecStruct memory _cls, uint256 _epoch) internal view returns (bool) { return ( _currentEpoch(_cls) >= _epoch + _cls.epochsToAssumedFinality && _epoch > LastConsensusLayerReport.get().epoch && _epoch % _cls.epochsPerFrame == 0 ); } /// @notice Retrieves the maximum increase in balance based on current total underlying supply and period since last report /// @param _rb The report bounds struct /// @param _prevTotalEth The total underlying supply during reporting /// @param _timeElapsed The time since last report /// @return The maximum allowed increase in balance function _maxIncrease(ReportBounds.ReportBoundsStruct memory _rb, uint256 _prevTotalEth, uint256 _timeElapsed) internal pure returns (uint256) { return (_prevTotalEth * _rb.annualAprUpperBound * _timeElapsed) / (LibBasisPoints.BASIS_POINTS_MAX * ONE_YEAR); } /// @notice Retrieves the maximum decrease in balance based on current total underlying supply /// @param _rb The report bounds struct /// @param _prevTotalEth The total underlying supply during reporting /// @return The maximum allowed decrease in balance function _maxDecrease(ReportBounds.ReportBoundsStruct memory _rb, uint256 _prevTotalEth) internal pure returns (uint256) { return (_prevTotalEth * _rb.relativeLowerBound) / LibBasisPoints.BASIS_POINTS_MAX; } /// @notice Retrieve the number of seconds between two epochs /// @param _cls The consensus layer spec struct /// @param _epochPast The starting epoch /// @param _epochNow The current epoch /// @return The number of seconds between the two epochs function _timeBetweenEpochs(CLSpec.CLSpecStruct memory _cls, uint256 _epochPast, uint256 _epochNow) internal pure returns (uint256) { return (_epochNow - _epochPast) * (_cls.secondsPerSlot * _cls.slotsPerEpoch); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../interfaces/components/ISharesManager.1.sol"; import "../libraries/LibSanitize.sol"; import "../state/river/Shares.sol"; import "../state/river/SharesPerOwner.sol"; import "../state/shared/ApprovalsPerOwner.sol"; /// @title Shares Manager (v1) /// @author Kiln /// @notice This contract handles the shares of the depositor and the ERC20 interface abstract contract SharesManagerV1 is ISharesManagerV1 { /// @notice Internal hook triggered on the external transfer call /// @dev Must be overridden /// @param _from Address of the sender /// @param _to Address of the recipient function _onTransfer(address _from, address _to) internal view virtual; /// @notice Internal method to override to provide the total underlying asset balance /// @dev Must be overridden /// @return The total asset balance of the system function _assetBalance() internal view virtual returns (uint256); /// @notice Modifier used to ensure that the transfer is allowed by using the internal hook to perform internal checks /// @param _from Address of the sender /// @param _to Address of the recipient modifier transferAllowed(address _from, address _to) { _onTransfer(_from, _to); _; } /// @notice Modifier used to ensure the amount transferred is not 0 /// @param _value Amount to check modifier isNotZero(uint256 _value) { if (_value == 0) { revert NullTransfer(); } _; } /// @notice Modifier used to ensure that the sender has enough funds for the transfer /// @param _owner Address of the sender /// @param _value Value that is required to be sent modifier hasFunds(address _owner, uint256 _value) { if (_balanceOf(_owner) < _value) { revert BalanceTooLow(); } _; } /// @inheritdoc ISharesManagerV1 function name() external pure returns (string memory) { return "Liquid Staked ETH"; } /// @inheritdoc ISharesManagerV1 function symbol() external pure returns (string memory) { return "LsETH"; } /// @inheritdoc ISharesManagerV1 function decimals() external pure returns (uint8) { return 18; } /// @inheritdoc ISharesManagerV1 function totalSupply() external view returns (uint256) { return _totalSupply(); } /// @inheritdoc ISharesManagerV1 function totalUnderlyingSupply() external view returns (uint256) { return _assetBalance(); } /// @inheritdoc ISharesManagerV1 function balanceOf(address _owner) external view returns (uint256) { return _balanceOf(_owner); } /// @inheritdoc ISharesManagerV1 function balanceOfUnderlying(address _owner) public view returns (uint256) { return _balanceFromShares(SharesPerOwner.get(_owner)); } /// @inheritdoc ISharesManagerV1 function underlyingBalanceFromShares(uint256 _shares) external view returns (uint256) { return _balanceFromShares(_shares); } /// @inheritdoc ISharesManagerV1 function sharesFromUnderlyingBalance(uint256 _underlyingAssetAmount) external view returns (uint256) { return _sharesFromBalance(_underlyingAssetAmount); } /// @inheritdoc ISharesManagerV1 function allowance(address _owner, address _spender) external view returns (uint256) { return ApprovalsPerOwner.get(_owner, _spender); } /// @inheritdoc ISharesManagerV1 function transfer(address _to, uint256 _value) external transferAllowed(msg.sender, _to) isNotZero(_value) hasFunds(msg.sender, _value) returns (bool) { if (_to == address(0)) { revert UnauthorizedTransfer(msg.sender, address(0)); } return _transfer(msg.sender, _to, _value); } /// @inheritdoc ISharesManagerV1 function transferFrom(address _from, address _to, uint256 _value) external transferAllowed(_from, _to) isNotZero(_value) hasFunds(_from, _value) returns (bool) { if (_to == address(0)) { revert UnauthorizedTransfer(_from, address(0)); } _spendAllowance(_from, _value); return _transfer(_from, _to, _value); } /// @inheritdoc ISharesManagerV1 function approve(address _spender, uint256 _value) external returns (bool) { _approve(msg.sender, _spender, _value); return true; } /// @inheritdoc ISharesManagerV1 function increaseAllowance(address _spender, uint256 _additionalValue) external returns (bool) { _approve(msg.sender, _spender, ApprovalsPerOwner.get(msg.sender, _spender) + _additionalValue); return true; } /// @inheritdoc ISharesManagerV1 function decreaseAllowance(address _spender, uint256 _subtractableValue) external returns (bool) { _approve(msg.sender, _spender, ApprovalsPerOwner.get(msg.sender, _spender) - _subtractableValue); return true; } /// @notice Internal utility to spend the allowance of an account from the message sender /// @param _from Address owning the allowance /// @param _value Amount of allowance in shares to spend function _spendAllowance(address _from, uint256 _value) internal { uint256 currentAllowance = ApprovalsPerOwner.get(_from, msg.sender); if (currentAllowance < _value) { revert AllowanceTooLow(_from, msg.sender, currentAllowance, _value); } if (currentAllowance != type(uint256).max) { _approve(_from, msg.sender, currentAllowance - _value); } } /// @notice Internal utility to change the allowance of an owner to a spender /// @param _owner The owner of the shares /// @param _spender The allowed spender of the shares /// @param _value The new allowance value function _approve(address _owner, address _spender, uint256 _value) internal { LibSanitize._notZeroAddress(_owner); LibSanitize._notZeroAddress(_spender); ApprovalsPerOwner.set(_owner, _spender, _value); emit Approval(_owner, _spender, _value); } /// @notice Internal utility to retrieve the total supply of tokens /// @return The total supply function _totalSupply() internal view returns (uint256) { return Shares.get(); } /// @notice Internal utility to perform an unchecked transfer /// @param _from Address sending the tokens /// @param _to Address receiving the tokens /// @param _value Amount of shares to be sent /// @return True if success function _transfer(address _from, address _to, uint256 _value) internal returns (bool) { SharesPerOwner.set(_from, SharesPerOwner.get(_from) - _value); SharesPerOwner.set(_to, SharesPerOwner.get(_to) + _value); emit Transfer(_from, _to, _value); return true; } /// @notice Internal utility to retrieve the underlying asset balance for the given shares /// @param _shares Amount of shares to convert /// @return The balance from the given shares function _balanceFromShares(uint256 _shares) internal view returns (uint256) { uint256 _totalSharesValue = Shares.get(); if (_totalSharesValue == 0) { return 0; } return ((_shares * _assetBalance())) / _totalSharesValue; } /// @notice Internal utility to retrieve the shares count for a given underlying asset amount /// @param _balance Amount of underlying asset balance to convert /// @return The shares from the given balance function _sharesFromBalance(uint256 _balance) internal view returns (uint256) { uint256 _totalSharesValue = Shares.get(); if (_totalSharesValue == 0) { return 0; } return (_balance * _totalSharesValue) / _assetBalance(); } /// @notice Internal utility to mint shares for the specified user /// @dev This method assumes that funds received are now part of the _assetBalance() /// @param _owner Account that should receive the new shares /// @param _underlyingAssetValue Value of underlying asset received, to convert into shares /// @return sharesToMint The amnount of minted shares function _mintShares(address _owner, uint256 _underlyingAssetValue) internal returns (uint256 sharesToMint) { uint256 oldTotalAssetBalance = _assetBalance() - _underlyingAssetValue; if (oldTotalAssetBalance == 0) { sharesToMint = _underlyingAssetValue; _mintRawShares(_owner, _underlyingAssetValue); } else { sharesToMint = (_underlyingAssetValue * _totalSupply()) / oldTotalAssetBalance; _mintRawShares(_owner, sharesToMint); } } /// @notice Internal utility to retrieve the amount of shares per owner /// @param _owner Account to be checked /// @return The balance of the account in shares function _balanceOf(address _owner) internal view returns (uint256) { return SharesPerOwner.get(_owner); } /// @notice Internal utility to mint shares without any conversion, and emits a mint Transfer event /// @param _owner Account that should receive the new shares /// @param _value Amount of shares to mint function _mintRawShares(address _owner, uint256 _value) internal { _setTotalSupply(Shares.get() + _value); SharesPerOwner.set(_owner, SharesPerOwner.get(_owner) + _value); emit Transfer(address(0), _owner, _value); } /// @notice Internal utility to burn shares without any conversion, and emits a burn Transfer event /// @param _owner Account that should burn its shares /// @param _value Amount of shares to burn function _burnRawShares(address _owner, uint256 _value) internal { _setTotalSupply(Shares.get() - _value); SharesPerOwner.set(_owner, SharesPerOwner.get(_owner) - _value); emit Transfer(_owner, address(0), _value); } /// @notice Internal utility to set the total supply and emit an event /// @param newTotalSupply The new total supply value function _setTotalSupply(uint256 newTotalSupply) internal { Shares.set(newTotalSupply); emit SetTotalSupply(newTotalSupply); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../interfaces/components/IUserDepositManager.1.sol"; import "../libraries/LibSanitize.sol"; import "../state/river/BalanceToDeposit.sol"; /// @title User Deposit Manager (v1) /// @author Kiln /// @notice This contract handles the inbound transfers cases or the explicit submissions abstract contract UserDepositManagerV1 is IUserDepositManagerV1 { /// @notice Handler called whenever a user has sent funds to the contract /// @dev Must be overridden /// @param _depositor Address that made the deposit /// @param _recipient Address that receives the minted shares /// @param _amount Amount deposited function _onDeposit(address _depositor, address _recipient, uint256 _amount) internal virtual; function _setBalanceToDeposit(uint256 newBalanceToDeposit) internal virtual; /// @inheritdoc IUserDepositManagerV1 function deposit() external payable { _deposit(msg.sender); } /// @inheritdoc IUserDepositManagerV1 function depositAndTransfer(address _recipient) external payable { LibSanitize._notZeroAddress(_recipient); _deposit(_recipient); } /// @inheritdoc IUserDepositManagerV1 receive() external payable { _deposit(msg.sender); } /// @inheritdoc IUserDepositManagerV1 fallback() external payable { revert LibErrors.InvalidCall(); } /// @notice Internal utility calling the deposit handler and emitting the deposit details /// @param _recipient The account receiving the minted shares function _deposit(address _recipient) internal { if (msg.value == 0) { revert EmptyDeposit(); } _setBalanceToDeposit(BalanceToDeposit.get() + msg.value); _onDeposit(msg.sender, _recipient, msg.value); emit UserDeposit(msg.sender, _recipient, msg.value); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Administrable Interface /// @author Kiln /// @notice This interface exposes methods to handle the ownership of the contracts interface IAdministrable { /// @notice The pending admin address changed /// @param pendingAdmin New pending admin address event SetPendingAdmin(address indexed pendingAdmin); /// @notice The admin address changed /// @param admin New admin address event SetAdmin(address indexed admin); /// @notice Retrieves the current admin address /// @return The admin address function getAdmin() external view returns (address); /// @notice Retrieve the current pending admin address /// @return The pending admin address function getPendingAdmin() external view returns (address); /// @notice Proposes a new address as admin /// @dev This security prevents setting an invalid address as an admin. The pending /// @dev admin has to claim its ownership of the contract, and prove that the new /// @dev address is able to perform regular transactions. /// @param _newAdmin New admin address function proposeAdmin(address _newAdmin) external; /// @notice Accept the transfer of ownership /// @dev Only callable by the pending admin. Resets the pending admin if succesful. function acceptAdmin() external; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Allowlist Interface (v1) /// @author Kiln /// @notice This interface exposes methods to handle the list of allowed recipients. interface IAllowlistV1 { /// @notice The permissions of several accounts have changed /// @param accounts List of accounts /// @param permissions New permissions for each account at the same index event SetAllowlistPermissions(address[] accounts, uint256[] permissions); /// @notice The stored allower address has been changed /// @param allower The new allower address event SetAllower(address indexed allower); /// @notice The provided accounts list is empty error InvalidAlloweeCount(); /// @notice The account is denied access /// @param _account The denied account error Denied(address _account); /// @notice The provided accounts and permissions list have different lengths error MismatchedAlloweeAndStatusCount(); /// @notice Initializes the allowlist /// @param _admin Address of the Allowlist administrator /// @param _allower Address of the allower function initAllowlistV1(address _admin, address _allower) external; /// @notice Retrieves the allower address /// @return The address of the allower function getAllower() external view returns (address); /// @notice This method returns true if the user has the expected permission and /// is not in the deny list /// @param _account Recipient to verify /// @param _mask Combination of permissions to verify /// @return True if mask is respected and user is allowed function isAllowed(address _account, uint256 _mask) external view returns (bool); /// @notice This method returns true if the user is in the deny list /// @param _account Recipient to verify /// @return True if user is denied access function isDenied(address _account) external view returns (bool); /// @notice This method returns true if the user has the expected permission /// ignoring any deny list membership /// @param _account Recipient to verify /// @param _mask Combination of permissions to verify /// @return True if mask is respected function hasPermission(address _account, uint256 _mask) external view returns (bool); /// @notice This method retrieves the raw permission value /// @param _account Recipient to verify /// @return The raw permissions value of the account function getPermissions(address _account) external view returns (uint256); /// @notice This method should be used as a modifier and is expected to revert /// if the user hasn't got the required permission or if the user is /// in the deny list. /// @param _account Recipient to verify /// @param _mask Combination of permissions to verify function onlyAllowed(address _account, uint256 _mask) external view; /// @notice Changes the allower address /// @param _newAllowerAddress New address allowed to edit the allowlist function setAllower(address _newAllowerAddress) external; /// @notice Sets the allowlisting status for one or more accounts /// @dev The permission value is overridden and not updated /// @param _accounts Accounts with statuses to edit /// @param _permissions Allowlist permissions for each account, in the same order as _accounts function allow(address[] calldata _accounts, uint256[] calldata _permissions) external; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Coverage Fund Interface (v1) /// @author Kiln /// @notice This interface exposes methods to receive donations for the slashing coverage fund and pull the funds into river interface ICoverageFundV1 { /// @notice The storage river address has changed /// @param river The new river address event SetRiver(address indexed river); /// @notice A donation has been made to the coverage fund /// @param donator Address that performed the donation /// @param amount The amount donated event Donate(address indexed donator, uint256 amount); /// @notice The fallback or receive callback has been triggered error InvalidCall(); /// @notice A donation with 0 ETH has been performed error EmptyDonation(); /// @notice Initialize the coverage fund with the required arguments /// @param _riverAddress Address of River function initCoverageFundV1(address _riverAddress) external; /// @notice Pulls ETH into the River contract /// @dev Only callable by the River contract /// @param _maxAmount The maximum amount to pull into the system function pullCoverageFunds(uint256 _maxAmount) external; /// @notice Donates ETH to the coverage fund contract function donate() external payable; /// @notice Ether receiver receive() external payable; /// @notice Invalid fallback detector fallback() external payable; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Deposit Contract Interface /// @notice This interface exposes methods to perform validator deposits interface IDepositContract { /// @notice Official deposit method to activate a validator on the consensus layer /// @param pubkey The 48 bytes long BLS Public key representing the validator /// @param withdrawalCredentials The 32 bytes long withdrawal credentials, configures the withdrawal recipient /// @param signature The 96 bytes long BLS Signature performed by the pubkey's private key /// @param depositDataRoot The root hash of the whole deposit data structure function deposit( bytes calldata pubkey, bytes calldata withdrawalCredentials, bytes calldata signature, bytes32 depositDataRoot ) external payable; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Execution Layer Fee Recipient Interface (v1) /// @author Kiln /// @notice This interface exposes methods to receive all the execution layer fees from the proposed blocks + bribes interface IELFeeRecipientV1 { /// @notice The storage river address has changed /// @param river The new river address event SetRiver(address indexed river); /// @notice The fallback has been triggered error InvalidCall(); /// @notice Initialize the fee recipient with the required arguments /// @param _riverAddress Address of River function initELFeeRecipientV1(address _riverAddress) external; /// @notice Pulls ETH to the River contract /// @dev Only callable by the River contract /// @param _maxAmount The maximum amount to pull into the system function pullELFees(uint256 _maxAmount) external; /// @notice Ether receiver receive() external payable; /// @notice Invalid fallback detector fallback() external payable; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../state/operatorsRegistry/Operators.2.sol"; /// @title Operators Registry Interface (v1) /// @author Kiln /// @notice This interface exposes methods to handle the list of operators and their keys interface IOperatorsRegistryV1 { /// @notice A new operator has been added to the registry /// @param index The operator index /// @param name The operator display name /// @param operatorAddress The operator address event AddedOperator(uint256 indexed index, string name, address indexed operatorAddress); /// @notice The operator status has been changed /// @param index The operator index /// @param active True if the operator is active event SetOperatorStatus(uint256 indexed index, bool active); /// @notice The operator limit has been changed /// @param index The operator index /// @param newLimit The new operator staking limit event SetOperatorLimit(uint256 indexed index, uint256 newLimit); /// @notice The operator stopped validator count has been changed /// @param index The operator index /// @param newStoppedValidatorCount The new stopped validator count event SetOperatorStoppedValidatorCount(uint256 indexed index, uint256 newStoppedValidatorCount); /// @notice The operator address has been changed /// @param index The operator index /// @param newOperatorAddress The new operator address event SetOperatorAddress(uint256 indexed index, address indexed newOperatorAddress); /// @notice The operator display name has been changed /// @param index The operator index /// @param newName The new display name event SetOperatorName(uint256 indexed index, string newName); /// @notice The operator or the admin added new validator keys and signatures /// @dev The public keys and signatures are concatenated /// @dev A public key is 48 bytes long /// @dev A signature is 96 bytes long /// @dev [P1, S1, P2, S2, ..., PN, SN] where N is the bytes length divided by (96 + 48) /// @param index The operator index /// @param publicKeysAndSignatures The concatenated public keys and signatures event AddedValidatorKeys(uint256 indexed index, bytes publicKeysAndSignatures); /// @notice The operator or the admin removed a public key and its signature from the registry /// @param index The operator index /// @param publicKey The BLS public key that has been removed event RemovedValidatorKey(uint256 indexed index, bytes publicKey); /// @notice The stored river address has been changed /// @param river The new river address event SetRiver(address indexed river); /// @notice The operator edited its keys after the snapshot block /// @dev This means that we cannot assume that its key set is checked by the snapshot /// @dev This happens only if the limit was meant to be increased /// @param index The operator index /// @param currentLimit The current operator limit /// @param newLimit The new operator limit that was attempted to be set /// @param latestKeysEditBlockNumber The last block number at which the operator changed its keys /// @param snapshotBlock The block number of the snapshot event OperatorEditsAfterSnapshot( uint256 indexed index, uint256 currentLimit, uint256 newLimit, uint256 indexed latestKeysEditBlockNumber, uint256 indexed snapshotBlock ); /// @notice The call didn't alter the limit of the operator /// @param index The operator index /// @param limit The limit of the operator event OperatorLimitUnchanged(uint256 indexed index, uint256 limit); /// @notice The stopped validator array has been changed /// @notice A validator is considered stopped if exiting, exited or slashed /// @notice This event is emitted when the oracle reports new stopped validators counts /// @param stoppedValidatorCounts The new stopped validator counts event UpdatedStoppedValidators(uint32[] stoppedValidatorCounts); /// @notice The requested exit count has been updated /// @param index The operator index /// @param count The count of requested exits event RequestedValidatorExits(uint256 indexed index, uint256 count); /// @notice The exit request demand has been updated /// @param previousValidatorExitsDemand The previous exit request demand /// @param nextValidatorExitsDemand The new exit request demand event SetCurrentValidatorExitsDemand(uint256 previousValidatorExitsDemand, uint256 nextValidatorExitsDemand); /// @notice The total requested exit has been updated /// @param previousTotalValidatorExitsRequested The previous total requested exit /// @param newTotalValidatorExitsRequested The new total requested exit event SetTotalValidatorExitsRequested( uint256 previousTotalValidatorExitsRequested, uint256 newTotalValidatorExitsRequested ); /// @notice A validator key got funded on the deposit contract /// @notice This event was introduced during a contract upgrade, in order to cover all possible public keys, this event /// @notice will be replayed for past funded keys in order to have a complete coverage of all the funded public keys. /// @notice In this particuliar scenario, the deferred value will be set to true, to indicate that we are not going to have /// @notice the expected additional events and side effects in the same transaction (deposit to official DepositContract etc ...) because /// @notice the event was synthetically crafted. /// @param index The operator index /// @param publicKeys BLS Public key that got funded /// @param deferred True if event has been replayed in the context of a migration event FundedValidatorKeys(uint256 indexed index, bytes[] publicKeys, bool deferred); /// @notice The requested exit count has been update to fill the gap with the reported stopped count /// @param index The operator index /// @param oldRequestedExits The old requested exit count /// @param newRequestedExits The new requested exit count event UpdatedRequestedValidatorExitsUponStopped( uint256 indexed index, uint32 oldRequestedExits, uint32 newRequestedExits ); /// @notice The calling operator is inactive /// @param index The operator index error InactiveOperator(uint256 index); /// @notice A funded key deletion has been attempted error InvalidFundedKeyDeletionAttempt(); /// @notice The index provided are not sorted properly (descending order) error InvalidUnsortedIndexes(); /// @notice The provided operator and limits array have different lengths error InvalidArrayLengths(); /// @notice The provided operator and limits array are empty error InvalidEmptyArray(); /// @notice The provided key count is 0 error InvalidKeyCount(); /// @notice The provided concatenated keys do not have the expected length error InvalidKeysLength(); /// @notice The index that is removed is out of bounds error InvalidIndexOutOfBounds(); /// @notice The value for the operator limit is too high /// @param index The operator index /// @param limit The new limit provided /// @param keyCount The operator key count error OperatorLimitTooHigh(uint256 index, uint256 limit, uint256 keyCount); /// @notice The value for the limit is too low /// @param index The operator index /// @param limit The new limit provided /// @param fundedKeyCount The operator funded key count error OperatorLimitTooLow(uint256 index, uint256 limit, uint256 fundedKeyCount); /// @notice The provided list of operators is not in increasing order error UnorderedOperatorList(); /// @notice Thrown when an invalid empty stopped validator array is provided error InvalidEmptyStoppedValidatorCountsArray(); /// @notice Thrown when the sum of stopped validators is invalid error InvalidStoppedValidatorCountsSum(); /// @notice Throw when an element in the stopped validator array is decreasing error StoppedValidatorCountsDecreased(); /// @notice Thrown when the number of elements in the array is too high compared to operator count error StoppedValidatorCountsTooHigh(); /// @notice Thrown when no exit requests can be performed error NoExitRequestsToPerform(); /// @notice The provided stopped validator count array is shrinking error StoppedValidatorCountArrayShrinking(); /// @notice The provided stopped validator count of an operator is above its funded validator count error StoppedValidatorCountAboveFundedCount(uint256 operatorIndex, uint32 stoppedCount, uint32 fundedCount); /// @notice Initializes the operators registry /// @param _admin Admin in charge of managing operators /// @param _river Address of River system function initOperatorsRegistryV1(address _admin, address _river) external; /// @notice Initializes the operators registry for V1_1 function initOperatorsRegistryV1_1() external; /// @notice Retrieve the River address /// @return The address of River function getRiver() external view returns (address); /// @notice Get operator details /// @param _index The index of the operator /// @return The details of the operator function getOperator(uint256 _index) external view returns (OperatorsV2.Operator memory); /// @notice Get operator count /// @return The operator count function getOperatorCount() external view returns (uint256); /// @notice Retrieve the stopped validator count for an operator index /// @param _idx The index of the operator /// @return The stopped validator count of the operator function getOperatorStoppedValidatorCount(uint256 _idx) external view returns (uint32); /// @notice Retrieve the total stopped validator count /// @return The total stopped validator count function getTotalStoppedValidatorCount() external view returns (uint32); /// @notice Retrieve the total requested exit count /// @notice This value is the amount of exit requests that have been performed, emitting an event for operators to catch /// @return The total requested exit count function getTotalValidatorExitsRequested() external view returns (uint256); /// @notice Get the current exit request demand waiting to be triggered /// @notice This value is the amount of exit requests that are demanded and not yet performed by the contract /// @return The current exit request demand function getCurrentValidatorExitsDemand() external view returns (uint256); /// @notice Retrieve the total stopped and requested exit count /// @return The total stopped count /// @return The total requested exit count function getStoppedAndRequestedExitCounts() external view returns (uint32, uint256); /// @notice Retrieve the raw stopped validators array from storage /// @return The stopped validator array function getStoppedValidatorCountPerOperator() external view returns (uint32[] memory); /// @notice Get the details of a validator /// @param _operatorIndex The index of the operator /// @param _validatorIndex The index of the validator /// @return publicKey The public key of the validator /// @return signature The signature used during deposit /// @return funded True if validator has been funded function getValidator(uint256 _operatorIndex, uint256 _validatorIndex) external view returns (bytes memory publicKey, bytes memory signature, bool funded); /// @notice Retrieve the active operator set /// @return The list of active operators and their details function listActiveOperators() external view returns (OperatorsV2.Operator[] memory); /// @notice Allows river to override the stopped validators array /// @notice This actions happens during the Oracle report processing /// @param _stoppedValidatorCounts The new stopped validators array /// @param _depositedValidatorCount The total deposited validator count function reportStoppedValidatorCounts(uint32[] calldata _stoppedValidatorCounts, uint256 _depositedValidatorCount) external; /// @notice Adds an operator to the registry /// @dev Only callable by the administrator /// @param _name The name identifying the operator /// @param _operator The address representing the operator, receiving the rewards /// @return The index of the new operator function addOperator(string calldata _name, address _operator) external returns (uint256); /// @notice Changes the operator address of an operator /// @dev Only callable by the administrator or the previous operator address /// @param _index The operator index /// @param _newOperatorAddress The new address of the operator function setOperatorAddress(uint256 _index, address _newOperatorAddress) external; /// @notice Changes the operator name /// @dev Only callable by the administrator or the operator /// @param _index The operator index /// @param _newName The new operator name function setOperatorName(uint256 _index, string calldata _newName) external; /// @notice Changes the operator status /// @dev Only callable by the administrator /// @param _index The operator index /// @param _newStatus The new status of the operator function setOperatorStatus(uint256 _index, bool _newStatus) external; /// @notice Changes the operator staking limit /// @dev Only callable by the administrator /// @dev The operator indexes must be in increasing order and contain no duplicate /// @dev The limit cannot exceed the total key count of the operator /// @dev The _indexes and _newLimits must have the same length. /// @dev Each limit value is applied to the operator index at the same index in the _indexes array. /// @param _operatorIndexes The operator indexes, in increasing order and duplicate free /// @param _newLimits The new staking limit of the operators /// @param _snapshotBlock The block number at which the snapshot was computed function setOperatorLimits( uint256[] calldata _operatorIndexes, uint32[] calldata _newLimits, uint256 _snapshotBlock ) external; /// @notice Adds new keys for an operator /// @dev Only callable by the administrator or the operator address /// @param _index The operator index /// @param _keyCount The amount of keys provided /// @param _publicKeysAndSignatures Public keys of the validator, concatenated function addValidators(uint256 _index, uint32 _keyCount, bytes calldata _publicKeysAndSignatures) external; /// @notice Remove validator keys /// @dev Only callable by the administrator or the operator address /// @dev The indexes must be provided sorted in decreasing order and duplicate-free, otherwise the method will revert /// @dev The operator limit will be set to the lowest deleted key index if the operator's limit wasn't equal to its total key count /// @dev The operator or the admin cannot remove funded keys /// @dev When removing validators, the indexes of specific unfunded keys can be changed in order to properly /// @dev remove the keys from the storage array. Beware of this specific behavior when chaining calls as the /// @dev targeted public key indexes can point to a different key after a first call was made and performed /// @dev some swaps /// @param _index The operator index /// @param _indexes The indexes of the keys to remove function removeValidators(uint256 _index, uint256[] calldata _indexes) external; /// @notice Retrieve validator keys based on operator statuses /// @param _count Max amount of keys requested /// @return publicKeys An array of public keys /// @return signatures An array of signatures linked to the public keys function pickNextValidatorsToDeposit(uint256 _count) external returns (bytes[] memory publicKeys, bytes[] memory signatures); /// @notice Public endpoint to consume the exit request demand and perform the actual exit requests /// @notice The selection algorithm will pick validators based on their active validator counts /// @notice This value is computed by using the count of funded keys and taking into account the stopped validator counts and exit requests /// @param _count Max amount of exits to request function requestValidatorExits(uint256 _count) external; /// @notice Increases the exit request demand /// @dev This method is only callable by the river contract, and to actually forward the information to the node operators via event emission, the unprotected requestValidatorExits method must be called /// @param _count The amount of exit requests to add to the demand /// @param _depositedValidatorCount The total deposited validator count function demandValidatorExits(uint256 _count, uint256 _depositedValidatorCount) external; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../state/redeemManager/RedeemQueue.sol"; import "../state/redeemManager/WithdrawalStack.sol"; /// @title Redeem Manager Interface (v1) /// @author Kiln /// @notice This contract handles the redeem requests of all users interface IRedeemManagerV1 { /// @notice Emitted when a redeem request is created /// @param owner The owner of the redeem request /// @param height The height of the redeem request in LsETH /// @param amount The amount of the redeem request in LsETH /// @param maxRedeemableEth The maximum amount of eth that can be redeemed from this request /// @param id The id of the new redeem request event RequestedRedeem(address indexed owner, uint256 height, uint256 amount, uint256 maxRedeemableEth, uint32 id); /// @notice Emitted when a withdrawal event is created /// @param height The height of the withdrawal event in LsETH /// @param amount The amount of the withdrawal event in LsETH /// @param ethAmount The amount of eth to distrubute to claimers /// @param id The id of the withdrawal event event ReportedWithdrawal(uint256 height, uint256 amount, uint256 ethAmount, uint32 id); /// @notice Emitted when a redeem request has been satisfied and filled (even partially) from a withdrawal event /// @param redeemRequestId The id of the redeem request /// @param withdrawalEventId The id of the withdrawal event used to fill the request /// @param lsEthAmountSatisfied The amount of LsETH filled /// @param ethAmountSatisfied The amount of ETH filled /// @param lsEthAmountRemaining The amount of LsETH remaining /// @param ethAmountExceeding The amount of eth added to the exceeding buffer event SatisfiedRedeemRequest( uint32 indexed redeemRequestId, uint32 indexed withdrawalEventId, uint256 lsEthAmountSatisfied, uint256 ethAmountSatisfied, uint256 lsEthAmountRemaining, uint256 ethAmountExceeding ); /// @notice Emitted when a redeem request claim has been processed and matched at least once and funds are sent to the recipient /// @param redeemRequestId The id of the redeem request /// @param recipient The address receiving the redeem request funds /// @param ethAmount The amount of eth retrieved /// @param lsEthAmount The total amount of LsETH used to redeem the eth /// @param remainingLsEthAmount The amount of LsETH remaining event ClaimedRedeemRequest( uint32 indexed redeemRequestId, address indexed recipient, uint256 ethAmount, uint256 lsEthAmount, uint256 remainingLsEthAmount ); /// @notice Emitted when the redeem demand is set /// @param oldRedeemDemand The old redeem demand /// @param newRedeemDemand The new redeem demand event SetRedeemDemand(uint256 oldRedeemDemand, uint256 newRedeemDemand); /// @notice Emitted when the River address is set /// @param river The new river address event SetRiver(address river); /// @notice Thrown When a zero value is provided error InvalidZeroAmount(); /// @notice Thrown when a transfer error occured with LsETH error TransferError(); /// @notice Thrown when the provided arrays don't have matching lengths error IncompatibleArrayLengths(); /// @notice Thrown when the provided redeem request id is out of bounds /// @param id The redeem request id error RedeemRequestOutOfBounds(uint256 id); /// @notice Thrown when the withdrawal request id if out of bounds /// @param id The withdrawal event id error WithdrawalEventOutOfBounds(uint256 id); /// @notice Thrown when the redeem request id is already claimed /// @param id The redeem request id error RedeemRequestAlreadyClaimed(uint256 id); /// @notice Thrown when the redeem request and withdrawal event are not matching during claim /// @param redeemRequestId The provided redeem request id /// @param withdrawalEventId The provided associated withdrawal event id error DoesNotMatch(uint256 redeemRequestId, uint256 withdrawalEventId); /// @notice Thrown when the provided withdrawal event exceeds the redeem demand /// @param withdrawalAmount The amount of the withdrawal event /// @param redeemDemand The current redeem demand error WithdrawalExceedsRedeemDemand(uint256 withdrawalAmount, uint256 redeemDemand); /// @notice Thrown when the payment after a claim failed /// @param recipient The recipient of the payment /// @param rdata The revert data error ClaimRedeemFailed(address recipient, bytes rdata); /// @param _river The address of the River contract function initializeRedeemManagerV1(address _river) external; /// @notice Retrieve the global count of redeem requests function getRedeemRequestCount() external view returns (uint256); /// @notice Retrieve the details of a specific redeem request /// @param _redeemRequestId The id of the request /// @return The redeem request details function getRedeemRequestDetails(uint32 _redeemRequestId) external view returns (RedeemQueue.RedeemRequest memory); /// @notice Retrieve the global count of withdrawal events function getWithdrawalEventCount() external view returns (uint256); /// @notice Retrieve the details of a specific withdrawal event /// @param _withdrawalEventId The id of the withdrawal event /// @return The withdrawal event details function getWithdrawalEventDetails(uint32 _withdrawalEventId) external view returns (WithdrawalStack.WithdrawalEvent memory); /// @notice Retrieve the amount of redeemed LsETH pending to be supplied with withdrawn ETH /// @return The amount of eth in the buffer function getBufferedExceedingEth() external view returns (uint256); /// @notice Retrieve the amount of LsETH waiting to be exited /// @return The amount of LsETH waiting to be exited function getRedeemDemand() external view returns (uint256); /// @notice Resolves the provided list of redeem request ids /// @dev The result is an array of equal length with ids or error code /// @dev -1 means that the request is not satisfied yet /// @dev -2 means that the request is out of bounds /// @dev -3 means that the request has already been claimed /// @dev This call was created to be called by an off-chain interface, the output could then be used to perform the claimRewards call in a regular transaction /// @param _redeemRequestIds The list of redeem requests to resolve /// @return withdrawalEventIds The list of withdrawal events matching every redeem request (or error codes) function resolveRedeemRequests(uint32[] calldata _redeemRequestIds) external view returns (int64[] memory withdrawalEventIds); /// @notice Creates a redeem request /// @param _lsETHAmount The amount of LsETH to redeem /// @param _recipient The recipient owning the redeem request /// @return redeemRequestId The id of the redeem request function requestRedeem(uint256 _lsETHAmount, address _recipient) external returns (uint32 redeemRequestId); /// @notice Creates a redeem request using msg.sender as recipient /// @param _lsETHAmount The amount of LsETH to redeem /// @return redeemRequestId The id of the redeem request function requestRedeem(uint256 _lsETHAmount) external returns (uint32 redeemRequestId); /// @notice Claims the rewards of the provided redeem request ids /// @param _redeemRequestIds The list of redeem requests to claim /// @param _withdrawalEventIds The list of withdrawal events to use for every redeem request claim /// @param _skipAlreadyClaimed True if the call should not revert on claiming of already claimed requests /// @param _depth The maximum recursive depth for the resolution of the redeem requests /// @return claimStatuses The list of claim statuses. 0 for fully claimed, 1 for partially claimed, 2 for skipped function claimRedeemRequests( uint32[] calldata _redeemRequestIds, uint32[] calldata _withdrawalEventIds, bool _skipAlreadyClaimed, uint16 _depth ) external returns (uint8[] memory claimStatuses); /// @notice Claims the rewards of the provided redeem request ids /// @param _redeemRequestIds The list of redeem requests to claim /// @param _withdrawalEventIds The list of withdrawal events to use for every redeem request claim /// @return claimStatuses The list of claim statuses. 0 for fully claimed, 1 for partially claimed, 2 for skipped function claimRedeemRequests(uint32[] calldata _redeemRequestIds, uint32[] calldata _withdrawalEventIds) external returns (uint8[] memory claimStatuses); /// @notice Reports a withdraw event from River /// @param _lsETHWithdrawable The amount of LsETH that can be redeemed due to this new withdraw event function reportWithdraw(uint256 _lsETHWithdrawable) external payable; /// @notice Pulls exceeding buffer eth /// @param _max The maximum amount that should be pulled function pullExceedingEth(uint256 _max) external; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../state/river/DailyCommittableLimits.sol"; import "./components/IConsensusLayerDepositManager.1.sol"; import "./components/IOracleManager.1.sol"; import "./components/ISharesManager.1.sol"; import "./components/IUserDepositManager.1.sol"; /// @title River Interface (v1) /// @author Kiln /// @notice The main system interface interface IRiverV1 is IConsensusLayerDepositManagerV1, IUserDepositManagerV1, ISharesManagerV1, IOracleManagerV1 { /// @notice Funds have been pulled from the Execution Layer Fee Recipient /// @param amount The amount pulled event PulledELFees(uint256 amount); /// @notice Funds have been pulled from the Coverage Fund /// @param amount The amount pulled event PulledCoverageFunds(uint256 amount); /// @notice Emitted when funds are pulled from the redeem manager /// @param amount The amount pulled event PulledRedeemManagerExceedingEth(uint256 amount); /// @notice Emitted when funds are pulled from the CL recipient /// @param pulledSkimmedEthAmount The amount of skimmed ETH pulled /// @param pullExitedEthAmount The amount of exited ETH pulled event PulledCLFunds(uint256 pulledSkimmedEthAmount, uint256 pullExitedEthAmount); /// @notice The stored Execution Layer Fee Recipient has been changed /// @param elFeeRecipient The new Execution Layer Fee Recipient event SetELFeeRecipient(address indexed elFeeRecipient); /// @notice The stored Coverage Fund has been changed /// @param coverageFund The new Coverage Fund event SetCoverageFund(address indexed coverageFund); /// @notice The stored Collector has been changed /// @param collector The new Collector event SetCollector(address indexed collector); /// @notice The stored Allowlist has been changed /// @param allowlist The new Allowlist event SetAllowlist(address indexed allowlist); /// @notice The stored Global Fee has been changed /// @param fee The new Global Fee event SetGlobalFee(uint256 fee); /// @notice The stored Operators Registry has been changed /// @param operatorRegistry The new Operators Registry event SetOperatorsRegistry(address indexed operatorRegistry); /// @notice The stored Metadata URI string has been changed /// @param metadataURI The new Metadata URI string event SetMetadataURI(string metadataURI); /// @notice The system underlying supply increased. This is a snapshot of the balances for accounting purposes /// @param _collector The address of the collector during this event /// @param _oldTotalUnderlyingBalance Old total ETH balance under management by River /// @param _oldTotalSupply Old total supply in shares /// @param _newTotalUnderlyingBalance New total ETH balance under management by River /// @param _newTotalSupply New total supply in shares event RewardsEarned( address indexed _collector, uint256 _oldTotalUnderlyingBalance, uint256 _oldTotalSupply, uint256 _newTotalUnderlyingBalance, uint256 _newTotalSupply ); /// @notice Emitted when the daily committable limits are changed /// @param minNetAmount The minimum amount that must be used as the daily committable amount /// @param maxRelativeAmount The maximum amount that can be used as the daily committable amount, relative to the total underlying supply event SetMaxDailyCommittableAmounts(uint256 minNetAmount, uint256 maxRelativeAmount); /// @notice Emitted when the redeem manager address is changed /// @param redeemManager The address of the redeem manager event SetRedeemManager(address redeemManager); /// @notice Emitted when the balance to deposit is updated /// @param oldAmount The old balance to deposit /// @param newAmount The new balance to deposit event SetBalanceToDeposit(uint256 oldAmount, uint256 newAmount); /// @notice Emitted when the balance to redeem is updated /// @param oldAmount The old balance to redeem /// @param newAmount The new balance to redeem event SetBalanceToRedeem(uint256 oldAmount, uint256 newAmount); /// @notice Emitted when the balance committed to deposit /// @param oldAmount The old balance committed to deposit /// @param newAmount The new balance committed to deposit event SetBalanceCommittedToDeposit(uint256 oldAmount, uint256 newAmount); /// @notice Emitted when the redeem manager received a withdraw event report /// @param redeemManagerDemand The total demand in LsETH of the redeem manager /// @param suppliedRedeemManagerDemand The amount of LsETH demand actually supplied /// @param suppliedRedeemManagerDemandInEth The amount in ETH of the supplied demand event ReportedRedeemManager( uint256 redeemManagerDemand, uint256 suppliedRedeemManagerDemand, uint256 suppliedRedeemManagerDemandInEth ); /// @notice Thrown when the amount received from the Withdraw contract doe not match the requested amount /// @param requested The amount that was requested /// @param received The amount that was received error InvalidPulledClFundsAmount(uint256 requested, uint256 received); /// @notice The computed amount of shares to mint is 0 error ZeroMintedShares(); /// @notice The access was denied /// @param account The account that was denied error Denied(address account); /// @notice Initializes the River system /// @param _depositContractAddress Address to make Consensus Layer deposits /// @param _elFeeRecipientAddress Address that receives the execution layer fees /// @param _withdrawalCredentials Credentials to use for every validator deposit /// @param _oracleAddress The address of the Oracle contract /// @param _systemAdministratorAddress Administrator address /// @param _allowlistAddress Address of the allowlist contract /// @param _operatorRegistryAddress Address of the operator registry /// @param _collectorAddress Address receiving the the global fee on revenue /// @param _globalFee Amount retained when the ETH balance increases and sent to the collector function initRiverV1( address _depositContractAddress, address _elFeeRecipientAddress, bytes32 _withdrawalCredentials, address _oracleAddress, address _systemAdministratorAddress, address _allowlistAddress, address _operatorRegistryAddress, address _collectorAddress, uint256 _globalFee ) external; /// @notice Initialized version 1.1 of the River System /// @param _redeemManager The redeem manager address /// @param _epochsPerFrame The amounts of epochs in a frame /// @param _slotsPerEpoch The slots inside an epoch /// @param _secondsPerSlot The seconds inside a slot /// @param _genesisTime The genesis timestamp /// @param _epochsToAssumedFinality The number of epochs before an epoch is considered final on-chain /// @param _annualAprUpperBound The reporting upper bound /// @param _relativeLowerBound The reporting lower bound /// @param _maxDailyNetCommittableAmount_ The net daily committable limit /// @param _maxDailyRelativeCommittableAmount_ The relative daily committable limit function initRiverV1_1( address _redeemManager, uint64 _epochsPerFrame, uint64 _slotsPerEpoch, uint64 _secondsPerSlot, uint64 _genesisTime, uint64 _epochsToAssumedFinality, uint256 _annualAprUpperBound, uint256 _relativeLowerBound, uint128 _maxDailyNetCommittableAmount_, uint128 _maxDailyRelativeCommittableAmount_ ) external; /// @notice Get the current global fee /// @return The global fee function getGlobalFee() external view returns (uint256); /// @notice Retrieve the allowlist address /// @return The allowlist address function getAllowlist() external view returns (address); /// @notice Retrieve the collector address /// @return The collector address function getCollector() external view returns (address); /// @notice Retrieve the execution layer fee recipient /// @return The execution layer fee recipient address function getELFeeRecipient() external view returns (address); /// @notice Retrieve the coverage fund /// @return The coverage fund address function getCoverageFund() external view returns (address); /// @notice Retrieve the redeem manager /// @return The redeem manager address function getRedeemManager() external view returns (address); /// @notice Retrieve the operators registry /// @return The operators registry address function getOperatorsRegistry() external view returns (address); /// @notice Retrieve the metadata uri string value /// @return The metadata uri string value function getMetadataURI() external view returns (string memory); /// @notice Retrieve the configured daily committable limits /// @return The daily committable limits structure function getDailyCommittableLimits() external view returns (DailyCommittableLimits.DailyCommittableLimitsStruct memory); /// @notice Resolves the provided redeem requests by calling the redeem manager /// @param _redeemRequestIds The list of redeem requests to resolve /// @return withdrawalEventIds The list of matching withdrawal events, or error codes function resolveRedeemRequests(uint32[] calldata _redeemRequestIds) external view returns (int64[] memory withdrawalEventIds); /// @notice Set the daily committable limits /// @param _dcl The Daily Committable Limits structure function setDailyCommittableLimits(DailyCommittableLimits.DailyCommittableLimitsStruct memory _dcl) external; /// @notice Retrieve the current balance to redeem /// @return The current balance to redeem function getBalanceToRedeem() external view returns (uint256); /// @notice Performs a redeem request on the redeem manager /// @param _lsETHAmount The amount of LsETH to redeem /// @param _recipient The address that will own the redeem request /// @return redeemRequestId The ID of the newly created redeem request function requestRedeem(uint256 _lsETHAmount, address _recipient) external returns (uint32 redeemRequestId); /// @notice Claims several redeem requests /// @param _redeemRequestIds The list of redeem requests to claim /// @param _withdrawalEventIds The list of resolved withdrawal event ids /// @return claimStatuses The operation status results function claimRedeemRequests(uint32[] calldata _redeemRequestIds, uint32[] calldata _withdrawalEventIds) external returns (uint8[] memory claimStatuses); /// @notice Changes the global fee parameter /// @param _newFee New fee value function setGlobalFee(uint256 _newFee) external; /// @notice Changes the allowlist address /// @param _newAllowlist New address for the allowlist function setAllowlist(address _newAllowlist) external; /// @notice Changes the collector address /// @param _newCollector New address for the collector function setCollector(address _newCollector) external; /// @notice Changes the execution layer fee recipient /// @param _newELFeeRecipient New address for the recipient function setELFeeRecipient(address _newELFeeRecipient) external; /// @notice Changes the coverage fund /// @param _newCoverageFund New address for the fund function setCoverageFund(address _newCoverageFund) external; /// @notice Sets the metadata uri string value /// @param _metadataURI The new metadata uri string value function setMetadataURI(string memory _metadataURI) external; /// @notice Input for execution layer fee earnings function sendELFees() external payable; /// @notice Input for consensus layer funds, containing both exit and skimming function sendCLFunds() external payable; /// @notice Input for coverage funds function sendCoverageFunds() external payable; /// @notice Input for the redeem manager funds function sendRedeemManagerExceedingFunds() external payable; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Withdraw Interface (V1) /// @author Kiln /// @notice This contract is in charge of holding the exit and skimming funds and allow river to pull these funds interface IWithdrawV1 { /// @notice Emitted when the linked River address is changed /// @param river The new River address event SetRiver(address river); /// @param _river The address of the River contract function initializeWithdrawV1(address _river) external; /// @notice Retrieve the withdrawal credentials to use /// @return The withdrawal credentials function getCredentials() external view returns (bytes32); /// @notice Retrieve the linked River address /// @return The River address function getRiver() external view returns (address); /// @notice Callable by River, sends the specified amount of ETH to River /// @param _amount The amount to pull function pullEth(uint256 _amount) external; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Consensys Layer Deposit Manager Interface (v1) /// @author Kiln /// @notice This interface exposes methods to handle the interactions with the official deposit contract interface IConsensusLayerDepositManagerV1 { /// @notice The stored deposit contract address changed /// @param depositContract Address of the deposit contract event SetDepositContractAddress(address indexed depositContract); /// @notice The stored withdrawal credentials changed /// @param withdrawalCredentials The withdrawal credentials to use for deposits event SetWithdrawalCredentials(bytes32 withdrawalCredentials); /// @notice Emitted when the deposited validator count is updated /// @param oldDepositedValidatorCount The old deposited validator count value /// @param newDepositedValidatorCount The new deposited validator count value event SetDepositedValidatorCount(uint256 oldDepositedValidatorCount, uint256 newDepositedValidatorCount); /// @notice Not enough funds to deposit one validator error NotEnoughFunds(); /// @notice The length of the BLS Public key is invalid during deposit error InconsistentPublicKeys(); /// @notice The length of the BLS Signature is invalid during deposit error InconsistentSignatures(); /// @notice The internal key retrieval returned no keys error NoAvailableValidatorKeys(); /// @notice The received count of public keys to deposit is invalid error InvalidPublicKeyCount(); /// @notice The received count of signatures to deposit is invalid error InvalidSignatureCount(); /// @notice The withdrawal credentials value is null error InvalidWithdrawalCredentials(); /// @notice An error occured during the deposit error ErrorOnDeposit(); /// @notice Returns the amount of ETH not yet committed for deposit /// @return The amount of ETH not yet committed for deposit function getBalanceToDeposit() external view returns (uint256); /// @notice Returns the amount of ETH committed for deposit /// @return The amount of ETH committed for deposit function getCommittedBalance() external view returns (uint256); /// @notice Retrieve the withdrawal credentials /// @return The withdrawal credentials function getWithdrawalCredentials() external view returns (bytes32); /// @notice Get the deposited validator count (the count of deposits made by the contract) /// @return The deposited validator count function getDepositedValidatorCount() external view returns (uint256); /// @notice Deposits current balance to the Consensus Layer by batches of 32 ETH /// @param _maxCount The maximum amount of validator keys to fund function depositToConsensusLayer(uint256 _maxCount) external; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../state/river/CLSpec.sol"; import "../../state/river/ReportBounds.sol"; /// @title Oracle Manager (v1) /// @author Kiln /// @notice This interface exposes methods to handle the inputs provided by the oracle interface IOracleManagerV1 { /// @notice The stored oracle address changed /// @param oracleAddress The new oracle address event SetOracle(address indexed oracleAddress); /// @notice The consensus layer data provided by the oracle has been updated /// @param validatorCount The new count of validators running on the consensus layer /// @param validatorTotalBalance The new total balance sum of all validators /// @param roundId Round identifier event ConsensusLayerDataUpdate(uint256 validatorCount, uint256 validatorTotalBalance, bytes32 roundId); /// @notice The Consensus Layer Spec is changed /// @param epochsPerFrame The number of epochs inside a frame /// @param slotsPerEpoch The number of slots inside an epoch /// @param secondsPerSlot The number of seconds inside a slot /// @param genesisTime The genesis timestamp /// @param epochsToAssumedFinality The number of epochs before an epoch is considered final event SetSpec( uint64 epochsPerFrame, uint64 slotsPerEpoch, uint64 secondsPerSlot, uint64 genesisTime, uint64 epochsToAssumedFinality ); /// @notice The Report Bounds are changed /// @param annualAprUpperBound The reporting upper bound /// @param relativeLowerBound The reporting lower bound event SetBounds(uint256 annualAprUpperBound, uint256 relativeLowerBound); /// @notice The provided report has beend processed /// @param report The report that was provided /// @param trace The trace structure providing more insights on internals event ProcessedConsensusLayerReport( IOracleManagerV1.ConsensusLayerReport report, ConsensusLayerDataReportingTrace trace ); /// @notice The reported validator count is invalid /// @param providedValidatorCount The received validator count value /// @param depositedValidatorCount The number of deposits performed by the system /// @param lastReportedValidatorCount The last reported validator count error InvalidValidatorCountReport( uint256 providedValidatorCount, uint256 depositedValidatorCount, uint256 lastReportedValidatorCount ); /// @notice Thrown when an invalid epoch was reported /// @param epoch Invalid epoch error InvalidEpoch(uint256 epoch); /// @notice The balance increase is higher than the maximum allowed by the upper bound /// @param prevTotalEthIncludingExited The previous total balance, including all exited balance /// @param postTotalEthIncludingExited The post-report total balance, including all exited balance /// @param timeElapsed The time in seconds since last report /// @param annualAprUpperBound The upper bound value that was used error TotalValidatorBalanceIncreaseOutOfBound( uint256 prevTotalEthIncludingExited, uint256 postTotalEthIncludingExited, uint256 timeElapsed, uint256 annualAprUpperBound ); /// @notice The balance decrease is higher than the maximum allowed by the lower bound /// @param prevTotalEthIncludingExited The previous total balance, including all exited balance /// @param postTotalEthIncludingExited The post-report total balance, including all exited balance /// @param timeElapsed The time in seconds since last report /// @param relativeLowerBound The lower bound value that was used error TotalValidatorBalanceDecreaseOutOfBound( uint256 prevTotalEthIncludingExited, uint256 postTotalEthIncludingExited, uint256 timeElapsed, uint256 relativeLowerBound ); /// @notice The total exited balance decreased /// @param currentValidatorsExitedBalance The current exited balance /// @param newValidatorsExitedBalance The new exited balance error InvalidDecreasingValidatorsExitedBalance( uint256 currentValidatorsExitedBalance, uint256 newValidatorsExitedBalance ); /// @notice The total skimmed balance decreased /// @param currentValidatorsSkimmedBalance The current exited balance /// @param newValidatorsSkimmedBalance The new exited balance error InvalidDecreasingValidatorsSkimmedBalance( uint256 currentValidatorsSkimmedBalance, uint256 newValidatorsSkimmedBalance ); /// @notice Trace structure emitted via logs during reporting struct ConsensusLayerDataReportingTrace { uint256 rewards; uint256 pulledELFees; uint256 pulledRedeemManagerExceedingEthBuffer; uint256 pulledCoverageFunds; } /// @notice The format of the oracle report struct ConsensusLayerReport { // this is the epoch at which the report was performed // data should be fetched up to the state of this epoch by the oracles uint256 epoch; // the sum of all the validator balances on the consensus layer // when a validator enters the exit queue, the validator is considered stopped, its balance is accounted in both validatorsExitingBalance and validatorsBalance // when a validator leaves the exit queue and the funds are sweeped onto the execution layer, the balance is only accounted in validatorsExitedBalance and not in validatorsBalance // this value can decrease between reports uint256 validatorsBalance; // the sum of all the skimmings performed on the validators // these values can be found in the execution layer block bodies under the withdrawals field // a withdrawal is considered skimming if // - the epoch at which it happened is < validator.withdrawableEpoch // - the epoch at which it happened is >= validator.withdrawableEpoch and in that case we only account for what would be above 32 eth as skimming // this value cannot decrease over reports uint256 validatorsSkimmedBalance; // the sum of all the exits performed on the validators // these values can be found in the execution layer block bodies under the withdrawals field // a withdrawal is considered exit if // - the epoch at which it happened is >= validator.withdrawableEpoch and in that case we only account for what would be <= 32 eth as exit // this value cannot decrease over reports uint256 validatorsExitedBalance; // the sum of all the exiting balance, which is all the validators on their way to get sweeped and exited // this includes voluntary exits and slashings // this value can decrease between reports uint256 validatorsExitingBalance; // the count of activated validators // even validators that are exited are still accounted // this value cannot decrease over reports uint32 validatorsCount; // an array containing the count of stopped validators per operator // the first element of the array is the sum of all stopped validators // then index 1 would be operator 0 // these values cannot decrease over reports uint32[] stoppedValidatorCountPerOperator; // flag enabled by the oracles when the buffer rebalancing is activated // the activation logic is written in the oracle specification and all oracle members must agree on the activation // when active, the eth in the deposit buffer can be used to pay for exits in the redeem manager bool rebalanceDepositToRedeemMode; // flag enabled by the oracles when the slashing containment is activated // the activation logic is written in the oracle specification and all oracle members must agree on the activation // This flag is activated when a pre-defined threshold of slashed validators in our set of validators is reached // This flag is deactivated when a bottom threshold is met, this means that when we reach the upper threshold and activate the flag, we will deactivate it when we reach the bottom threshold and not before // when active, no more validator exits can be requested by the protocol bool slashingContainmentMode; } /// @notice The format of the oracle report in storage /// @notice These fields have the exact same function as the ones in ConsensusLayerReport, but this struct is optimized for storage struct StoredConsensusLayerReport { uint256 epoch; uint256 validatorsBalance; uint256 validatorsSkimmedBalance; uint256 validatorsExitedBalance; uint256 validatorsExitingBalance; uint32 validatorsCount; bool rebalanceDepositToRedeemMode; bool slashingContainmentMode; } /// @notice Get oracle address /// @return The oracle address function getOracle() external view returns (address); /// @notice Get CL validator total balance /// @return The CL Validator total balance function getCLValidatorTotalBalance() external view returns (uint256); /// @notice Get CL validator count (the amount of validator reported by the oracles) /// @return The CL validator count function getCLValidatorCount() external view returns (uint256); /// @notice Verifies if the provided epoch is valid /// @param epoch The epoch to lookup /// @return True if valid function isValidEpoch(uint256 epoch) external view returns (bool); /// @notice Retrieve the block timestamp /// @return The current timestamp from the EVM context function getTime() external view returns (uint256); /// @notice Retrieve expected epoch id /// @return The current expected epoch id function getExpectedEpochId() external view returns (uint256); /// @notice Retrieve the last completed epoch id /// @return The last completed epoch id function getLastCompletedEpochId() external view returns (uint256); /// @notice Retrieve the current epoch id based on block timestamp /// @return The current epoch id function getCurrentEpochId() external view returns (uint256); /// @notice Retrieve the current cl spec /// @return The Consensus Layer Specification function getCLSpec() external view returns (CLSpec.CLSpecStruct memory); /// @notice Retrieve the current frame details /// @return _startEpochId The epoch at the beginning of the frame /// @return _startTime The timestamp of the beginning of the frame in seconds /// @return _endTime The timestamp of the end of the frame in seconds function getCurrentFrame() external view returns (uint256 _startEpochId, uint256 _startTime, uint256 _endTime); /// @notice Retrieve the first epoch id of the frame of the provided epoch id /// @param _epochId Epoch id used to get the frame /// @return The first epoch id of the frame containing the given epoch id function getFrameFirstEpochId(uint256 _epochId) external view returns (uint256); /// @notice Retrieve the report bounds /// @return The report bounds function getReportBounds() external view returns (ReportBounds.ReportBoundsStruct memory); /// @notice Retrieve the last consensus layer report /// @return The stored consensus layer report function getLastConsensusLayerReport() external view returns (IOracleManagerV1.StoredConsensusLayerReport memory); /// @notice Set the oracle address /// @param _oracleAddress Address of the oracle function setOracle(address _oracleAddress) external; /// @notice Set the consensus layer spec /// @param _newValue The new consensus layer spec value function setCLSpec(CLSpec.CLSpecStruct calldata _newValue) external; /// @notice Set the report bounds /// @param _newValue The new report bounds value function setReportBounds(ReportBounds.ReportBoundsStruct calldata _newValue) external; /// @notice Performs all the reporting logics /// @param _report The consensus layer report structure function setConsensusLayerData(ConsensusLayerReport calldata _report) external; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; /// @title Shares Manager Interface (v1) /// @author Kiln /// @notice This interface exposes methods to handle the shares of the depositor and the ERC20 interface interface ISharesManagerV1 is IERC20 { /// @notice Emitted when the total supply is changed event SetTotalSupply(uint256 totalSupply); /// @notice Balance too low to perform operation error BalanceTooLow(); /// @notice Allowance too low to perform operation /// @param _from Account where funds are sent from /// @param _operator Account attempting the transfer /// @param _allowance Current allowance /// @param _value Requested transfer value in shares error AllowanceTooLow(address _from, address _operator, uint256 _allowance, uint256 _value); /// @notice Invalid empty transfer error NullTransfer(); /// @notice Invalid transfer recipients /// @param _from Account sending the funds in the invalid transfer /// @param _to Account receiving the funds in the invalid transfer error UnauthorizedTransfer(address _from, address _to); /// @notice Retrieve the token name /// @return The token name function name() external pure returns (string memory); /// @notice Retrieve the token symbol /// @return The token symbol function symbol() external pure returns (string memory); /// @notice Retrieve the decimal count /// @return The decimal count function decimals() external pure returns (uint8); /// @notice Retrieve the total token supply /// @return The total supply in shares function totalSupply() external view returns (uint256); /// @notice Retrieve the total underlying asset supply /// @return The total underlying asset supply function totalUnderlyingSupply() external view returns (uint256); /// @notice Retrieve the balance of an account /// @param _owner Address to be checked /// @return The balance of the account in shares function balanceOf(address _owner) external view returns (uint256); /// @notice Retrieve the underlying asset balance of an account /// @param _owner Address to be checked /// @return The underlying balance of the account function balanceOfUnderlying(address _owner) external view returns (uint256); /// @notice Retrieve the underlying asset balance from an amount of shares /// @param _shares Amount of shares to convert /// @return The underlying asset balance represented by the shares function underlyingBalanceFromShares(uint256 _shares) external view returns (uint256); /// @notice Retrieve the shares count from an underlying asset amount /// @param _underlyingAssetAmount Amount of underlying asset to convert /// @return The amount of shares worth the underlying asset amopunt function sharesFromUnderlyingBalance(uint256 _underlyingAssetAmount) external view returns (uint256); /// @notice Retrieve the allowance value for a spender /// @param _owner Address that issued the allowance /// @param _spender Address that received the allowance /// @return The allowance in shares for a given spender function allowance(address _owner, address _spender) external view returns (uint256); /// @notice Performs a transfer from the message sender to the provided account /// @param _to Address receiving the tokens /// @param _value Amount of shares to be sent /// @return True if success function transfer(address _to, uint256 _value) external returns (bool); /// @notice Performs a transfer between two recipients /// @param _from Address sending the tokens /// @param _to Address receiving the tokens /// @param _value Amount of shares to be sent /// @return True if success function transferFrom(address _from, address _to, uint256 _value) external returns (bool); /// @notice Approves an account for future spendings /// @dev An approved account can use transferFrom to transfer funds on behalf of the token owner /// @param _spender Address that is allowed to spend the tokens /// @param _value The allowed amount in shares, will override previous value /// @return True if success function approve(address _spender, uint256 _value) external returns (bool); /// @notice Increase allowance to another account /// @param _spender Spender that receives the allowance /// @param _additionalValue Amount of shares to add /// @return True if success function increaseAllowance(address _spender, uint256 _additionalValue) external returns (bool); /// @notice Decrease allowance to another account /// @param _spender Spender that receives the allowance /// @param _subtractableValue Amount of shares to subtract /// @return True if success function decreaseAllowance(address _spender, uint256 _subtractableValue) external returns (bool); }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title User Deposit Manager (v1) /// @author Kiln /// @notice This interface exposes methods to handle the inbound transfers cases or the explicit submissions interface IUserDepositManagerV1 { /// @notice User deposited ETH in the system /// @param depositor Address performing the deposit /// @param recipient Address receiving the minted shares /// @param amount Amount in ETH deposited event UserDeposit(address indexed depositor, address indexed recipient, uint256 amount); /// @notice And empty deposit attempt was made error EmptyDeposit(); /// @notice Explicit deposit method to mint on msg.sender function deposit() external payable; /// @notice Explicit deposit method to mint on msg.sender and transfer to _recipient /// @param _recipient Address receiving the minted LsETH function depositAndTransfer(address _recipient) external payable; /// @notice Implicit deposit method, when the user performs a regular transfer to the contract receive() external payable; /// @notice Invalid call, when the user sends a transaction with a data payload but no method matched fallback() external payable; }
//SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "../state/shared/AdministratorAddress.sol"; import "../state/shared/PendingAdministratorAddress.sol"; /// @title Lib Administrable /// @author Kiln /// @notice This library handles the admin and pending admin storage vars library LibAdministrable { /// @notice Retrieve the system admin /// @return The address of the system admin function _getAdmin() internal view returns (address) { return AdministratorAddress.get(); } /// @notice Retrieve the pending system admin /// @return The adress of the pending system admin function _getPendingAdmin() internal view returns (address) { return PendingAdministratorAddress.get(); } /// @notice Sets the system admin /// @param _admin New system admin function _setAdmin(address _admin) internal { AdministratorAddress.set(_admin); } /// @notice Sets the pending system admin /// @param _pendingAdmin New pending system admin function _setPendingAdmin(address _pendingAdmin) internal { PendingAdministratorAddress.set(_pendingAdmin); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Lib Allowlist Masks /// @notice Holds all the mask values library LibAllowlistMasks { /// @notice Mask used for denied accounts uint256 internal constant DENY_MASK = 0x1 << 255; /// @notice The mask for the deposit right uint256 internal constant DEPOSIT_MASK = 0x1; /// @notice The mask for the donation right uint256 internal constant DONATE_MASK = 0x1 << 1; /// @notice The mask for the redeem right uint256 internal constant REDEEM_MASK = 0x1 << 2; }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Lib Basis Points /// @notice Holds the basis points max value library LibBasisPoints { /// @notice The max value for basis points (represents 100%) uint256 internal constant BASIS_POINTS_MAX = 10_000; }
//SPDX-License-Identifier: MIT pragma solidity 0.8.10; /// @title Lib Bytes /// @notice This library helps manipulating bytes library LibBytes { /// @notice The length overflows an uint error SliceOverflow(); /// @notice The slice is outside of the initial bytes bounds error SliceOutOfBounds(); /// @notice Slices the provided bytes /// @param _bytes Bytes to slice /// @param _start The starting index of the slice /// @param _length The length of the slice /// @return The slice of _bytes starting at _start of length _length function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) { unchecked { if (_length + 31 < _length) { revert SliceOverflow(); } } if (_bytes.length < _start + _length) { revert SliceOutOfBounds(); } bytes memory tempBytes; // solhint-disable-next-line no-inline-assembly assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.10; /// @title Lib Errors /// @notice Library of common errors library LibErrors { /// @notice The operator is unauthorized for the caller /// @param caller Address performing the call error Unauthorized(address caller); /// @notice The call was invalid error InvalidCall(); /// @notice The argument was invalid error InvalidArgument(); /// @notice The address is zero error InvalidZeroAddress(); /// @notice The string is empty error InvalidEmptyString(); /// @notice The fee is invalid error InvalidFee(); }
//SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "./LibErrors.sol"; import "./LibBasisPoints.sol"; /// @title Lib Sanitize /// @notice Utilities to sanitize input values library LibSanitize { /// @notice Reverts if address is 0 /// @param _address Address to check function _notZeroAddress(address _address) internal pure { if (_address == address(0)) { revert LibErrors.InvalidZeroAddress(); } } /// @notice Reverts if string is empty /// @param _string String to check function _notEmptyString(string memory _string) internal pure { if (bytes(_string).length == 0) { revert LibErrors.InvalidEmptyString(); } } /// @notice Reverts if fee is invalid /// @param _fee Fee to check function _validFee(uint256 _fee) internal pure { if (_fee > LibBasisPoints.BASIS_POINTS_MAX) { revert LibErrors.InvalidFee(); } } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.10; /// @title Lib Uint256 /// @notice Utilities to perform uint operations library LibUint256 { /// @notice Converts a value to little endian (64 bits) /// @param _value The value to convert /// @return result The converted value function toLittleEndian64(uint256 _value) internal pure returns (uint256 result) { result = 0; uint256 tempValue = _value; result = tempValue & 0xFF; tempValue >>= 8; result = (result << 8) | (tempValue & 0xFF); tempValue >>= 8; result = (result << 8) | (tempValue & 0xFF); tempValue >>= 8; result = (result << 8) | (tempValue & 0xFF); tempValue >>= 8; result = (result << 8) | (tempValue & 0xFF); tempValue >>= 8; result = (result << 8) | (tempValue & 0xFF); tempValue >>= 8; result = (result << 8) | (tempValue & 0xFF); tempValue >>= 8; result = (result << 8) | (tempValue & 0xFF); tempValue >>= 8; assert(0 == tempValue); // fully converted result <<= (24 * 8); } /// @notice Returns the minimum value /// @param _a First value /// @param _b Second value /// @return Smallest value between _a and _b function min(uint256 _a, uint256 _b) internal pure returns (uint256) { return (_a > _b ? _b : _a); } /// @notice Returns the max value /// @param _a First value /// @param _b Second value /// @return Highest value between _a and _b function max(uint256 _a, uint256 _b) internal pure returns (uint256) { return (_a < _b ? _b : _a); } /// @notice Performs a ceiled division /// @param _a Numerator /// @param _b Denominator /// @return ceil(_a / _b) function ceil(uint256 _a, uint256 _b) internal pure returns (uint256) { return (_a / _b) + (_a % _b > 0 ? 1 : 0); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; /// @title Lib Unstructured Storage /// @notice Utilities to work with unstructured storage library LibUnstructuredStorage { /// @notice Retrieve a bool value at a storage slot /// @param _position The storage slot to retrieve /// @return data The bool value function getStorageBool(bytes32 _position) internal view returns (bool data) { // solhint-disable-next-line no-inline-assembly assembly { data := sload(_position) } } /// @notice Retrieve an address value at a storage slot /// @param _position The storage slot to retrieve /// @return data The address value function getStorageAddress(bytes32 _position) internal view returns (address data) { // solhint-disable-next-line no-inline-assembly assembly { data := sload(_position) } } /// @notice Retrieve a bytes32 value at a storage slot /// @param _position The storage slot to retrieve /// @return data The bytes32 value function getStorageBytes32(bytes32 _position) internal view returns (bytes32 data) { // solhint-disable-next-line no-inline-assembly assembly { data := sload(_position) } } /// @notice Retrieve an uint256 value at a storage slot /// @param _position The storage slot to retrieve /// @return data The uint256 value function getStorageUint256(bytes32 _position) internal view returns (uint256 data) { // solhint-disable-next-line no-inline-assembly assembly { data := sload(_position) } } /// @notice Sets a bool value at a storage slot /// @param _position The storage slot to set /// @param _data The bool value to set function setStorageBool(bytes32 _position, bool _data) internal { // solhint-disable-next-line no-inline-assembly assembly { sstore(_position, _data) } } /// @notice Sets an address value at a storage slot /// @param _position The storage slot to set /// @param _data The address value to set function setStorageAddress(bytes32 _position, address _data) internal { // solhint-disable-next-line no-inline-assembly assembly { sstore(_position, _data) } } /// @notice Sets a bytes32 value at a storage slot /// @param _position The storage slot to set /// @param _data The bytes32 value to set function setStorageBytes32(bytes32 _position, bytes32 _data) internal { // solhint-disable-next-line no-inline-assembly assembly { sstore(_position, _data) } } /// @notice Sets an uint256 value at a storage slot /// @param _position The storage slot to set /// @param _data The uint256 value to set function setStorageUint256(bytes32 _position, uint256 _data) internal { // solhint-disable-next-line no-inline-assembly assembly { sstore(_position, _data) } } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibSanitize.sol"; /// @title Operators Storage /// @notice Utility to manage the Operators in storage library OperatorsV2 { /// @notice Storage slot of the Operators bytes32 internal constant OPERATORS_SLOT = bytes32(uint256(keccak256("river.state.v2.operators")) - 1); /// @notice The Operator structure in storage struct Operator { /// @dev The following values respect this invariant: /// @dev keys >= limit >= funded >= RequestedExits /// @custom:attribute Staking limit of the operator uint32 limit; /// @custom:attribute The count of funded validators uint32 funded; /// @custom:attribute The count of exit requests made to this operator uint32 requestedExits; /// @custom:attribute The total count of keys of the operator uint32 keys; /// @custom attribute The block at which the last edit happened in the operator details uint64 latestKeysEditBlockNumber; /// @custom:attribute True if the operator is active and allowed to operate on River bool active; /// @custom:attribute Display name of the operator string name; /// @custom:attribute Address of the operator address operator; } /// @notice The Operator structure when loaded in memory struct CachedOperator { /// @custom:attribute Staking limit of the operator uint32 limit; /// @custom:attribute The count of funded validators uint32 funded; /// @custom:attribute The count of exit requests made to this operator uint32 requestedExits; /// @custom:attribute The original index of the operator uint32 index; /// @custom:attribute The amount of picked keys, buffer used before changing funded in storage uint32 picked; } /// @notice The Operator structure when loaded in memory for the exit selection struct CachedExitableOperator { /// @custom:attribute The count of funded validators uint32 funded; /// @custom:attribute The count of exit requests made to this operator uint32 requestedExits; /// @custom:attribute The original index of the operator uint32 index; /// @custom:attribute The amount of picked keys, buffer used before changing funded in storage uint32 picked; } /// @notice The structure at the storage slot struct SlotOperator { /// @custom:attribute Array containing all the operators Operator[] value; } /// @notice The operator was not found /// @param index The provided index error OperatorNotFound(uint256 index); /// @notice Retrieve the operator in storage /// @param _index The index of the operator /// @return The Operator structure function get(uint256 _index) internal view returns (Operator storage) { bytes32 slot = OPERATORS_SLOT; SlotOperator storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } if (r.value.length <= _index) { revert OperatorNotFound(_index); } return r.value[_index]; } /// @notice Retrieve the operators in storage /// @return The Operator structure array function getAll() internal view returns (Operator[] storage) { bytes32 slot = OPERATORS_SLOT; SlotOperator storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value; } /// @notice Retrieve the operator count in storage /// @return The count of operators in storage function getCount() internal view returns (uint256) { bytes32 slot = OPERATORS_SLOT; SlotOperator storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value.length; } /// @notice Retrieve all the active operators /// @return The list of active operator structures function getAllActive() internal view returns (Operator[] memory) { bytes32 slot = OPERATORS_SLOT; SlotOperator storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } uint256 activeCount = 0; uint256 operatorCount = r.value.length; for (uint256 idx = 0; idx < operatorCount;) { if (r.value[idx].active) { unchecked { ++activeCount; } } unchecked { ++idx; } } Operator[] memory activeOperators = new Operator[](activeCount); uint256 activeIdx = 0; for (uint256 idx = 0; idx < operatorCount;) { if (r.value[idx].active) { activeOperators[activeIdx] = r.value[idx]; unchecked { ++activeIdx; } } unchecked { ++idx; } } return activeOperators; } /// @notice Retrieve the stopped validator count for an operator by its index /// @param stoppedValidatorCounts The storage pointer to the raw array containing the stopped validator counts /// @param index The index of the operator to lookup /// @return The amount of stopped validators for the given operator index function _getStoppedValidatorCountAtIndex(uint32[] storage stoppedValidatorCounts, uint256 index) internal view returns (uint32) { if (index + 1 >= stoppedValidatorCounts.length) { return 0; } return stoppedValidatorCounts[index + 1]; } /// @notice Retrieve all the active and fundable operators /// @dev This method will return a memory array of length equal to the number of operator, but only /// @dev populated up to the fundable operator count, also returned by the method /// @return The list of active and fundable operators /// @return The count of active and fundable operators function getAllFundable() internal view returns (CachedOperator[] memory, uint256) { bytes32 slot = OPERATORS_SLOT; SlotOperator storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } uint256 fundableCount = 0; uint256 operatorCount = r.value.length; CachedOperator[] memory fundableOperators = new CachedOperator[](operatorCount); uint32[] storage stoppedValidatorCounts = getStoppedValidators(); for (uint256 idx = 0; idx < operatorCount;) { if ( _hasFundableKeys(r.value[idx]) && _getStoppedValidatorCountAtIndex(stoppedValidatorCounts, idx) >= r.value[idx].requestedExits ) { Operator storage op = r.value[idx]; fundableOperators[fundableCount] = CachedOperator({ limit: op.limit, funded: op.funded, requestedExits: op.requestedExits, index: uint32(idx), picked: 0 }); unchecked { ++fundableCount; } } unchecked { ++idx; } } return (fundableOperators, fundableCount); } /// @notice Retrieve all the active and exitable operators /// @dev This method will return a memory array of length equal to the number of operator, but only /// @dev populated up to the exitable operator count, also returned by the method /// @return The list of active and exitable operators /// @return The count of active and exitable operators function getAllExitable() internal view returns (CachedExitableOperator[] memory, uint256) { bytes32 slot = OPERATORS_SLOT; SlotOperator storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } uint256 exitableCount = 0; uint256 operatorCount = r.value.length; CachedExitableOperator[] memory exitableOperators = new CachedExitableOperator[](operatorCount); for (uint256 idx = 0; idx < operatorCount;) { if (_hasExitableKeys(r.value[idx])) { Operator storage op = r.value[idx]; exitableOperators[exitableCount] = CachedExitableOperator({ funded: op.funded, requestedExits: op.requestedExits, index: uint32(idx), picked: 0 }); unchecked { ++exitableCount; } } unchecked { ++idx; } } return (exitableOperators, exitableCount); } /// @notice Add a new operator in storage /// @param _newOperator Value of the new operator /// @return The size of the operator array after the operation function push(Operator memory _newOperator) internal returns (uint256) { LibSanitize._notZeroAddress(_newOperator.operator); LibSanitize._notEmptyString(_newOperator.name); bytes32 slot = OPERATORS_SLOT; SlotOperator storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } r.value.push(_newOperator); return r.value.length; } /// @notice Atomic operation to set the key count and update the latestKeysEditBlockNumber field at the same time /// @param _index The operator index /// @param _newKeys The new value for the key count function setKeys(uint256 _index, uint32 _newKeys) internal { Operator storage op = get(_index); op.keys = _newKeys; op.latestKeysEditBlockNumber = uint64(block.number); } /// @notice Checks if an operator is active and has fundable keys /// @param _operator The operator details /// @return True if active and fundable function _hasFundableKeys(OperatorsV2.Operator memory _operator) internal pure returns (bool) { return (_operator.active && _operator.limit > _operator.funded); } /// @notice Checks if an operator is active and has exitable keys /// @param _operator The operator details /// @return True if active and exitable function _hasExitableKeys(OperatorsV2.Operator memory _operator) internal pure returns (bool) { return (_operator.active && _operator.funded > _operator.requestedExits); } /// @notice Storage slot of the Stopped Validators bytes32 internal constant STOPPED_VALIDATORS_SLOT = bytes32(uint256(keccak256("river.state.stoppedValidators")) - 1); struct SlotStoppedValidators { uint32[] value; } /// @notice Retrieve the storage pointer of the Stopped Validators array /// @return The Stopped Validators storage pointer function getStoppedValidators() internal view returns (uint32[] storage) { bytes32 slot = STOPPED_VALIDATORS_SLOT; SlotStoppedValidators storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value; } /// @notice Sets the entire stopped validators array /// @param value The new stopped validators array function setRawStoppedValidators(uint32[] memory value) internal { bytes32 slot = STOPPED_VALIDATORS_SLOT; SlotStoppedValidators storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } r.value = value; } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Redeem Manager Redeem Queue storage /// @notice Utility to manage the Redeem Queue in the Redeem Manager library RedeemQueue { /// @notice Storage slot of the Redeem Queue bytes32 internal constant REDEEM_QUEUE_ID_SLOT = bytes32(uint256(keccak256("river.state.redeemQueue")) - 1); /// @notice The Redeemer structure represents the redeem request made by a user struct RedeemRequest { /// @custom:attribute The amount of the redeem request in LsETH uint256 amount; /// @custom:attribute The maximum amount of ETH redeemable by this request uint256 maxRedeemableEth; /// @custom:attribute The owner of the redeem request address owner; /// @custom:attribute The height is the cumulative sum of all the sizes of preceding redeem requests uint256 height; } /// @notice Retrieve the Redeem Queue array storage pointer /// @return data The Redeem Queue array storage pointer function get() internal pure returns (RedeemRequest[] storage data) { bytes32 position = REDEEM_QUEUE_ID_SLOT; assembly { data.slot := position } } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Redeem Manager Withdrawal Stack storage /// @notice Utility to manage the Withdrawal Stack in the Redeem Manager library WithdrawalStack { /// @notice Storage slot of the Withdrawal Stack bytes32 internal constant WITHDRAWAL_STACK_ID_SLOT = bytes32(uint256(keccak256("river.state.withdrawalStack")) - 1); /// @notice The Redeemer structure represents the withdrawal events made by River struct WithdrawalEvent { /// @custom:attribute The amount of the withdrawal event in LsETH uint256 amount; /// @custom:attribute The amount of the withdrawal event in ETH uint256 withdrawnEth; /// @custom:attribute The height is the cumulative sum of all the sizes of preceding withdrawal events uint256 height; } /// @notice Retrieve the Withdrawal Stack array storage pointer /// @return data The Withdrawal Stack array storage pointer function get() internal pure returns (WithdrawalEvent[] storage data) { bytes32 position = WITHDRAWAL_STACK_ID_SLOT; assembly { data.slot := position } } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; import "../../libraries/LibSanitize.sol"; /// @title Allowlist Address Storage /// @notice Utility to manage the Allowlist Address in storage library AllowlistAddress { /// @notice Storage slot of the Allowlist Address bytes32 internal constant ALLOWLIST_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.allowlistAddress")) - 1); /// @notice Retrieve the Allowlist Address /// @return The Allowlist Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(ALLOWLIST_ADDRESS_SLOT); } /// @notice Sets the Allowlist Address /// @param _newValue New Allowlist Address function set(address _newValue) internal { LibSanitize._notZeroAddress(_newValue); LibUnstructuredStorage.setStorageAddress(ALLOWLIST_ADDRESS_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; library BalanceToDeposit { bytes32 internal constant BALANCE_TO_DEPOSIT_SLOT = bytes32(uint256(keccak256("river.state.balanceToDeposit")) - 1); function get() internal view returns (uint256) { return LibUnstructuredStorage.getStorageUint256(BALANCE_TO_DEPOSIT_SLOT); } function set(uint256 newValue) internal { LibUnstructuredStorage.setStorageUint256(BALANCE_TO_DEPOSIT_SLOT, newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; library BalanceToRedeem { bytes32 internal constant BALANCE_TO_REDEEM_SLOT = bytes32(uint256(keccak256("river.state.balanceToRedeem")) - 1); function get() internal view returns (uint256) { return LibUnstructuredStorage.getStorageUint256(BALANCE_TO_REDEEM_SLOT); } function set(uint256 newValue) internal { LibUnstructuredStorage.setStorageUint256(BALANCE_TO_REDEEM_SLOT, newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Consensus Layer Spec Storage /// @notice Utility to manage the Consensus Layer Spec in storage library CLSpec { /// @notice Storage slot of the Consensus Layer Spec bytes32 internal constant CL_SPEC_SLOT = bytes32(uint256(keccak256("river.state.clSpec")) - 1); /// @notice The Consensus Layer Spec structure struct CLSpecStruct { /// @custom:attribute The count of epochs per frame, 225 means 24h uint64 epochsPerFrame; /// @custom:attribute The count of slots in an epoch (32 on mainnet) uint64 slotsPerEpoch; /// @custom:attribute The seconds in a slot (12 on mainnet) uint64 secondsPerSlot; /// @custom:attribute The block timestamp of the first consensus layer block uint64 genesisTime; /// @custom:attribute The count of epochs before considering an epoch final on-chain uint64 epochsToAssumedFinality; } /// @notice The structure in storage struct Slot { /// @custom:attribute The structure in storage CLSpecStruct value; } /// @notice Retrieve the Consensus Layer Spec from storage /// @return The Consensus Layer Spec function get() internal view returns (CLSpecStruct memory) { bytes32 slot = CL_SPEC_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value; } /// @notice Set the Consensus Layer Spec value in storage /// @param _newCLSpec The new value to set in storage function set(CLSpecStruct memory _newCLSpec) internal { bytes32 slot = CL_SPEC_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } r.value = _newCLSpec; } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Consensus Layer Validator Count Storage /// @notice Utility to manage the Consensus Layer Validator Count in storage /// @notice This state variable is deprecated and was kept due to migration logic needs library CLValidatorCount { /// @notice Storage slot of the Consensus Layer Validator Count bytes32 internal constant CL_VALIDATOR_COUNT_SLOT = bytes32(uint256(keccak256("river.state.clValidatorCount")) - 1); /// @notice Retrieve the Consensus Layer Validator Count /// @return The Consensus Layer Validator Count function get() internal view returns (uint256) { return LibUnstructuredStorage.getStorageUint256(CL_VALIDATOR_COUNT_SLOT); } /// @notice Sets the Consensus Layer Validator Count /// @param _newValue New Consensus Layer Validator Count function set(uint256 _newValue) internal { LibUnstructuredStorage.setStorageUint256(CL_VALIDATOR_COUNT_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Consensus Layer Validator Total Balance Storage /// @notice Utility to manage the Consensus Layer Validator Total Balance in storage /// @notice This state variable is deprecated and was kept due to migration logic needs library CLValidatorTotalBalance { /// @notice Storage slot of the Consensus Layer Validator Total Balance bytes32 internal constant CL_VALIDATOR_TOTAL_BALANCE_SLOT = bytes32(uint256(keccak256("river.state.clValidatorTotalBalance")) - 1); /// @notice Retrieve the Consensus Layer Validator Total Balance /// @return The Consensus Layer Validator Total Balance function get() internal view returns (uint256) { return LibUnstructuredStorage.getStorageUint256(CL_VALIDATOR_TOTAL_BALANCE_SLOT); } /// @notice Sets the Consensus Layer Validator Total Balance /// @param _newValue New Consensus Layer Validator Total Balance function set(uint256 _newValue) internal { LibUnstructuredStorage.setStorageUint256(CL_VALIDATOR_TOTAL_BALANCE_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; import "../../libraries/LibSanitize.sol"; /// @title Collector Address Storage /// @notice Utility to manage the Collector Address in storage library CollectorAddress { /// @notice Storage slot of the Collector Address bytes32 internal constant COLLECTOR_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.collectorAddress")) - 1); /// @notice Retrieve the Collector Address /// @return The Collector Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(COLLECTOR_ADDRESS_SLOT); } /// @notice Sets the Collector Address /// @param _newValue New Collector Address function set(address _newValue) internal { LibSanitize._notZeroAddress(_newValue); LibUnstructuredStorage.setStorageAddress(COLLECTOR_ADDRESS_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; library CommittedBalance { bytes32 internal constant COMMITTED_BALANCE_SLOT = bytes32(uint256(keccak256("river.state.committedBalance")) - 1); function get() internal view returns (uint256) { return LibUnstructuredStorage.getStorageUint256(COMMITTED_BALANCE_SLOT); } function set(uint256 newValue) internal { LibUnstructuredStorage.setStorageUint256(COMMITTED_BALANCE_SLOT, newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; import "../../libraries/LibSanitize.sol"; /// @title Coverage Fund Address Storage /// @notice Utility to manage the Coverage Fund Address in storage library CoverageFundAddress { /// @notice Storage slot of the Coverage Fund Address bytes32 internal constant COVERAGE_FUND_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.coverageFundAddress")) - 1); /// @notice Retrieve the Coverage Fund Address /// @return The Coverage Fund Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(COVERAGE_FUND_ADDRESS_SLOT); } /// @notice Sets the Coverage Fund Address /// @param _newValue New Coverage Fund Address function set(address _newValue) internal { LibSanitize._notZeroAddress(_newValue); LibUnstructuredStorage.setStorageAddress(COVERAGE_FUND_ADDRESS_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibSanitize.sol"; /// @title Daily Committable Limits storage /// @notice Utility to manage the Daily Committable Limits in storage library DailyCommittableLimits { /// @notice Storage slot of the Daily Committable Limits storage bytes32 internal constant DAILY_COMMITTABLE_LIMITS_SLOT = bytes32(uint256(keccak256("river.state.dailyCommittableLimits")) - 1); /// @notice The daily committable limits structure struct DailyCommittableLimitsStruct { uint128 minDailyNetCommittableAmount; uint128 maxDailyRelativeCommittableAmount; } /// @notice The structure in storage struct Slot { /// @custom:attribute The structure in storage DailyCommittableLimitsStruct value; } /// @notice Retrieve the Daily Committable Limits from storage /// @return The Daily Committable Limits function get() internal view returns (DailyCommittableLimitsStruct memory) { bytes32 slot = DAILY_COMMITTABLE_LIMITS_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value; } /// @notice Set the Daily Committable Limits value in storage /// @param _newValue The new value to set in storage function set(DailyCommittableLimitsStruct memory _newValue) internal { bytes32 slot = DAILY_COMMITTABLE_LIMITS_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } r.value = _newValue; } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibSanitize.sol"; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Deposit Contract Address Storage /// @notice Utility to manage the Deposit Contract Address in storage library DepositContractAddress { /// @notice Storage slot of the Deposit Contract Address bytes32 internal constant DEPOSIT_CONTRACT_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.depositContractAddress")) - 1); /// @notice Retrieve the Deposit Contract Address /// @return The Deposit Contract Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(DEPOSIT_CONTRACT_ADDRESS_SLOT); } /// @notice Sets the Deposit Contract Address /// @param _newValue New Deposit Contract Address function set(address _newValue) internal { LibSanitize._notZeroAddress(_newValue); LibUnstructuredStorage.setStorageAddress(DEPOSIT_CONTRACT_ADDRESS_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Deposited Validator Count Storage /// @notice Utility to manage the Deposited Validator Count in storage library DepositedValidatorCount { /// @notice Storage slot of the Deposited Validator Count bytes32 internal constant DEPOSITED_VALIDATOR_COUNT_SLOT = bytes32(uint256(keccak256("river.state.depositedValidatorCount")) - 1); /// @notice Retrieve the Deposited Validator Count /// @return The Deposited Validator Count function get() internal view returns (uint256) { return LibUnstructuredStorage.getStorageUint256(DEPOSITED_VALIDATOR_COUNT_SLOT); } /// @notice Sets the Deposited Validator Count /// @param _newValue New Deposited Validator Count function set(uint256 _newValue) internal { LibUnstructuredStorage.setStorageUint256(DEPOSITED_VALIDATOR_COUNT_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; import "../../libraries/LibSanitize.sol"; /// @title Execution Layer Fee Recipient Address Storage /// @notice Utility to manage the Execution Layer Fee Recipient Address in storage library ELFeeRecipientAddress { /// @notice Storage slot of the Execution Layer Fee Recipient Address bytes32 internal constant EL_FEE_RECIPIENT_ADDRESS = bytes32(uint256(keccak256("river.state.elFeeRecipientAddress")) - 1); /// @notice Retrieve the Execution Layer Fee Recipient Address /// @return The Execution Layer Fee Recipient Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(EL_FEE_RECIPIENT_ADDRESS); } /// @notice Sets the Execution Layer Fee Recipient Address /// @param _newValue New Execution Layer Fee Recipient Address function set(address _newValue) internal { LibSanitize._notZeroAddress(_newValue); LibUnstructuredStorage.setStorageAddress(EL_FEE_RECIPIENT_ADDRESS, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibSanitize.sol"; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Global Fee Storage /// @notice Utility to manage the Global Fee in storage library GlobalFee { /// @notice Storage slot of the Global Fee bytes32 internal constant GLOBAL_FEE_SLOT = bytes32(uint256(keccak256("river.state.globalFee")) - 1); /// @notice Retrieve the Global Fee /// @return The Global Fee function get() internal view returns (uint256) { return LibUnstructuredStorage.getStorageUint256(GLOBAL_FEE_SLOT); } /// @notice Sets the Global Fee /// @param _newValue New Global Fee function set(uint256 _newValue) internal { LibSanitize._validFee(_newValue); LibUnstructuredStorage.setStorageUint256(GLOBAL_FEE_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../interfaces/components/IOracleManager.1.sol"; /// @title Last Consensus Layer Report Storage /// @notice Utility to manage the Last Consensus Layer Report in storage library LastConsensusLayerReport { /// @notice Storage slot of the Last Consensus Layer Report bytes32 internal constant LAST_CONSENSUS_LAYER_REPORT_SLOT = bytes32(uint256(keccak256("river.state.lastConsensusLayerReport")) - 1); /// @notice The structure in storage struct Slot { /// @custom:attribute The structure in storage IOracleManagerV1.StoredConsensusLayerReport value; } /// @notice Retrieve the Last Consensus Layer Report from storage /// @return The Last Consensus Layer Report function get() internal view returns (IOracleManagerV1.StoredConsensusLayerReport storage) { bytes32 slot = LAST_CONSENSUS_LAYER_REPORT_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value; } /// @notice Set the Last Consensus Layer Report value in storage /// @param _newValue The new value to set in storage function set(IOracleManagerV1.StoredConsensusLayerReport memory _newValue) internal { bytes32 slot = LAST_CONSENSUS_LAYER_REPORT_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } r.value = _newValue; } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Last Oracle Round Id Storage /// @notice Utility to manage the Last Oracle Round Id in storage /// @notice This state variable is deprecated and was kept due to migration logic needs library LastOracleRoundId { /// @notice Storage slot of the Last Oracle Round Id bytes32 internal constant LAST_ORACLE_ROUND_ID_SLOT = bytes32(uint256(keccak256("river.state.lastOracleRoundId")) - 1); /// @notice Retrieve the Last Oracle Round Id /// @return The Last Oracle Round Id function get() internal view returns (bytes32) { return LibUnstructuredStorage.getStorageBytes32(LAST_ORACLE_ROUND_ID_SLOT); } /// @notice Sets the Last Oracle Round Id /// @param _newValue New Last Oracle Round Id function set(bytes32 _newValue) internal { LibUnstructuredStorage.setStorageBytes32(LAST_ORACLE_ROUND_ID_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Metadata URI Storage /// @notice Utility to manage the Metadata in storage library MetadataURI { /// @notice Storage slot of the Metadata URI bytes32 internal constant METADATA_URI_SLOT = bytes32(uint256(keccak256("river.state.metadataUri")) - 1); /// @notice Structure in storage struct Slot { /// @custom:attribute The metadata value string value; } /// @notice Retrieve the metadata URI /// @return The metadata URI string function get() internal view returns (string memory) { bytes32 slot = METADATA_URI_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value; } /// @notice Set the metadata URI value /// @param _newValue The new metadata URI value function set(string memory _newValue) internal { bytes32 slot = METADATA_URI_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } r.value = _newValue; } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; import "../../libraries/LibSanitize.sol"; /// @title Operators Registry Address Storage /// @notice Utility to manage the Operators Registry Address in storage library OperatorsRegistryAddress { /// @notice Storage slot of the Operators Registry Address bytes32 internal constant OPERATORS_REGISTRY_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.operatorsRegistryAddress")) - 1); /// @notice Retrieve the Operators Registry Address /// @return The Operators Registry Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(OPERATORS_REGISTRY_ADDRESS_SLOT); } /// @notice Sets the Operators Registry Address /// @param _newValue New Operators Registry Address function set(address _newValue) internal { LibSanitize._notZeroAddress(_newValue); LibUnstructuredStorage.setStorageAddress(OPERATORS_REGISTRY_ADDRESS_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; import "../../libraries/LibSanitize.sol"; /// @title Oracle Address Storage /// @notice Utility to manage the Oracle Address in storage library OracleAddress { /// @notice Storage slot of the Oracle Address bytes32 internal constant ORACLE_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.oracleAddress")) - 1); /// @notice Retrieve the Oracle Address /// @return The Oracle Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(ORACLE_ADDRESS_SLOT); } /// @notice Sets the Oracle Address /// @param _newValue New Oracle Address function set(address _newValue) internal { LibSanitize._notZeroAddress(_newValue); LibUnstructuredStorage.setStorageAddress(ORACLE_ADDRESS_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; import "../../libraries/LibSanitize.sol"; /// @title Redeem Manager Address Storage /// @notice Utility to manage the Redeem Manager Address in storage library RedeemManagerAddress { /// @notice Storage slot of the Redeem Manager Address bytes32 internal constant REDEEM_MANAGER_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.redeemManagerAddress")) - 1); /// @notice Retrieve the Redeem Manager Address /// @return The Redeem Manager Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(REDEEM_MANAGER_ADDRESS_SLOT); } /// @notice Sets the Redeem Manager Address /// @param _newValue New Redeem Manager Address function set(address _newValue) internal { LibSanitize._notZeroAddress(_newValue); LibUnstructuredStorage.setStorageAddress(REDEEM_MANAGER_ADDRESS_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Report Bounds Storage /// @notice Utility to manage the Report Bounds in storage library ReportBounds { /// @notice Storage slot of the Report Bounds bytes32 internal constant REPORT_BOUNDS_SLOT = bytes32(uint256(keccak256("river.state.reportBounds")) - 1); /// @notice The Report Bounds structure struct ReportBoundsStruct { /// @custom:attribute The maximum allowed annual apr, checked before submitting a report to River uint256 annualAprUpperBound; /// @custom:attribute The maximum allowed balance decrease, also checked before submitting a report to River uint256 relativeLowerBound; } /// @notice The structure in storage struct Slot { /// @custom:attribute The structure in storage ReportBoundsStruct value; } /// @notice Retrieve the Report Bounds from storage /// @return The Report Bounds function get() internal view returns (ReportBoundsStruct memory) { bytes32 slot = REPORT_BOUNDS_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value; } /// @notice Set the Report Bounds in storage /// @param _newReportBounds The new Report Bounds value function set(ReportBoundsStruct memory _newReportBounds) internal { bytes32 slot = REPORT_BOUNDS_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } r.value = _newReportBounds; } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Shares Count Storage /// @notice Utility to manage the Shares Count in storage library Shares { /// @notice Storage slot of the Shares Count bytes32 internal constant SHARES_SLOT = bytes32(uint256(keccak256("river.state.shares")) - 1); /// @notice Retrieve the Shares Count /// @return The Shares Count function get() internal view returns (uint256) { return LibUnstructuredStorage.getStorageUint256(SHARES_SLOT); } /// @notice Sets the Shares Count /// @param _newValue New Shares Count function set(uint256 _newValue) internal { LibUnstructuredStorage.setStorageUint256(SHARES_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Shares Per Owner Storage /// @notice Utility to manage the Shares Per Owner in storage library SharesPerOwner { /// @notice Storage slot of the Shares Per Owner bytes32 internal constant SHARES_PER_OWNER_SLOT = bytes32(uint256(keccak256("river.state.sharesPerOwner")) - 1); /// @notice Structure in storage struct Slot { /// @custom:attribute The mapping from an owner to its share count mapping(address => uint256) value; } /// @notice Retrieve the share count for given owner /// @param _owner The address to get the balance of /// @return The amount of shares function get(address _owner) internal view returns (uint256) { bytes32 slot = SHARES_PER_OWNER_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value[_owner]; } /// @notice Set the amount of shares for an owner /// @param _owner The owner of the shares to edit /// @param _newValue The new shares value for the owner function set(address _owner, uint256 _newValue) internal { bytes32 slot = SHARES_PER_OWNER_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } r.value[_owner] = _newValue; } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibErrors.sol"; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Withdrawal Credentials Storage /// @notice Utility to manage the Withdrawal Credentials in storage library WithdrawalCredentials { /// @notice Storage slot of the Withdrawal Credentials bytes32 internal constant WITHDRAWAL_CREDENTIALS_SLOT = bytes32(uint256(keccak256("river.state.withdrawalCredentials")) - 1); /// @notice Retrieve the Withdrawal Credentials /// @return The Withdrawal Credentials function get() internal view returns (bytes32) { return LibUnstructuredStorage.getStorageBytes32(WITHDRAWAL_CREDENTIALS_SLOT); } /// @notice Retrieve the Withdrawal Credential under its address format /// @return The Withdrawal Credentials in its address format function getAddress() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(WITHDRAWAL_CREDENTIALS_SLOT); } /// @notice Sets the Withdrawal Credentials /// @param _newValue New Withdrawal Credentials function set(bytes32 _newValue) internal { if (_newValue == bytes32(0)) { revert LibErrors.InvalidArgument(); } LibUnstructuredStorage.setStorageBytes32(WITHDRAWAL_CREDENTIALS_SLOT, _newValue); } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; import "../../libraries/LibSanitize.sol"; /// @title Administrator Address Storage /// @notice Utility to manage the Administrator Address in storage library AdministratorAddress { /// @notice Storage slot of the Administrator Address bytes32 public constant ADMINISTRATOR_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.administratorAddress")) - 1); /// @notice Retrieve the Administrator Address /// @return The Administrator Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(ADMINISTRATOR_ADDRESS_SLOT); } /// @notice Sets the Administrator Address /// @param _newValue New Administrator Address function set(address _newValue) internal { LibSanitize._notZeroAddress(_newValue); LibUnstructuredStorage.setStorageAddress(ADMINISTRATOR_ADDRESS_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; /// @title Approvals Per Owner Storage /// @notice Utility to manage the Approvals Per Owner in storage library ApprovalsPerOwner { /// @notice Storage slot of the Approvals Per Owner bytes32 internal constant APPROVALS_PER_OWNER_SLOT = bytes32(uint256(keccak256("river.state.approvalsPerOwner")) - 1); /// @notice The structure in storage struct Slot { /// @custom:attribute The mapping from an owner to an operator to the approval amount mapping(address => mapping(address => uint256)) value; } /// @notice Retrieve the approval for an owner to an operator /// @param _owner The account that gave the approval /// @param _operator The account receiving the approval /// @return The value of the approval function get(address _owner, address _operator) internal view returns (uint256) { bytes32 slot = APPROVALS_PER_OWNER_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } return r.value[_owner][_operator]; } /// @notice Set the approval value for an owner to an operator /// @param _owner The account that gives the approval /// @param _operator The account receiving the approval /// @param _newValue The value of the approval function set(address _owner, address _operator, uint256 _newValue) internal { bytes32 slot = APPROVALS_PER_OWNER_SLOT; Slot storage r; // solhint-disable-next-line no-inline-assembly assembly { r.slot := slot } r.value[_owner][_operator] = _newValue; } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Pending Administrator Address Storage /// @notice Utility to manage the Pending Administrator Address in storage library PendingAdministratorAddress { /// @notice Storage slot of the Pending Administrator Address bytes32 public constant PENDING_ADMINISTRATOR_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.pendingAdministratorAddress")) - 1); /// @notice Retrieve the Pending Administrator Address /// @return The Pending Administrator Address function get() internal view returns (address) { return LibUnstructuredStorage.getStorageAddress(PENDING_ADMINISTRATOR_ADDRESS_SLOT); } /// @notice Sets the Pending Administrator Address /// @param _newValue New Pending Administrator Address function set(address _newValue) internal { LibUnstructuredStorage.setStorageAddress(PENDING_ADMINISTRATOR_ADDRESS_SLOT, _newValue); } }
//SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "../../libraries/LibUnstructuredStorage.sol"; /// @title Version Storage /// @notice Utility to manage the Version in storage library Version { /// @notice Storage slot of the Version bytes32 public constant VERSION_SLOT = bytes32(uint256(keccak256("river.state.version")) - 1); /// @notice Retrieve the Version /// @return The Version function get() internal view returns (uint256) { return LibUnstructuredStorage.getStorageUint256(VERSION_SLOT); } /// @notice Sets the Version /// @param _newValue New Version function set(uint256 _newValue) internal { LibUnstructuredStorage.setStorageUint256(VERSION_SLOT, _newValue); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface 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); }
{ "optimizer": { "enabled": true, "runs": 100 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"uint256","name":"_allowance","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"AllowanceTooLow","type":"error"},{"inputs":[],"name":"BalanceTooLow","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"Denied","type":"error"},{"inputs":[],"name":"EmptyDeposit","type":"error"},{"inputs":[],"name":"ErrorOnDeposit","type":"error"},{"inputs":[],"name":"InconsistentPublicKeys","type":"error"},{"inputs":[],"name":"InconsistentSignatures","type":"error"},{"inputs":[],"name":"InvalidArgument","type":"error"},{"inputs":[],"name":"InvalidCall","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentValidatorsExitedBalance","type":"uint256"},{"internalType":"uint256","name":"newValidatorsExitedBalance","type":"uint256"}],"name":"InvalidDecreasingValidatorsExitedBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentValidatorsSkimmedBalance","type":"uint256"},{"internalType":"uint256","name":"newValidatorsSkimmedBalance","type":"uint256"}],"name":"InvalidDecreasingValidatorsSkimmedBalance","type":"error"},{"inputs":[],"name":"InvalidEmptyString","type":"error"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"InvalidEpoch","type":"error"},{"inputs":[],"name":"InvalidFee","type":"error"},{"inputs":[{"internalType":"uint256","name":"version","type":"uint256"},{"internalType":"uint256","name":"expectedVersion","type":"uint256"}],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidPublicKeyCount","type":"error"},{"inputs":[{"internalType":"uint256","name":"requested","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"InvalidPulledClFundsAmount","type":"error"},{"inputs":[],"name":"InvalidSignatureCount","type":"error"},{"inputs":[{"internalType":"uint256","name":"providedValidatorCount","type":"uint256"},{"internalType":"uint256","name":"depositedValidatorCount","type":"uint256"},{"internalType":"uint256","name":"lastReportedValidatorCount","type":"uint256"}],"name":"InvalidValidatorCountReport","type":"error"},{"inputs":[],"name":"InvalidWithdrawalCredentials","type":"error"},{"inputs":[],"name":"InvalidZeroAddress","type":"error"},{"inputs":[],"name":"NoAvailableValidatorKeys","type":"error"},{"inputs":[],"name":"NotEnoughFunds","type":"error"},{"inputs":[],"name":"NullTransfer","type":"error"},{"inputs":[],"name":"SliceOutOfBounds","type":"error"},{"inputs":[],"name":"SliceOverflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"prevTotalEthIncludingExited","type":"uint256"},{"internalType":"uint256","name":"postTotalEthIncludingExited","type":"uint256"},{"internalType":"uint256","name":"timeElapsed","type":"uint256"},{"internalType":"uint256","name":"relativeLowerBound","type":"uint256"}],"name":"TotalValidatorBalanceDecreaseOutOfBound","type":"error"},{"inputs":[{"internalType":"uint256","name":"prevTotalEthIncludingExited","type":"uint256"},{"internalType":"uint256","name":"postTotalEthIncludingExited","type":"uint256"},{"internalType":"uint256","name":"timeElapsed","type":"uint256"},{"internalType":"uint256","name":"annualAprUpperBound","type":"uint256"}],"name":"TotalValidatorBalanceIncreaseOutOfBound","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"Unauthorized","type":"error"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"UnauthorizedTransfer","type":"error"},{"inputs":[],"name":"ZeroMintedShares","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"validatorCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"validatorTotalBalance","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"roundId","type":"bytes32"}],"name":"ConsensusLayerDataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"cdata","type":"bytes"}],"name":"Initialize","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"validatorsBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsSkimmedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitingBalance","type":"uint256"},{"internalType":"uint32","name":"validatorsCount","type":"uint32"},{"internalType":"uint32[]","name":"stoppedValidatorCountPerOperator","type":"uint32[]"},{"internalType":"bool","name":"rebalanceDepositToRedeemMode","type":"bool"},{"internalType":"bool","name":"slashingContainmentMode","type":"bool"}],"indexed":false,"internalType":"struct IOracleManagerV1.ConsensusLayerReport","name":"report","type":"tuple"},{"components":[{"internalType":"uint256","name":"rewards","type":"uint256"},{"internalType":"uint256","name":"pulledELFees","type":"uint256"},{"internalType":"uint256","name":"pulledRedeemManagerExceedingEthBuffer","type":"uint256"},{"internalType":"uint256","name":"pulledCoverageFunds","type":"uint256"}],"indexed":false,"internalType":"struct IOracleManagerV1.ConsensusLayerDataReportingTrace","name":"trace","type":"tuple"}],"name":"ProcessedConsensusLayerReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pulledSkimmedEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pullExitedEthAmount","type":"uint256"}],"name":"PulledCLFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PulledCoverageFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PulledELFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PulledRedeemManagerExceedingEth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"redeemManagerDemand","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"suppliedRedeemManagerDemand","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"suppliedRedeemManagerDemandInEth","type":"uint256"}],"name":"ReportedRedeemManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_collector","type":"address"},{"indexed":false,"internalType":"uint256","name":"_oldTotalUnderlyingBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_oldTotalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newTotalUnderlyingBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newTotalSupply","type":"uint256"}],"name":"RewardsEarned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"SetAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"allowlist","type":"address"}],"name":"SetAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"SetBalanceCommittedToDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"SetBalanceToDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"SetBalanceToRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"annualAprUpperBound","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"relativeLowerBound","type":"uint256"}],"name":"SetBounds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collector","type":"address"}],"name":"SetCollector","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"coverageFund","type":"address"}],"name":"SetCoverageFund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositContract","type":"address"}],"name":"SetDepositContractAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldDepositedValidatorCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDepositedValidatorCount","type":"uint256"}],"name":"SetDepositedValidatorCount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"elFeeRecipient","type":"address"}],"name":"SetELFeeRecipient","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetGlobalFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minNetAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxRelativeAmount","type":"uint256"}],"name":"SetMaxDailyCommittableAmounts","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"metadataURI","type":"string"}],"name":"SetMetadataURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operatorRegistry","type":"address"}],"name":"SetOperatorsRegistry","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracleAddress","type":"address"}],"name":"SetOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingAdmin","type":"address"}],"name":"SetPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"redeemManager","type":"address"}],"name":"SetRedeemManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"epochsPerFrame","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"slotsPerEpoch","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"secondsPerSlot","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"genesisTime","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"epochsToAssumedFinality","type":"uint64"}],"name":"SetSpec","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"SetTotalSupply","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"withdrawalCredentials","type":"bytes32"}],"name":"SetWithdrawalCredentials","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UserDeposit","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"DEPOSIT_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLIC_KEY_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNATURE_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_DEPOSIT_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOfUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_redeemRequestIds","type":"uint32[]"},{"internalType":"uint32[]","name":"_withdrawalEventIds","type":"uint32[]"}],"name":"claimRedeemRequests","outputs":[{"internalType":"uint8[]","name":"claimStatuses","type":"uint8[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_subtractableValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"depositAndTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxCount","type":"uint256"}],"name":"depositToConsensusLayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowlist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalanceToDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalanceToRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCLSpec","outputs":[{"components":[{"internalType":"uint64","name":"epochsPerFrame","type":"uint64"},{"internalType":"uint64","name":"slotsPerEpoch","type":"uint64"},{"internalType":"uint64","name":"secondsPerSlot","type":"uint64"},{"internalType":"uint64","name":"genesisTime","type":"uint64"},{"internalType":"uint64","name":"epochsToAssumedFinality","type":"uint64"}],"internalType":"struct CLSpec.CLSpecStruct","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCLValidatorCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCLValidatorTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCommittedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCoverageFund","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentFrame","outputs":[{"internalType":"uint256","name":"_startEpochId","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_endTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDailyCommittableLimits","outputs":[{"components":[{"internalType":"uint128","name":"minDailyNetCommittableAmount","type":"uint128"},{"internalType":"uint128","name":"maxDailyRelativeCommittableAmount","type":"uint128"}],"internalType":"struct DailyCommittableLimits.DailyCommittableLimitsStruct","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDepositedValidatorCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getELFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExpectedEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epochId","type":"uint256"}],"name":"getFrameFirstEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastCompletedEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastConsensusLayerReport","outputs":[{"components":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"validatorsBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsSkimmedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitingBalance","type":"uint256"},{"internalType":"uint32","name":"validatorsCount","type":"uint32"},{"internalType":"bool","name":"rebalanceDepositToRedeemMode","type":"bool"},{"internalType":"bool","name":"slashingContainmentMode","type":"bool"}],"internalType":"struct IOracleManagerV1.StoredConsensusLayerReport","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMetadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOperatorsRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRedeemManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReportBounds","outputs":[{"components":[{"internalType":"uint256","name":"annualAprUpperBound","type":"uint256"},{"internalType":"uint256","name":"relativeLowerBound","type":"uint256"}],"internalType":"struct ReportBounds.ReportBoundsStruct","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalCredentials","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_additionalValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_depositContractAddress","type":"address"},{"internalType":"address","name":"_elFeeRecipientAddress","type":"address"},{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"},{"internalType":"address","name":"_oracleAddress","type":"address"},{"internalType":"address","name":"_systemAdministratorAddress","type":"address"},{"internalType":"address","name":"_allowlistAddress","type":"address"},{"internalType":"address","name":"_operatorRegistryAddress","type":"address"},{"internalType":"address","name":"_collectorAddress","type":"address"},{"internalType":"uint256","name":"_globalFee","type":"uint256"}],"name":"initRiverV1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_redeemManager","type":"address"},{"internalType":"uint64","name":"_epochsPerFrame","type":"uint64"},{"internalType":"uint64","name":"_slotsPerEpoch","type":"uint64"},{"internalType":"uint64","name":"_secondsPerSlot","type":"uint64"},{"internalType":"uint64","name":"_genesisTime","type":"uint64"},{"internalType":"uint64","name":"_epochsToAssumedFinality","type":"uint64"},{"internalType":"uint256","name":"_annualAprUpperBound","type":"uint256"},{"internalType":"uint256","name":"_relativeLowerBound","type":"uint256"},{"internalType":"uint128","name":"_minDailyNetCommittableAmount_","type":"uint128"},{"internalType":"uint128","name":"_maxDailyRelativeCommittableAmount_","type":"uint128"}],"name":"initRiverV1_1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"isValidEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"proposeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lsETHAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"requestRedeem","outputs":[{"internalType":"uint32","name":"_redeemRequestId","type":"uint32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_redeemRequestIds","type":"uint32[]"}],"name":"resolveRedeemRequests","outputs":[{"internalType":"int64[]","name":"withdrawalEventIds","type":"int64[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sendCLFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sendCoverageFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sendELFees","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sendRedeemManagerExceedingFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAllowlist","type":"address"}],"name":"setAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"epochsPerFrame","type":"uint64"},{"internalType":"uint64","name":"slotsPerEpoch","type":"uint64"},{"internalType":"uint64","name":"secondsPerSlot","type":"uint64"},{"internalType":"uint64","name":"genesisTime","type":"uint64"},{"internalType":"uint64","name":"epochsToAssumedFinality","type":"uint64"}],"internalType":"struct CLSpec.CLSpecStruct","name":"_newValue","type":"tuple"}],"name":"setCLSpec","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newCollector","type":"address"}],"name":"setCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"validatorsBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsSkimmedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitingBalance","type":"uint256"},{"internalType":"uint32","name":"validatorsCount","type":"uint32"},{"internalType":"uint32[]","name":"stoppedValidatorCountPerOperator","type":"uint32[]"},{"internalType":"bool","name":"rebalanceDepositToRedeemMode","type":"bool"},{"internalType":"bool","name":"slashingContainmentMode","type":"bool"}],"internalType":"struct IOracleManagerV1.ConsensusLayerReport","name":"_report","type":"tuple"}],"name":"setConsensusLayerData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newCoverageFund","type":"address"}],"name":"setCoverageFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"minDailyNetCommittableAmount","type":"uint128"},{"internalType":"uint128","name":"maxDailyRelativeCommittableAmount","type":"uint128"}],"internalType":"struct DailyCommittableLimits.DailyCommittableLimitsStruct","name":"_dcl","type":"tuple"}],"name":"setDailyCommittableLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newELFeeRecipient","type":"address"}],"name":"setELFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setGlobalFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_metadataURI","type":"string"}],"name":"setMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracleAddress","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"annualAprUpperBound","type":"uint256"},{"internalType":"uint256","name":"relativeLowerBound","type":"uint256"}],"internalType":"struct ReportBounds.ReportBoundsStruct","name":"_newValue","type":"tuple"}],"name":"setReportBounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_underlyingAssetAmount","type":"uint256"}],"name":"sharesFromUnderlyingBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUnderlyingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"underlyingBalanceFromShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b506200002a6000196200007060201b620024aa1760201c565b7f1809e49bba43f2d39fa57894b50cd6ccb428cc438230e065cac3eb24a1355a716000196000366040516200006293929190620000bd565b60405180910390a162000119565b620000b6620000a160017f82055909238c0f5e63d6f174068ebb8f51bcec9bd37de63bb68f6551feec0cfd620000f3565b60001b82620000b960201b620024dd1760201c565b50565b9055565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b6000828210156200011457634e487b7160e01b600052601160045260246000fd5b500390565b615fb480620001296000396000f3fe6080604052600436106103ba5760003560e01c80635d95e801116101f9578063a29a839f1161011e578063d4970524116100b6578063efd668461161007a578063efd6684614610c07578063f79c3f0214610c27578063f9f95a9014610c47578063fb5b82d014610c67578063fe7c12ae14610c87576103ca565b8063d497052414610b9b578063d7f8f47414610790578063dd62ed3e14610ba3578063e3a88e6114610bc3578063efd6034714610bff576103ca565b8063a29a839f14610acc578063a457c2d714610ae1578063a9059cbb14610b01578063ac232bde14610b21578063bb6583ec14610b34578063bf15af5614610b54578063c5eff3d014610b69578063d046815614610b7e578063d0e30db014610b93576103ca565b80637adbf973116101915780637adbf973146109b8578063833b1fce146109d857806386a92af7146109ed57806387f2adfb14610a0257806389896aef14610a175780639332525d14610a2c57806395d89b4114610a595780639b498e2614610a875780639d49cca114610a9c576103ca565b80635d95e801146108a95780635f2e5f07146108b157806363f62aaf146108de5780636e9960c3146108f357806370a082311461090857806372f79b1314610928578063750521f51461095857806378a010e814610978578063799a195414610998576103ca565b806323b872dd116102df5780633af9e669116102775780633af9e669146107cd57806346425ef0146107ed5780634b47b74f146108025780635022820114610817578063540bc5ea1461082c578063557ed1ba14610841578063563967151461085457806357fa85471461086957806358bf3c7f14610889576103ca565b806323b872dd14610686578063281a3122146106a6578063291206f6146106c65780632cb562e1146106e65780632d6b59bf146106fb5780632dc5c97c14610710578063313ce5671461077457806336bf33251461079057806339509351146107ad576103ca565b80631311cf8d116103525780631311cf8d1461052557806313d86aed14610545578063143a08d414610565578063147bf6c41461057a5780631546962b1461059a57806315ca4cee146105bc57806317e64858146105dc57806318160ddd1461065c5780631bcbfaba14610671576103ca565b8063020f086e146103e35780630407de471461040357806304843a1714610423578063056850c61461044b57806306fdde0314610453578063095ea7b3146104965780630e18b681146104c6578063107703ab146104db578063107d7fa014610510576103ca565b366103ca576103c833610c9c565b005b60405163574b16a760e11b815260040160405180910390fd5b3480156103ef57600080fd5b506103c86103fe366004615048565b610d23565b34801561040f57600080fd5b506103c861041e366004615091565b610da7565b34801561042f57600080fd5b50610438610ec9565b6040519081526020015b60405180910390f35b6103c8610ed8565b34801561045f57600080fd5b50604080518082019091526011815270098d2e2ead2c840a6e8c2d6cac8408aa89607b1b60208201525b6040516104429190615195565b3480156104a257600080fd5b506104b66104b13660046151a8565b610f15565b6040519015158152602001610442565b3480156104d257600080fd5b506103c8610f2b565b3480156104e757600080fd5b506104fb6104f63660046151d2565b610f80565b60405163ffffffff9091168152602001610442565b34801561051c57600080fd5b50610438611078565b34801561053157600080fd5b506103c8610540366004615048565b611091565b34801561055157600080fd5b506103c86105603660046151fe565b61110c565b34801561057157600080fd5b506104386112b4565b34801561058657600080fd5b506103c8610595366004615048565b6112be565b3480156105a657600080fd5b506105af611305565b6040516104429190615217565b3480156105c857600080fd5b506103c86105d736600461522b565b61130f565b3480156105e857600080fd5b506105f16113a2565b6040516104429190600061010082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015263ffffffff60a08401511660a083015260c0830151151560c083015260e0830151151560e083015292915050565b34801561066857600080fd5b50610438611425565b34801561067d57600080fd5b5061043861142f565b34801561069257600080fd5b506104b66106a136600461523d565b611439565b3480156106b257600080fd5b506103c86106c1366004615279565b6114ec565b3480156106d257600080fd5b506103c86106e13660046151fe565b6116a7565b3480156106f257600080fd5b506105af61171b565b34801561070757600080fd5b50610438611725565b34801561071c57600080fd5b5061072561172f565b604051610442919081516001600160401b039081168252602080840151821690830152604080840151821690830152606080840151821690830152608092830151169181019190915260a00190565b34801561078057600080fd5b5060405160128152602001610442565b34801561079c57600080fd5b506104386801bc16d674ec80000081565b3480156107b957600080fd5b506104b66107c83660046151a8565b61173f565b3480156107d957600080fd5b506104386107e8366004615048565b611760565b3480156107f957600080fd5b50610438611779565b34801561080e57600080fd5b5061043861178c565b34801561082357600080fd5b506105af6117f5565b34801561083857600080fd5b50610438606081565b34801561084d57600080fd5b5042610438565b34801561086057600080fd5b506104386117ff565b34801561087557600080fd5b506104386108843660046151fe565b611809565b34801561089557600080fd5b506103c86108a4366004615048565b611831565b6103c86118ac565b3480156108bd57600080fd5b506108d16108cc36600461535e565b6118b4565b604051610442919061539f565b3480156108ea57600080fd5b506105af611930565b3480156108ff57600080fd5b506105af61193a565b34801561091457600080fd5b50610438610923366004615048565b611944565b34801561093457600080fd5b5061093d61194f565b60408051938452602084019290925290820152606001610442565b34801561096457600080fd5b506103c861097336600461547b565b611a1f565b34801561098457600080fd5b506103c86109933660046154fa565b611a9b565b3480156109a457600080fd5b506104386109b33660046151fe565b611b6c565b3480156109c457600080fd5b506103c86109d3366004615048565b611b77565b3480156109e457600080fd5b506105af611bf2565b3480156109f957600080fd5b50610489611bfc565b348015610a0e57600080fd5b50610438611c06565b348015610a2357600080fd5b50610438611c10565b348015610a3857600080fd5b50610a4c610a4736600461550c565b611c20565b6040516104429190615577565b348015610a6557600080fd5b50604080518082019091526005815264098e68aa8960db1b6020820152610489565b348015610a9357600080fd5b506105af611cb2565b348015610aa857600080fd5b50610ab1611cbc565b60408051825181526020928301519281019290925201610442565b348015610ad857600080fd5b50610438611cd8565b348015610aed57600080fd5b506104b6610afc3660046151a8565b611cea565b348015610b0d57600080fd5b506104b6610b1c3660046151a8565b611d06565b6103c8610b2f366004615048565b611da5565b348015610b4057600080fd5b506103c8610b4f3660046155b2565b611db7565b348015610b6057600080fd5b50610438603081565b348015610b7557600080fd5b506105af611dfb565b348015610b8a57600080fd5b506105af611e05565b6103c8611e0f565b6103c8611e18565b348015610baf57600080fd5b50610438610bbe3660046155ef565b611e20565b348015610bcf57600080fd5b50610bd8611e2c565b6040805182516001600160801b039081168252602093840151169281019290925201610442565b6103c8611e48565b348015610c1357600080fd5b506103c8610c22366004615619565b611e50565b348015610c3357600080fd5b50610438610c423660046151fe565b612407565b348015610c5357600080fd5b506104b6610c623660046151fe565b612412565b348015610c7357600080fd5b506103c8610c82366004615048565b612425565b348015610c9357600080fd5b506104386124a0565b34610cba576040516395b66fe960e01b815260040160405180910390fd5b610cd534610cc66124e1565b610cd0919061566a565b612515565b610ce033823461255e565b6040513481526001600160a01b0382169033907f3bc57f469ad6d10d7723ea226cd22bd2b9e527def2b529f6ab44645a166895829060200160405180910390a350565b610d2b6126f6565b6001600160a01b0316336001600160a01b031614610d67573360405163472511eb60e11b8152600401610d5e9190615217565b60405180910390fd5b610d7081612700565b6040516001600160a01b038216907f67b26a33f305cc027b2d45b2f6f418793afcd3e22f7376afa7be068ce18604e890600090a250565b6001610db1612737565b8114610de25780610dc0612737565b604051631cfd276760e31b815260048101929092526024820152604401610d5e565b610df5610df082600161566a565b6124aa565b610dfe8b612767565b7faf890c07e266df31e0725841eb0e85596a0caa1b17bbae5c0b206fdcc92d7ce18b604051610e2d9190615217565b60405180910390a1610e646040518060400160405280856001600160801b03168152602001846001600160801b031681525061279e565b610e738a8a8a8a8a8a8a6127f2565b610e80308c60001961294b565b7f1809e49bba43f2d39fa57894b50cd6ccb428cc438230e065cac3eb24a1355a7181600036604051610eb493929190615682565b60405180910390a15050505050505050505050565b6000610ed36124e1565b905090565b610ee06129ba565b6001600160a01b0316336001600160a01b031614610f13573360405163472511eb60e11b8152600401610d5e9190615217565b565b6000610f2233848461294b565b50600192915050565b610f336129ea565b6001600160a01b0316336001600160a01b031614610f66573360405163472511eb60e11b8152600401610d5e9190615217565b610f76610f716129ea565b6129f4565b610f136000612a3d565b6000610f8a612a7d565b6001600160a01b0316635a4091023360046040518363ffffffff1660e01b8152600401610fb89291906156b8565b60006040518083038186803b158015610fd057600080fd5b505afa158015610fe4573d6000803e3d6000fd5b50505050610ff3333085612aad565b50610ffc6129ba565b60405163107703ab60e01b8152600481018590526001600160a01b038481166024830152919091169063107703ab906044016020604051808303816000875af115801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906156e3565b9392505050565b6000611082612b29565b6005015463ffffffff16919050565b6110996126f6565b6001600160a01b0316336001600160a01b0316146110cc573360405163472511eb60e11b8152600401610d5e9190615217565b6110d581612b57565b6040516001600160a01b038216907f1da4c245099590dc40be61880c9b97792f3694d970acc1e67ac0e6cc90f3780d90600090a250565b6000611116612b8e565b905060006111366111306801bc16d674ec80000084615716565b84612bbe565b90508061115657604051631036b5ad60e31b815260040160405180910390fd5b60008061116283612bd3565b81519193509150806111875760405163200149ad60e21b815260040160405180910390fd5b838111156111a857604051635993bd5760e01b815260040160405180910390fd5b60006111b2612c5b565b9050806111d257604051639be7315960e01b815260040160405180910390fd5b60005b828110156112225761121a8582815181106111f2576111f261572a565b602002602001015185838151811061120c5761120c61572a565b602002602001015184612c8b565b6001016111d5565b50611248611239836801bc16d674ec800000615740565b611243908861575f565b6130dc565b6000611252613125565b9050611266611261848361566a565b613155565b7f220ab8fd274cf58c09b0825ccf00e74ba4ce4117fd47285adc2183a635838f1b81611292858261566a565b6040805192835260208301919091520160405180910390a15050505050505050565b6000610ed3613183565b6112c66126f6565b6001600160a01b0316336001600160a01b0316146112f9573360405163472511eb60e11b8152600401610d5e9190615217565b61130281612a3d565b50565b6000610ed3613242565b611317613272565b6001600160a01b0316336001600160a01b03161461134a573360405163472511eb60e11b8152600401610d5e9190615217565b61136161135c36839003830183615776565b61327c565b6040805182358152602080840135908201527f5ab79ffcd89b6380c7fbdd89d02cfe3d9c53c99a85e150c2319075018d1aac5c91015b60405180910390a150565b6113aa614e9b565b6113b2612b29565b60408051610100810182528254815260018301546020820152600283015491810191909152600382015460608201526004820154608082015260059091015463ffffffff811660a083015260ff64010000000082048116151560c0840152600160281b90910416151560e0820152919050565b6000610ed36132bf565b6000610ed36132c9565b6000838361144782826132f9565b8380611466576040516336b216db60e21b815260040160405180910390fd5b86858061147283613425565b1015611491576040516351940b3960e11b815260040160405180910390fd5b6001600160a01b0388166114ca57604051637617407560e11b81526001600160a01b038a16600482015260006024820152604401610d5e565b6114d48988613430565b6114df898989612aad565b9998505050505050505050565b60006114f6612737565b81146115055780610dc0612737565b611513610df082600161566a565b61151c866129f4565b61152583613496565b6040516001600160a01b038416907f0cc5437d7c9c1d9eab549acbb533eea3e9868e9443dd75309ed5820b33a3774e90600090a2611562826134cd565b6040518281527fbd533e726baaf59b36f3914d950053f7e78f527057c97cd3f0043257fc0fc8849060200160405180910390a161159e89612b57565b6040516001600160a01b038a16907f1da4c245099590dc40be61880c9b97792f3694d970acc1e67ac0e6cc90f3780d90600090a26115db85613504565b6040516001600160a01b038616907f30f015a5d3c72c0a9414538199baa022323a483fa9e4ba2cd581596cf8ca042490600090a26116188461353b565b6040516001600160a01b038516907fffc0721ef0563a1b0a51a0dc92113025f33ca434ada9ee3eebff2f385d2a8f9a90600090a26116568a89613572565b61165f87611bb2565b7f1809e49bba43f2d39fa57894b50cd6ccb428cc438230e065cac3eb24a1355a718160003660405161169393929190615682565b60405180910390a150505050505050505050565b6116af6126f6565b6001600160a01b0316336001600160a01b0316146116e2573360405163472511eb60e11b8152600401610d5e9190615217565b6116eb816134cd565b6040518181527fbd533e726baaf59b36f3914d950053f7e78f527057c97cd3f0043257fc0fc88490602001611397565b6000610ed36135ee565b6000610ed361361e565b611737614eea565b610ed361364e565b6000610f2233848461175133886136da565b61175b919061566a565b61294b565b600061177361176e83613732565b613780565b92915050565b6000611783612b29565b60010154905090565b60008061179761364e565b905060006117a4826137b8565b90506117ee82600001516001600160401b03166117bf612b29565b546117ca919061566a565b83516117df906001600160401b0316846157a8565b6117e9908461575f565b613803565b9250505090565b6000610ed3613812565b6000610ed3612c5b565b600061181361364e565b51611827906001600160401b0316836157a8565b611773908361575f565b6118396126f6565b6001600160a01b0316336001600160a01b03161461186c573360405163472511eb60e11b8152600401610d5e9190615217565b61187581613504565b6040516001600160a01b038216907f30f015a5d3c72c0a9414538199baa022323a483fa9e4ba2cd581596cf8ca042490600090a250565b610ee0612c5b565b60606118be6129ba565b6001600160a01b0316635f2e5f0784846040518363ffffffff1660e01b81526004016118eb92919061580d565b600060405180830381865afa158015611908573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110719190810190615844565b6000610ed36129ba565b6000610ed36126f6565b600061177382613425565b60008060008061195d61364e565b9050600061196a826137b8565b8251909150611982906001600160401b0316826157a8565b61198c908261575f565b945081604001516001600160401b031682602001516001600160401b0316866119b59190615740565b6119bf9190615740565b9350600182604001516001600160401b031683602001516001600160401b031684600001516001600160401b0316886119f8919061566a565b611a029190615740565b611a0c9190615740565b611a16919061575f565b92505050909192565b611a276126f6565b6001600160a01b0316336001600160a01b031614611a5a573360405163472511eb60e11b8152600401610d5e9190615217565b611a6381613842565b611a6c81613861565b7f8d2df192dd17edf92a7964b78aa322f3d717b2ab9de00651bee32bbc4c5da63a816040516113979190615195565b611aa3613272565b6001600160a01b0316336001600160a01b031614611ad6573360405163472511eb60e11b8152600401610d5e9190615217565b611aed611ae8368390038301836158e4565b6138ab565b7f25777eb44be046f64180acf8275f0ac2ec51e63a65a5f8a0f2f6d86ba25b74cf611b1b6020830183615971565b611b2b6040840160208501615971565b611b3b6060850160408601615971565b611b4b6080860160608701615971565b611b5b60a0870160808801615971565b60405161139795949392919061598c565b600061177382613967565b611b7f613272565b6001600160a01b0316336001600160a01b031614611bb2573360405163472511eb60e11b8152600401610d5e9190615217565b611bbb81613994565b6040516001600160a01b038216907fd3b5d1e0ffaeff528910f3663f0adace7694ab8241d58e17a91351ced2e0803190600090a250565b6000610ed36139cb565b6060610ed36139fb565b6000610ed3613125565b6000611c1a612b29565b54919050565b6060611c2a6129ba565b6001600160a01b0316637c044e5586868686600161ffff6040518763ffffffff1660e01b8152600401611c62969594939291906159be565b6000604051808303816000875af1158015611c81573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ca99190810190615a04565b95945050505050565b6000610ed3613ac1565b6040805180820190915260008082526020820152610ed3613af1565b6000610ed3611ce561364e565b6137b8565b6000610f22338484611cfc33886136da565b61175b919061575f565b60003383611d1482826132f9565b8380611d33576040516336b216db60e21b815260040160405180910390fd5b338580611d3f83613425565b1015611d5e576040516351940b3960e11b815260040160405180910390fd5b6001600160a01b038816611d8e57604051637617407560e11b815233600482015260006024820152604401610d5e565b611d99338989612aad565b98975050505050505050565b611dae81613b51565b61130281610c9c565b611dbf6126f6565b6001600160a01b0316336001600160a01b031614611df2573360405163472511eb60e11b8152600401610d5e9190615217565b6113028161279e565b6000610ed3612a7d565b6000610ed36129ea565b610f1333610c9c565b610ee0613242565b600061107183836136da565b6040805180820190915260008082526020820152610ed3613b78565b610ee06135ee565b611e586139cb565b6001600160a01b0316336001600160a01b031614611e8b573360405163472511eb60e11b8152600401610d5e9190615217565b6000611e9561364e565b9050611ea2818335613be6565b611ec25760405163a225656d60e01b815282356004820152602401610d5e565b611eca614f18565b6000611ed4612b29565b60038101546040840181905290915060608501351015611f19576040808301519051621ee1cf60e11b8152600481019190915260608501356024820152604401610d5e565b6040820151611f2c90606086013561575f565b608083015260028101546060830181905260408501351015611f7357606082015160408051636f24834360e01b815260048101929092528501356024820152604401610d5e565b611f7b613125565b611f8b60c0860160a08701615a99565b63ffffffff161180611fbb5750600581015463ffffffff16611fb360c0860160a08701615a99565b63ffffffff16105b1561201057611fd060c0850160a08601615a99565b611fd8613125565b6005830154604051632f776b1760e01b815263ffffffff93841660048201526024810192909252919091166044820152606401610d5e565b606082015161202390604086013561575f565b60a083015280546120379084908635613c43565b60c083015250612045613183565b815260a0810151608082015160009161205d9161566a565b1115612075576120758160a001518260800151613c7e565b61207d614e9b565b83358152602080850135908201526040808501359082015260608085013590820152608080850135908201526120b960c0850160a08601615a99565b63ffffffff1660a08201526120d5610100850160e08601615acf565b151560c08201526120ee61012085016101008601615acf565b151560e08201526120fe81613dab565b506000612109613af1565b905060006121208284600001518560c00151613e57565b905061212a613183565b602084018190528351116121bf57825161214590829061566a565b8360200151111561218d578251602084015160c0850151845160405163eb7a968960e01b81526004810194909452602484019290925260448301526064820152608401610d5e565b8251602084015161219e919061575f565b610120840180519190915251516121b5908261575f565b60e084015261225b565b60006121cf838560000151613e8b565b90506121df818560000151612bbe565b84516121eb919061575f565b8460200151101561223957835160208086015160c08701519186015160405163063bb83f60e11b8152610d5e9493919060040193845260208401929092526040830152606082015260800190565b6020840151845161224a919061575f565b612254908361566a565b60e0850152505b60e0830151156122b9576122728360e00151613ea0565b610120840180516020908101929092525190810151815190919061229790839061566a565b9052506101208301516020015160e0840180516122b590839061575f565b9052505b60e0830151156122f8576122d08360e00151613f68565b6101208401805160409081019290925251015160e0840180516122f490839061575f565b9052505b60e08301511561231a5761230f8360e0015161402e565b610120840151606001525b6101208301515115612336576101208301515161233690614100565b6123a5608086013561234b60c0880188615aec565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061238e92505050610100890160e08a01615acf565b6123a06101208a016101008b01615acf565b614232565b6123ad61452d565b6123b56146b2565b6123c28360c001516146da565b7f49ac0d2bb2a688ca460f7993eb93eccd3b9c9188da6b0727e9a409cf8b105875858461012001516040516123f8929190615b7d565b60405180910390a15050505050565b600061177382613780565b600061177361241f61364e565b83613be6565b61242d6126f6565b6001600160a01b0316336001600160a01b031614612460573360405163472511eb60e11b8152600401610d5e9190615217565b61246981613496565b6040516001600160a01b038216907f0cc5437d7c9c1d9eab549acbb533eea3e9868e9443dd75309ed5820b33a3774e90600090a250565b6000610ed3612b8e565b6113026124d860017f82055909238c0f5e63d6f174068ebb8f51bcec9bd37de63bb68f6551feec0cfd61575f565b829055565b9055565b6000610ed361251160017f2b6136e423ab70d76431e2a635e877e16ea2dd9a895e054ad7f35f89d6c7b71161575f565b5490565b7f48f67c1dada0cab2163f6282292ad97ea97376cfed46bb3851654aaa630db72761253e6124e1565b60408051918252602082018490520160405180910390a161130281614790565b600061256a84836147be565b90506000612576612a7d565b9050836001600160a01b0316856001600160a01b031614156125f657604051632d20488160e11b81526001600160a01b03821690635a409102906125c19088906001906004016156b8565b60006040518083038186803b1580156125d957600080fd5b505afa1580156125ed573d6000803e3d6000fd5b505050506126ef565b604051632d20488160e11b81526001600160a01b03821690635a409102906126259088906001906004016156b8565b60006040518083038186803b15801561263d57600080fd5b505afa158015612651573d6000803e3d6000fd5b505060405163e838dfbb60e01b81526001600160a01b038416925063e838dfbb9150612681908790600401615217565b602060405180830381865afa15801561269e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c29190615c51565b156126e2578360405163e7d05e2760e01b8152600401610d5e9190615217565b6126ed858584612aad565b505b5050505050565b6000610ed361481d565b61270981613b51565b6113026124d860017ff4271262f3552a4108cde54dc75061de8de495709221d793b126e448522d6a8061575f565b6000610ed361251160017f82055909238c0f5e63d6f174068ebb8f51bcec9bd37de63bb68f6551feec0cfd61575f565b61277081613b51565b6113026124d860017fe458cbedf69109e7d57b7f8c96816615aac0017187d87abab9001d22db32bae461575f565b6127a78161484d565b805160208201516040517e4180017d3dd609da6980999655a6bd2591e313d31d6230b1889c369a9713a0926113979290916001600160801b0392831681529116602082015260400190565b61284e6040518060a00160405280896001600160401b03168152602001886001600160401b03168152602001876001600160401b03168152602001866001600160401b03168152602001856001600160401b03168152506138ab565b7f25777eb44be046f64180acf8275f0ac2ec51e63a65a5f8a0f2f6d86ba25b74cf878787878760405161288595949392919061598c565b60405180910390a16128aa60405180604001604052808481526020018381525061327c565b60408051838152602081018390527f5ab79ffcd89b6380c7fbdd89d02cfe3d9c53c99a85e150c2319075018d1aac5c910160405180910390a16128eb614e9b565b6128f361489f565b81526128fd6148cf565b602082015260006040820181905260608201819052608082015261291f6148ff565b63ffffffff1660a0820152600060c0820181905260e082015261294181613dab565b5050505050505050565b61295483613b51565b61295d82613b51565b61296883838361492f565b816001600160a01b0316836001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516129ad91815260200190565b60405180910390a3505050565b6000610ed361251160017fe458cbedf69109e7d57b7f8c96816615aac0017187d87abab9001d22db32bae461575f565b6000610ed3614986565b6129fd81613b51565b612a06816149b6565b6040516001600160a01b038216907f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a190600090a250565b612a46816149bf565b6040516001600160a01b038216907f2a0f8515de3fa34ef68b99300347b8793c01683350743e96fe440594528298f490600090a250565b6000610ed361251160017f867d8f1a5e39d11d5bebde854d5359a509530ad32450f581da63c06ec8d1a78061575f565b6000612acc8483612abd87613732565b612ac7919061575f565b6149c8565b612ae48383612ada86613732565b612ac7919061566a565b826001600160a01b0316846001600160a01b0316600080516020615f5f83398151915284604051612b1791815260200190565b60405180910390a35060019392505050565b60008061177360017fdbc0527c99b54cd325d6ce9eaae3a8413cd447b5205f37385f0ebc6551033c6d61575f565b612b6081613b51565b6113026124d860017f8e9e2a1d30fed357d8a000c1131fc77ed65d2052918caf1ccc6eb1e7af3d13b661575f565b6000610ed361251160017fbcfa5a69252c74010ad3e9ab18cfbdc116fcf85f084db1a8dc577a339fbee58b61575f565b6000818311612bcd5782611071565b50919050565b606080612bde613ac1565b6001600160a01b031663277c9d45846040518263ffffffff1660e01b8152600401612c0b91815260200190565b6000604051808303816000875af1158015612c2a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c529190810190615d34565b91509150915091565b6000610ed361251160017fb649e50315f962b32d487e696a81b4828631b11f8424daaaa37e9e97766a2c4261575f565b6030835114612cad5760405163050cb55360e41b815260040160405180910390fd5b6060825114612ccf5760405163408ebd3960e01b815260040160405180910390fd5b6801bc16d674ec8000006000612ce9633b9aca0083615716565b90506000600286600060801b604051602001612d06929190615d97565b60408051601f1981840301815290829052612d2091615dc6565b602060405180830381855afa158015612d3d573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612d609190615de2565b90506000600280612d748860006040614a14565b604051612d819190615dc6565b602060405180830381855afa158015612d9e573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612dc19190615de2565b6002612dd9896040612dd481606061575f565b614a14565b604051612dec9190600090602001615dfb565b60408051601f1981840301815290829052612e0691615dc6565b602060405180830381855afa158015612e23573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612e469190615de2565b60408051602081019390935282015260600160408051601f1981840301815290829052612e7291615dc6565b602060405180830381855afa158015612e8f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612eb29190615de2565b905060006002808488604051602001612ed5929190918252602082015260400190565b60408051601f1981840301815290829052612eef91615dc6565b602060405180830381855afa158015612f0c573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612f2f9190615de2565b6002612f3a87614ad7565b604080516020810192909252810186905260600160408051601f1981840301815290829052612f6891615dc6565b602060405180830381855afa158015612f85573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612fa89190615de2565b60408051602081019390935282015260600160408051601f1981840301815290829052612fd491615dc6565b602060405180830381855afa158015612ff1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906130149190615de2565b90506000613022864761575f565b905061302c614b44565b6001600160a01b03166322895118878b8a60405160200161304f91815260200190565b6040516020818303038152906040528c876040518663ffffffff1660e01b815260040161307f9493929190615e1d565b6000604051808303818588803b15801561309857600080fd5b505af11580156130ac573d6000803e3d6000fd5b50505050508047146130d157604051638051a6bb60e01b815260040160405180910390fd5b505050505050505050565b7f86fd21e9b5bd76b20471c7f93a82aa4e25c37d48b179bda0a4d1a45e22a842f4613105612b8e565b60408051918252602082018490520160405180910390a161130281614b74565b6000610ed361251160017fc77078e3530c08cdb2440817c81de4836500b4708ea4d15672b7fe98956423a861575f565b6113026124d860017fc77078e3530c08cdb2440817c81de4836500b4708ea4d15672b7fe98956423a861575f565b60008061318e612b29565b600581015490915063ffffffff1660006131a6613125565b90508082101561321b576801bc16d674ec8000006131c4838361575f565b6131ce9190615740565b6131d661361e565b6131de612b8e565b6131e66124e1565b86600101546131f5919061566a565b6131ff919061566a565b613209919061566a565b613213919061566a565b935050505090565b61322361361e565b61322b612b8e565b6132336124e1565b85600101546131ff919061566a565b6000610ed361251160017ff4271262f3552a4108cde54dc75061de8de495709221d793b126e448522d6a8061575f565b6000610ed361193a565b60006132a960017ff81b149de6749a3f46464b2cce61e24462f67599ea4a5ce028aaf4ab1521f96e61575f565b8251815560209092015160019092019190915550565b6000610ed3614ba2565b6000610ed361251160017f094efef62d2ce60c14ffacd35a1b50546d3a9d503aff1df040176fffd6c92a3761575f565b6000613303612a7d565b60405163e838dfbb60e01b81529091506001600160a01b0382169063e838dfbb90613332908690600401615217565b602060405180830381865afa15801561334f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133739190615c51565b15613393578260405163e7d05e2760e01b8152600401610d5e9190615217565b60405163e838dfbb60e01b81526001600160a01b0382169063e838dfbb906133bf908590600401615217565b602060405180830381865afa1580156133dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134009190615c51565b15613420578160405163e7d05e2760e01b8152600401610d5e9190615217565b505050565b600061177382613732565b600061343c83336136da565b90508181101561347e57604051637b936de360e01b81526001600160a01b03841660048201523360248201526044810182905260648101839052608401610d5e565b600019811461342057613420833361175b858561575f565b61349f81613b51565b6113026124d860017f082b6d18de7b10e438e6b1002141db737519cb4ceed679bc815e3aac00cd222761575f565b6134d681614bd2565b6113026124d860017f094efef62d2ce60c14ffacd35a1b50546d3a9d503aff1df040176fffd6c92a3761575f565b61350d81613b51565b6113026124d860017f867d8f1a5e39d11d5bebde854d5359a509530ad32450f581da63c06ec8d1a78061575f565b61354481613b51565b6113026124d860017f3f075dea7ef99b1e5db245018e5e4ed8d2a0d93953f5932b2176bef59bd6906161575f565b61357b82614bf5565b6040516001600160a01b038316907e043cf7635f276413ae358250286a479a631abd9d74d57d4aa0bb87ebc7d11790600090a26135b781614c2c565b6040518181527f4c86ba184ea1a1558f84835ca34f6d67e222e8ee5cc4f324b8861dda4cf1740c9060200160405180910390a15050565b6000610ed361251160017f8e9e2a1d30fed357d8a000c1131fc77ed65d2052918caf1ccc6eb1e7af3d13b661575f565b6000610ed361251160017f850308dd4e453a2a1bc3efb444560401d95c1a8bdea5b35c5c79531cd2241f1d61575f565b613656614eea565b600061368360017fd84ee2c84c954c65bef1459fe03b761a42f49234527e3cd8fd9dce87cb83742b61575f565b6040805160a08101825282546001600160401b038082168352600160401b820481166020840152600160801b8204811693830193909352600160c01b90048216606082015260019092015416608082015292915050565b60008061370860017fc852254d5b703a16bb13b3e233a335d6459c5da5db0ca732d7a684ee0540784761575f565b6001600160a01b039485166000908152602091825260408082209590961681529390525050205490565b60008061376060017f0fb4a5ac9287f4f508aa7253ee2d57c6a228b1b30e210d73fffd59389d3a883861575f565b6001600160a01b0390931660009081526020939093525050604090205490565b60008061378b614ba2565b90508061379b5750600092915050565b806137a4613183565b6137ae9085615740565b6110719190615716565b600081602001516001600160401b031682604001516001600160401b031683606001516001600160401b0316426137ef919061575f565b6137f99190615716565b6117739190615716565b6000818310612bcd5782611071565b6000610ed361251160017f082b6d18de7b10e438e6b1002141db737519cb4ceed679bc815e3aac00cd222761575f565b805161130257604051638d46fe0560e01b815260040160405180910390fd5b600061388e60017fb63f3482ec84cb93d74a71645ad2e9e896fa02723e42170b4aad20a4bed6cdd661575f565b825190915081906138a59082906020860190614f93565b50505050565b60006138d860017fd84ee2c84c954c65bef1459fe03b761a42f49234527e3cd8fd9dce87cb83742b61575f565b825181546020850151604086015160608701516001600160401b039485166001600160801b031990941693909317600160401b92851692909202919091176001600160801b0316600160801b918416919091026001600160c01b031617600160c01b918316919091021782556080909301516001909101805467ffffffffffffffff1916919093161790915550565b600080613972614ba2565b9050806139825750600092915050565b61398a613183565b6137ae8285615740565b61399d81613b51565b6113026124d860017fc8cbea9407c380ae944f052b5a442330057683c5abdbd453493f9750806afecb61575f565b6000610ed361251160017fc8cbea9407c380ae944f052b5a442330057683c5abdbd453493f9750806afecb61575f565b60606000613a2a60017fb63f3482ec84cb93d74a71645ad2e9e896fa02723e42170b4aad20a4bed6cdd661575f565b805490915081908190613a3c90615e68565b80601f0160208091040260200160405190810160405280929190818152602001828054613a6890615e68565b8015613ab55780601f10613a8a57610100808354040283529160200191613ab5565b820191906000526020600020905b815481529060010190602001808311613a9857829003601f168201915b50505050509250505090565b6000610ed361251160017f3f075dea7ef99b1e5db245018e5e4ed8d2a0d93953f5932b2176bef59bd6906161575f565b60408051808201909152600080825260208201526000613b3260017ff81b149de6749a3f46464b2cce61e24462f67599ea4a5ce028aaf4ab1521f96e61575f565b6040805180820190915281548152600190910154602082015292915050565b6001600160a01b0381166113025760405163f6b2911f60e01b815260040160405180910390fd5b60408051808201909152600080825260208201526000613bb960017fc305db9f63aeed94a45229ff5ab4174e72b223a38ab4c5e8f518ee4f437918d161575f565b6040805180820190915290546001600160801b038082168352600160801b90910416602082015292915050565b600082608001516001600160401b031682613c01919061566a565b613c0a846137b8565b10158015613c1f5750613c1b612b29565b5482115b801561107157508251613c3b906001600160401b0316836157a8565b159392505050565b600083602001518460400151613c599190615e9d565b6001600160401b0316613c6c848461575f565b613c769190615740565b949350505050565b476000613c8b838561566a565b9050613c95612c5b565b6001600160a01b031663ea74f479826040518263ffffffff1660e01b8152600401613cc291815260200190565b600060405180830381600087803b158015613cdc57600080fd5b505af1158015613cf0573d6000803e3d6000fd5b5050505060008247613d02919061575f565b9050613d0e848661566a565b8114613d4257613d1e848661566a565b6040516349a1938b60e01b8152600481019190915260248101829052604401610d5e565b8415613d5457613d5485610cc66124e1565b8315613d7557613d7584613d6661361e565b613d70919061566a565b614c78565b60408051868152602081018690527fcb5410dc8f29b2f498e023c3f9237dbd600255a717edf94a6072bcd03b0c773c91016123f8565b6000613dd860017fdbc0527c99b54cd325d6ce9eaae3a8413cd447b5205f37385f0ebc6551033c6d61575f565b825181556020830151600182015560408301516002820155606083015160038201556080830151600482015560a08301516005909101805460c085015160e0909501511515600160281b0265ff0000000000199515156401000000000264ffffffffff1990921663ffffffff9094169390931717939093161790915550565b6000613e696301e13380612710615740565b84518390613e779086615740565b613e819190615740565b613c769190615716565b60006127108360200151836137ae9190615740565b600080613eab6135ee565b60405163c8a6dfd360e01b81526004810185905290915047906001600160a01b0383169063c8a6dfd390602401600060405180830381600087803b158015613ef257600080fd5b505af1158015613f06573d6000803e3d6000fd5b5050505060008147613f18919061575f565b90508015613f2c57613f2c81610cc66124e1565b6040518181527fda841d3042d792e2509a333b9dcbd4b3dd9b9047d382011f8788fab90ca7e3c7906020015b60405180910390a1949350505050565b600047613f736129ba565b6001600160a01b0316630c779401846040518263ffffffff1660e01b8152600401613fa091815260200190565b600060405180830381600087803b158015613fba57600080fd5b505af1158015613fce573d6000803e3d6000fd5b5050505060008147613fe0919061575f565b90508015613ff457613ff481610cc66124e1565b6040518181527f4e484734eb4d444bfa106f917d05d9ceb8ce18bf516c85d7aeb9b322925339f99060200160405180910390a19392505050565b600080614039613242565b90506001600160a01b0381166140525750600092915050565b604051638ede6b6b60e01b81526004810184905247906001600160a01b03831690638ede6b6b90602401600060405180830381600087803b15801561409657600080fd5b505af11580156140aa573d6000803e3d6000fd5b50505050600081476140bc919061575f565b905080156140d0576140d081610cc66124e1565b6040518181527fd500b67e5bd8019c0af744cadeec120d1b5e3d3a3a011f18cf182aa4c97947b690602001613f58565b600061410a6132bf565b90508061412a57604051630d35acd760e21b815260040160405180910390fd5b6000614134613183565b905060006141406132c9565b905060008161414f8587615740565b6141599190615740565b905060006141678387615740565b61417361271086615740565b61417d919061575f565b905060008115614196576141918284615716565b614199565b60005b905080156142295760006141ab613812565b90506141b78183614cc1565b60006141c16132bf565b905060006141cf8a8961575f565b60408051828152602081018c90529081018a9052606081018490529091506001600160a01b038416907f3d1669e813a9845c288f0e1f642a4343a451103b87886d12de37e63b39bbd9429060800160405180910390a25050505b50505050505050565b61423a613ac1565b6001600160a01b031663b405e17484614251613125565b6040518363ffffffff1660e01b815260040161426e929190615ecc565b600060405180830381600087803b15801561428857600080fd5b505af115801561429c573d6000803e3d6000fd5b5050505080156142ab576138a5565b60006142b56132bf565b905080156126ef5760006142c761361e565b905060006142d36124e1565b905060006143436142e26129ba565b6001600160a01b0316630d8d2a546040518163ffffffff1660e01b8152600401602060405180830381865afa15801561431f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176e9190615de2565b905080614350898561566a565b1015612941578580156143635750600082115b156143b457600061438883856143798c8661575f565b614383919061575f565b612bbe565b905080156143b25761439a818561566a565b93506143a584614c78565b6143b2610cd0828561575f565b505b60006143be613ac1565b9050600080826001600160a01b0316634a3c63bb6040518163ffffffff1660e01b81526004016040805180830381865afa158015614400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144249190615f1a565b915063ffffffff16915060006801bc16d674ec800000838311614448576000614452565b614452848461575f565b61445c9190615740565b9050848161446a8e8a61566a565b614474919061566a565b101561451f5760006144ad8261448a8f8b61566a565b614494919061566a565b61449e908861575f565b6801bc16d674ec800000614d1e565b9050846001600160a01b0316632d1fc39d826144c7613125565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561450557600080fd5b505af1158015614519573d6000803e3d6000fd5b50505050505b505050505050505050505050565b60006145376129ba565b90506000614543613183565b9050600061454f6132bf565b90506000821180156145615750600081115b15613420576000836001600160a01b0316630d8d2a546040518163ffffffff1660e01b8152600401602060405180830381865afa1580156145a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145ca9190615de2565b90508060006145d882613780565b905060006145e461361e565b9050808211156145fd578091506145fa82613967565b92505b60408051858152602081018590529081018390527f709263092d8d9fef472d907900405b5edae3d76f8ff4354858025b18424d71019060600160405180910390a1811561422957614651613d70838361575f565b61465b8784614d51565b60405163b30d8bb760e01b8152600481018490526001600160a01b0388169063b30d8bb79084906024016000604051808303818588803b15801561469e57600080fd5b505af115801561451f573d6000803e3d6000fd5b60006146bc61361e565b90508015611302576146d081610cc66124e1565b6113026000614c78565b60006146e4613183565b905060006146f06124e1565b905060006146fc613b78565b8051909150600090614740906001600160801b031661271061471e868861575f565b85602001516001600160801b03166147369190615740565b6117e99190615716565b90506000614765620151806147558885615740565b61475f9190615716565b85612bbe565b905080156126ed5761478381614779612b8e565b611243919061566a565b6126ed610cd0828661575f565b6113026124d860017f2b6136e423ab70d76431e2a635e877e16ea2dd9a895e054ad7f35f89d6c7b71161575f565b600080826147ca613183565b6147d4919061575f565b9050806147ed578291506147e88484614cc1565b614816565b806147f66132bf565b6148009085615740565b61480a9190615716565b91506148168483614cc1565b5092915050565b6000610ed361251160017fb5b37715a3e346e996104f0086703f19825def429233930fd9399c38e05fb11361575f565b600061487a60017fc305db9f63aeed94a45229ff5ab4174e72b223a38ab4c5e8f518ee4f437918d161575f565b82516020909301516001600160801b03908116600160801b0293169290921790915550565b6000610ed361251160017fd7f2d45e512a86049f7a113657b39731b6b558609584243063a52cd31a8eb52961575f565b6000610ed361251160017ffedfd2c285a57fb23bf45a3fe9ac02d36a76ebb72801b1c8aaf553d74e9d465361575f565b6000610ed361251160017f0f1e7733641e4d843128fea0d2ec90d3d06a40b0fe244ff603d8c1aa200dc0f961575f565b600061495c60017fc852254d5b703a16bb13b3e233a335d6459c5da5db0ca732d7a684ee0540784761575f565b6001600160a01b039485166000908152602091825260408082209590961681529390525091902055565b6000610ed361251160017f6e6ab8b7c7aaba79eef8cc633522d606bb008c101cf9832c9ad05d10a984728161575f565b61130281614da1565b61130281614dd8565b60006149f560017f0fb4a5ac9287f4f508aa7253ee2d57c6a228b1b30e210d73fffd59389d3a883861575f565b6001600160a01b03909316600090815260209390935250604090912055565b60608182601f011015614a3a576040516323d5783d60e11b815260040160405180910390fd5b614a44828461566a565b84511015614a6557604051633b99b53d60e01b815260040160405180910390fd5b606082158015614a845760405191506000825260208201604052614ace565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614abd578051835260209283019201614aa5565b5050858452601f01601f1916604052505b50949350505050565b603881901c60ff908116603083901c8216602884901c8316602085901c8416601886901c8516601087901c8616600888811c9790971688881b61ff001617871b17861b17851b17841b17831b1790911b17604082901c8015614b3b57614b3b615f48565b5060c01b919050565b6000610ed361251160017f35efb61d8784060218d9d6aa40eae55904de43779c1afc79c74dfefcfdf9126061575f565b6113026124d860017fbcfa5a69252c74010ad3e9ab18cfbdc116fcf85f084db1a8dc577a339fbee58b61575f565b6000610ed361251160017f6b842b424335d94ccad97e54548dfa02673c1268aba38d3c3c32d28c8988b70b61575f565b612710811115611302576040516358d620b360e01b815260040160405180910390fd5b614bfe81613b51565b6113026124d860017f35efb61d8784060218d9d6aa40eae55904de43779c1afc79c74dfefcfdf9126061575f565b80614c4a5760405163a9cb9e0d60e01b815260040160405180910390fd5b6113026124d860017fb649e50315f962b32d487e696a81b4828631b11f8424daaaa37e9e97766a2c4261575f565b7f215c2b83e8c232e42091088056ab75d2ff643855c32997024f786cddb22d2290614ca161361e565b60408051918252602082018490520160405180910390a161130281614e06565b614cdc81614ccd614ba2565b614cd7919061566a565b614e34565b614cea8282612ada85613732565b6040518181526001600160a01b03831690600090600080516020615f5f833981519152906020015b60405180910390a35050565b600080614d2b83856157a8565b11614d37576000614d3a565b60015b60ff16614d478385615716565b611071919061566a565b614d6781614d5d614ba2565b614cd7919061575f565b614d758282612abd85613732565b6040518181526000906001600160a01b03841690600080516020615f5f83398151915290602001614d12565b614daa81613b51565b6113026124d860017fb5b37715a3e346e996104f0086703f19825def429233930fd9399c38e05fb11361575f565b6113026124d860017f6e6ab8b7c7aaba79eef8cc633522d606bb008c101cf9832c9ad05d10a984728161575f565b6113026124d860017f850308dd4e453a2a1bc3efb444560401d95c1a8bdea5b35c5c79531cd2241f1d61575f565b614e3d81614e6d565b6040518181527fc80ea35a3f9016535e5b7c87746740c5045afe42188d02c5786eb97495c2f42990602001611397565b6113026124d860017f6b842b424335d94ccad97e54548dfa02673c1268aba38d3c3c32d28c8988b70b61575f565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600063ffffffff1681526020016000151581526020016000151581525090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604051806101400160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001614f8e6040518060800160405280600081526020016000815260200160008152602001600081525090565b905290565b828054614f9f90615e68565b90600052602060002090601f016020900481019282614fc15760008555615007565b82601f10614fda57805160ff1916838001178555615007565b82800160010185558215615007579182015b82811115615007578251825591602001919060010190614fec565b50615013929150615017565b5090565b5b808211156150135760008155600101615018565b80356001600160a01b038116811461504357600080fd5b919050565b60006020828403121561505a57600080fd5b6110718261502c565b80356001600160401b038116811461504357600080fd5b80356001600160801b038116811461504357600080fd5b6000806000806000806000806000806101408b8d0312156150b157600080fd5b6150ba8b61502c565b99506150c860208c01615063565b98506150d660408c01615063565b97506150e460608c01615063565b96506150f260808c01615063565b955061510060a08c01615063565b945060c08b0135935060e08b0135925061511d6101008c0161507a565b915061512c6101208c0161507a565b90509295989b9194979a5092959850565b60005b83811015615158578181015183820152602001615140565b838111156138a55750506000910152565b6000815180845261518181602086016020860161513d565b601f01601f19169290920160200192915050565b6020815260006110716020830184615169565b600080604083850312156151bb57600080fd5b6151c48361502c565b946020939093013593505050565b600080604083850312156151e557600080fd5b823591506151f56020840161502c565b90509250929050565b60006020828403121561521057600080fd5b5035919050565b6001600160a01b0391909116815260200190565b600060408284031215612bcd57600080fd5b60008060006060848603121561525257600080fd5b61525b8461502c565b92506152696020850161502c565b9150604084013590509250925092565b60008060008060008060008060006101208a8c03121561529857600080fd5b6152a18a61502c565b98506152af60208b0161502c565b975060408a013596506152c460608b0161502c565b95506152d260808b0161502c565b94506152e060a08b0161502c565b93506152ee60c08b0161502c565b92506152fc60e08b0161502c565b91506101008a013590509295985092959850929598565b60008083601f84011261532557600080fd5b5081356001600160401b0381111561533c57600080fd5b6020830191508360208260051b850101111561535757600080fd5b9250929050565b6000806020838503121561537157600080fd5b82356001600160401b0381111561538757600080fd5b61539385828601615313565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156153da57835160070b835292840192918401916001016153bb565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561541e5761541e6153e6565b60405290565b604051601f8201601f191681016001600160401b038111828210171561544c5761544c6153e6565b604052919050565b60006001600160401b0382111561546d5761546d6153e6565b50601f01601f191660200190565b60006020828403121561548d57600080fd5b81356001600160401b038111156154a357600080fd5b8201601f810184136154b457600080fd5b80356154c76154c282615454565b615424565b8181528560208385010111156154dc57600080fd5b81602084016020830137600091810160200191909152949350505050565b600060a08284031215612bcd57600080fd5b6000806000806040858703121561552257600080fd5b84356001600160401b038082111561553957600080fd5b61554588838901615313565b9096509450602087013591508082111561555e57600080fd5b5061556b87828801615313565b95989497509550505050565b6020808252825182820181905260009190848201906040850190845b818110156153da57835160ff1683529284019291840191600101615593565b6000604082840312156155c457600080fd5b6155cc6153fc565b6155d58361507a565b81526155e36020840161507a565b60208201529392505050565b6000806040838503121561560257600080fd5b61560b8361502c565b91506151f56020840161502c565b60006020828403121561562b57600080fd5b81356001600160401b0381111561564157600080fd5b8201610120818503121561107157600080fd5b634e487b7160e01b600052601160045260246000fd5b6000821982111561567d5761567d615654565b500190565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b6001600160a01b03929092168252602082015260400190565b63ffffffff8116811461130257600080fd5b6000602082840312156156f557600080fd5b8151611071816156d1565b634e487b7160e01b600052601260045260246000fd5b60008261572557615725615700565b500490565b634e487b7160e01b600052603260045260246000fd5b600081600019048311821515161561575a5761575a615654565b500290565b60008282101561577157615771615654565b500390565b60006040828403121561578857600080fd5b6157906153fc565b82358152602083013560208201528091505092915050565b6000826157b7576157b7615700565b500690565b8035615043816156d1565b8183526000602080850194508260005b858110156158025781356157ea816156d1565b63ffffffff16875295820195908201906001016157d7565b509495945050505050565b602081526000613c766020830184866157c7565b60006001600160401b0382111561583a5761583a6153e6565b5060051b60200190565b6000602080838503121561585757600080fd5b82516001600160401b0381111561586d57600080fd5b8301601f8101851361587e57600080fd5b805161588c6154c282615821565b81815260059190911b820183019083810190878311156158ab57600080fd5b928401925b828410156158d95783518060070b81146158ca5760008081fd5b825292840192908401906158b0565b979650505050505050565b600060a082840312156158f657600080fd5b60405160a081018181106001600160401b0382111715615918576159186153e6565b60405261592483615063565b815261593260208401615063565b602082015261594360408401615063565b604082015261595460608401615063565b606082015261596560808401615063565b60808201529392505050565b60006020828403121561598357600080fd5b61107182615063565b6001600160401b0395861681529385166020850152918416604084015283166060830152909116608082015260a00190565b6080815260006159d260808301888a6157c7565b82810360208401526159e58187896157c7565b9415156040840152505061ffff91909116606090910152949350505050565b60006020808385031215615a1757600080fd5b82516001600160401b03811115615a2d57600080fd5b8301601f81018513615a3e57600080fd5b8051615a4c6154c282615821565b81815260059190911b82018301908381019087831115615a6b57600080fd5b928401925b828410156158d957835160ff81168114615a8a5760008081fd5b82529284019290840190615a70565b600060208284031215615aab57600080fd5b8135611071816156d1565b801515811461130257600080fd5b803561504381615ab6565b600060208284031215615ae157600080fd5b813561107181615ab6565b6000808335601e19843603018112615b0357600080fd5b8301803591506001600160401b03821115615b1d57600080fd5b6020019150600581901b360382131561535757600080fd5b6000808335601e19843603018112615b4c57600080fd5b83016020810192503590506001600160401b03811115615b6b57600080fd5b8060051b360383131561535757600080fd5b60a08152823560a0820152602083013560c0820152604083013560e08201526000610100606085013581840152610120608086013581850152615bc260a087016157bc565b63ffffffff16610140850152615bdb60c0870187615b35565b82610160870152615bf16101c0870182846157c7565b92505050615c0160e08701615ac4565b1515610180850152615c14868301615ac4565b8015156101a08601529150915061107190506020830184805182526020810151602083015260408101516040830152606081015160608301525050565b600060208284031215615c6357600080fd5b815161107181615ab6565b600082601f830112615c7f57600080fd5b81516020615c8f6154c283615821565b82815260059290921b84018101918181019086841115615cae57600080fd5b8286015b84811015615d295780516001600160401b03811115615cd15760008081fd5b8701603f81018913615ce35760008081fd5b848101516040615cf56154c283615454565b8281528b82848601011115615d0a5760008081fd5b615d198389830184870161513d565b8652505050918301918301615cb2565b509695505050505050565b60008060408385031215615d4757600080fd5b82516001600160401b0380821115615d5e57600080fd5b615d6a86838701615c6e565b93506020850151915080821115615d8057600080fd5b50615d8d85828601615c6e565b9150509250929050565b60008351615da981846020880161513d565b6001600160801b0319939093169190920190815260100192915050565b60008251615dd881846020870161513d565b9190910192915050565b600060208284031215615df457600080fd5b5051919050565b60008351615e0d81846020880161513d565b9190910191825250602001919050565b608081526000615e306080830187615169565b8281036020840152615e428187615169565b90508281036040840152615e568186615169565b91505082606083015295945050505050565b600181811c90821680615e7c57607f821691505b60208210811415612bcd57634e487b7160e01b600052602260045260246000fd5b60006001600160401b0380831681851681830481118215151615615ec357615ec3615654565b02949350505050565b604080825283519082018190526000906020906060840190828701845b82811015615f0b57815163ffffffff1684529284019290840190600101615ee9565b50505092019290925292915050565b60008060408385031215615f2d57600080fd5b8251615f38816156d1565b6020939093015192949293505050565b634e487b7160e01b600052600160045260246000fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122075e48ff7ca1ef56a4380c2b504633a9f2bf34000bc77bdf03103b2444951f22564736f6c634300080a0033
Deployed Bytecode
0x6080604052600436106103ba5760003560e01c80635d95e801116101f9578063a29a839f1161011e578063d4970524116100b6578063efd668461161007a578063efd6684614610c07578063f79c3f0214610c27578063f9f95a9014610c47578063fb5b82d014610c67578063fe7c12ae14610c87576103ca565b8063d497052414610b9b578063d7f8f47414610790578063dd62ed3e14610ba3578063e3a88e6114610bc3578063efd6034714610bff576103ca565b8063a29a839f14610acc578063a457c2d714610ae1578063a9059cbb14610b01578063ac232bde14610b21578063bb6583ec14610b34578063bf15af5614610b54578063c5eff3d014610b69578063d046815614610b7e578063d0e30db014610b93576103ca565b80637adbf973116101915780637adbf973146109b8578063833b1fce146109d857806386a92af7146109ed57806387f2adfb14610a0257806389896aef14610a175780639332525d14610a2c57806395d89b4114610a595780639b498e2614610a875780639d49cca114610a9c576103ca565b80635d95e801146108a95780635f2e5f07146108b157806363f62aaf146108de5780636e9960c3146108f357806370a082311461090857806372f79b1314610928578063750521f51461095857806378a010e814610978578063799a195414610998576103ca565b806323b872dd116102df5780633af9e669116102775780633af9e669146107cd57806346425ef0146107ed5780634b47b74f146108025780635022820114610817578063540bc5ea1461082c578063557ed1ba14610841578063563967151461085457806357fa85471461086957806358bf3c7f14610889576103ca565b806323b872dd14610686578063281a3122146106a6578063291206f6146106c65780632cb562e1146106e65780632d6b59bf146106fb5780632dc5c97c14610710578063313ce5671461077457806336bf33251461079057806339509351146107ad576103ca565b80631311cf8d116103525780631311cf8d1461052557806313d86aed14610545578063143a08d414610565578063147bf6c41461057a5780631546962b1461059a57806315ca4cee146105bc57806317e64858146105dc57806318160ddd1461065c5780631bcbfaba14610671576103ca565b8063020f086e146103e35780630407de471461040357806304843a1714610423578063056850c61461044b57806306fdde0314610453578063095ea7b3146104965780630e18b681146104c6578063107703ab146104db578063107d7fa014610510576103ca565b366103ca576103c833610c9c565b005b60405163574b16a760e11b815260040160405180910390fd5b3480156103ef57600080fd5b506103c86103fe366004615048565b610d23565b34801561040f57600080fd5b506103c861041e366004615091565b610da7565b34801561042f57600080fd5b50610438610ec9565b6040519081526020015b60405180910390f35b6103c8610ed8565b34801561045f57600080fd5b50604080518082019091526011815270098d2e2ead2c840a6e8c2d6cac8408aa89607b1b60208201525b6040516104429190615195565b3480156104a257600080fd5b506104b66104b13660046151a8565b610f15565b6040519015158152602001610442565b3480156104d257600080fd5b506103c8610f2b565b3480156104e757600080fd5b506104fb6104f63660046151d2565b610f80565b60405163ffffffff9091168152602001610442565b34801561051c57600080fd5b50610438611078565b34801561053157600080fd5b506103c8610540366004615048565b611091565b34801561055157600080fd5b506103c86105603660046151fe565b61110c565b34801561057157600080fd5b506104386112b4565b34801561058657600080fd5b506103c8610595366004615048565b6112be565b3480156105a657600080fd5b506105af611305565b6040516104429190615217565b3480156105c857600080fd5b506103c86105d736600461522b565b61130f565b3480156105e857600080fd5b506105f16113a2565b6040516104429190600061010082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015263ffffffff60a08401511660a083015260c0830151151560c083015260e0830151151560e083015292915050565b34801561066857600080fd5b50610438611425565b34801561067d57600080fd5b5061043861142f565b34801561069257600080fd5b506104b66106a136600461523d565b611439565b3480156106b257600080fd5b506103c86106c1366004615279565b6114ec565b3480156106d257600080fd5b506103c86106e13660046151fe565b6116a7565b3480156106f257600080fd5b506105af61171b565b34801561070757600080fd5b50610438611725565b34801561071c57600080fd5b5061072561172f565b604051610442919081516001600160401b039081168252602080840151821690830152604080840151821690830152606080840151821690830152608092830151169181019190915260a00190565b34801561078057600080fd5b5060405160128152602001610442565b34801561079c57600080fd5b506104386801bc16d674ec80000081565b3480156107b957600080fd5b506104b66107c83660046151a8565b61173f565b3480156107d957600080fd5b506104386107e8366004615048565b611760565b3480156107f957600080fd5b50610438611779565b34801561080e57600080fd5b5061043861178c565b34801561082357600080fd5b506105af6117f5565b34801561083857600080fd5b50610438606081565b34801561084d57600080fd5b5042610438565b34801561086057600080fd5b506104386117ff565b34801561087557600080fd5b506104386108843660046151fe565b611809565b34801561089557600080fd5b506103c86108a4366004615048565b611831565b6103c86118ac565b3480156108bd57600080fd5b506108d16108cc36600461535e565b6118b4565b604051610442919061539f565b3480156108ea57600080fd5b506105af611930565b3480156108ff57600080fd5b506105af61193a565b34801561091457600080fd5b50610438610923366004615048565b611944565b34801561093457600080fd5b5061093d61194f565b60408051938452602084019290925290820152606001610442565b34801561096457600080fd5b506103c861097336600461547b565b611a1f565b34801561098457600080fd5b506103c86109933660046154fa565b611a9b565b3480156109a457600080fd5b506104386109b33660046151fe565b611b6c565b3480156109c457600080fd5b506103c86109d3366004615048565b611b77565b3480156109e457600080fd5b506105af611bf2565b3480156109f957600080fd5b50610489611bfc565b348015610a0e57600080fd5b50610438611c06565b348015610a2357600080fd5b50610438611c10565b348015610a3857600080fd5b50610a4c610a4736600461550c565b611c20565b6040516104429190615577565b348015610a6557600080fd5b50604080518082019091526005815264098e68aa8960db1b6020820152610489565b348015610a9357600080fd5b506105af611cb2565b348015610aa857600080fd5b50610ab1611cbc565b60408051825181526020928301519281019290925201610442565b348015610ad857600080fd5b50610438611cd8565b348015610aed57600080fd5b506104b6610afc3660046151a8565b611cea565b348015610b0d57600080fd5b506104b6610b1c3660046151a8565b611d06565b6103c8610b2f366004615048565b611da5565b348015610b4057600080fd5b506103c8610b4f3660046155b2565b611db7565b348015610b6057600080fd5b50610438603081565b348015610b7557600080fd5b506105af611dfb565b348015610b8a57600080fd5b506105af611e05565b6103c8611e0f565b6103c8611e18565b348015610baf57600080fd5b50610438610bbe3660046155ef565b611e20565b348015610bcf57600080fd5b50610bd8611e2c565b6040805182516001600160801b039081168252602093840151169281019290925201610442565b6103c8611e48565b348015610c1357600080fd5b506103c8610c22366004615619565b611e50565b348015610c3357600080fd5b50610438610c423660046151fe565b612407565b348015610c5357600080fd5b506104b6610c623660046151fe565b612412565b348015610c7357600080fd5b506103c8610c82366004615048565b612425565b348015610c9357600080fd5b506104386124a0565b34610cba576040516395b66fe960e01b815260040160405180910390fd5b610cd534610cc66124e1565b610cd0919061566a565b612515565b610ce033823461255e565b6040513481526001600160a01b0382169033907f3bc57f469ad6d10d7723ea226cd22bd2b9e527def2b529f6ab44645a166895829060200160405180910390a350565b610d2b6126f6565b6001600160a01b0316336001600160a01b031614610d67573360405163472511eb60e11b8152600401610d5e9190615217565b60405180910390fd5b610d7081612700565b6040516001600160a01b038216907f67b26a33f305cc027b2d45b2f6f418793afcd3e22f7376afa7be068ce18604e890600090a250565b6001610db1612737565b8114610de25780610dc0612737565b604051631cfd276760e31b815260048101929092526024820152604401610d5e565b610df5610df082600161566a565b6124aa565b610dfe8b612767565b7faf890c07e266df31e0725841eb0e85596a0caa1b17bbae5c0b206fdcc92d7ce18b604051610e2d9190615217565b60405180910390a1610e646040518060400160405280856001600160801b03168152602001846001600160801b031681525061279e565b610e738a8a8a8a8a8a8a6127f2565b610e80308c60001961294b565b7f1809e49bba43f2d39fa57894b50cd6ccb428cc438230e065cac3eb24a1355a7181600036604051610eb493929190615682565b60405180910390a15050505050505050505050565b6000610ed36124e1565b905090565b610ee06129ba565b6001600160a01b0316336001600160a01b031614610f13573360405163472511eb60e11b8152600401610d5e9190615217565b565b6000610f2233848461294b565b50600192915050565b610f336129ea565b6001600160a01b0316336001600160a01b031614610f66573360405163472511eb60e11b8152600401610d5e9190615217565b610f76610f716129ea565b6129f4565b610f136000612a3d565b6000610f8a612a7d565b6001600160a01b0316635a4091023360046040518363ffffffff1660e01b8152600401610fb89291906156b8565b60006040518083038186803b158015610fd057600080fd5b505afa158015610fe4573d6000803e3d6000fd5b50505050610ff3333085612aad565b50610ffc6129ba565b60405163107703ab60e01b8152600481018590526001600160a01b038481166024830152919091169063107703ab906044016020604051808303816000875af115801561104d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107191906156e3565b9392505050565b6000611082612b29565b6005015463ffffffff16919050565b6110996126f6565b6001600160a01b0316336001600160a01b0316146110cc573360405163472511eb60e11b8152600401610d5e9190615217565b6110d581612b57565b6040516001600160a01b038216907f1da4c245099590dc40be61880c9b97792f3694d970acc1e67ac0e6cc90f3780d90600090a250565b6000611116612b8e565b905060006111366111306801bc16d674ec80000084615716565b84612bbe565b90508061115657604051631036b5ad60e31b815260040160405180910390fd5b60008061116283612bd3565b81519193509150806111875760405163200149ad60e21b815260040160405180910390fd5b838111156111a857604051635993bd5760e01b815260040160405180910390fd5b60006111b2612c5b565b9050806111d257604051639be7315960e01b815260040160405180910390fd5b60005b828110156112225761121a8582815181106111f2576111f261572a565b602002602001015185838151811061120c5761120c61572a565b602002602001015184612c8b565b6001016111d5565b50611248611239836801bc16d674ec800000615740565b611243908861575f565b6130dc565b6000611252613125565b9050611266611261848361566a565b613155565b7f220ab8fd274cf58c09b0825ccf00e74ba4ce4117fd47285adc2183a635838f1b81611292858261566a565b6040805192835260208301919091520160405180910390a15050505050505050565b6000610ed3613183565b6112c66126f6565b6001600160a01b0316336001600160a01b0316146112f9573360405163472511eb60e11b8152600401610d5e9190615217565b61130281612a3d565b50565b6000610ed3613242565b611317613272565b6001600160a01b0316336001600160a01b03161461134a573360405163472511eb60e11b8152600401610d5e9190615217565b61136161135c36839003830183615776565b61327c565b6040805182358152602080840135908201527f5ab79ffcd89b6380c7fbdd89d02cfe3d9c53c99a85e150c2319075018d1aac5c91015b60405180910390a150565b6113aa614e9b565b6113b2612b29565b60408051610100810182528254815260018301546020820152600283015491810191909152600382015460608201526004820154608082015260059091015463ffffffff811660a083015260ff64010000000082048116151560c0840152600160281b90910416151560e0820152919050565b6000610ed36132bf565b6000610ed36132c9565b6000838361144782826132f9565b8380611466576040516336b216db60e21b815260040160405180910390fd5b86858061147283613425565b1015611491576040516351940b3960e11b815260040160405180910390fd5b6001600160a01b0388166114ca57604051637617407560e11b81526001600160a01b038a16600482015260006024820152604401610d5e565b6114d48988613430565b6114df898989612aad565b9998505050505050505050565b60006114f6612737565b81146115055780610dc0612737565b611513610df082600161566a565b61151c866129f4565b61152583613496565b6040516001600160a01b038416907f0cc5437d7c9c1d9eab549acbb533eea3e9868e9443dd75309ed5820b33a3774e90600090a2611562826134cd565b6040518281527fbd533e726baaf59b36f3914d950053f7e78f527057c97cd3f0043257fc0fc8849060200160405180910390a161159e89612b57565b6040516001600160a01b038a16907f1da4c245099590dc40be61880c9b97792f3694d970acc1e67ac0e6cc90f3780d90600090a26115db85613504565b6040516001600160a01b038616907f30f015a5d3c72c0a9414538199baa022323a483fa9e4ba2cd581596cf8ca042490600090a26116188461353b565b6040516001600160a01b038516907fffc0721ef0563a1b0a51a0dc92113025f33ca434ada9ee3eebff2f385d2a8f9a90600090a26116568a89613572565b61165f87611bb2565b7f1809e49bba43f2d39fa57894b50cd6ccb428cc438230e065cac3eb24a1355a718160003660405161169393929190615682565b60405180910390a150505050505050505050565b6116af6126f6565b6001600160a01b0316336001600160a01b0316146116e2573360405163472511eb60e11b8152600401610d5e9190615217565b6116eb816134cd565b6040518181527fbd533e726baaf59b36f3914d950053f7e78f527057c97cd3f0043257fc0fc88490602001611397565b6000610ed36135ee565b6000610ed361361e565b611737614eea565b610ed361364e565b6000610f2233848461175133886136da565b61175b919061566a565b61294b565b600061177361176e83613732565b613780565b92915050565b6000611783612b29565b60010154905090565b60008061179761364e565b905060006117a4826137b8565b90506117ee82600001516001600160401b03166117bf612b29565b546117ca919061566a565b83516117df906001600160401b0316846157a8565b6117e9908461575f565b613803565b9250505090565b6000610ed3613812565b6000610ed3612c5b565b600061181361364e565b51611827906001600160401b0316836157a8565b611773908361575f565b6118396126f6565b6001600160a01b0316336001600160a01b03161461186c573360405163472511eb60e11b8152600401610d5e9190615217565b61187581613504565b6040516001600160a01b038216907f30f015a5d3c72c0a9414538199baa022323a483fa9e4ba2cd581596cf8ca042490600090a250565b610ee0612c5b565b60606118be6129ba565b6001600160a01b0316635f2e5f0784846040518363ffffffff1660e01b81526004016118eb92919061580d565b600060405180830381865afa158015611908573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110719190810190615844565b6000610ed36129ba565b6000610ed36126f6565b600061177382613425565b60008060008061195d61364e565b9050600061196a826137b8565b8251909150611982906001600160401b0316826157a8565b61198c908261575f565b945081604001516001600160401b031682602001516001600160401b0316866119b59190615740565b6119bf9190615740565b9350600182604001516001600160401b031683602001516001600160401b031684600001516001600160401b0316886119f8919061566a565b611a029190615740565b611a0c9190615740565b611a16919061575f565b92505050909192565b611a276126f6565b6001600160a01b0316336001600160a01b031614611a5a573360405163472511eb60e11b8152600401610d5e9190615217565b611a6381613842565b611a6c81613861565b7f8d2df192dd17edf92a7964b78aa322f3d717b2ab9de00651bee32bbc4c5da63a816040516113979190615195565b611aa3613272565b6001600160a01b0316336001600160a01b031614611ad6573360405163472511eb60e11b8152600401610d5e9190615217565b611aed611ae8368390038301836158e4565b6138ab565b7f25777eb44be046f64180acf8275f0ac2ec51e63a65a5f8a0f2f6d86ba25b74cf611b1b6020830183615971565b611b2b6040840160208501615971565b611b3b6060850160408601615971565b611b4b6080860160608701615971565b611b5b60a0870160808801615971565b60405161139795949392919061598c565b600061177382613967565b611b7f613272565b6001600160a01b0316336001600160a01b031614611bb2573360405163472511eb60e11b8152600401610d5e9190615217565b611bbb81613994565b6040516001600160a01b038216907fd3b5d1e0ffaeff528910f3663f0adace7694ab8241d58e17a91351ced2e0803190600090a250565b6000610ed36139cb565b6060610ed36139fb565b6000610ed3613125565b6000611c1a612b29565b54919050565b6060611c2a6129ba565b6001600160a01b0316637c044e5586868686600161ffff6040518763ffffffff1660e01b8152600401611c62969594939291906159be565b6000604051808303816000875af1158015611c81573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ca99190810190615a04565b95945050505050565b6000610ed3613ac1565b6040805180820190915260008082526020820152610ed3613af1565b6000610ed3611ce561364e565b6137b8565b6000610f22338484611cfc33886136da565b61175b919061575f565b60003383611d1482826132f9565b8380611d33576040516336b216db60e21b815260040160405180910390fd5b338580611d3f83613425565b1015611d5e576040516351940b3960e11b815260040160405180910390fd5b6001600160a01b038816611d8e57604051637617407560e11b815233600482015260006024820152604401610d5e565b611d99338989612aad565b98975050505050505050565b611dae81613b51565b61130281610c9c565b611dbf6126f6565b6001600160a01b0316336001600160a01b031614611df2573360405163472511eb60e11b8152600401610d5e9190615217565b6113028161279e565b6000610ed3612a7d565b6000610ed36129ea565b610f1333610c9c565b610ee0613242565b600061107183836136da565b6040805180820190915260008082526020820152610ed3613b78565b610ee06135ee565b611e586139cb565b6001600160a01b0316336001600160a01b031614611e8b573360405163472511eb60e11b8152600401610d5e9190615217565b6000611e9561364e565b9050611ea2818335613be6565b611ec25760405163a225656d60e01b815282356004820152602401610d5e565b611eca614f18565b6000611ed4612b29565b60038101546040840181905290915060608501351015611f19576040808301519051621ee1cf60e11b8152600481019190915260608501356024820152604401610d5e565b6040820151611f2c90606086013561575f565b608083015260028101546060830181905260408501351015611f7357606082015160408051636f24834360e01b815260048101929092528501356024820152604401610d5e565b611f7b613125565b611f8b60c0860160a08701615a99565b63ffffffff161180611fbb5750600581015463ffffffff16611fb360c0860160a08701615a99565b63ffffffff16105b1561201057611fd060c0850160a08601615a99565b611fd8613125565b6005830154604051632f776b1760e01b815263ffffffff93841660048201526024810192909252919091166044820152606401610d5e565b606082015161202390604086013561575f565b60a083015280546120379084908635613c43565b60c083015250612045613183565b815260a0810151608082015160009161205d9161566a565b1115612075576120758160a001518260800151613c7e565b61207d614e9b565b83358152602080850135908201526040808501359082015260608085013590820152608080850135908201526120b960c0850160a08601615a99565b63ffffffff1660a08201526120d5610100850160e08601615acf565b151560c08201526120ee61012085016101008601615acf565b151560e08201526120fe81613dab565b506000612109613af1565b905060006121208284600001518560c00151613e57565b905061212a613183565b602084018190528351116121bf57825161214590829061566a565b8360200151111561218d578251602084015160c0850151845160405163eb7a968960e01b81526004810194909452602484019290925260448301526064820152608401610d5e565b8251602084015161219e919061575f565b610120840180519190915251516121b5908261575f565b60e084015261225b565b60006121cf838560000151613e8b565b90506121df818560000151612bbe565b84516121eb919061575f565b8460200151101561223957835160208086015160c08701519186015160405163063bb83f60e11b8152610d5e9493919060040193845260208401929092526040830152606082015260800190565b6020840151845161224a919061575f565b612254908361566a565b60e0850152505b60e0830151156122b9576122728360e00151613ea0565b610120840180516020908101929092525190810151815190919061229790839061566a565b9052506101208301516020015160e0840180516122b590839061575f565b9052505b60e0830151156122f8576122d08360e00151613f68565b6101208401805160409081019290925251015160e0840180516122f490839061575f565b9052505b60e08301511561231a5761230f8360e0015161402e565b610120840151606001525b6101208301515115612336576101208301515161233690614100565b6123a5608086013561234b60c0880188615aec565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061238e92505050610100890160e08a01615acf565b6123a06101208a016101008b01615acf565b614232565b6123ad61452d565b6123b56146b2565b6123c28360c001516146da565b7f49ac0d2bb2a688ca460f7993eb93eccd3b9c9188da6b0727e9a409cf8b105875858461012001516040516123f8929190615b7d565b60405180910390a15050505050565b600061177382613780565b600061177361241f61364e565b83613be6565b61242d6126f6565b6001600160a01b0316336001600160a01b031614612460573360405163472511eb60e11b8152600401610d5e9190615217565b61246981613496565b6040516001600160a01b038216907f0cc5437d7c9c1d9eab549acbb533eea3e9868e9443dd75309ed5820b33a3774e90600090a250565b6000610ed3612b8e565b6113026124d860017f82055909238c0f5e63d6f174068ebb8f51bcec9bd37de63bb68f6551feec0cfd61575f565b829055565b9055565b6000610ed361251160017f2b6136e423ab70d76431e2a635e877e16ea2dd9a895e054ad7f35f89d6c7b71161575f565b5490565b7f48f67c1dada0cab2163f6282292ad97ea97376cfed46bb3851654aaa630db72761253e6124e1565b60408051918252602082018490520160405180910390a161130281614790565b600061256a84836147be565b90506000612576612a7d565b9050836001600160a01b0316856001600160a01b031614156125f657604051632d20488160e11b81526001600160a01b03821690635a409102906125c19088906001906004016156b8565b60006040518083038186803b1580156125d957600080fd5b505afa1580156125ed573d6000803e3d6000fd5b505050506126ef565b604051632d20488160e11b81526001600160a01b03821690635a409102906126259088906001906004016156b8565b60006040518083038186803b15801561263d57600080fd5b505afa158015612651573d6000803e3d6000fd5b505060405163e838dfbb60e01b81526001600160a01b038416925063e838dfbb9150612681908790600401615217565b602060405180830381865afa15801561269e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c29190615c51565b156126e2578360405163e7d05e2760e01b8152600401610d5e9190615217565b6126ed858584612aad565b505b5050505050565b6000610ed361481d565b61270981613b51565b6113026124d860017ff4271262f3552a4108cde54dc75061de8de495709221d793b126e448522d6a8061575f565b6000610ed361251160017f82055909238c0f5e63d6f174068ebb8f51bcec9bd37de63bb68f6551feec0cfd61575f565b61277081613b51565b6113026124d860017fe458cbedf69109e7d57b7f8c96816615aac0017187d87abab9001d22db32bae461575f565b6127a78161484d565b805160208201516040517e4180017d3dd609da6980999655a6bd2591e313d31d6230b1889c369a9713a0926113979290916001600160801b0392831681529116602082015260400190565b61284e6040518060a00160405280896001600160401b03168152602001886001600160401b03168152602001876001600160401b03168152602001866001600160401b03168152602001856001600160401b03168152506138ab565b7f25777eb44be046f64180acf8275f0ac2ec51e63a65a5f8a0f2f6d86ba25b74cf878787878760405161288595949392919061598c565b60405180910390a16128aa60405180604001604052808481526020018381525061327c565b60408051838152602081018390527f5ab79ffcd89b6380c7fbdd89d02cfe3d9c53c99a85e150c2319075018d1aac5c910160405180910390a16128eb614e9b565b6128f361489f565b81526128fd6148cf565b602082015260006040820181905260608201819052608082015261291f6148ff565b63ffffffff1660a0820152600060c0820181905260e082015261294181613dab565b5050505050505050565b61295483613b51565b61295d82613b51565b61296883838361492f565b816001600160a01b0316836001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516129ad91815260200190565b60405180910390a3505050565b6000610ed361251160017fe458cbedf69109e7d57b7f8c96816615aac0017187d87abab9001d22db32bae461575f565b6000610ed3614986565b6129fd81613b51565b612a06816149b6565b6040516001600160a01b038216907f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a190600090a250565b612a46816149bf565b6040516001600160a01b038216907f2a0f8515de3fa34ef68b99300347b8793c01683350743e96fe440594528298f490600090a250565b6000610ed361251160017f867d8f1a5e39d11d5bebde854d5359a509530ad32450f581da63c06ec8d1a78061575f565b6000612acc8483612abd87613732565b612ac7919061575f565b6149c8565b612ae48383612ada86613732565b612ac7919061566a565b826001600160a01b0316846001600160a01b0316600080516020615f5f83398151915284604051612b1791815260200190565b60405180910390a35060019392505050565b60008061177360017fdbc0527c99b54cd325d6ce9eaae3a8413cd447b5205f37385f0ebc6551033c6d61575f565b612b6081613b51565b6113026124d860017f8e9e2a1d30fed357d8a000c1131fc77ed65d2052918caf1ccc6eb1e7af3d13b661575f565b6000610ed361251160017fbcfa5a69252c74010ad3e9ab18cfbdc116fcf85f084db1a8dc577a339fbee58b61575f565b6000818311612bcd5782611071565b50919050565b606080612bde613ac1565b6001600160a01b031663277c9d45846040518263ffffffff1660e01b8152600401612c0b91815260200190565b6000604051808303816000875af1158015612c2a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c529190810190615d34565b91509150915091565b6000610ed361251160017fb649e50315f962b32d487e696a81b4828631b11f8424daaaa37e9e97766a2c4261575f565b6030835114612cad5760405163050cb55360e41b815260040160405180910390fd5b6060825114612ccf5760405163408ebd3960e01b815260040160405180910390fd5b6801bc16d674ec8000006000612ce9633b9aca0083615716565b90506000600286600060801b604051602001612d06929190615d97565b60408051601f1981840301815290829052612d2091615dc6565b602060405180830381855afa158015612d3d573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612d609190615de2565b90506000600280612d748860006040614a14565b604051612d819190615dc6565b602060405180830381855afa158015612d9e573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612dc19190615de2565b6002612dd9896040612dd481606061575f565b614a14565b604051612dec9190600090602001615dfb565b60408051601f1981840301815290829052612e0691615dc6565b602060405180830381855afa158015612e23573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612e469190615de2565b60408051602081019390935282015260600160408051601f1981840301815290829052612e7291615dc6565b602060405180830381855afa158015612e8f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612eb29190615de2565b905060006002808488604051602001612ed5929190918252602082015260400190565b60408051601f1981840301815290829052612eef91615dc6565b602060405180830381855afa158015612f0c573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612f2f9190615de2565b6002612f3a87614ad7565b604080516020810192909252810186905260600160408051601f1981840301815290829052612f6891615dc6565b602060405180830381855afa158015612f85573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612fa89190615de2565b60408051602081019390935282015260600160408051601f1981840301815290829052612fd491615dc6565b602060405180830381855afa158015612ff1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906130149190615de2565b90506000613022864761575f565b905061302c614b44565b6001600160a01b03166322895118878b8a60405160200161304f91815260200190565b6040516020818303038152906040528c876040518663ffffffff1660e01b815260040161307f9493929190615e1d565b6000604051808303818588803b15801561309857600080fd5b505af11580156130ac573d6000803e3d6000fd5b50505050508047146130d157604051638051a6bb60e01b815260040160405180910390fd5b505050505050505050565b7f86fd21e9b5bd76b20471c7f93a82aa4e25c37d48b179bda0a4d1a45e22a842f4613105612b8e565b60408051918252602082018490520160405180910390a161130281614b74565b6000610ed361251160017fc77078e3530c08cdb2440817c81de4836500b4708ea4d15672b7fe98956423a861575f565b6113026124d860017fc77078e3530c08cdb2440817c81de4836500b4708ea4d15672b7fe98956423a861575f565b60008061318e612b29565b600581015490915063ffffffff1660006131a6613125565b90508082101561321b576801bc16d674ec8000006131c4838361575f565b6131ce9190615740565b6131d661361e565b6131de612b8e565b6131e66124e1565b86600101546131f5919061566a565b6131ff919061566a565b613209919061566a565b613213919061566a565b935050505090565b61322361361e565b61322b612b8e565b6132336124e1565b85600101546131ff919061566a565b6000610ed361251160017ff4271262f3552a4108cde54dc75061de8de495709221d793b126e448522d6a8061575f565b6000610ed361193a565b60006132a960017ff81b149de6749a3f46464b2cce61e24462f67599ea4a5ce028aaf4ab1521f96e61575f565b8251815560209092015160019092019190915550565b6000610ed3614ba2565b6000610ed361251160017f094efef62d2ce60c14ffacd35a1b50546d3a9d503aff1df040176fffd6c92a3761575f565b6000613303612a7d565b60405163e838dfbb60e01b81529091506001600160a01b0382169063e838dfbb90613332908690600401615217565b602060405180830381865afa15801561334f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133739190615c51565b15613393578260405163e7d05e2760e01b8152600401610d5e9190615217565b60405163e838dfbb60e01b81526001600160a01b0382169063e838dfbb906133bf908590600401615217565b602060405180830381865afa1580156133dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134009190615c51565b15613420578160405163e7d05e2760e01b8152600401610d5e9190615217565b505050565b600061177382613732565b600061343c83336136da565b90508181101561347e57604051637b936de360e01b81526001600160a01b03841660048201523360248201526044810182905260648101839052608401610d5e565b600019811461342057613420833361175b858561575f565b61349f81613b51565b6113026124d860017f082b6d18de7b10e438e6b1002141db737519cb4ceed679bc815e3aac00cd222761575f565b6134d681614bd2565b6113026124d860017f094efef62d2ce60c14ffacd35a1b50546d3a9d503aff1df040176fffd6c92a3761575f565b61350d81613b51565b6113026124d860017f867d8f1a5e39d11d5bebde854d5359a509530ad32450f581da63c06ec8d1a78061575f565b61354481613b51565b6113026124d860017f3f075dea7ef99b1e5db245018e5e4ed8d2a0d93953f5932b2176bef59bd6906161575f565b61357b82614bf5565b6040516001600160a01b038316907e043cf7635f276413ae358250286a479a631abd9d74d57d4aa0bb87ebc7d11790600090a26135b781614c2c565b6040518181527f4c86ba184ea1a1558f84835ca34f6d67e222e8ee5cc4f324b8861dda4cf1740c9060200160405180910390a15050565b6000610ed361251160017f8e9e2a1d30fed357d8a000c1131fc77ed65d2052918caf1ccc6eb1e7af3d13b661575f565b6000610ed361251160017f850308dd4e453a2a1bc3efb444560401d95c1a8bdea5b35c5c79531cd2241f1d61575f565b613656614eea565b600061368360017fd84ee2c84c954c65bef1459fe03b761a42f49234527e3cd8fd9dce87cb83742b61575f565b6040805160a08101825282546001600160401b038082168352600160401b820481166020840152600160801b8204811693830193909352600160c01b90048216606082015260019092015416608082015292915050565b60008061370860017fc852254d5b703a16bb13b3e233a335d6459c5da5db0ca732d7a684ee0540784761575f565b6001600160a01b039485166000908152602091825260408082209590961681529390525050205490565b60008061376060017f0fb4a5ac9287f4f508aa7253ee2d57c6a228b1b30e210d73fffd59389d3a883861575f565b6001600160a01b0390931660009081526020939093525050604090205490565b60008061378b614ba2565b90508061379b5750600092915050565b806137a4613183565b6137ae9085615740565b6110719190615716565b600081602001516001600160401b031682604001516001600160401b031683606001516001600160401b0316426137ef919061575f565b6137f99190615716565b6117739190615716565b6000818310612bcd5782611071565b6000610ed361251160017f082b6d18de7b10e438e6b1002141db737519cb4ceed679bc815e3aac00cd222761575f565b805161130257604051638d46fe0560e01b815260040160405180910390fd5b600061388e60017fb63f3482ec84cb93d74a71645ad2e9e896fa02723e42170b4aad20a4bed6cdd661575f565b825190915081906138a59082906020860190614f93565b50505050565b60006138d860017fd84ee2c84c954c65bef1459fe03b761a42f49234527e3cd8fd9dce87cb83742b61575f565b825181546020850151604086015160608701516001600160401b039485166001600160801b031990941693909317600160401b92851692909202919091176001600160801b0316600160801b918416919091026001600160c01b031617600160c01b918316919091021782556080909301516001909101805467ffffffffffffffff1916919093161790915550565b600080613972614ba2565b9050806139825750600092915050565b61398a613183565b6137ae8285615740565b61399d81613b51565b6113026124d860017fc8cbea9407c380ae944f052b5a442330057683c5abdbd453493f9750806afecb61575f565b6000610ed361251160017fc8cbea9407c380ae944f052b5a442330057683c5abdbd453493f9750806afecb61575f565b60606000613a2a60017fb63f3482ec84cb93d74a71645ad2e9e896fa02723e42170b4aad20a4bed6cdd661575f565b805490915081908190613a3c90615e68565b80601f0160208091040260200160405190810160405280929190818152602001828054613a6890615e68565b8015613ab55780601f10613a8a57610100808354040283529160200191613ab5565b820191906000526020600020905b815481529060010190602001808311613a9857829003601f168201915b50505050509250505090565b6000610ed361251160017f3f075dea7ef99b1e5db245018e5e4ed8d2a0d93953f5932b2176bef59bd6906161575f565b60408051808201909152600080825260208201526000613b3260017ff81b149de6749a3f46464b2cce61e24462f67599ea4a5ce028aaf4ab1521f96e61575f565b6040805180820190915281548152600190910154602082015292915050565b6001600160a01b0381166113025760405163f6b2911f60e01b815260040160405180910390fd5b60408051808201909152600080825260208201526000613bb960017fc305db9f63aeed94a45229ff5ab4174e72b223a38ab4c5e8f518ee4f437918d161575f565b6040805180820190915290546001600160801b038082168352600160801b90910416602082015292915050565b600082608001516001600160401b031682613c01919061566a565b613c0a846137b8565b10158015613c1f5750613c1b612b29565b5482115b801561107157508251613c3b906001600160401b0316836157a8565b159392505050565b600083602001518460400151613c599190615e9d565b6001600160401b0316613c6c848461575f565b613c769190615740565b949350505050565b476000613c8b838561566a565b9050613c95612c5b565b6001600160a01b031663ea74f479826040518263ffffffff1660e01b8152600401613cc291815260200190565b600060405180830381600087803b158015613cdc57600080fd5b505af1158015613cf0573d6000803e3d6000fd5b5050505060008247613d02919061575f565b9050613d0e848661566a565b8114613d4257613d1e848661566a565b6040516349a1938b60e01b8152600481019190915260248101829052604401610d5e565b8415613d5457613d5485610cc66124e1565b8315613d7557613d7584613d6661361e565b613d70919061566a565b614c78565b60408051868152602081018690527fcb5410dc8f29b2f498e023c3f9237dbd600255a717edf94a6072bcd03b0c773c91016123f8565b6000613dd860017fdbc0527c99b54cd325d6ce9eaae3a8413cd447b5205f37385f0ebc6551033c6d61575f565b825181556020830151600182015560408301516002820155606083015160038201556080830151600482015560a08301516005909101805460c085015160e0909501511515600160281b0265ff0000000000199515156401000000000264ffffffffff1990921663ffffffff9094169390931717939093161790915550565b6000613e696301e13380612710615740565b84518390613e779086615740565b613e819190615740565b613c769190615716565b60006127108360200151836137ae9190615740565b600080613eab6135ee565b60405163c8a6dfd360e01b81526004810185905290915047906001600160a01b0383169063c8a6dfd390602401600060405180830381600087803b158015613ef257600080fd5b505af1158015613f06573d6000803e3d6000fd5b5050505060008147613f18919061575f565b90508015613f2c57613f2c81610cc66124e1565b6040518181527fda841d3042d792e2509a333b9dcbd4b3dd9b9047d382011f8788fab90ca7e3c7906020015b60405180910390a1949350505050565b600047613f736129ba565b6001600160a01b0316630c779401846040518263ffffffff1660e01b8152600401613fa091815260200190565b600060405180830381600087803b158015613fba57600080fd5b505af1158015613fce573d6000803e3d6000fd5b5050505060008147613fe0919061575f565b90508015613ff457613ff481610cc66124e1565b6040518181527f4e484734eb4d444bfa106f917d05d9ceb8ce18bf516c85d7aeb9b322925339f99060200160405180910390a19392505050565b600080614039613242565b90506001600160a01b0381166140525750600092915050565b604051638ede6b6b60e01b81526004810184905247906001600160a01b03831690638ede6b6b90602401600060405180830381600087803b15801561409657600080fd5b505af11580156140aa573d6000803e3d6000fd5b50505050600081476140bc919061575f565b905080156140d0576140d081610cc66124e1565b6040518181527fd500b67e5bd8019c0af744cadeec120d1b5e3d3a3a011f18cf182aa4c97947b690602001613f58565b600061410a6132bf565b90508061412a57604051630d35acd760e21b815260040160405180910390fd5b6000614134613183565b905060006141406132c9565b905060008161414f8587615740565b6141599190615740565b905060006141678387615740565b61417361271086615740565b61417d919061575f565b905060008115614196576141918284615716565b614199565b60005b905080156142295760006141ab613812565b90506141b78183614cc1565b60006141c16132bf565b905060006141cf8a8961575f565b60408051828152602081018c90529081018a9052606081018490529091506001600160a01b038416907f3d1669e813a9845c288f0e1f642a4343a451103b87886d12de37e63b39bbd9429060800160405180910390a25050505b50505050505050565b61423a613ac1565b6001600160a01b031663b405e17484614251613125565b6040518363ffffffff1660e01b815260040161426e929190615ecc565b600060405180830381600087803b15801561428857600080fd5b505af115801561429c573d6000803e3d6000fd5b5050505080156142ab576138a5565b60006142b56132bf565b905080156126ef5760006142c761361e565b905060006142d36124e1565b905060006143436142e26129ba565b6001600160a01b0316630d8d2a546040518163ffffffff1660e01b8152600401602060405180830381865afa15801561431f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176e9190615de2565b905080614350898561566a565b1015612941578580156143635750600082115b156143b457600061438883856143798c8661575f565b614383919061575f565b612bbe565b905080156143b25761439a818561566a565b93506143a584614c78565b6143b2610cd0828561575f565b505b60006143be613ac1565b9050600080826001600160a01b0316634a3c63bb6040518163ffffffff1660e01b81526004016040805180830381865afa158015614400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144249190615f1a565b915063ffffffff16915060006801bc16d674ec800000838311614448576000614452565b614452848461575f565b61445c9190615740565b9050848161446a8e8a61566a565b614474919061566a565b101561451f5760006144ad8261448a8f8b61566a565b614494919061566a565b61449e908861575f565b6801bc16d674ec800000614d1e565b9050846001600160a01b0316632d1fc39d826144c7613125565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561450557600080fd5b505af1158015614519573d6000803e3d6000fd5b50505050505b505050505050505050505050565b60006145376129ba565b90506000614543613183565b9050600061454f6132bf565b90506000821180156145615750600081115b15613420576000836001600160a01b0316630d8d2a546040518163ffffffff1660e01b8152600401602060405180830381865afa1580156145a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145ca9190615de2565b90508060006145d882613780565b905060006145e461361e565b9050808211156145fd578091506145fa82613967565b92505b60408051858152602081018590529081018390527f709263092d8d9fef472d907900405b5edae3d76f8ff4354858025b18424d71019060600160405180910390a1811561422957614651613d70838361575f565b61465b8784614d51565b60405163b30d8bb760e01b8152600481018490526001600160a01b0388169063b30d8bb79084906024016000604051808303818588803b15801561469e57600080fd5b505af115801561451f573d6000803e3d6000fd5b60006146bc61361e565b90508015611302576146d081610cc66124e1565b6113026000614c78565b60006146e4613183565b905060006146f06124e1565b905060006146fc613b78565b8051909150600090614740906001600160801b031661271061471e868861575f565b85602001516001600160801b03166147369190615740565b6117e99190615716565b90506000614765620151806147558885615740565b61475f9190615716565b85612bbe565b905080156126ed5761478381614779612b8e565b611243919061566a565b6126ed610cd0828661575f565b6113026124d860017f2b6136e423ab70d76431e2a635e877e16ea2dd9a895e054ad7f35f89d6c7b71161575f565b600080826147ca613183565b6147d4919061575f565b9050806147ed578291506147e88484614cc1565b614816565b806147f66132bf565b6148009085615740565b61480a9190615716565b91506148168483614cc1565b5092915050565b6000610ed361251160017fb5b37715a3e346e996104f0086703f19825def429233930fd9399c38e05fb11361575f565b600061487a60017fc305db9f63aeed94a45229ff5ab4174e72b223a38ab4c5e8f518ee4f437918d161575f565b82516020909301516001600160801b03908116600160801b0293169290921790915550565b6000610ed361251160017fd7f2d45e512a86049f7a113657b39731b6b558609584243063a52cd31a8eb52961575f565b6000610ed361251160017ffedfd2c285a57fb23bf45a3fe9ac02d36a76ebb72801b1c8aaf553d74e9d465361575f565b6000610ed361251160017f0f1e7733641e4d843128fea0d2ec90d3d06a40b0fe244ff603d8c1aa200dc0f961575f565b600061495c60017fc852254d5b703a16bb13b3e233a335d6459c5da5db0ca732d7a684ee0540784761575f565b6001600160a01b039485166000908152602091825260408082209590961681529390525091902055565b6000610ed361251160017f6e6ab8b7c7aaba79eef8cc633522d606bb008c101cf9832c9ad05d10a984728161575f565b61130281614da1565b61130281614dd8565b60006149f560017f0fb4a5ac9287f4f508aa7253ee2d57c6a228b1b30e210d73fffd59389d3a883861575f565b6001600160a01b03909316600090815260209390935250604090912055565b60608182601f011015614a3a576040516323d5783d60e11b815260040160405180910390fd5b614a44828461566a565b84511015614a6557604051633b99b53d60e01b815260040160405180910390fd5b606082158015614a845760405191506000825260208201604052614ace565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614abd578051835260209283019201614aa5565b5050858452601f01601f1916604052505b50949350505050565b603881901c60ff908116603083901c8216602884901c8316602085901c8416601886901c8516601087901c8616600888811c9790971688881b61ff001617871b17861b17851b17841b17831b1790911b17604082901c8015614b3b57614b3b615f48565b5060c01b919050565b6000610ed361251160017f35efb61d8784060218d9d6aa40eae55904de43779c1afc79c74dfefcfdf9126061575f565b6113026124d860017fbcfa5a69252c74010ad3e9ab18cfbdc116fcf85f084db1a8dc577a339fbee58b61575f565b6000610ed361251160017f6b842b424335d94ccad97e54548dfa02673c1268aba38d3c3c32d28c8988b70b61575f565b612710811115611302576040516358d620b360e01b815260040160405180910390fd5b614bfe81613b51565b6113026124d860017f35efb61d8784060218d9d6aa40eae55904de43779c1afc79c74dfefcfdf9126061575f565b80614c4a5760405163a9cb9e0d60e01b815260040160405180910390fd5b6113026124d860017fb649e50315f962b32d487e696a81b4828631b11f8424daaaa37e9e97766a2c4261575f565b7f215c2b83e8c232e42091088056ab75d2ff643855c32997024f786cddb22d2290614ca161361e565b60408051918252602082018490520160405180910390a161130281614e06565b614cdc81614ccd614ba2565b614cd7919061566a565b614e34565b614cea8282612ada85613732565b6040518181526001600160a01b03831690600090600080516020615f5f833981519152906020015b60405180910390a35050565b600080614d2b83856157a8565b11614d37576000614d3a565b60015b60ff16614d478385615716565b611071919061566a565b614d6781614d5d614ba2565b614cd7919061575f565b614d758282612abd85613732565b6040518181526000906001600160a01b03841690600080516020615f5f83398151915290602001614d12565b614daa81613b51565b6113026124d860017fb5b37715a3e346e996104f0086703f19825def429233930fd9399c38e05fb11361575f565b6113026124d860017f6e6ab8b7c7aaba79eef8cc633522d606bb008c101cf9832c9ad05d10a984728161575f565b6113026124d860017f850308dd4e453a2a1bc3efb444560401d95c1a8bdea5b35c5c79531cd2241f1d61575f565b614e3d81614e6d565b6040518181527fc80ea35a3f9016535e5b7c87746740c5045afe42188d02c5786eb97495c2f42990602001611397565b6113026124d860017f6b842b424335d94ccad97e54548dfa02673c1268aba38d3c3c32d28c8988b70b61575f565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600063ffffffff1681526020016000151581526020016000151581525090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604051806101400160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001614f8e6040518060800160405280600081526020016000815260200160008152602001600081525090565b905290565b828054614f9f90615e68565b90600052602060002090601f016020900481019282614fc15760008555615007565b82601f10614fda57805160ff1916838001178555615007565b82800160010185558215615007579182015b82811115615007578251825591602001919060010190614fec565b50615013929150615017565b5090565b5b808211156150135760008155600101615018565b80356001600160a01b038116811461504357600080fd5b919050565b60006020828403121561505a57600080fd5b6110718261502c565b80356001600160401b038116811461504357600080fd5b80356001600160801b038116811461504357600080fd5b6000806000806000806000806000806101408b8d0312156150b157600080fd5b6150ba8b61502c565b99506150c860208c01615063565b98506150d660408c01615063565b97506150e460608c01615063565b96506150f260808c01615063565b955061510060a08c01615063565b945060c08b0135935060e08b0135925061511d6101008c0161507a565b915061512c6101208c0161507a565b90509295989b9194979a5092959850565b60005b83811015615158578181015183820152602001615140565b838111156138a55750506000910152565b6000815180845261518181602086016020860161513d565b601f01601f19169290920160200192915050565b6020815260006110716020830184615169565b600080604083850312156151bb57600080fd5b6151c48361502c565b946020939093013593505050565b600080604083850312156151e557600080fd5b823591506151f56020840161502c565b90509250929050565b60006020828403121561521057600080fd5b5035919050565b6001600160a01b0391909116815260200190565b600060408284031215612bcd57600080fd5b60008060006060848603121561525257600080fd5b61525b8461502c565b92506152696020850161502c565b9150604084013590509250925092565b60008060008060008060008060006101208a8c03121561529857600080fd5b6152a18a61502c565b98506152af60208b0161502c565b975060408a013596506152c460608b0161502c565b95506152d260808b0161502c565b94506152e060a08b0161502c565b93506152ee60c08b0161502c565b92506152fc60e08b0161502c565b91506101008a013590509295985092959850929598565b60008083601f84011261532557600080fd5b5081356001600160401b0381111561533c57600080fd5b6020830191508360208260051b850101111561535757600080fd5b9250929050565b6000806020838503121561537157600080fd5b82356001600160401b0381111561538757600080fd5b61539385828601615313565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156153da57835160070b835292840192918401916001016153bb565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561541e5761541e6153e6565b60405290565b604051601f8201601f191681016001600160401b038111828210171561544c5761544c6153e6565b604052919050565b60006001600160401b0382111561546d5761546d6153e6565b50601f01601f191660200190565b60006020828403121561548d57600080fd5b81356001600160401b038111156154a357600080fd5b8201601f810184136154b457600080fd5b80356154c76154c282615454565b615424565b8181528560208385010111156154dc57600080fd5b81602084016020830137600091810160200191909152949350505050565b600060a08284031215612bcd57600080fd5b6000806000806040858703121561552257600080fd5b84356001600160401b038082111561553957600080fd5b61554588838901615313565b9096509450602087013591508082111561555e57600080fd5b5061556b87828801615313565b95989497509550505050565b6020808252825182820181905260009190848201906040850190845b818110156153da57835160ff1683529284019291840191600101615593565b6000604082840312156155c457600080fd5b6155cc6153fc565b6155d58361507a565b81526155e36020840161507a565b60208201529392505050565b6000806040838503121561560257600080fd5b61560b8361502c565b91506151f56020840161502c565b60006020828403121561562b57600080fd5b81356001600160401b0381111561564157600080fd5b8201610120818503121561107157600080fd5b634e487b7160e01b600052601160045260246000fd5b6000821982111561567d5761567d615654565b500190565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b6001600160a01b03929092168252602082015260400190565b63ffffffff8116811461130257600080fd5b6000602082840312156156f557600080fd5b8151611071816156d1565b634e487b7160e01b600052601260045260246000fd5b60008261572557615725615700565b500490565b634e487b7160e01b600052603260045260246000fd5b600081600019048311821515161561575a5761575a615654565b500290565b60008282101561577157615771615654565b500390565b60006040828403121561578857600080fd5b6157906153fc565b82358152602083013560208201528091505092915050565b6000826157b7576157b7615700565b500690565b8035615043816156d1565b8183526000602080850194508260005b858110156158025781356157ea816156d1565b63ffffffff16875295820195908201906001016157d7565b509495945050505050565b602081526000613c766020830184866157c7565b60006001600160401b0382111561583a5761583a6153e6565b5060051b60200190565b6000602080838503121561585757600080fd5b82516001600160401b0381111561586d57600080fd5b8301601f8101851361587e57600080fd5b805161588c6154c282615821565b81815260059190911b820183019083810190878311156158ab57600080fd5b928401925b828410156158d95783518060070b81146158ca5760008081fd5b825292840192908401906158b0565b979650505050505050565b600060a082840312156158f657600080fd5b60405160a081018181106001600160401b0382111715615918576159186153e6565b60405261592483615063565b815261593260208401615063565b602082015261594360408401615063565b604082015261595460608401615063565b606082015261596560808401615063565b60808201529392505050565b60006020828403121561598357600080fd5b61107182615063565b6001600160401b0395861681529385166020850152918416604084015283166060830152909116608082015260a00190565b6080815260006159d260808301888a6157c7565b82810360208401526159e58187896157c7565b9415156040840152505061ffff91909116606090910152949350505050565b60006020808385031215615a1757600080fd5b82516001600160401b03811115615a2d57600080fd5b8301601f81018513615a3e57600080fd5b8051615a4c6154c282615821565b81815260059190911b82018301908381019087831115615a6b57600080fd5b928401925b828410156158d957835160ff81168114615a8a5760008081fd5b82529284019290840190615a70565b600060208284031215615aab57600080fd5b8135611071816156d1565b801515811461130257600080fd5b803561504381615ab6565b600060208284031215615ae157600080fd5b813561107181615ab6565b6000808335601e19843603018112615b0357600080fd5b8301803591506001600160401b03821115615b1d57600080fd5b6020019150600581901b360382131561535757600080fd5b6000808335601e19843603018112615b4c57600080fd5b83016020810192503590506001600160401b03811115615b6b57600080fd5b8060051b360383131561535757600080fd5b60a08152823560a0820152602083013560c0820152604083013560e08201526000610100606085013581840152610120608086013581850152615bc260a087016157bc565b63ffffffff16610140850152615bdb60c0870187615b35565b82610160870152615bf16101c0870182846157c7565b92505050615c0160e08701615ac4565b1515610180850152615c14868301615ac4565b8015156101a08601529150915061107190506020830184805182526020810151602083015260408101516040830152606081015160608301525050565b600060208284031215615c6357600080fd5b815161107181615ab6565b600082601f830112615c7f57600080fd5b81516020615c8f6154c283615821565b82815260059290921b84018101918181019086841115615cae57600080fd5b8286015b84811015615d295780516001600160401b03811115615cd15760008081fd5b8701603f81018913615ce35760008081fd5b848101516040615cf56154c283615454565b8281528b82848601011115615d0a5760008081fd5b615d198389830184870161513d565b8652505050918301918301615cb2565b509695505050505050565b60008060408385031215615d4757600080fd5b82516001600160401b0380821115615d5e57600080fd5b615d6a86838701615c6e565b93506020850151915080821115615d8057600080fd5b50615d8d85828601615c6e565b9150509250929050565b60008351615da981846020880161513d565b6001600160801b0319939093169190920190815260100192915050565b60008251615dd881846020870161513d565b9190910192915050565b600060208284031215615df457600080fd5b5051919050565b60008351615e0d81846020880161513d565b9190910191825250602001919050565b608081526000615e306080830187615169565b8281036020840152615e428187615169565b90508281036040840152615e568186615169565b91505082606083015295945050505050565b600181811c90821680615e7c57607f821691505b60208210811415612bcd57634e487b7160e01b600052602260045260246000fd5b60006001600160401b0380831681851681830481118215151615615ec357615ec3615654565b02949350505050565b604080825283519082018190526000906020906060840190828701845b82811015615f0b57815163ffffffff1684529284019290840190600101615ee9565b50505092019290925292915050565b60008060408385031215615f2d57600080fd5b8251615f38816156d1565b6020939093015192949293505050565b634e487b7160e01b600052600160045260246000fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122075e48ff7ca1ef56a4380c2b504633a9f2bf34000bc77bdf03103b2444951f22564736f6c634300080a0033
Deployed Bytecode Sourcemap
1247:25504:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1276:20:6;1285:10;1276:8;:20::i;:::-;1247:25504:2;;1396:23:6;;-1:-1:-1;;;1396:23:6;;;;;;;;;;;7275:176:2;;;;;;;;;;-1:-1:-1;7275:176:2;;;;;:::i;:::-;;:::i;2647:1145::-;;;;;;;;;;-1:-1:-1;2647:1145:2;;;;;:::i;:::-;;:::i;3105:109:3:-;;;;;;;;;;;;;:::i;:::-;;;1725:25:60;;;1713:2;1698:18;3105:109:3;;;;;;;;8507:188:2;;;:::i;1945:97:5:-;;;;;;;;;;-1:-1:-1;2009:26:5;;;;;;;;;;;;-1:-1:-1;;;2009:26:5;;;;1945:97;;;;;;;:::i;4385:151::-;;;;;;;;;;-1:-1:-1;4385:151:5;;;;;:::i;:::-;;:::i;:::-;;;3032:14:60;;3025:22;3007:41;;2995:2;2980:18;4385:151:5;2867:187:60;1276:150:0;;;;;;;;;;;;;:::i;5704:377:2:-;;;;;;;;;;-1:-1:-1;5704:377:2;;;;;:::i;:::-;;:::i;:::-;;;3591:10:60;3579:23;;;3561:42;;3549:2;3534:18;5704:377:2;3417:192:60;7120:133:4;;;;;;;;;;;;;:::i;7052:188:2:-;;;;;;;;;;-1:-1:-1;7052:188:2;;;;;:::i;:::-;;:::i;3630:1658:3:-;;;;;;;;;;-1:-1:-1;3630:1658:3;;;;;:::i;:::-;;:::i;2470:104:5:-;;;;;;;;;;;;;:::i;1131::0:-;;;;;;;;;;-1:-1:-1;1131:104:0;;;;;:::i;:::-;;:::i;4378:108:2:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;10165:230:4:-;;;;;;;;;;-1:-1:-1;10165:230:4;;;;;:::i;:::-;;:::i;9363:168::-;;;;;;;;;;;;;:::i;:::-;;;;;;4396:4:60;4438:3;4427:9;4423:19;4415:27;;4475:6;4469:13;4458:9;4451:32;4539:4;4531:6;4527:17;4521:24;4514:4;4503:9;4499:20;4492:54;4602:4;4594:6;4590:17;4584:24;4577:4;4566:9;4562:20;4555:54;4665:4;4657:6;4653:17;4647:24;4640:4;4629:9;4625:20;4618:54;4728:4;4720:6;4716:17;4710:24;4703:4;4692:9;4688:20;4681:54;4803:10;4795:4;4787:6;4783:17;4777:24;4773:41;4766:4;4755:9;4751:20;4744:71;4885:4;4877:6;4873:17;4867:24;4860:32;4853:40;4846:4;4835:9;4831:20;4824:70;4964:4;4956:6;4952:17;4946:24;4939:32;4932:40;4925:4;4914:9;4910:20;4903:70;4216:763;;;;;2334:93:5;;;;;;;;;;;;;:::i;3827:95:2:-;;;;;;;;;;;;;:::i;3942:400:5:-;;;;;;;;;;-1:-1:-1;3942:400:5;;;;;:::i;:::-;;:::i;1457:1155:2:-;;;;;;;;;;-1:-1:-1;1457:1155:2;;;;;:::i;:::-;;:::i;6498:133::-;;;;;;;;;;-1:-1:-1;6498:133:2;;;;;:::i;:::-;;:::i;4231:112::-;;;;;;;;;;;;;:::i;5264:107::-;;;;;;;;;;;;;:::i;8317:108:4:-;;;;;;;;;;;;;:::i;:::-;;;;;;6360:13:60;;-1:-1:-1;;;;;6356:22:60;;;6338:41;;6439:4;6427:17;;;6421:24;6417:33;;6395:20;;;6388:63;6511:4;6499:17;;;6493:24;6489:33;;6467:20;;;6460:63;6583:4;6571:17;;;6565:24;6561:33;;6539:20;;;6532:63;6655:4;6643:17;;;6637:24;6633:33;6611:20;;;6604:63;;;;6288:3;6273:19;;6094:579;2215:76:5;;;;;;;;;;-1:-1:-1;2215:76:5;;2282:2;6820:36:60;;6808:2;6793:18;2215:76:5;6678:184:60;1438:47:3;;;;;;;;;;;;1477:8;1438:47;;4579:227:5;;;;;;;;;;-1:-1:-1;4579:227:5;;;;;:::i;:::-;;:::i;2769:145::-;;;;;;;;;;-1:-1:-1;2769:145:5;;;;;:::i;:::-;;:::i;6935:142:4:-;;;;;;;;;;;;;:::i;7296:351::-;;;;;;;;;;;;;:::i;4094:102:2:-;;;;;;;;;;;;;:::i;1346:45:3:-;;;;;;;;;;;;1389:2;1346:45;;7859:90:4;;;;;;;;;;-1:-1:-1;7927:15:4;7859:90;;3272:119:3;;;;;;;;;;;;;:::i;8990:155:4:-;;;;;;;;;;-1:-1:-1;8990:155:4;;;;;:::i;:::-;;:::i;6666:158:2:-;;;;;;;;;;-1:-1:-1;6666:158:2;;;;;:::i;:::-;;:::i;8088:176::-;;;:::i;5406:263::-;;;;;;;;;;-1:-1:-1;5406:263:2;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4521:110::-;;;;;;;;;;;;;:::i;827:104:0:-;;;;;;;;;;;;;:::i;2617:109:5:-;;;;;;;;;;-1:-1:-1;2617:109:5;;;;;:::i;:::-;;:::i;8468:479:4:-;;;;;;;;;;;;;:::i;:::-;;;;8710:25:60;;;8766:2;8751:18;;8744:34;;;;8794:18;;;8787:34;8698:2;8683:18;8468:479:4;8508:319:60;7486:211:2;;;;;;;;;;-1:-1:-1;7486:211:2;;;;;:::i;:::-;;:::i;9774:348:4:-;;;;;;;;;;-1:-1:-1;9774:348:4;;;;;:::i;:::-;;:::i;3137:167:5:-;;;;;;;;;;-1:-1:-1;3137:167:5;;;;;:::i;:::-;;:::i;9574:157:4:-;;;;;;;;;;-1:-1:-1;9574:157:4;;;;;:::i;:::-;;:::i;6796:96::-;;;;;;;;;;;;;:::i;4666:105:2:-;;;;;;;;;;;;;:::i;3449:123:3:-;;;;;;;;;;;;;:::i;7992:127:4:-;;;;;;;;;;;;;:::i;6116:347:2:-;;;;;;;;;;-1:-1:-1;6116:347:2;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2085:87:5:-;;;;;;;;;;-1:-1:-1;2151:14:5;;;;;;;;;;;;-1:-1:-1;;;2151:14:5;;;;2085:87;;7732:118:2;;;;;;;;;;;;;:::i;9188:132:4:-;;;;;;;;;;;;;:::i;:::-;;;;12228:13:60;;12210:32;;12298:4;12286:17;;;12280:24;12258:20;;;12251:54;;;;12183:18;9188:132:4;11992:319:60;8162:112:4;;;;;;;;;;;;;:::i;4849:231:5:-;;;;;;;;;;-1:-1:-1;4849:231:5;;;;;:::i;:::-;;:::i;3538:361::-;;;;;;;;;;-1:-1:-1;3538:361:5;;;;;:::i;:::-;;:::i;1040:151:6:-;;;;;;:::i;:::-;;:::i;5041:188:2:-;;;;;;;;;;-1:-1:-1;5041:188:2;;;;;:::i;:::-;;:::i;1245:46:3:-;;;;;;;;;;;;1289:2;1245:46;;3957:102:2;;;;;;;;;;;;;:::i;972:118:0:-;;;;;;;;;;;;;:::i;919:73:6:-;;;:::i;8299:173:2:-;;;:::i;3347:148:5:-;;;;;;;;;;-1:-1:-1;3347:148:5;;;;;:::i;:::-;;:::i;4806:200:2:-;;;;;;;;;;;;;:::i;:::-;;;;13260:13:60;;-1:-1:-1;;;;;13256:22:60;;;13238:41;;13339:4;13327:17;;;13321:24;13317:33;13295:20;;;13288:63;;;;13173:18;4806:200:2;12962:395:60;7885:168:2;;;:::i;10993:9597:4:-;;;;;;;;;;-1:-1:-1;10993:9597:4;;;;;:::i;:::-;;:::i;2957:137:5:-;;;;;;;;;;-1:-1:-1;2957:137:5;;;;;:::i;:::-;;:::i;7690:126:4:-;;;;;;;;;;-1:-1:-1;7690:126:4;;;;;:::i;:::-;;:::i;6859:158:2:-;;;;;;;;;;-1:-1:-1;6859:158:2;;;;;:::i;:::-;;:::i;2938:109:3:-;;;;;;;;;;;;;:::i;1592:314:6:-;1653:9;1649:66;;1690:14;;-1:-1:-1;;;1690:14:6;;;;;;;;;;;1649:66;1725:56;1771:9;1746:22;:20;:22::i;:::-;:34;;;;:::i;:::-;1725:20;:56::i;:::-;1792:45;1803:10;1815;1827:9;1792:10;:45::i;:::-;1853:46;;1889:9;1725:25:60;;-1:-1:-1;;;;;1853:46:6;;;1865:10;;1853:46;;1713:2:60;1698:18;1853:46:6;;;;;;;1592:314;:::o;7275:176:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;:::-;;;;;;;;429:114;7355:41:2::1;7379:16;7355:23;:41::i;:::-;7411:33;::::0;-1:-1:-1;;;;;7411:33:2;::::1;::::0;::::1;::::0;;;::::1;7275:176:::0;:::o;2647:1145::-;3063:1;1146:13:1;:11;:13::i;:::-;1134:8;:25;1130:109;;1204:8;1214:13;:11;:13::i;:::-;1182:46;;-1:-1:-1;;;1182:46:1;;;;;14206:25:60;;;;14247:18;;;14240:34;14179:18;;1182:46:1;14032:248:60;1130:109:1;1248:25;1260:12;:8;1271:1;1260:12;:::i;:::-;1248:11;:25::i;:::-;3076:40:2::1;3101:14;3076:24;:40::i;:::-;3131:32;3148:14;3131:32;;;;;;:::i;:::-;;;;;;;;3174:283;3214:233;;;;;;;;3314:30;-1:-1:-1::0;;;;;3214:233:2::1;;;;;3397:35;-1:-1:-1::0;;;;;3214:233:2::1;;;::::0;3174:26:::1;:283::i;:::-;3468:248;3503:15;3532:14;3560:15;3589:12;3615:24;3653:20;3687:19;3468:21;:248::i;:::-;3727:58;3744:4;3751:14;-1:-1:-1::0;;3727:8:2::1;:58::i;:::-;1343:30:1::0;1354:8;1364;;1343:30;;;;;;;;:::i;:::-;;;;;;;;2647:1145:2;;;;;;;;;;;:::o;3105:109:3:-;3159:7;3185:22;:20;:22::i;:::-;3178:29;;3105:109;:::o;8507:188:2:-;8595:26;:24;:26::i;:::-;-1:-1:-1;;;;;8581:40:2;:10;-1:-1:-1;;;;;8581:40:2;;8577:112;;8667:10;8644:34;;-1:-1:-1;;;8644:34:2;;;;;;;;:::i;8577:112::-;8507:188::o;4385:151:5:-;4454:4;4470:38;4479:10;4491:8;4501:6;4470:8;:38::i;:::-;-1:-1:-1;4525:4:5;4385:151;;;;:::o;1276:150:0:-;666:35;:33;:35::i;:::-;-1:-1:-1;;;;;652:49:0;:10;-1:-1:-1;;;;;652:49:0;;648:121;;747:10;724:34;;-1:-1:-1;;;724:34:0;;;;;;;;:::i;648:121::-;1335:46:::1;1345:35;:33;:35::i;:::-;1335:9;:46::i;:::-;1391:28;1416:1;1391:16;:28::i;5704:377:2:-:0;5787:23;5835:22;:20;:22::i;:::-;-1:-1:-1;;;;;5822:48:2;;5871:10;547:8:21;5822:91:2;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5923:50;5933:10;5953:4;5960:12;5923:9;:50::i;:::-;;6007:26;:24;:26::i;:::-;5990:84;;-1:-1:-1;;;5990:84:2;;;;;15202:25:60;;;-1:-1:-1;;;;;15263:32:60;;;15243:18;;;15236:60;5990:58:2;;;;;;;15175:18:60;;5990:84:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5983:91;5704:377;-1:-1:-1;;;5704:377:2:o;7120:133:4:-;7174:7;7200:30;:28;:30::i;:::-;:46;;;;;;7120:133;-1:-1:-1;7120:133:4:o;7052:188:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;7136:45:2::1;7162:18;7136:25;:45::i;:::-;7196:37;::::0;-1:-1:-1;;;;;7196:37:2;::::1;::::0;::::1;::::0;;;::::1;7052:188:::0;:::o;3630:1658:3:-;3701:24;3728:22;:20;:22::i;:::-;3701:49;-1:-1:-1;3760:25:3;3788:58;3803:31;1477:8;3701:49;3803:31;:::i;:::-;3836:9;3788:14;:58::i;:::-;3760:86;-1:-1:-1;3861:22:3;3857:76;;3906:16;;-1:-1:-1;;;3906:16:3;;;;;;;;;;;3857:76;4102:25;4129;4158:37;4177:17;4158:18;:37::i;:::-;4239:17;;4101:94;;-1:-1:-1;4101:94:3;-1:-1:-1;4271:27:3;4267:91;;4321:26;;-1:-1:-1;;;4321:26:3;;;;;;;;;;;4267:91;4397:17;4372:22;:42;4368:103;;;4437:23;;-1:-1:-1;;;4437:23:3;;;;;;;;;;;4368:103;4481:29;4513:27;:25;:27::i;:::-;4481:59;-1:-1:-1;4555:26:3;4551:94;;4604:30;;-1:-1:-1;;;4604:30:3;;;;;;;;;;;4551:94;4660:11;4655:213;4683:22;4677:3;:28;4655:213;;;4722:74;4740:10;4751:3;4740:15;;;;;;;;:::i;:::-;;;;;;;4757:10;4768:3;4757:15;;;;;;;;:::i;:::-;;;;;;;4774:21;4722:17;:74::i;:::-;4838:5;;4655:213;;;-1:-1:-1;4877:78:3;4917:37;4932:22;1477:8;4917:37;:::i;:::-;4898:56;;:16;:56;:::i;:::-;4877:20;:78::i;:::-;4965:38;5006:29;:27;:29::i;:::-;4965:70;-1:-1:-1;5045:84:3;5073:55;5106:22;4965:70;5073:55;:::i;:::-;5045:27;:84::i;:::-;5144:137;5184:30;5216:55;5249:22;5184:30;5216:55;:::i;:::-;5144:137;;;14206:25:60;;;14262:2;14247:18;;14240:34;;;;14179:18;5144:137:3;;;;;;;3691:1597;;;;;;;3630:1658;:::o;2470:104:5:-;2526:7;2552:15;:13;:15::i;1131:104:0:-;447:28;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;1201:27:::1;1218:9;1201:16;:27::i;:::-;1131:104:::0;:::o;4378:108:2:-;4428:7;4454:25;:23;:25::i;10165:230:4:-;4283:16;:14;:16::i;:::-;-1:-1:-1;;;;;4269:30:4;:10;-1:-1:-1;;;;;4269:30:4;;4265:102;;4345:10;4322:34;;-1:-1:-1;;;4322:34:4;;;;;;;;:::i;4265:102::-;10276:27:::1;;;::::0;;::::1;::::0;::::1;10293:9:::0;10276:27:::1;:::i;:::-;:16;:27::i;:::-;10318:70;::::0;;10328:29;::::1;14206:25:60::0;;10359:28:4::1;::::0;;::::1;;14247:18:60::0;;;14240:34;10318:70:4::1;::::0;14179:18:60;10318:70:4::1;;;;;;;;10165:230:::0;:::o;9363:168::-;9425:50;;:::i;:::-;9494:30;:28;:30::i;:::-;9487:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9487:37:4;;;;;;;;;;;9363:168;-1:-1:-1;9363:168:4:o;2334:93:5:-;2380:7;2406:14;:12;:14::i;3827:95:2:-;3874:7;3900:15;:13;:15::i;3942:400:5:-;4136:4;4049:5;4056:3;1267:23;1279:5;1286:3;1267:11;:23::i;:::-;4079:6;1473:11;1469:63:::1;;1507:14;;-1:-1:-1::0;;;1507:14:5::1;;;;;;;;;;;1469:63;4104:5:::2;4111:6;1830;1809:18;1820:6;1809:10;:18::i;:::-;:27;1805:80;;;1859:15;;-1:-1:-1::0;;;1859:15:5::2;;;;;;;;;;;1805:80;-1:-1:-1::0;;;;;4160:17:5;::::3;4156:94;;4200:39;::::0;-1:-1:-1;;;4200:39:5;;-1:-1:-1;;;;;16968:15:60;;4200:39:5::3;::::0;::::3;16950:34:60::0;4236:1:5::3;17000:18:60::0;;;16993:43;16885:18;;4200:39:5::3;16738:304:60::0;4156:94:5::3;4259:30;4275:5;4282:6;4259:15;:30::i;:::-;4306:29;4316:5;4323:3;4328:6;4306:9;:29::i;:::-;4299:36:::0;3942:400;-1:-1:-1;;;;;;;;;3942:400:5:o;1457:1155:2:-;1836:1;1146:13:1;:11;:13::i;:::-;1134:8;:25;1130:109;;1204:8;1214:13;:11;:13::i;1130:109::-;1248:25;1260:12;:8;1271:1;1260:12;:::i;1248:25::-;1849:38:2::1;1859:27;1849:9;:38::i;:::-;1898:39;1919:17;1898:20;:39::i;:::-;1952:31;::::0;-1:-1:-1;;;;;1952:31:2;::::1;::::0;::::1;::::0;;;::::1;1994:25;2008:10;1994:13;:25::i;:::-;2034:24;::::0;1725:25:60;;;2034:24:2::1;::::0;1713:2:60;1698:18;2034:24:2::1;;;;;;;2069:49;2095:22;2069:25;:49::i;:::-;2133:41;::::0;-1:-1:-1;;;;;2133:41:2;::::1;::::0;::::1;::::0;;;::::1;2185:39;2206:17;2185:20;:39::i;:::-;2239:31;::::0;-1:-1:-1;;;;;2239:31:2;::::1;::::0;::::1;::::0;;;::::1;2281:54;2310:24;2281:28;:54::i;:::-;2350:46;::::0;-1:-1:-1;;;;;2350:46:2;::::1;::::0;::::1;::::0;;;::::1;2407:136;2486:23;2511:22;2407:65;:136::i;:::-;2554:51;2590:14;2554:35;:51::i;:::-;1343:30:1::0;1354:8;1364;;1343:30;;;;;;;;:::i;:::-;;;;;;;;1457:1155:2;;;;;;;;;;:::o;6498:133::-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;6566:22:2::1;6580:7;6566:13;:22::i;:::-;6603:21;::::0;1725:25:60;;;6603:21:2::1;::::0;1713:2:60;1698:18;6603:21:2::1;1579:177:60::0;4231:112:2;4283:7;4309:27;:25;:27::i;5264:107::-;5317:7;5343:21;:19;:21::i;8317:108:4:-;8361:26;;:::i;:::-;8406:12;:10;:12::i;4579:227:5:-;4668:4;4684:94;4693:10;4705:8;4761:16;4715:43;4737:10;4749:8;4715:21;:43::i;:::-;:62;;;;:::i;:::-;4684:8;:94::i;2769:145::-;2835:7;2861:46;2880:26;2899:6;2880:18;:26::i;:::-;2861:18;:46::i;:::-;2854:53;2769:145;-1:-1:-1;;2769:145:5:o;6935:142:4:-;6996:7;7022:30;:28;:30::i;:::-;:48;;;7015:55;;6935:142;:::o;7296:351::-;7349:7;7368:30;7401:12;:10;:12::i;:::-;7368:45;;7423:20;7446:18;7460:3;7446:13;:18::i;:::-;7423:41;;7481:159;7548:3;:18;;;-1:-1:-1;;;;;7509:57:4;:30;:28;:30::i;:::-;:36;:57;;;;:::i;:::-;7611:18;;7596:33;;-1:-1:-1;;;;;7596:33:4;:12;:33;:::i;:::-;7580:50;;:12;:50;:::i;:::-;7481:14;:159::i;:::-;7474:166;;;;7296:351;:::o;4094:102:2:-;4141:7;4167:22;:20;:22::i;3272:119:3:-;3331:7;3357:27;:25;:27::i;8990:155:4:-;9061:7;9110:12;:10;:12::i;:::-;:27;9099:38;;-1:-1:-1;;;;;9099:38:4;:8;:38;:::i;:::-;9087:51;;:8;:51;:::i;6666:158:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;6740:35:2::1;6761:13;6740:20;:35::i;:::-;6790:27;::::0;-1:-1:-1;;;;;6790:27:2;::::1;::::0;::::1;::::0;;;::::1;6666:158:::0;:::o;8088:176::-;8156:34;:32;:34::i;5406:263::-;5521:33;5594:26;:24;:26::i;:::-;-1:-1:-1;;;;;5577:66:2;;5644:17;;5577:85;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5577:85:2;;;;;;;;;;;;:::i;4521:110::-;4572:7;4598:26;:24;:26::i;827:104:0:-;870:7;896:28;:26;:28::i;2617:109:5:-;2675:7;2701:18;2712:6;2701:10;:18::i;8468:479:4:-;8518:21;8541:18;8561:16;8589:30;8622:12;:10;:12::i;:::-;8589:45;;8644:20;8667:18;8681:3;8667:13;:18::i;:::-;8742;;8644:41;;-1:-1:-1;8727:33:4;;-1:-1:-1;;;;;8727:33:4;8644:41;8727:33;:::i;:::-;8711:50;;:12;:50;:::i;:::-;8695:66;;8820:3;:18;;;-1:-1:-1;;;;;8784:54:4;8800:3;:17;;;-1:-1:-1;;;;;8784:33:4;:13;:33;;;;:::i;:::-;:54;;;;:::i;:::-;8771:67;;8939:1;8918:3;:18;;;-1:-1:-1;;;;;8859:77:4;8898:3;:17;;;-1:-1:-1;;;;;8859:56:4;8876:3;:18;;;-1:-1:-1;;;;;8860:34:4;:13;:34;;;;:::i;:::-;8859:56;;;;:::i;:::-;:77;;;;:::i;:::-;:81;;;;:::i;:::-;8848:92;;8579:368;;8468:479;;;:::o;7486:211:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;7567:41:2::1;7595:12;7567:27;:41::i;:::-;7618:29;7634:12;7618:15;:29::i;:::-;7662:28;7677:12;7662:28;;;;;;:::i;9774:348:4:-:0;4283:16;:14;:16::i;:::-;-1:-1:-1;;;;;4269:30:4;:10;-1:-1:-1;;;;;4269:30:4;;4265:102;;4345:10;4322:34;;-1:-1:-1;;;4322:34:4;;;;;;;;:::i;4265:102::-;9867:21:::1;;;::::0;;::::1;::::0;::::1;9878:9:::0;9867:21:::1;:::i;:::-;:10;:21::i;:::-;9903:212;9924:24;;::::0;::::1;:9:::0;:24:::1;:::i;:::-;9962:23;::::0;;;::::1;::::0;::::1;;:::i;:::-;9999:24;::::0;;;::::1;::::0;::::1;;:::i;:::-;10037:21;::::0;;;::::1;::::0;::::1;;:::i;:::-;10072:33;::::0;;;::::1;::::0;::::1;;:::i;:::-;9903:212;;;;;;;;;;:::i;3137:167:5:-:0;3229:7;3255:42;3274:22;3255:18;:42::i;9574:157:4:-;4283:16;:14;:16::i;:::-;-1:-1:-1;;;;;4269:30:4;:10;-1:-1:-1;;;;;4269:30:4;;4265:102;;4345:10;4322:34;;-1:-1:-1;;;4322:34:4;;;;;;;;:::i;4265:102::-;9651:33:::1;9669:14;9651:17;:33::i;:::-;9699:25;::::0;-1:-1:-1;;;;;9699:25:4;::::1;::::0;::::1;::::0;;;::::1;9574:157:::0;:::o;6796:96::-;6840:7;6866:19;:17;:19::i;4666:105:2:-;4715:13;4747:17;:15;:17::i;3449:123:3:-;3510:7;3536:29;:27;:29::i;7992:127:4:-;8050:7;8076:30;:28;:30::i;:::-;:36;;7992:127;-1:-1:-1;7992:127:4:o;6116:347:2:-;6255:28;6323:26;:24;:26::i;:::-;-1:-1:-1;;;;;6306:64:2;;6384:17;;6403:19;;6424:4;6430:16;6306:150;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6306:150:2;;;;;;;;;;;;:::i;:::-;6299:157;6116:347;-1:-1:-1;;;;;6116:347:2:o;7732:118::-;7787:7;7813:30;:28;:30::i;9188:132:4:-;-1:-1:-1;;;;;;;;;;;;;;;;;9295:18:4;:16;:18::i;8162:112::-;8214:7;8240:27;8254:12;:10;:12::i;:::-;8240:13;:27::i;4849:231:5:-;4940:4;4956:96;4965:10;4977:8;5033:18;4987:43;5009:10;5021:8;4987:21;:43::i;:::-;:64;;;;:::i;3538:361::-;3723:4;3626:10;3638:3;1267:23;1279:5;1286:3;1267:11;:23::i;:::-;3661:6;1473:11;1469:63:::1;;1507:14;;-1:-1:-1::0;;;1507:14:5::1;;;;;;;;;;;1469:63;3686:10:::2;3698:6;1830;1809:18;1820:6;1809:10;:18::i;:::-;:27;1805:80;;;1859:15;;-1:-1:-1::0;;;1859:15:5::2;;;;;;;;;;;1805:80;-1:-1:-1::0;;;;;3747:17:5;::::3;3743:99;;3787:44;::::0;-1:-1:-1;;;3787:44:5;;3808:10:::3;3787:44;::::0;::::3;16950:34:60::0;3828:1:5::3;17000:18:60::0;;;16993:43;16885:18;;3787:44:5::3;16738:304:60::0;3743:99:5::3;3858:34;3868:10;3880:3;3885:6;3858:9;:34::i;:::-;3851:41:::0;3538:361;-1:-1:-1;;;;;;;;3538:361:5:o;1040:151:6:-;1115:39;1143:10;1115:27;:39::i;:::-;1164:20;1173:10;1164:8;:20::i;5041:188:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;5190:32:2::1;5217:4;5190:26;:32::i;3957:102::-:0;4004:7;4030:22;:20;:22::i;972:118:0:-;1022:7;1048:35;:33;:35::i;919:73:6:-;965:20;974:10;965:8;:20::i;8299:173:2:-;8373:25;:23;:25::i;3347:148:5:-;3423:7;3449:39;3471:6;3479:8;3449:21;:39::i;4806:200:2:-;-1:-1:-1;;;;;;;;;;;;;;;;;4971:28:2;:26;:28::i;7885:168::-;7952:27;:25;:27::i;10993:9597:4:-;11177:19;:17;:19::i;:::-;-1:-1:-1;;;;;11163:33:4;:10;-1:-1:-1;;;;;11163:33:4;;11159:105;;11242:10;11219:34;;-1:-1:-1;;;11219:34:4;;;;;;;;:::i;11159:105::-;11274:30;11307:12;:10;:12::i;:::-;11274:45;-1:-1:-1;11435:33:4;11274:45;11454:13;;11435;:33::i;:::-;11430:99;;11491:27;;-1:-1:-1;;;11491:27:4;;11504:13;;11491:27;;;1725:25:60;1698:18;;11491:27:4;1579:177:60;11430:99:4;11539:48;;:::i;:::-;11612:68;11683:30;:28;:30::i;:::-;11759:40;;;;11728:28;;;:71;;;11612:101;;-1:-1:-1;11900:31:4;;;;:62;11896:249;;;12051:28;;;;;11989:141;;-1:-1:-1;;;11989:141:4;;;;;14206:25:60;;;;12081:31:4;;;;14247:18:60;;;14240:34;14179:18;;11989:141:4;14032:248:60;11896:249:4;12310:28;;;;12276:62;;:31;;;;:62;:::i;:::-;12248:25;;;:90;12385:41;;;;12353:29;;;:73;;;12528:32;;;;:64;12524:254;;;12682:29;;;;12713:32;12619:144;;-1:-1:-1;;;12619:144:4;;;;;14206:25:60;;;;12713:32:4;;;14247:18:60;;;14240:34;14179:18;;12619:144:4;14032:248:60;12524:254:4;12916:29;:27;:29::i;:::-;12890:23;;;;;;;;:::i;:::-;:55;;;:137;;;-1:-1:-1;12995:32:4;;;;;;12969:23;;;;;;;;:::i;:::-;:58;;;12890:137;12869:368;;;13116:23;;;;;;;;:::i;:::-;13141:29;:27;:29::i;:::-;13172:32;;;;13067:155;;-1:-1:-1;;;13067:155:4;;13172:32;23049:15:60;;;13067:155:4;;;23031:34:60;23081:18;;;23074:34;;;;13172:32:4;;;;23124:18:60;;;23117:43;22975:18;;13067:155:4;22802:364:60;12869:368:4;13400:29;;;;13365:64;;:32;;;;:64;:::i;:::-;13336:26;;;:93;13502:22;;13478:62;;13497:3;;13526:13;;13478:18;:62::i;:::-;13444:31;;;:96;-1:-1:-1;13706:15:4;:13;:15::i;:::-;13672:49;;13871:26;;;;13843:25;;;;13672:31;;13843:54;;;:::i;:::-;:58;13839:240;;;14001:67;14014:4;:26;;;14042:4;:25;;;14001:12;:67::i;:::-;14224:63;;:::i;:::-;14323:13;;14302:34;;14383:25;;;;;14350:30;;;:58;14462:32;;;;;14422:37;;;:72;14547:31;;;;;14508:36;;;:70;14632:32;;;;;14592:37;;;:72;14709:23;;;;;;;;:::i;:::-;14678:54;;:28;;;:54;14790:36;;;;;;;;:::i;:::-;14746:80;;:41;;;:80;14879:31;;;;;;;;:::i;:::-;14840:70;;:36;;;:70;14924:42;14840:12;14924:28;:42::i;:::-;14089:888;14987:41;15031:18;:16;:18::i;:::-;14987:62;;15152:19;15174:82;15187:2;15191:4;:31;;;15224:4;:31;;;15174:12;:82::i;:::-;15152:104;;15394:15;:13;:15::i;:::-;15359:32;;;:50;;;15924:31;;-1:-1:-1;15884:2086:4;;16091:31;;:45;;16125:11;;16091:45;:::i;:::-;16056:4;:32;;;:80;16052:387;;;16224:31;;16277:32;;;;16331:31;;;;16384:22;;16163:261;;-1:-1:-1;;;16163:261:4;;;;;23904:25:60;;;;23945:18;;;23938:34;;;;23988:18;;;23981:34;24031:18;;;24024:34;23876:19;;16163:261:4;23673:391:60;16052:387:4;16573:31;;16538:32;;;;:66;;16573:31;16538:66;:::i;:::-;16517:10;;;;;:87;;;;16808:10;:18;16794:32;;:11;:32;:::i;:::-;16759;;;:67;15884:2086;;;17041:19;17063:49;17076:2;17080:4;:31;;;17063:12;:49::i;:::-;17041:71;;17292:60;17307:11;17320:4;:31;;;17292:14;:60::i;:::-;17258:31;;:94;;;;:::i;:::-;17203:4;:32;;;:149;17182:485;;;17453:31;;17506:32;;;;;17560:31;;;;17613:21;;;;17392:260;;-1:-1:-1;;;17392:260:4;;;;17453:31;17560;17613:21;17392:260;;23904:25:60;;;23960:2;23945:18;;23938:34;;;;24003:2;23988:18;;23981:34;24046:2;24031:18;;24024:34;23891:3;23876:19;;23673:391;17182:485:4;17926:32;;;;17892:31;;:66;;17926:32;17892:66;:::i;:::-;17877:82;;:11;:82;:::i;:::-;17826:32;;;:133;-1:-1:-1;15884:2086:4;18077:32;;;;:36;18073:437;;18227:45;18239:4;:32;;;18227:11;:45::i;:::-;18201:10;;;;;:23;;;;:71;;;;18345:10;:23;;;;18323:45;;18345:23;;:10;18323:45;;18345:23;;18323:45;:::i;:::-;;;-1:-1:-1;18476:10:4;;;;:23;;;18440:32;;;:59;;;;18476:23;;18440:59;:::i;:::-;;;-1:-1:-1;18073:437:4;18620:32;;;;:36;18616:439;;18824:64;18855:4;:32;;;18824:30;:64::i;:::-;18757:10;;;;;:48;;;;:131;;;;18996:10;:48;;-1:-1:-1;18960:32:4;;:84;;;;18996:48;;18960:84;:::i;:::-;;;-1:-1:-1;18616:439:4;19197:32;;;;:36;19193:407;;19343:52;19362:4;:32;;;19343:18;:52::i;:::-;19310:10;;;;:30;;:85;19193:407;19691:10;;;;:18;:22;19687:84;;19741:10;;;;:18;19729:31;;:11;:31::i;:::-;19781:254;19844:32;;;;19890:40;;;;19844:7;19890:40;:::i;:::-;19781:254;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19944:36:4;;-1:-1:-1;;;19944:36:4;;;;;;;:::i;:::-;19994:31;;;;;;;;:::i;:::-;19781:49;:254::i;:::-;20147:32;:30;:32::i;:::-;20281:28;:26;:28::i;:::-;20395:56;20419:4;:31;;;20395:23;:56::i;:::-;20533:50;20563:7;20572:4;:10;;;20533:50;;;;;;;:::i;:::-;;;;;;;;11089:9501;;;;10993:9597;:::o;2957:137:5:-;3034:7;3060:27;3079:7;3060:18;:27::i;7690:126:4:-;7751:4;7774:35;7788:12;:10;:12::i;:::-;7802:6;7774:13;:35::i;6859:158:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;6933:35:2::1;6954:13;6933:20;:35::i;:::-;6983:27;::::0;-1:-1:-1;;;;;6983:27:2;::::1;::::0;::::1;::::0;;;::::1;6859:158:::0;:::o;2938:109:3:-;2992:7;3018:22;:20;:22::i;627:123:58:-;678:65;308:45;352:1;316:32;308:45;:::i;:::-;733:9;3024:24:27;;2865:199;;3024:24;;2865:199::o;268:136:32:-;306:7;332:65;206:54;259:1;214:41;206:54;:::i;:::-;1622:16:27;;1442:212;15543:239:2;15658:65;15678:22;:20;:22::i;:::-;15658:65;;;14206:25:60;;;14262:2;14247:18;;14240:34;;;14179:18;15658:65:2;;;;;;;15733:42;15754:20;15733;:42::i;9729:741::-;9834:20;9857:48;9885:10;9897:7;9857:27;:48::i;:::-;9834:71;;9915:22;9953;:20;:22::i;:::-;9915:61;;10004:10;-1:-1:-1;;;;;9990:24:2;:10;-1:-1:-1;;;;;9990:24:2;;9986:478;;;10030:65;;-1:-1:-1;;;10030:65:2;;-1:-1:-1;;;;;10030:21:2;;;;;:65;;10052:10;;350:3:21;;10030:65:2;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9986:478;;;10173:65;;-1:-1:-1;;;10173:65:2;;-1:-1:-1;;;;;10173:21:2;;;;;:65;;10195:10;;350:3:21;;10173:65:2;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;10303:30:2;;-1:-1:-1;;;10303:30:2;;-1:-1:-1;;;;;10303:18:2;;;-1:-1:-1;10303:18:2;;-1:-1:-1;10303:30:2;;10322:10;;10303:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10299:94;;;10367:10;10360:18;;-1:-1:-1;;;10360:18:2;;;;;;;;:::i;10299:94::-;10406:47;10416:10;10428;10440:12;10406:9;:47::i;:::-;;9986:478;9824:646;;9729:741;;;:::o;407:103:20:-;451:7;477:26;:24;:26::i;829:185:39:-;880:38;908:9;880:27;:38::i;:::-;928:79;428:57;484:1;436:44;428:57;:::i;426:125:58:-;464:7;490:54;308:45;352:1;316:32;308:45;:::i;840:186:50:-;891:38;919:9;891:27;:38::i;:::-;939:80;433:58;490:1;441:45;433:58;:::i;15123:278:2:-;15243:32;15270:4;15243:26;:32::i;:::-;15320:33;;15355:38;;;;15290:104;;;;;;15320:33;;-1:-1:-1;;;;;27392:15:60;;;27374:34;;27444:15;;27439:2;27424:18;;27417:43;27324:2;27309:18;;27162:304;5137:1616:4;5433:324;5457:290;;;;;;;;5511:15;-1:-1:-1;;;;;5457:290:4;;;;;5559:14;-1:-1:-1;;;;;5457:290:4;;;;;5607:15;-1:-1:-1;;;;;5457:290:4;;;;;5653:12;-1:-1:-1;;;;;5457:290:4;;;;;5708:24;-1:-1:-1;;;;;5457:290:4;;;;5433:10;:324::i;:::-;5772:97;5780:15;5797:14;5813:15;5830:12;5844:24;5772:97;;;;;;;;;;:::i;:::-;;;;;;;;5879:203;5909:163;;;;;;;;5980:20;5909:163;;;;6038:19;5909:163;;;5879:16;:203::i;:::-;6097:52;;;14206:25:60;;;14262:2;14247:18;;14240:34;;;6097:52:4;;14179:18:60;6097:52:4;;;;;;;6160:63;;:::i;:::-;6262:23;:21;:23::i;:::-;6233:53;;6329:29;:27;:29::i;:::-;6296:30;;;:62;6408:1;6368:37;;;:41;;;6419:36;;;:40;;;6469:37;;;:41;6558:22;:20;:22::i;:::-;6520:61;;:28;;;:61;6635:5;6591:41;;;:49;;;6650:36;;;:44;6704:42;6520:12;6704:28;:42::i;:::-;5423:1330;5137:1616;;;;;;;:::o;5941:282:5:-;6028:35;6056:6;6028:27;:35::i;:::-;6073:37;6101:8;6073:27;:37::i;:::-;6120:47;6142:6;6150:8;6160:6;6120:21;:47::i;:::-;6199:8;-1:-1:-1;;;;;6182:34:5;6191:6;-1:-1:-1;;;;;6182:34:5;;6209:6;6182:34;;;;1725:25:60;;1713:2;1698:18;;1579:177;6182:34:5;;;;;;;;5941:282;;;:::o;594:140:50:-;632:7;658:69;433:58;490:1;441:45;433:58;:::i;621:117:20:-;672:7;698:33;:31;:33::i;1536:171:0:-;1590:35;1618:6;1590:27;:35::i;:::-;1635:34;1662:6;1635:26;:34::i;:::-;1684:16;;-1:-1:-1;;;;;1684:16:0;;;;;;;;1536:171;:::o;1840:168::-;1908:48;1942:13;1908:33;:48::i;:::-;1971:30;;-1:-1:-1;;;;;1971:30:0;;;;;;;;1840:168;:::o;548:135:31:-;586:7;612:64;401:54;454:1;409:41;401:54;:::i;6676:298:5:-;6757:4;6773:61;6792:5;6827:6;6799:25;6818:5;6799:18;:25::i;:::-;:34;;;;:::i;:::-;6773:18;:61::i;:::-;6844:57;6863:3;6894:6;6868:23;6887:3;6868:18;:23::i;:::-;:32;;;;:::i;6844:57::-;6933:3;-1:-1:-1;;;;;6917:28:5;6926:5;-1:-1:-1;;;;;6917:28:5;-1:-1:-1;;;;;;;;;;;6938:6:5;6917:28;;;;1725:25:60;;1713:2;1698:18;;1579:177;6917:28:5;;;;;;;;-1:-1:-1;6963:4:5;6676:298;;;;;:::o;789:318:45:-;827:51;;421:62;482:1;429:49;421:62;:::i;941:183:43:-;992:38;1020:9;992:27;:38::i;:::-;1040:77;476:59;534:1;484:46;476:59;:::i;267:135:38:-;305:7;331:64;205:54;258:1;213:41;205:54;:::i;1295:112:26:-;1355:7;1387:2;1382;:7;:17;;1397:2;1382:17;;;-1:-1:-1;1392:2:26;1295:112;-1:-1:-1;1295:112:26:o;10859:285:2:-;10964:25;10991;11060:30;:28;:30::i;:::-;-1:-1:-1;;;;;11039:80:2;;11120:16;11039:98;;;;;;;;;;;;;1725:25:60;;1713:2;1698:18;;1579:177;11039:98:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11039:98:2;;;;;;;;;;;;:::i;:::-;11032:105;;;;10859:285;;;:::o;594:140:54:-;632:7;658:69;432:59;490:1;440:46;432:59;:::i;5565:1394:3:-;1289:2;5709:10;:17;:38;5705:100;;5770:24;;-1:-1:-1;;;5770:24:3;;;;;;;;;;;5705:100;1389:2;5819:10;:17;:37;5815:99;;5879:24;;-1:-1:-1;;;5879:24:3;;;;;;;;;;;5815:99;1477:8;5923:13;5986:14;5994:6;1477:8;5986:14;:::i;:::-;5962:38;;6011:18;6032:44;6052:10;6072:1;6064:10;;6039:36;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;6039:36:3;;;;;;;;;;6032:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6011:65;;6086:21;6110:220;6160:41;6167:33;6182:10;6194:1;6197:2;6167:14;:33::i;:::-;6160:41;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6219:87;6239:53;6254:10;6266:2;6270:21;6266:2;1389;6270:21;:::i;:::-;6239:14;:53::i;:::-;6226:79;;;;;6302:1;;6226:79;;;:::i;:::-;;;;-1:-1:-1;;6226:79:3;;;;;;;;;;6219:87;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6130:190;;;;;;30900:19:60;;;;30935:12;;30928:28;30972:12;;6130:190:3;;;-1:-1:-1;;6130:190:3;;;;;;;;;;6110:220;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6086:244;;6341:23;6367:236;6417:56;6437:10;6449:22;6424:48;;;;;;;;30900:19:60;;;30944:2;30935:12;;30928:28;30981:2;30972:12;;30743:247;6424:48:3;;;;-1:-1:-1;;6424:48:3;;;;;;;;;;6417:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6491:88;6519:42;6547:13;6519:27;:42::i;:::-;6498:80;;;;;;30900:19:60;;;;30935:12;;30928:28;;;30972:12;;6498:80:3;;;-1:-1:-1;;6498:80:3;;;;;;;;;;6491:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6387:206;;;;;;30900:19:60;;;;30935:12;;30928:28;30972:12;;6387:206:3;;;-1:-1:-1;;6387:206:3;;;;;;;;;;6367:236;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6341:262;-1:-1:-1;6614:21:3;6638:29;6662:5;6638:21;:29;:::i;:::-;6614:53;;6695:28;:26;:28::i;:::-;-1:-1:-1;;;;;6678:54:3;;6740:5;6760:10;6789:22;6772:40;;;;;;31124:19:60;;31168:2;31159:12;;30995:182;6772:40:3;;;;;;;;;;;;;6814:10;6826:15;6678:173;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6890:13;6865:21;:38;6861:92;;6926:16;;-1:-1:-1;;;6926:16:3;;;;;;;;;;;6861:92;5695:1264;;;;;;5565:1394;;;:::o;16323:258:2:-;16448:74;16477:22;:20;:22::i;:::-;16448:74;;;14206:25:60;;;14262:2;14247:18;;14240:34;;;14179:18;16448:74:2;;;;;;;16532:42;16553:20;16532;:42::i;576:143:42:-;614:7;640:72;406:61;466:1;414:48;406:61;:::i;831:141::-;882:83;406:61;466:1;414:48;406:61;:::i;14167:828:2:-;14258:7;14277:64;14344:30;:28;:30::i;:::-;14411:28;;;;14277:97;;-1:-1:-1;14411:28:2;;14384:24;14483:29;:27;:29::i;:::-;14449:63;;14545:23;14526:16;:42;14522:467;;;1477:8:3;14731:42:2;14757:16;14731:23;:42;:::i;:::-;14730:90;;;;:::i;:::-;14690:21;:19;:21::i;:::-;14649:22;:20;:22::i;:::-;14624;:20;:22::i;:::-;14591:12;:30;;;:55;;;;:::i;:::-;:80;;;;:::i;:::-;:120;;;;:::i;:::-;:229;;;;:::i;:::-;14584:236;;;;;14167:828;:::o;14522:467::-;14957:21;:19;:21::i;:::-;14932:22;:20;:22::i;:::-;14907;:20;:22::i;:::-;14874:12;:30;;;:55;;;;:::i;586:139:39:-;624:7;650:68;428:57;484:1;436:44;428:57;:::i;8820:201:2:-;8959:7;8989:25;:23;:25::i;1360:291:51:-;1436:12;285:50;334:1;293:37;285:50;:::i;:::-;1618:26;;;;;;;;;;;;;;;;;-1:-1:-1;1360:291:51:o;6334:92:5:-;6381:7;6407:12;:10;:12::i;492:128:44:-;530:7;556:57;366:47;412:1;374:34;366:47;:::i;9176:316:2:-;9258:22;9296;:20;:22::i;:::-;9333:25;;-1:-1:-1;;;9333:25:2;;9258:61;;-1:-1:-1;;;;;;9333:18:2;;;;;:25;;9352:5;;9333:25;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9329:76;;;9388:5;9381:13;;-1:-1:-1;;;9381:13:2;;;;;;;;:::i;9329:76::-;9418:23;;-1:-1:-1;;;9418:23:2;;-1:-1:-1;;;;;9418:18:2;;;;;:23;;9437:3;;9418:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9414:72;;;9471:3;9464:11;;-1:-1:-1;;;9464:11:2;;;;;;;;:::i;9414:72::-;9248:244;9176:316;;:::o;9023:118:5:-;9082:7;9108:26;9127:6;9108:18;:26::i;5291:412::-;5366:24;5393:40;5415:5;5422:10;5393:21;:40::i;:::-;5366:67;;5466:6;5447:16;:25;5443:123;;;5495:60;;-1:-1:-1;;;5495:60:5;;-1:-1:-1;;;;;32087:15:60;;5495:60:5;;;32069:34:60;5518:10:5;32119:18:60;;;32112:43;32171:18;;;32164:34;;;32214:18;;;32207:34;;;32003:19;;5495:60:5;31800:447:60;5443:123:5;-1:-1:-1;;5579:16:5;:37;5575:122;;5632:54;5641:5;5648:10;5660:25;5679:6;5660:16;:25;:::i;779:181:37:-;830:38;858:9;830:27;:38::i;:::-;878:75;401:54;454:1;409:41;401:54;:::i;702:168:44:-;753:32;775:9;753:21;:32::i;:::-;795:68;366:47;412:1;374:34;366:47;:::i;779:181:31:-;830:38;858:9;830:27;:38::i;:::-;878:75;401:54;454:1;409:41;401:54;:::i;884:190:48:-;935:38;963:9;935:27;:38::i;:::-;983:84;453:62;514:1;461:49;453:62;:::i;2494:386:3:-;2634:51;2661:23;2634:26;:51::i;:::-;2700:50;;-1:-1:-1;;;;;2700:50:3;;;;;;;;2761:49;2787:22;2761:25;:49::i;:::-;2825:48;;1725:25:60;;;2825:48:3;;1713:2:60;1698:18;2825:48:3;;;;;;;2494:386;;:::o;668:137:43:-;706:7;732:66;476:59;534:1;484:46;476:59;:::i;265:135:33:-;303:7;329:64;204:53;256:1;212:40;204:53;:::i;1241:266:34:-;1279:19;;:::i;:::-;1310:12;294:44;337:1;302:31;294:44;:::i;:::-;1486:14;;;;;;;;;;-1:-1:-1;;;;;1486:14:34;;;;;-1:-1:-1;;;1486:14:34;;;;;;;;-1:-1:-1;;;1486:14:34;;;;;;;;;;;-1:-1:-1;;;1486:14:34;;;;;;;;;;;;;;;;;;;1241:266;-1:-1:-1;;1241:266:34:o;833:318:56:-;904:7;;322:55;376:1;330:42;322:55;:::i;:::-;-1:-1:-1;;;;;1118:15:56;;;314:64;1118:15;;;;;;;;;;;:26;;;;;;;;;-1:-1:-1;;1118:26:56;;;833:318::o;689:285:53:-;741:7;;299:52;350:1;307:39;299:52;:::i;:::-;-1:-1:-1;;;;;952:15:53;;;291:61;952:15;;;;;;;;-1:-1:-1;;952:15:53;;;;;689:285::o;7176:272:5:-;7244:7;7263:25;7291:12;:10;:12::i;:::-;7263:40;-1:-1:-1;7318:22:5;7314:61;;-1:-1:-1;7363:1:5;;7176:272;-1:-1:-1;;7176:272:5:o;7314:61::-;7424:17;7404:15;:13;:15::i;:::-;7394:25;;:7;:25;:::i;:::-;7392:49;;;;:::i;20756:193:4:-;20835:7;20924:4;:18;;;-1:-1:-1;;;;;20861:81:4;20901:4;:19;;;-1:-1:-1;;;;;20862:58:4;20881:4;:16;;;-1:-1:-1;;;;;20863:34:4;:15;:34;;;;:::i;:::-;20862:58;;;;:::i;:::-;20861:81;;;;:::i;1560:112:26:-;1620:7;1652:2;1647;:7;:17;;1662:2;1647:17;;548:135:37;586:7;612:64;401:54;454:1;409:41;401:54;:::i;543:172:25:-;619:21;;615:94;;668:30;;-1:-1:-1;;;668:30:25;;;;;;;;;;;914:264:47;971:12;276:49;324:1;284:36;276:49;:::i;:::-;1152:19;;268:58;;-1:-1:-1;268:58:47;;1152:19;;268:58;;1152:19;;;;;:::i;:::-;;961:217;;914:264;:::o;1633:267:34:-;1697:12;294:44;337:1;302:31;294:44;:::i;:::-;1873:20;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1873:20:34;;;-1:-1:-1;;;;;;1873:20:34;;;;;;;-1:-1:-1;;;1873:20:34;;;;;;;;;;;-1:-1:-1;;;;;1873:20:34;-1:-1:-1;;;1873:20:34;;;;;;;-1:-1:-1;;;;;1873:20:34;;-1:-1:-1;;;1873:20:34;;;;;;;;;;;;;;;-1:-1:-1;1873:20:34;;;;;-1:-1:-1;;1873:20:34;;;;;;;;;-1:-1:-1;1633:267:34:o;7672:272:5:-;7741:7;7760:25;7788:12;:10;:12::i;:::-;7760:40;-1:-1:-1;7815:22:5;7811:61;;-1:-1:-1;7860:1:5;;7672:272;-1:-1:-1;;7672:272:5:o;7811:61::-;7922:15;:13;:15::i;:::-;7890:28;7901:17;7890:8;:28;:::i;746:178:49:-;797:38;825:9;797:27;:38::i;:::-;845:72;386:51;436:1;394:38;386:51;:::i;524:132::-;562:7;588:61;386:51;436:1;394:38;386:51;:::i;548:265:47:-;586:13;611:12;276:49;324:1;284:36;276:49;:::i;:::-;792:14;;268:58;;-1:-1:-1;268:58:47;;;;792:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;548:265;:::o;626:144:48:-;664:7;690:73;453:62;514:1;461:49;453:62;:::i;967:278:51:-;-1:-1:-1;;;;;;;;;;;;;;;;;1042:12:51;285:50;334:1;293:37;285:50;:::i;:::-;1224:14;;;;;;;;;;;;;;;;;;;;;;;967:278;-1:-1:-1;;967:278:51:o;292:163:25:-;-1:-1:-1;;;;;363:22:25;;359:90;;408:30;;-1:-1:-1;;;408:30:25;;;;;;;;;;;944:299:40;-1:-1:-1;;;;;;;;;;;;;;;;;1029:12:40;398:60;457:1;406:47;398:60;:::i;:::-;1222:14;;;;;;;;;;;-1:-1:-1;;;;;1222:14:40;;;;;-1:-1:-1;;;1222:14:40;;;;;;;;;944:299;-1:-1:-1;;944:299:40:o;21132:311:4:-;21227:4;21296;:28;;;-1:-1:-1;;;;;21287:37:4;:6;:37;;;;:::i;:::-;21264:19;21278:4;21264:13;:19::i;:::-;:60;;:125;;;;;21353:30;:28;:30::i;:::-;:36;21344:45;;21264:125;:162;;;;-1:-1:-1;21402:19:4;;21393:28;;-1:-1:-1;;;;;21393:28:4;:6;:28;:::i;:::-;:33;;21132:311;-1:-1:-1;;;21132:311:4:o;22903:253::-;23050:7;23130:4;:18;;;23108:4;:19;;;:40;;;;:::i;:::-;-1:-1:-1;;;;;23080:69:4;23081:22;23093:10;23081:9;:22;:::i;:::-;23080:69;;;;:::i;:::-;23073:76;22903:253;-1:-1:-1;;;;22903:253:4:o;16829:885:2:-;16957:21;16932:22;17016:36;17036:16;17016:17;:36;:::i;:::-;16988:64;;17074:34;:32;:34::i;:::-;-1:-1:-1;;;;;17062:55:2;;17118:17;17062:74;;;;;;;;;;;;;1725:25:60;;1713:2;1698:18;;1579:177;17062:74:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17146:24;17197:14;17173:21;:38;;;;:::i;:::-;17146:65;-1:-1:-1;17245:36:2;17265:16;17245:17;:36;:::i;:::-;17225:16;:56;17221:176;;17331:36;17351:16;17331:17;:36;:::i;:::-;17304:82;;-1:-1:-1;;;17304:82:2;;;;;14206:25:60;;;;14247:18;;;14240:34;;;14179:18;;17304:82:2;14032:248:60;17221:176:2;17410:21;;17406:116;;17447:64;17493:17;17468:22;:20;:22::i;17447:64::-;17535:20;;17531:112;;17571:61;17615:16;17591:21;:19;:21::i;:::-;:40;;;;:::i;:::-;17571:19;:61::i;:::-;17657:50;;;14206:25:60;;;14262:2;14247:18;;14240:34;;;17657:50:2;;14179:18:60;17657:50:2;14032:248:60;1239:316:45;1333:12;421:62;482:1;429:49;421:62;:::i;:::-;1529:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1529:19:45;-1:-1:-1;;1529:19:45;;;;;-1:-1:-1;;1529:19:45;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1239:316:45:o;21806:298:4:-;21964:7;22054:42;1050:8;273:6:22;22054:42:4;:::i;:::-;22011:23;;22037:12;;21995:39;;:13;:39;:::i;:::-;:54;;;;:::i;:::-;21994:103;;;;:::i;22383:247::-;22519:7;273:6:22;22566:3:4;:22;;;22550:13;:38;;;;:::i;11442:536:2:-;11504:7;11523:22;11548:27;:25;:27::i;:::-;11641:59;;-1:-1:-1;;;11641:59:2;;;;;1725:25:60;;;11523:52:2;;-1:-1:-1;11610:21:2;;-1:-1:-1;;;;;11641:53:2;;;;;1698:18:60;;11641:59:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11710:23;11760:14;11736:21;:38;;;;:::i;:::-;11710:64;-1:-1:-1;11788:19:2;;11784:112;;11823:62;11869:15;11844:22;:20;:22::i;11823:62::-;11910:29;;1725:25:60;;;11910:29:2;;1713:2:60;1698:18;11910:29:2;;;;;;;;11956:15;11442:536;-1:-1:-1;;;;11442:536:2:o;17840:550::-;17921:7;17965:21;18013:26;:24;:26::i;:::-;-1:-1:-1;;;;;17996:61:2;;18058:4;17996:67;;;;;;;;;;;;;1725:25:60;;1713:2;1698:18;;1579:177;17996:67:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18073:29;18129:14;18105:21;:38;;;;:::i;:::-;18073:70;-1:-1:-1;18157:25:2;;18153:124;;18198:68;18244:21;18219:22;:20;:22::i;18198:68::-;18291:54;;1725:25:60;;;18291:54:2;;1713:2:60;1698:18;18291:54:2;;;;;;;18362:21;17840:550;-1:-1:-1;;;17840:550:2:o;12228:658::-;12297:7;12316:20;12339:25;:23;:25::i;:::-;12316:48;-1:-1:-1;;;;;;12378:26:2;;12374:65;;-1:-1:-1;12427:1:2;;12228:658;-1:-1:-1;;12228:658:2:o;12374:65::-;12504:62;;-1:-1:-1;;;12504:62:2;;;;;1725:25:60;;;12473:21:2;;-1:-1:-1;;;;;12504:56:2;;;;;1698:18:60;;12504:62:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12576:30;12633:14;12609:21;:38;;;;:::i;:::-;12576:71;-1:-1:-1;12661:26:2;;12657:126;;12703:69;12749:22;12724;:20;:22::i;12703:69::-;12797:43;;1725:25:60;;;12797:43:2;;1713:2:60;1698:18;12797:43:2;1579:177:60;13082:925:2;13148:22;13173:14;:12;:14::i;:::-;13148:39;-1:-1:-1;13201:19:2;13197:75;;13243:18;;-1:-1:-1;;;13243:18:2;;;;;;;;;;;13197:75;13281:23;13307:15;:13;:15::i;:::-;13281:41;;13332:17;13352:15;:13;:15::i;:::-;13332:35;-1:-1:-1;13377:17:2;13332:35;13397:24;13407:14;13397:7;:24;:::i;:::-;:36;;;;:::i;:::-;13377:56;-1:-1:-1;13443:19:2;13520;13530:9;13520:7;:19;:::i;:::-;13466:49;273:6:22;13466:15:2;:49;:::i;:::-;13465:75;;;;:::i;:::-;13443:97;-1:-1:-1;13550:20:2;13573:16;;:48;;13597:23;13609:11;13597:9;:23;:::i;:::-;13573:48;;;13592:1;13573:48;13550:71;-1:-1:-1;13636:16:2;;13632:369;;13668:17;13688:22;:20;:22::i;:::-;13668:42;;13724:39;13739:9;13750:12;13724:14;:39::i;:::-;13777:22;13802:14;:12;:14::i;:::-;13777:39;-1:-1:-1;13830:23:2;13856:25;13874:7;13856:15;:25;:::i;:::-;13900:90;;;23904:25:60;;;23960:2;23945:18;;23938:34;;;23988:18;;;23981:34;;;24046:2;24031:18;;24024:34;;;13830:51:2;;-1:-1:-1;;;;;;13900:90:2;;;;;23891:3:60;23876:19;13900:90:2;;;;;;;13654:347;;;13632:369;13138:869;;;;;;13082:925;:::o;20698:3283::-;20989:30;:28;:30::i;:::-;-1:-1:-1;;;;;20968:81:2;;21063:23;21088:29;:27;:29::i;:::-;20968:159;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21142:31;21138:68;;;21189:7;;21138:68;21216:19;21238:14;:12;:14::i;:::-;21216:36;-1:-1:-1;21266:15:2;;21262:2713;;21297:32;21332:21;:19;:21::i;:::-;21297:56;;21367:33;21403:22;:20;:22::i;:::-;21367:58;;21439:32;21490:82;21526:26;:24;:26::i;:::-;-1:-1:-1;;;;;21509:60:2;;:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;21490:82::-;21439:133;-1:-1:-1;21439:133:2;21817:42;21844:15;21817:24;:42;:::i;:::-;:69;21813:2152;;;22059:34;:67;;;;;22125:1;22097:25;:29;22059:67;22055:606;;;22150:25;22178:158;22218:25;22290:24;22245:42;22272:15;22245:24;:42;:::i;:::-;:69;;;;:::i;:::-;22178:14;:158::i;:::-;22150:186;-1:-1:-1;22362:21:2;;22358:285;;22411:45;22439:17;22411:45;;:::i;:::-;;;22482;22502:24;22482:19;:45::i;:::-;22553:67;22574:45;22602:17;22574:25;:45;:::i;22553:67::-;22128:533;22055:606;22679:23;22726:30;:28;:30::i;:::-;22679:78;;22777:34;22813:32;22869:2;-1:-1:-1;;;;;22869:35:2;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22776:130;;;;;;23228:25;1477:8:3;23305:26:2;23278:24;:53;:163;;23440:1;23278:163;;;23359:53;23386:26;23359:24;:53;:::i;:::-;23256:218;;;;:::i;:::-;23228:246;-1:-1:-1;23562:24:2;23228:246;23497:42;23524:15;23497:24;:42;:::i;:::-;:62;;;;:::i;:::-;:89;23493:458;;;23610:28;23641:192;23755:17;23710:42;23737:15;23710:24;:42;:::i;:::-;:62;;;;:::i;:::-;23682:91;;:24;:91;:::i;:::-;1477:8:3;23641:15:2;:192::i;:::-;23610:223;;23856:2;-1:-1:-1;;;;;23856:23:2;;23880:20;23902:29;:27;:29::i;:::-;23856:76;;-1:-1:-1;;;;;;23856:76:2;;;;;;;;;;14206:25:60;;;;14247:18;;;14240:34;14179:18;;23856:76:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23588:363;23493:458;21888:2077;;;;21283:2692;;;20958:3023;20698:3283;;;;:::o;18489:1896::-;18559:31;18610:26;:24;:26::i;:::-;18559:78;;18647:30;18680:15;:13;:15::i;:::-;18647:48;;18705:19;18727:14;:12;:14::i;:::-;18705:36;;18781:1;18756:22;:26;:45;;;;;18800:1;18786:11;:15;18756:45;18752:1627;;;18920:27;18950:14;-1:-1:-1;;;;;18950:30:2;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18920:62;-1:-1:-1;18920:62:2;18996:35;19110:47;18920:62;19110:18;:47::i;:::-;19067:90;;19171:32;19206:21;:19;:21::i;:::-;19171:56;;19385:24;19350:32;:59;19346:257;;;19464:24;19429:59;;19536:52;19555:32;19536:18;:52::i;:::-;19506:82;;19346:257;19622:135;;;8710:25:60;;;8766:2;8751:18;;8744:34;;;8794:18;;;8787:34;;;19622:135:2;;8698:2:60;8683:18;19622:135:2;;;;;;;19776:36;;19772:597;;19894:80;19914:59;19941:32;19914:24;:59;:::i;19894:80::-;20096:68;20119:14;20136:27;20096:14;:68::i;:::-;20255:99;;-1:-1:-1;;;20255:99:2;;;;;1725:25:60;;;-1:-1:-1;;;;;20255:29:2;;;;;20292:32;;1698:18:60;;20255:99:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24077:452;24143:32;24178:21;:19;:21::i;:::-;24143:56;-1:-1:-1;24361:28:2;;24357:166;;24405:71;24451:24;24426:22;:20;:22::i;24405:71::-;24490:22;24510:1;24490:19;:22::i;24953:1796::-;25031:30;25064:15;:13;:15::i;:::-;25031:48;;25089:31;25123:22;:20;:22::i;:::-;25089:56;;25155:62;25220:28;:26;:28::i;:::-;26049:32;;25155:93;;-1:-1:-1;25978:40:2;;26021:235;;-1:-1:-1;;;;;26021:235:2;273:6:22;26146:48:2;26171:23;26146:22;:48;:::i;:::-;26104:3;:37;;;-1:-1:-1;;;;;26096:46:2;:99;;;;:::i;:::-;26095:151;;;;:::i;26021:235::-;25978:278;-1:-1:-1;26363:35:2;26413:94;26475:6;26429:42;26464:7;25978:278;26429:42;:::i;:::-;26428:53;;;;:::i;:::-;26483:23;26413:14;:94::i;:::-;26363:144;-1:-1:-1;26522:31:2;;26518:225;;26569:74;26615:27;26590:22;:20;:22::i;:::-;:52;;;;:::i;26569:74::-;26657:75;26678:53;26704:27;26678:23;:53;:::i;410:132:32:-;460:75;206:54;259:1;214:41;206:54;:::i;8329:515:5:-;8415:20;8447:28;8496:21;8478:15;:13;:15::i;:::-;:39;;;;:::i;:::-;8447:70;-1:-1:-1;8532:25:5;8528:310;;8588:21;8573:36;;8623:45;8638:6;8646:21;8623:14;:45::i;:::-;8528:310;;;8757:20;8739:14;:12;:14::i;:::-;8715:38;;:21;:38;:::i;:::-;8714:63;;;;:::i;:::-;8699:78;;8791:36;8806:6;8814:12;8791:14;:36::i;:::-;8437:407;8329:515;;;;:::o;581:139:55:-;619:7;645:68;422:58;479:1;430:45;422:58;:::i;1372:298:40:-;1451:12;398:60;457:1;406:47;398:60;:::i;:::-;1644:19;;;;;;;-1:-1:-1;;;;;1644:19:40;;;-1:-1:-1;;;1644:19:40;;;;;;;;;;-1:-1:-1;1372:298:40:o;622:138:46:-;660:7;686:67;468:55;522:1;476:42;468:55;:::i;735:144:36:-;773:7;799:73;537:61;597:1;545:48;537:61;:::i;665:136:35:-;703:7;729:65;490:54;543:1;498:41;490:54;:::i;1393:319:56:-;1479:12;322:55;376:1;330:42;322:55;:::i;:::-;-1:-1:-1;;;;;1667:15:56;;;314:64;1667:15;;;;;;;;;;;:26;;;;;;;;;-1:-1:-1;1667:26:56;;;:38;1393:319::o;601:147:57:-;639:7;665:76;419:65;483:1;427:52;419:65;:::i;821:93:20:-;875:32;900:6;875:24;:32::i;1020:121::-;1088:46;1120:13;1088:31;:46::i;1148:286:53:-;1215:12;299:52;350:1;307:39;299:52;:::i;:::-;-1:-1:-1;;;;;1400:15:53;;;291:61;1400:15;;;;;;;;-1:-1:-1;1400:15:53;;;;:27;1148:286::o;572:2856:23:-;664:12;731:7;716;726:2;716:12;:22;712:83;;;765:15;;-1:-1:-1;;;765:15:23;;;;;;;;;;;712:83;834:16;843:7;834:6;:16;:::i;:::-;818:6;:13;:32;814:88;;;873:18;;-1:-1:-1;;;873:18:23;;;;;;;;;;;814:88;912:22;1031:15;;1059:1931;;;;3131:4;3125:11;3112:24;;3317:1;3306:9;3299:20;3365:4;3354:9;3350:20;3344:4;3337:34;1024:2361;;1059:1931;1241:4;1235:11;1222:24;;1900:2;1891:7;1887:16;2282:9;2275:17;2269:4;2265:28;2253:9;2242;2238:25;2234:60;2330:7;2326:2;2322:16;2582:6;2568:9;2561:17;2555:4;2551:28;2539:9;2531:6;2527:22;2523:57;2519:70;2356:389;2615:3;2611:2;2608:11;2356:389;;;2733:9;;2722:21;;2656:4;2648:13;;;;2688;2356:389;;;-1:-1:-1;;2763:26:23;;;2971:2;2954:11;-1:-1:-1;;2950:25:23;2944:4;2937:39;-1:-1:-1;1024:2361:23;-1:-1:-1;3412:9:23;572:2856;-1:-1:-1;;;;572:2856:23:o;299:838:26:-;955:15;;;;467:4;1007:16;;;876:15;;;;928:16;;797:15;;;;849:16;;718:15;;;;770:16;;639:15;;;;691:16;;560:15;;;;612:16;;495:1;481:15;;;533:16;;;;517:11;;;;;516:34;596:11;;595:34;675:11;;674:34;754:11;;753:34;833:11;;832:34;912:11;;911:34;991:11;;;990:34;1034:15;;;;1067:14;;1060:22;;;;:::i;:::-;-1:-1:-1;1123:6:26;1111:19;;299:838;-1:-1:-1;299:838:26:o;610:142:41:-;648:7;674:71;443:60;502:1;451:47;443:60;:::i;408:131:38:-;458:74;205:54;258:1;213:41;205:54;:::i;450:124:52:-;488:7;514:53;323:44;366:1;331:31;323:44;:::i;796:161:25:-;273:6:22;857:4:25;:38;853:98;;;918:22;;-1:-1:-1;;;918:22:25;;;;;;;;;;;862:188:41;913:38;941:9;913:27;:38::i;:::-;961:82;443:60;502:1;451:47;443:60;:::i;1134:235:54:-;1189:23;1185:88;;1235:27;;-1:-1:-1;;;1235:27:54;;;;;;;;;;;1185:88;1282:80;432:59;490:1;440:46;432:59;:::i;15959:201:2:-;16041:62;16060:21;:19;:21::i;:::-;16041:62;;;14206:25:60;;;14262:2;14247:18;;14240:34;;;14179:18;16041:62:2;;;;;;;16113:40;16133:19;16113;:40::i;9363:244:5:-;9438:38;9469:6;9454:12;:10;:12::i;:::-;:21;;;;:::i;:::-;9438:15;:38::i;:::-;9486:63;9505:6;9542;9513:26;9532:6;9513:18;:26::i;9486:63::-;9564:36;;1725:25:60;;;-1:-1:-1;;;;;9564:36:5;;;9581:1;;-1:-1:-1;;;;;;;;;;;9564:36:5;1713:2:60;1698:18;9564:36:5;;;;;;;;9363:244;;:::o;1809:127:26:-;1870:7;;1909;1914:2;1909;:7;:::i;:::-;:11;:19;;1927:1;1909:19;;;1923:1;1909:19;1896:33;;1897:7;1902:2;1897;:7;:::i;:::-;1896:33;;;;:::i;9822:244:5:-;9897:38;9928:6;9913:12;:10;:12::i;:::-;:21;;;;:::i;9897:38::-;9945:63;9964:6;10001;9972:26;9991:6;9972:18;:26::i;9945:63::-;10023:36;;1725:25:60;;;10048:1:5;;-1:-1:-1;;;;;10023:36:5;;;-1:-1:-1;;;;;;;;;;;10023:36:5;1713:2:60;1698:18;10023:36:5;1579:177:60;824:185:55;875:38;903:9;875:27;:38::i;:::-;923:79;422:58;479:1;430:45;422:58;:::i;868:145:57:-;919:87;419:65;483:1;427:52;419:65;:::i;406:131:33:-;456:74;204:53;256:1;212:40;204:53;:::i;10204:146:5:-;10272:26;10283:14;10272:10;:26::i;:::-;10313:30;;1725:25:60;;;10313:30:5;;1713:2:60;1698:18;10313:30:5;1579:177:60;660:122:52;711:64;323:44;366:1;331:31;323:44;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:173:60;82:20;;-1:-1:-1;;;;;131:31:60;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;383:171::-;450:20;;-1:-1:-1;;;;;499:30:60;;489:41;;479:69;;544:1;541;534:12;559:173;627:20;;-1:-1:-1;;;;;676:31:60;;666:42;;656:70;;722:1;719;712:12;737:837;872:6;880;888;896;904;912;920;928;936;944;997:3;985:9;976:7;972:23;968:33;965:53;;;1014:1;1011;1004:12;965:53;1037:29;1056:9;1037:29;:::i;:::-;1027:39;;1085:37;1118:2;1107:9;1103:18;1085:37;:::i;:::-;1075:47;;1141:37;1174:2;1163:9;1159:18;1141:37;:::i;:::-;1131:47;;1197:37;1230:2;1219:9;1215:18;1197:37;:::i;:::-;1187:47;;1253:38;1286:3;1275:9;1271:19;1253:38;:::i;:::-;1243:48;;1310:38;1343:3;1332:9;1328:19;1310:38;:::i;:::-;1300:48;;1395:3;1384:9;1380:19;1367:33;1357:43;;1447:3;1436:9;1432:19;1419:33;1409:43;;1471:39;1505:3;1494:9;1490:19;1471:39;:::i;:::-;1461:49;;1529:39;1563:3;1552:9;1548:19;1529:39;:::i;:::-;1519:49;;737:837;;;;;;;;;;;;;:::o;1761:258::-;1833:1;1843:113;1857:6;1854:1;1851:13;1843:113;;;1933:11;;;1927:18;1914:11;;;1907:39;1879:2;1872:10;1843:113;;;1974:6;1971:1;1968:13;1965:48;;;-1:-1:-1;;2009:1:60;1991:16;;1984:27;1761:258::o;2024:::-;2066:3;2104:5;2098:12;2131:6;2126:3;2119:19;2147:63;2203:6;2196:4;2191:3;2187:14;2180:4;2173:5;2169:16;2147:63;:::i;:::-;2264:2;2243:15;-1:-1:-1;;2239:29:60;2230:39;;;;2271:4;2226:50;;2024:258;-1:-1:-1;;2024:258:60:o;2287:220::-;2436:2;2425:9;2418:21;2399:4;2456:45;2497:2;2486:9;2482:18;2474:6;2456:45;:::i;2512:254::-;2580:6;2588;2641:2;2629:9;2620:7;2616:23;2612:32;2609:52;;;2657:1;2654;2647:12;2609:52;2680:29;2699:9;2680:29;:::i;:::-;2670:39;2756:2;2741:18;;;;2728:32;;-1:-1:-1;;;2512:254:60:o;3059:::-;3127:6;3135;3188:2;3176:9;3167:7;3163:23;3159:32;3156:52;;;3204:1;3201;3194:12;3156:52;3240:9;3227:23;3217:33;;3269:38;3303:2;3292:9;3288:18;3269:38;:::i;:::-;3259:48;;3059:254;;;;;:::o;3614:180::-;3673:6;3726:2;3714:9;3705:7;3701:23;3697:32;3694:52;;;3742:1;3739;3732:12;3694:52;-1:-1:-1;3765:23:60;;3614:180;-1:-1:-1;3614:180:60:o;3799:203::-;-1:-1:-1;;;;;3963:32:60;;;;3945:51;;3933:2;3918:18;;3799:203::o;4007:204::-;4104:6;4157:2;4145:9;4136:7;4132:23;4128:32;4125:52;;;4173:1;4170;4163:12;4984:328;5061:6;5069;5077;5130:2;5118:9;5109:7;5105:23;5101:32;5098:52;;;5146:1;5143;5136:12;5098:52;5169:29;5188:9;5169:29;:::i;:::-;5159:39;;5217:38;5251:2;5240:9;5236:18;5217:38;:::i;:::-;5207:48;;5302:2;5291:9;5287:18;5274:32;5264:42;;4984:328;;;;;:::o;5317:772::-;5448:6;5456;5464;5472;5480;5488;5496;5504;5512;5565:3;5553:9;5544:7;5540:23;5536:33;5533:53;;;5582:1;5579;5572:12;5533:53;5605:29;5624:9;5605:29;:::i;:::-;5595:39;;5653:38;5687:2;5676:9;5672:18;5653:38;:::i;:::-;5643:48;;5738:2;5727:9;5723:18;5710:32;5700:42;;5761:38;5795:2;5784:9;5780:18;5761:38;:::i;:::-;5751:48;;5818:39;5852:3;5841:9;5837:19;5818:39;:::i;:::-;5808:49;;5876:39;5910:3;5899:9;5895:19;5876:39;:::i;:::-;5866:49;;5934:39;5968:3;5957:9;5953:19;5934:39;:::i;:::-;5924:49;;5992:39;6026:3;6015:9;6011:19;5992:39;:::i;:::-;5982:49;;6078:3;6067:9;6063:19;6050:33;6040:43;;5317:772;;;;;;;;;;;:::o;7049:366::-;7111:8;7121:6;7175:3;7168:4;7160:6;7156:17;7152:27;7142:55;;7193:1;7190;7183:12;7142:55;-1:-1:-1;7216:20:60;;-1:-1:-1;;;;;7248:30:60;;7245:50;;;7291:1;7288;7281:12;7245:50;7328:4;7320:6;7316:17;7304:29;;7388:3;7381:4;7371:6;7368:1;7364:14;7356:6;7352:27;7348:38;7345:47;7342:67;;;7405:1;7402;7395:12;7342:67;7049:366;;;;;:::o;7420:435::-;7505:6;7513;7566:2;7554:9;7545:7;7541:23;7537:32;7534:52;;;7582:1;7579;7572:12;7534:52;7622:9;7609:23;-1:-1:-1;;;;;7647:6:60;7644:30;7641:50;;;7687:1;7684;7677:12;7641:50;7726:69;7787:7;7778:6;7767:9;7763:22;7726:69;:::i;:::-;7814:8;;7700:95;;-1:-1:-1;7420:435:60;-1:-1:-1;;;;7420:435:60:o;7860:643::-;8027:2;8079:21;;;8149:13;;8052:18;;;8171:22;;;7998:4;;8027:2;8250:15;;;;8224:2;8209:18;;;7998:4;8293:184;8307:6;8304:1;8301:13;8293:184;;;8382:13;;8379:1;8368:28;8356:41;;8452:15;;;;8417:12;;;;8329:1;8322:9;8293:184;;;-1:-1:-1;8494:3:60;;7860:643;-1:-1:-1;;;;;;7860:643:60:o;8832:127::-;8893:10;8888:3;8884:20;8881:1;8874:31;8924:4;8921:1;8914:15;8948:4;8945:1;8938:15;8964:251;9036:2;9030:9;;;9066:15;;-1:-1:-1;;;;;9096:34:60;;9132:22;;;9093:62;9090:88;;;9158:18;;:::i;:::-;9194:2;9187:22;8964:251;:::o;9220:275::-;9291:2;9285:9;9356:2;9337:13;;-1:-1:-1;;9333:27:60;9321:40;;-1:-1:-1;;;;;9376:34:60;;9412:22;;;9373:62;9370:88;;;9438:18;;:::i;:::-;9474:2;9467:22;9220:275;;-1:-1:-1;9220:275:60:o;9500:187::-;9549:4;-1:-1:-1;;;;;9574:6:60;9571:30;9568:56;;;9604:18;;:::i;:::-;-1:-1:-1;9670:2:60;9649:15;-1:-1:-1;;9645:29:60;9676:4;9641:40;;9500:187::o;9692:673::-;9761:6;9814:2;9802:9;9793:7;9789:23;9785:32;9782:52;;;9830:1;9827;9820:12;9782:52;9870:9;9857:23;-1:-1:-1;;;;;9895:6:60;9892:30;9889:50;;;9935:1;9932;9925:12;9889:50;9958:22;;10011:4;10003:13;;9999:27;-1:-1:-1;9989:55:60;;10040:1;10037;10030:12;9989:55;10076:2;10063:16;10101:49;10117:32;10146:2;10117:32;:::i;:::-;10101:49;:::i;:::-;10173:2;10166:5;10159:17;10213:7;10208:2;10203;10199;10195:11;10191:20;10188:33;10185:53;;;10234:1;10231;10224:12;10185:53;10289:2;10284;10280;10276:11;10271:2;10264:5;10260:14;10247:45;10333:1;10312:14;;;10328:2;10308:23;10301:34;;;;10316:5;9692:673;-1:-1:-1;;;;9692:673:60:o;10370:199::-;10461:6;10514:3;10502:9;10493:7;10489:23;10485:33;10482:53;;;10531:1;10528;10521:12;10574:769;10694:6;10702;10710;10718;10771:2;10759:9;10750:7;10746:23;10742:32;10739:52;;;10787:1;10784;10777:12;10739:52;10827:9;10814:23;-1:-1:-1;;;;;10897:2:60;10889:6;10886:14;10883:34;;;10913:1;10910;10903:12;10883:34;10952:69;11013:7;11004:6;10993:9;10989:22;10952:69;:::i;:::-;11040:8;;-1:-1:-1;10926:95:60;-1:-1:-1;11128:2:60;11113:18;;11100:32;;-1:-1:-1;11144:16:60;;;11141:36;;;11173:1;11170;11163:12;11141:36;;11212:71;11275:7;11264:8;11253:9;11249:24;11212:71;:::i;:::-;10574:769;;;;-1:-1:-1;11302:8:60;-1:-1:-1;;;;10574:769:60:o;11348:639::-;11515:2;11567:21;;;11637:13;;11540:18;;;11659:22;;;11486:4;;11515:2;11738:15;;;;11712:2;11697:18;;;11486:4;11781:180;11795:6;11792:1;11789:13;11781:180;;;11860:13;;11875:4;11856:24;11844:37;;11936:15;;;;11901:12;;;;11817:1;11810:9;11781:180;;12316:376;12421:6;12474:2;12462:9;12453:7;12449:23;12445:32;12442:52;;;12490:1;12487;12480:12;12442:52;12516:22;;:::i;:::-;12561:29;12580:9;12561:29;:::i;:::-;12554:5;12547:44;12623:38;12657:2;12646:9;12642:18;12623:38;:::i;:::-;12618:2;12607:14;;12600:62;12611:5;12316:376;-1:-1:-1;;;12316:376:60:o;12697:260::-;12765:6;12773;12826:2;12814:9;12805:7;12801:23;12797:32;12794:52;;;12842:1;12839;12832:12;12794:52;12865:29;12884:9;12865:29;:::i;:::-;12855:39;;12913:38;12947:2;12936:9;12932:18;12913:38;:::i;13362:400::-;13461:6;13514:2;13502:9;13493:7;13489:23;13485:32;13482:52;;;13530:1;13527;13520:12;13482:52;13570:9;13557:23;-1:-1:-1;;;;;13595:6:60;13592:30;13589:50;;;13635:1;13632;13625:12;13589:50;13658:22;;13714:3;13696:16;;;13692:26;13689:46;;;13731:1;13728;13721:12;13767:127;13828:10;13823:3;13819:20;13816:1;13809:31;13859:4;13856:1;13849:15;13883:4;13880:1;13873:15;13899:128;13939:3;13970:1;13966:6;13963:1;13960:13;13957:39;;;13976:18;;:::i;:::-;-1:-1:-1;14012:9:60;;13899:128::o;14285:459::-;14470:6;14459:9;14452:25;14513:2;14508;14497:9;14493:18;14486:30;14552:6;14547:2;14536:9;14532:18;14525:34;14609:6;14601;14596:2;14585:9;14581:18;14568:48;14665:1;14636:22;;;14660:2;14632:31;;;14625:42;;;;14728:2;14707:15;;;-1:-1:-1;;14703:29:60;14688:45;14684:54;;14285:459;-1:-1:-1;;14285:459:60:o;14749:274::-;-1:-1:-1;;;;;14941:32:60;;;;14923:51;;15005:2;14990:18;;14983:34;14911:2;14896:18;;14749:274::o;15307:121::-;15392:10;15385:5;15381:22;15374:5;15371:33;15361:61;;15418:1;15415;15408:12;15433:249;15502:6;15555:2;15543:9;15534:7;15530:23;15526:32;15523:52;;;15571:1;15568;15561:12;15523:52;15603:9;15597:16;15622:30;15646:5;15622:30;:::i;15687:127::-;15748:10;15743:3;15739:20;15736:1;15729:31;15779:4;15776:1;15769:15;15803:4;15800:1;15793:15;15819:120;15859:1;15885;15875:35;;15890:18;;:::i;:::-;-1:-1:-1;15924:9:60;;15819:120::o;15944:127::-;16005:10;16000:3;15996:20;15993:1;15986:31;16036:4;16033:1;16026:15;16060:4;16057:1;16050:15;16076:168;16116:7;16182:1;16178;16174:6;16170:14;16167:1;16164:21;16159:1;16152:9;16145:17;16141:45;16138:71;;;16189:18;;:::i;:::-;-1:-1:-1;16229:9:60;;16076:168::o;16249:125::-;16289:4;16317:1;16314;16311:8;16308:34;;;16322:18;;:::i;:::-;-1:-1:-1;16359:9:60;;16249:125::o;16379:354::-;16474:6;16527:2;16515:9;16506:7;16502:23;16498:32;16495:52;;;16543:1;16540;16533:12;16495:52;16569:22;;:::i;:::-;16627:9;16614:23;16607:5;16600:38;16698:2;16687:9;16683:18;16670:32;16665:2;16658:5;16654:14;16647:56;16722:5;16712:15;;;16379:354;;;;:::o;17047:112::-;17079:1;17105;17095:35;;17110:18;;:::i;:::-;-1:-1:-1;17144:9:60;;17047:112::o;17164:132::-;17231:20;;17260:30;17231:20;17260:30;:::i;17301:511::-;17400:6;17395:3;17388:19;17370:3;17426:4;17455:2;17450:3;17446:12;17439:19;;17481:5;17504:1;17514:273;17528:6;17525:1;17522:13;17514:273;;;17605:6;17592:20;17625:32;17649:7;17625:32;:::i;:::-;17695:10;17682:24;17670:37;;17727:12;;;;17762:15;;;;17550:1;17543:9;17514:273;;;-1:-1:-1;17803:3:60;;17301:511;-1:-1:-1;;;;;17301:511:60:o;17817:285::-;18004:2;17993:9;17986:21;17967:4;18024:72;18092:2;18081:9;18077:18;18069:6;18061;18024:72;:::i;18107:181::-;18165:4;-1:-1:-1;;;;;18190:6:60;18187:30;18184:56;;;18220:18;;:::i;:::-;-1:-1:-1;18265:1:60;18261:14;18277:4;18257:25;;18107:181::o;18293:1050::-;18386:6;18417:2;18460;18448:9;18439:7;18435:23;18431:32;18428:52;;;18476:1;18473;18466:12;18428:52;18509:9;18503:16;-1:-1:-1;;;;;18534:6:60;18531:30;18528:50;;;18574:1;18571;18564:12;18528:50;18597:22;;18650:4;18642:13;;18638:27;-1:-1:-1;18628:55:60;;18679:1;18676;18669:12;18628:55;18708:2;18702:9;18731:58;18747:41;18785:2;18747:41;:::i;18731:58::-;18823:15;;;18905:1;18901:10;;;;18893:19;;18889:28;;;18854:12;;;;18929:19;;;18926:39;;;18961:1;18958;18951:12;18926:39;18985:11;;;;19005:308;19021:6;19016:3;19013:15;19005:308;;;19094:3;19088:10;19145:5;19142:1;19131:20;19124:5;19121:31;19111:129;;19194:1;19223:2;19219;19212:14;19111:129;19253:18;;19038:12;;;;19291;;;;19005:308;;;19332:5;18293:1050;-1:-1:-1;;;;;;;18293:1050:60:o;19348:736::-;19437:6;19490:3;19478:9;19469:7;19465:23;19461:33;19458:53;;;19507:1;19504;19497:12;19458:53;19540:2;19534:9;19582:3;19574:6;19570:16;19652:6;19640:10;19637:22;-1:-1:-1;;;;;19604:10:60;19601:34;19598:62;19595:88;;;19663:18;;:::i;:::-;19699:2;19692:22;19738:28;19756:9;19738:28;:::i;:::-;19730:6;19723:44;19800:37;19833:2;19822:9;19818:18;19800:37;:::i;:::-;19795:2;19787:6;19783:15;19776:62;19871:37;19904:2;19893:9;19889:18;19871:37;:::i;:::-;19866:2;19858:6;19854:15;19847:62;19942:37;19975:2;19964:9;19960:18;19942:37;:::i;:::-;19937:2;19929:6;19925:15;19918:62;20014:38;20047:3;20036:9;20032:19;20014:38;:::i;:::-;20008:3;19996:16;;19989:64;20000:6;19348:736;-1:-1:-1;;;19348:736:60:o;20089:184::-;20147:6;20200:2;20188:9;20179:7;20175:23;20171:32;20168:52;;;20216:1;20213;20206:12;20168:52;20239:28;20257:9;20239:28;:::i;20278:535::-;-1:-1:-1;;;;;20582:15:60;;;20564:34;;20634:15;;;20629:2;20614:18;;20607:43;20686:15;;;20681:2;20666:18;;20659:43;20738:15;;20733:2;20718:18;;20711:43;20791:15;;;20785:3;20770:19;;20763:44;20514:3;20499:19;;20278:535::o;20818:678::-;21139:3;21128:9;21121:22;21102:4;21166:73;21234:3;21223:9;21219:19;21211:6;21203;21166:73;:::i;:::-;21287:9;21279:6;21275:22;21270:2;21259:9;21255:18;21248:50;21315:60;21368:6;21360;21352;21315:60;:::i;:::-;21418:14;;21411:22;21406:2;21391:18;;21384:50;-1:-1:-1;;21482:6:60;21470:19;;;;21465:2;21450:18;;;21443:47;21307:68;20818:678;-1:-1:-1;;;;20818:678:60:o;21501:1046::-;21594:6;21625:2;21668;21656:9;21647:7;21643:23;21639:32;21636:52;;;21684:1;21681;21674:12;21636:52;21717:9;21711:16;-1:-1:-1;;;;;21742:6:60;21739:30;21736:50;;;21782:1;21779;21772:12;21736:50;21805:22;;21858:4;21850:13;;21846:27;-1:-1:-1;21836:55:60;;21887:1;21884;21877:12;21836:55;21916:2;21910:9;21939:58;21955:41;21993:2;21955:41;:::i;21939:58::-;22031:15;;;22113:1;22109:10;;;;22101:19;;22097:28;;;22062:12;;;;22137:19;;;22134:39;;;22169:1;22166;22159:12;22134:39;22193:11;;;;22213:304;22229:6;22224:3;22221:15;22213:304;;;22302:3;22296:10;22350:4;22343:5;22339:16;22332:5;22329:27;22319:125;;22398:1;22427:2;22423;22416:14;22319:125;22457:18;;22246:12;;;;22495;;;;22213:304;;22552:245;22610:6;22663:2;22651:9;22642:7;22638:23;22634:32;22631:52;;;22679:1;22676;22669:12;22631:52;22718:9;22705:23;22737:30;22761:5;22737:30;:::i;23171:118::-;23257:5;23250:13;23243:21;23236:5;23233:32;23223:60;;23279:1;23276;23269:12;23294:128;23359:20;;23388:28;23359:20;23388:28;:::i;23427:241::-;23483:6;23536:2;23524:9;23515:7;23511:23;23507:32;23504:52;;;23552:1;23549;23542:12;23504:52;23591:9;23578:23;23610:28;23632:5;23610:28;:::i;24069:544::-;24161:4;24167:6;24227:11;24214:25;24321:2;24317:7;24306:8;24290:14;24286:29;24282:43;24262:18;24258:68;24248:96;;24340:1;24337;24330:12;24248:96;24367:33;;24419:20;;;-1:-1:-1;;;;;;24451:30:60;;24448:50;;;24494:1;24491;24484:12;24448:50;24527:4;24515:17;;-1:-1:-1;24578:1:60;24574:14;;;24558;24554:35;24544:46;;24541:66;;;24603:1;24600;24593:12;24618:522;24687:5;24694:6;24754:3;24741:17;24840:2;24836:7;24825:8;24809:14;24805:29;24801:43;24781:18;24777:68;24767:96;;24859:1;24856;24849:12;24767:96;24887:33;;24991:4;24978:18;;;-1:-1:-1;24939:21:60;;-1:-1:-1;;;;;;25008:30:60;;25005:50;;;25051:1;25048;25041:12;25005:50;25108:6;25105:1;25101:14;25085;25081:35;25071:8;25067:50;25064:70;;;25130:1;25127;25120:12;25435:1472;25770:3;25759:9;25752:22;25824:6;25811:20;25805:3;25794:9;25790:19;25783:49;25894:4;25886:6;25882:17;25869:31;25863:3;25852:9;25848:19;25841:60;25963:4;25955:6;25951:17;25938:31;25932:3;25921:9;25917:19;25910:60;25733:4;25989:3;26053:4;26045:6;26041:17;26028:31;26023:2;26012:9;26008:18;26001:59;26079:6;26146:4;26138:6;26134:17;26121:31;26116:2;26105:9;26101:18;26094:59;26182:35;26212:3;26204:6;26200:16;26182:35;:::i;:::-;3394:10;3383:22;26273:3;26258:19;;3371:35;26323:67;26385:3;26373:16;;26377:6;26323:67;:::i;:::-;26427:2;26421:3;26410:9;26406:19;26399:31;26453:87;26535:3;26524:9;26520:19;26506:12;26490:14;26453:87;:::i;:::-;26439:101;;;;26571:33;26599:3;26591:6;26587:16;26571:33;:::i;:::-;2841:13;2834:21;26660:3;26645:19;;2822:34;26696:32;26712:15;;;26696:32;:::i;:::-;2841:13;;2834:21;26784:3;26769:19;;2822:34;26674:54;-1:-1:-1;26806:6:60;-1:-1:-1;26821:80:60;;-1:-1:-1;26895:4:60;26880:20;;26872:6;25249:5;25243:12;25238:3;25231:25;25305:4;25298:5;25294:16;25288:23;25281:4;25276:3;25272:14;25265:47;25361:4;25354:5;25350:16;25344:23;25337:4;25332:3;25328:14;25321:47;25417:4;25410:5;25406:16;25400:23;25393:4;25388:3;25384:14;25377:47;;;25145:285;26912:245;26979:6;27032:2;27020:9;27011:7;27007:23;27003:32;27000:52;;;27048:1;27045;27038:12;27000:52;27080:9;27074:16;27099:28;27121:5;27099:28;:::i;27471:1387::-;27534:5;27587:3;27580:4;27572:6;27568:17;27564:27;27554:55;;27605:1;27602;27595:12;27554:55;27634:6;27628:13;27660:4;27684:58;27700:41;27738:2;27700:41;:::i;27684:58::-;27776:15;;;27862:1;27858:10;;;;27846:23;;27842:32;;;27807:12;;;;27886:15;;;27883:35;;;27914:1;27911;27904:12;27883:35;27950:2;27942:6;27938:15;27962:867;27978:6;27973:3;27970:15;27962:867;;;28057:3;28051:10;-1:-1:-1;;;;;28080:11:60;28077:35;28074:125;;;28153:1;28182:2;28178;28171:14;28074:125;28222:24;;28281:2;28273:11;;28269:21;-1:-1:-1;28259:119:60;;28332:1;28361:2;28357;28350:14;28259:119;28415:2;28411;28407:11;28401:18;28442:2;28472:49;28488:32;28517:2;28488:32;:::i;28472:49::-;28550:2;28541:7;28534:19;28594:3;28589:2;28584;28580;28576:11;28572:20;28569:29;28566:119;;;28639:1;28668:2;28664;28657:14;28566:119;28698:56;28751:2;28746;28737:7;28733:16;28728:2;28724;28720:11;28698:56;:::i;:::-;28767:20;;-1:-1:-1;;;28807:12:60;;;;27995;;27962:867;;;-1:-1:-1;28847:5:60;27471:1387;-1:-1:-1;;;;;;27471:1387:60:o;28863:628::-;29010:6;29018;29071:2;29059:9;29050:7;29046:23;29042:32;29039:52;;;29087:1;29084;29077:12;29039:52;29120:9;29114:16;-1:-1:-1;;;;;29190:2:60;29182:6;29179:14;29176:34;;;29206:1;29203;29196:12;29176:34;29229:70;29291:7;29282:6;29271:9;29267:22;29229:70;:::i;:::-;29219:80;;29345:2;29334:9;29330:18;29324:25;29308:41;;29374:2;29364:8;29361:16;29358:36;;;29390:1;29387;29380:12;29358:36;;29413:72;29477:7;29466:8;29455:9;29451:24;29413:72;:::i;:::-;29403:82;;;28863:628;;;;;:::o;29496:399::-;29653:3;29691:6;29685:13;29707:53;29753:6;29748:3;29741:4;29733:6;29729:17;29707:53;:::i;:::-;-1:-1:-1;;;;;;29821:37:60;;;;29782:16;;;;29807:52;;;29886:2;29875:14;;29496:399;-1:-1:-1;;29496:399:60:o;29900:274::-;30029:3;30067:6;30061:13;30083:53;30129:6;30124:3;30117:4;30109:6;30105:17;30083:53;:::i;:::-;30152:16;;;;;29900:274;-1:-1:-1;;29900:274:60:o;30179:184::-;30249:6;30302:2;30290:9;30281:7;30277:23;30273:32;30270:52;;;30318:1;30315;30308:12;30270:52;-1:-1:-1;30341:16:60;;30179:184;-1:-1:-1;30179:184:60:o;30368:370::-;30525:3;30563:6;30557:13;30579:53;30625:6;30620:3;30613:4;30605:6;30601:17;30579:53;:::i;:::-;30654:16;;;;30679:21;;;-1:-1:-1;30727:4:60;30716:16;;30368:370;-1:-1:-1;30368:370:60:o;31182:613::-;31449:3;31438:9;31431:22;31412:4;31476:46;31517:3;31506:9;31502:19;31494:6;31476:46;:::i;:::-;31570:9;31562:6;31558:22;31553:2;31542:9;31538:18;31531:50;31604:33;31630:6;31622;31604:33;:::i;:::-;31590:47;;31685:9;31677:6;31673:22;31668:2;31657:9;31653:18;31646:50;31713:33;31739:6;31731;31713:33;:::i;:::-;31705:41;;;31782:6;31777:2;31766:9;31762:18;31755:34;31182:613;;;;;;;:::o;32252:380::-;32331:1;32327:12;;;;32374;;;32395:61;;32449:4;32441:6;32437:17;32427:27;;32395:61;32502:2;32494:6;32491:14;32471:18;32468:38;32465:161;;;32548:10;32543:3;32539:20;32536:1;32529:31;32583:4;32580:1;32573:15;32611:4;32608:1;32601:15;32637:270;32676:7;-1:-1:-1;;;;;32753:2:60;32750:1;32746:10;32783:2;32780:1;32776:10;32839:3;32835:2;32831:12;32826:3;32823:21;32816:3;32809:11;32802:19;32798:47;32795:73;;;32848:18;;:::i;:::-;32888:13;;32637:270;-1:-1:-1;;;;32637:270:60:o;32912:720::-;33128:2;33140:21;;;33210:13;;33113:18;;;33232:22;;;33080:4;;33307;;33285:2;33270:18;;;33334:15;;;33080:4;33377:186;33391:6;33388:1;33385:13;33377:186;;;33456:13;;33471:10;33452:30;33440:43;;33503:12;;;;33538:15;;;;33413:1;33406:9;33377:186;;;-1:-1:-1;;;33599:18:60;;33592:34;;;;33580:3;32912:720;-1:-1:-1;;32912:720:60:o;33826:310::-;33904:6;33912;33965:2;33953:9;33944:7;33940:23;33936:32;33933:52;;;33981:1;33978;33971:12;33933:52;34013:9;34007:16;34032:30;34056:5;34032:30;:::i;:::-;34126:2;34111:18;;;;34105:25;34081:5;;34105:25;;-1:-1:-1;;;33826:310:60:o;34141:127::-;34202:10;34197:3;34193:20;34190:1;34183:31;34233:4;34230:1;34223:15;34257:4;34254:1;34247:15
Swarm Source
ipfs://75e48ff7ca1ef56a4380c2b504633a9f2bf34000bc77bdf03103b2444951f225
Loading...
Loading
Loading...
Loading
OVERVIEW
Liquid Collective is a secure liquid staking protocol designed to meet the needs of institutions, built and run by a collective of industry-leading Web3 teams and governed in a decentralized manner by a broad and dispersed community.Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.