diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 6fbb43936..ab42f861d 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -95,55 +95,3 @@ jobs: - name: Run Solidity test coverage run: yarn test:coverage continue-on-error: false - - abi-lint: - name: ABI actuality linter - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - with: - persist-credentials: false - - - name: Setup node.js version - uses: actions/setup-node@v3 - with: - node-version: 16 - - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT - - - name: Cache yarn cache - id: cache-yarn-cache - uses: actions/cache@v3 - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: yarn-${{ hashFiles('**/yarn.lock') }} - - - name: Cache node_modules - id: cache-node-modules - uses: actions/cache@v3 - with: - path: '**/node_modules' - key: node_modules-${{ hashFiles('**/yarn.lock') }} - restore-keys: node_modules-${{ hashFiles('**/yarn.lock') }} - - - name: Install modules - run: yarn - if: | - steps.cache-yarn-cache.outputs.cache-hit != 'true' || - steps.cache-node-modules.outputs.cache-hit != 'true' - - - name: Compile code and extract ABI - run: yarn compile - - - name: Check for ABI changes - run: | - git diff --quiet lib/abi && status=clean || status=dirty - if [ $status == "dirty" ]; then - echo "The following ABIs should be commited" - git diff --compact-summary lib/abi - exit 1 - fi diff --git a/.gitignore b/.gitignore index 6888423e7..30c838c56 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .vscode **/build/ **/node_modules/ +**/lib/abi/*.json **/artifacts/ **/artifacts-userdoc/ .cache diff --git a/.husky/pre-commit b/.husky/pre-commit index b63c34415..b417ff56f 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -5,6 +5,4 @@ RED_COLOR='\033[0;31m' NO_COLOR='\033[0m' yarn compile -git diff --quiet lib/abi || (echo -e "${RED_COLOR}Unstaged ABIs detected${NO_COLOR}"; exit 1) - yarn lint diff --git a/contracts/0.4.24/Lido.sol b/contracts/0.4.24/Lido.sol index 8f66bff68..d006e5928 100644 --- a/contracts/0.4.24/Lido.sol +++ b/contracts/0.4.24/Lido.sol @@ -112,6 +112,8 @@ interface IStakingRouter { external view returns (uint256); + + function TOTAL_BASIS_POINTS() external view returns (uint256); } interface IWithdrawalQueue { @@ -266,11 +268,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { payable onlyInit { - uint256 amount = _bootstrapInitialHolder(); - _setBufferedEther(amount); - - emit Submitted(INITIAL_TOKEN_HOLDER, amount, 0); - + _bootstrapInitialHolder(); _initialize_v2(_lidoLocator, _eip712StETH); initialized(); } @@ -340,6 +338,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { */ function resumeStaking() external { _auth(STAKING_CONTROL_ROLE); + require(hasInitialized(), "NOT_INITIALIZED"); _resumeStaking(); } @@ -673,7 +672,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { * Depends on the bunker state and protocol's pause state */ function canDeposit() public view returns (bool) { - return !IWithdrawalQueue(getLidoLocator().withdrawalQueue()).isBunkerModeActive() && !isStopped(); + return !_withdrawalQueue().isBunkerModeActive() && !isStopped(); } /** @@ -682,7 +681,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { */ function getDepositableEther() public view returns (uint256) { uint256 bufferedEther = _getBufferedEther(); - uint256 withdrawalReserve = IWithdrawalQueue(getLidoLocator().withdrawalQueue()).unfinalizedStETH(); + uint256 withdrawalReserve = _withdrawalQueue().unfinalizedStETH(); return bufferedEther > withdrawalReserve ? bufferedEther - withdrawalReserve : 0; } @@ -698,7 +697,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { require(msg.sender == locator.depositSecurityModule(), "APP_AUTH_DSM_FAILED"); require(canDeposit(), "CAN_NOT_DEPOSIT"); - IStakingRouter stakingRouter = IStakingRouter(locator.stakingRouter()); + IStakingRouter stakingRouter = _stakingRouter(); uint256 depositsCount = Math256.min( _maxDepositsCount, stakingRouter.getStakingModuleMaxDepositsCount(_stakingModuleId, getDepositableEther()) @@ -730,7 +729,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { * @dev DEPRECATED: use StakingRouter.getWithdrawalCredentials() instead */ function getWithdrawalCredentials() external view returns (bytes32) { - return IStakingRouter(getLidoLocator().stakingRouter()).getWithdrawalCredentials(); + return _stakingRouter().getWithdrawalCredentials(); } /** @@ -746,7 +745,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { * @dev DEPRECATED: use LidoLocator.treasury() */ function getTreasury() external view returns (address) { - return getLidoLocator().treasury(); + return _treasury(); } /** @@ -757,11 +756,11 @@ contract Lido is Versioned, StETHPermit, AragonApp { * inaccurate because the actual value is truncated here to 1e4 precision. */ function getFee() external view returns (uint16 totalFee) { - totalFee = IStakingRouter(getLidoLocator().stakingRouter()).getTotalFeeE4Precision(); + totalFee = _stakingRouter().getTotalFeeE4Precision(); } /** - * @notice Returns current fee distribution + * @notice Returns current fee distribution, values relative to the total fee (getFee()) * @dev DEPRECATED: Now fees information is stored in StakingRouter and * with higher precision. Use StakingRouter.getStakingFeeAggregateDistribution() instead. * @return treasuryFeeBasisPoints return treasury fee in TOTAL_BASIS_POINTS (10000 is 100% fee) precision @@ -780,9 +779,15 @@ contract Lido is Versioned, StETHPermit, AragonApp { uint16 operatorsFeeBasisPoints ) { - insuranceFeeBasisPoints = 0; // explicitly set to zero - (treasuryFeeBasisPoints, operatorsFeeBasisPoints) = IStakingRouter(getLidoLocator().stakingRouter()) + IStakingRouter stakingRouter = _stakingRouter(); + uint256 totalBasisPoints = stakingRouter.TOTAL_BASIS_POINTS(); + uint256 totalFee = stakingRouter.getTotalFeeE4Precision(); + (uint256 treasuryFeeBasisPointsAbs, uint256 operatorsFeeBasisPointsAbs) = stakingRouter .getStakingFeeAggregateDistributionE4Precision(); + + insuranceFeeBasisPoints = 0; // explicitly set to zero + treasuryFeeBasisPoints = uint16((treasuryFeeBasisPointsAbs * totalBasisPoints) / totalFee); + operatorsFeeBasisPoints = uint16((operatorsFeeBasisPointsAbs * totalBasisPoints) / totalFee); } /* @@ -941,14 +946,6 @@ contract Lido is Versioned, StETHPermit, AragonApp { return sharesAmount; } - /** - * @dev Emits {Transfer} and {TransferShares} events where `from` is 0 address. Indicates mint events. - */ - function _emitTransferAfterMintingShares(address _to, uint256 _sharesAmount) internal { - emit Transfer(address(0), _to, getPooledEthByShares(_sharesAmount)); - emit TransferShares(address(0), _to, _sharesAmount); - } - /** * @dev Staking router rewards distribution. * @@ -970,7 +967,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { StakingRewardsDistribution memory ret, IStakingRouter router ) { - router = IStakingRouter(getLidoLocator().stakingRouter()); + router = _stakingRouter(); ( ret.recipients, @@ -1075,7 +1072,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { } function _transferTreasuryRewards(uint256 treasuryReward) internal { - address treasury = getLidoLocator().treasury(); + address treasury = _treasury(); _transferShares(address(this), treasury, treasuryReward); _emitTransferAfterMintingShares(treasury, treasuryReward); } @@ -1371,4 +1368,41 @@ contract Lido is Versioned, StETHPermit, AragonApp { ret.postTokenRebaseReceiver ) = getLidoLocator().oracleReportComponentsForLido(); } + + function _stakingRouter() internal view returns (IStakingRouter) { + return IStakingRouter(getLidoLocator().stakingRouter()); + } + + function _withdrawalQueue() internal view returns (IWithdrawalQueue) { + return IWithdrawalQueue(getLidoLocator().withdrawalQueue()); + } + + function _treasury() internal view returns (address) { + return getLidoLocator().treasury(); + } + + /** + * @notice Mints shares on behalf of 0xdead address, + * the shares amount is equal to the contract's balance. * + * + * Allows to get rid of zero checks for `totalShares` and `totalPooledEther` + * and overcome corner cases. + * + * NB: reverts if the current contract's balance is zero. + * + * @dev must be invoked before using the token + */ + function _bootstrapInitialHolder() internal { + uint256 balance = address(this).balance; + assert(balance != 0); + + if (_getTotalShares() == 0) { + // if protocol is empty bootstrap it with the contract's balance + // address(0xdead) is a holder for initial shares + _setBufferedEther(balance); + // emitting `Submitted` before Transfer events to preserver events order in tx + emit Submitted(INITIAL_TOKEN_HOLDER, balance, 0); + _mintInitialShares(balance); + } + } } diff --git a/contracts/0.4.24/StETH.sol b/contracts/0.4.24/StETH.sol index 771276090..86ec56d53 100644 --- a/contracts/0.4.24/StETH.sol +++ b/contracts/0.4.24/StETH.sol @@ -331,9 +331,8 @@ contract StETH is IERC20, Pausable { */ function transferShares(address _recipient, uint256 _sharesAmount) external returns (uint256) { _transferShares(msg.sender, _recipient, _sharesAmount); - emit TransferShares(msg.sender, _recipient, _sharesAmount); uint256 tokensAmount = getPooledEthByShares(_sharesAmount); - emit Transfer(msg.sender, _recipient, tokensAmount); + _emitTransferEvents(msg.sender, _recipient, tokensAmount, _sharesAmount); return tokensAmount; } @@ -362,8 +361,7 @@ contract StETH is IERC20, Pausable { _transferShares(_sender, _recipient, _sharesAmount); _approve(_sender, msg.sender, currentAllowance.sub(tokensAmount)); - emit TransferShares(_sender, _recipient, _sharesAmount); - emit Transfer(_sender, _recipient, tokensAmount); + _emitTransferEvents(_sender, _recipient, tokensAmount, _sharesAmount); return tokensAmount; } @@ -382,8 +380,7 @@ contract StETH is IERC20, Pausable { function _transfer(address _sender, address _recipient, uint256 _amount) internal { uint256 _sharesToTransfer = getSharesByPooledEth(_amount); _transferShares(_sender, _recipient, _sharesToTransfer); - emit Transfer(_sender, _recipient, _amount); - emit TransferShares(_sender, _recipient, _sharesToTransfer); + _emitTransferEvents(_sender, _recipient, _amount, _sharesToTransfer); } /** @@ -507,31 +504,25 @@ contract StETH is IERC20, Pausable { } /** - * @notice Mints shares on behalf of 0xdead address, - * the shares amount is equal to the contract's balance. * - * - * Allows to get rid of zero checks for `totalShares` and `totalPooledEther` - * and overcome corner cases. - * - * NB: reverts if the current contract's balance is zero. - * - * @dev must be invoked before using the token + * @dev Emits {Transfer} and {TransferShares} events */ - function _bootstrapInitialHolder() internal returns (uint256) { - uint256 balance = address(this).balance; - assert(balance != 0); - - if (_getTotalShares() == 0) { - // if protocol is empty bootstrap it with the contract's balance - // address(0xdead) is a holder for initial shares - _mintShares(INITIAL_TOKEN_HOLDER, balance); - - emit Transfer(0x0, INITIAL_TOKEN_HOLDER, balance); - emit TransferShares(0x0, INITIAL_TOKEN_HOLDER, balance); + function _emitTransferEvents(address _from, address _to, uint _tokenAmount, uint256 _sharesAmount) internal { + emit Transfer(_from, _to, _tokenAmount); + emit TransferShares(_from, _to, _sharesAmount); + } - return balance; - } + /** + * @dev Emits {Transfer} and {TransferShares} events where `from` is 0 address. Indicates mint events. + */ + function _emitTransferAfterMintingShares(address _to, uint256 _sharesAmount) internal { + _emitTransferEvents(address(0), _to, getPooledEthByShares(_sharesAmount), _sharesAmount); + } - return 0; + /** + * @dev Mints shares to INITIAL_TOKEN_HOLDER + */ + function _mintInitialShares(uint256 _sharesAmount) internal { + _mintShares(INITIAL_TOKEN_HOLDER, _sharesAmount); + _emitTransferAfterMintingShares(INITIAL_TOKEN_HOLDER, _sharesAmount); } } diff --git a/contracts/0.4.24/lib/Packed64x4.sol b/contracts/0.4.24/lib/Packed64x4.sol index 316bff166..109323f43 100644 --- a/contracts/0.4.24/lib/Packed64x4.sol +++ b/contracts/0.4.24/lib/Packed64x4.sol @@ -7,26 +7,43 @@ // solhint-disable-next-line pragma solidity ^0.4.24; +import {SafeMath} from "@aragon/os/contracts/lib/math/SafeMath.sol"; +/// @notice Provides an interface for gas-efficient operations on four uint64 type +/// variables tightly packed into one uint256 variable stored in memory library Packed64x4 { + using SafeMath for uint256; using Packed64x4 for Packed64x4.Packed; - // string private constant ERROR_OFFSET_OUT_OF_RANGE = "OFFSET_OUT_OF_RANGE"; uint256 internal constant UINT64_MAX = 0xFFFFFFFFFFFFFFFF; struct Packed { uint256 v; } - //extract n-th uint64 from uint256 - function get(Packed memory _self, uint8 n) internal pure returns (uint64 r) { - // require(n < 4, ERROR_OFFSET_OUT_OF_RANGE); - r = uint64((_self.v >> (64 * n)) & UINT64_MAX); + /// @dev Returns uint64 variable stored on position `n` as uint256 + function get(Packed memory _self, uint8 n) internal pure returns (uint256 r) { + r = (_self.v >> (64 * n)) & UINT64_MAX; } - //merge n-th uint64 to uint256 - function set(Packed memory _self, uint8 n, uint64 x) internal pure { - // require(n < 4, ERROR_OFFSET_OUT_OF_RANGE); - _self.v = _self.v & ~(UINT64_MAX << (64 * n)) | ((uint256(x) & UINT64_MAX) << (64 * n)); + /// @dev Writes value stored in passed `x` variable on position `n`. + /// The passed value must be less or equal to UINT64_MAX. + /// If the passed value exceeds UINT64_MAX method will + /// revert with a "PACKED_OVERFLOW" error message + function set(Packed memory _self, uint8 n, uint256 x) internal pure { + require(x <= UINT64_MAX, "PACKED_OVERFLOW"); + _self.v = _self.v & ~(UINT64_MAX << (64 * n)) | ((x & UINT64_MAX) << (64 * n)); + } + + /// @dev Adds value stored in passed `x` variable to variable stored on position `n` + /// using SafeMath lib + function add(Packed memory _self, uint8 n, uint256 x) internal pure { + set(_self, n, get(_self, n).add(x)); + } + + /// @dev Subtract value stored in passed `x` variable from variable stored on position `n` + /// using SafeMath lib + function sub(Packed memory _self, uint8 n, uint256 x) internal pure { + set(_self, n, get(_self, n).sub(x)); } } diff --git a/contracts/0.4.24/lib/SigningKeys.sol b/contracts/0.4.24/lib/SigningKeys.sol index 346dbcbea..feff94c17 100644 --- a/contracts/0.4.24/lib/SigningKeys.sol +++ b/contracts/0.4.24/lib/SigningKeys.sol @@ -41,7 +41,7 @@ library SigningKeys { bytes _pubkeys, bytes _signatures ) internal returns (uint256) { - require(_keysCount > 0 && _startIndex.add(_keysCount - 1) <= UINT64_MAX, "INVALID_KEYS_COUNT"); + require(_keysCount > 0 && _startIndex.add(_keysCount) <= UINT64_MAX, "INVALID_KEYS_COUNT"); require( _pubkeys.length == _keysCount.mul(PUBKEY_LENGTH) && _signatures.length == _keysCount.mul(SIGNATURE_LENGTH), "LENGTH_MISMATCH" diff --git a/contracts/0.4.24/lib/StakeLimitUtils.sol b/contracts/0.4.24/lib/StakeLimitUtils.sol index f9b85cf85..e7b035164 100644 --- a/contracts/0.4.24/lib/StakeLimitUtils.sol +++ b/contracts/0.4.24/lib/StakeLimitUtils.sol @@ -40,10 +40,10 @@ library StakeLimitState { * @dev Internal representation struct (slot-wide) */ struct Data { - uint32 prevStakeBlockNumber; - uint96 prevStakeLimit; - uint32 maxStakeLimitGrowthBlocks; - uint96 maxStakeLimit; + uint32 prevStakeBlockNumber; // block number of the previous stake submit + uint96 prevStakeLimit; // limit value (<= `maxStakeLimit`) obtained on the previous stake submit + uint32 maxStakeLimitGrowthBlocks; // limit regeneration speed expressed in blocks + uint96 maxStakeLimit; // maximum limit value } } @@ -145,13 +145,19 @@ library StakeLimitUtils { "TOO_SMALL_LIMIT_INCREASE" ); - // if staking was paused or unlimited previously, - // or new limit is lower than previous, then - // reset prev stake limit to the new max stake limit - if ((_data.maxStakeLimit == 0) || (_maxStakeLimit < _data.prevStakeLimit)) { + // reset prev stake limit to the new max stake limit if + if ( + // staking was paused or + _data.prevStakeBlockNumber == 0 || + // staking was unlimited or + _data.maxStakeLimit == 0 || + // new maximum limit value is lower than the value obtained on the previous stake submit + _maxStakeLimit < _data.prevStakeLimit + ) { _data.prevStakeLimit = uint96(_maxStakeLimit); } - _data.maxStakeLimitGrowthBlocks = _stakeLimitIncreasePerBlock != 0 ? uint32(_maxStakeLimit / _stakeLimitIncreasePerBlock) : 0; + _data.maxStakeLimitGrowthBlocks = + _stakeLimitIncreasePerBlock != 0 ? uint32(_maxStakeLimit / _stakeLimitIncreasePerBlock) : 0; _data.maxStakeLimit = uint96(_maxStakeLimit); diff --git a/contracts/0.4.24/nos/NodeOperatorsRegistry.sol b/contracts/0.4.24/nos/NodeOperatorsRegistry.sol index ba3cf7481..72f078d95 100644 --- a/contracts/0.4.24/nos/NodeOperatorsRegistry.sol +++ b/contracts/0.4.24/nos/NodeOperatorsRegistry.sol @@ -6,7 +6,6 @@ pragma solidity 0.4.24; import {AragonApp} from "@aragon/os/contracts/apps/AragonApp.sol"; import {SafeMath} from "@aragon/os/contracts/lib/math/SafeMath.sol"; -import {SafeMath64} from "@aragon/os/contracts/lib/math/SafeMath64.sol"; import {UnstructuredStorage} from "@aragon/os/contracts/common/UnstructuredStorage.sol"; import {Math256} from "../../common/lib/Math256.sol"; @@ -30,7 +29,6 @@ interface IStETH { /// NOTE: the code below assumes moderate amount of node operators, i.e. up to `MAX_NODE_OPERATORS_COUNT`. contract NodeOperatorsRegistry is AragonApp, Versioned { using SafeMath for uint256; - using SafeMath64 for uint64; using UnstructuredStorage for bytes32; using SigningKeys for bytes32; using Packed64x4 for Packed64x4.Packed; @@ -176,7 +174,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { /// 0 <= exitedSigningKeysCount <= depositedSigningKeysCount /// exitedSigningKeysCount <= depositedSigningKeysCount <= vettedSigningKeysCount /// depositedSigningKeysCount <= vettedSigningKeysCount <= totalSigningKeysCount - /// depositedSigningKeysCount <= totalSigningKeysCount <= MAX_UINT64 + /// depositedSigningKeysCount <= totalSigningKeysCount <= UINT64_MAX /// /// Additionally, the exitedSigningKeysCount and depositedSigningKeysCount values are monotonically increasing: /// : : : : : @@ -222,25 +220,23 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { Packed64x4.Packed memory signingKeysStats; Packed64x4.Packed memory operatorTargetStats; Packed64x4.Packed memory summarySigningKeysStats = Packed64x4.Packed(0); - uint64 vettedSigningKeysCountBefore; - uint64 totalSigningKeysCount; - uint64 depositedSigningKeysCount; + uint256 vettedSigningKeysCountBefore; + uint256 totalSigningKeysCount; + uint256 depositedSigningKeysCount; for (uint256 nodeOperatorId; nodeOperatorId < totalOperators; ++nodeOperatorId) { signingKeysStats = _loadOperatorSigningKeysStats(nodeOperatorId); vettedSigningKeysCountBefore = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); totalSigningKeysCount = signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET); depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); - uint64 vettedSigningKeysCountAfter; + uint256 vettedSigningKeysCountAfter; if (!_nodeOperators[nodeOperatorId].active) { // trim vetted signing keys count when node operator is not active vettedSigningKeysCountAfter = depositedSigningKeysCount; } else { - vettedSigningKeysCountAfter = uint64( - Math256.min( - totalSigningKeysCount, - Math256.max(uint256(depositedSigningKeysCount), uint256(vettedSigningKeysCountBefore)) - ) + vettedSigningKeysCountAfter = Math256.min( + totalSigningKeysCount, + Math256.max(depositedSigningKeysCount, vettedSigningKeysCountBefore) ); } @@ -254,28 +250,16 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { operatorTargetStats.set(MAX_VALIDATORS_COUNT_OFFSET, vettedSigningKeysCountAfter); _saveOperatorTargetValidatorsStats(nodeOperatorId, operatorTargetStats); - summarySigningKeysStats.set( - SUMMARY_MAX_VALIDATORS_COUNT_OFFSET, - summarySigningKeysStats.get(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET).add(vettedSigningKeysCountAfter) - ); - summarySigningKeysStats.set( - SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET, - summarySigningKeysStats.get(SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET).add(depositedSigningKeysCount) - ); - summarySigningKeysStats.set( + summarySigningKeysStats.add(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET, vettedSigningKeysCountAfter); + summarySigningKeysStats.add(SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET, depositedSigningKeysCount); + summarySigningKeysStats.add( SUMMARY_EXITED_KEYS_COUNT_OFFSET, - summarySigningKeysStats.get(SUMMARY_EXITED_KEYS_COUNT_OFFSET).add( - signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET) - ) - ); - summarySigningKeysStats.set( - SUMMARY_TOTAL_KEYS_COUNT_OFFSET, - summarySigningKeysStats.get(SUMMARY_TOTAL_KEYS_COUNT_OFFSET).add(totalSigningKeysCount) + signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET) ); + summarySigningKeysStats.add(SUMMARY_TOTAL_KEYS_COUNT_OFFSET, totalSigningKeysCount); } _saveSummarySigningKeysStats(summarySigningKeysStats); - _increaseValidatorsKeysNonce(); } @@ -354,8 +338,8 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { emit NodeOperatorActiveSet(_nodeOperatorId, false); Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); - uint64 vettedSigningKeysCount = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); - uint64 depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + uint256 vettedSigningKeysCount = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); + uint256 depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); // reset vetted keys count to the deposited validators count if (vettedSigningKeysCount > depositedSigningKeysCount) { @@ -407,14 +391,12 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { _onlyCorrectNodeOperatorState(getNodeOperatorIsActive(_nodeOperatorId)); Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); - uint64 vettedSigningKeysCountBefore = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); - uint64 depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); - uint64 totalSigningKeysCount = signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET); - - uint64 vettedSigningKeysCountAfter = uint64( - Math256.min( - totalSigningKeysCount, Math256.max(uint256(_vettedSigningKeysCount), uint256(depositedSigningKeysCount)) - ) + uint256 vettedSigningKeysCountBefore = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); + uint256 depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + uint256 totalSigningKeysCount = signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET); + + uint256 vettedSigningKeysCountAfter = Math256.min( + totalSigningKeysCount, Math256.max(_vettedSigningKeysCount, depositedSigningKeysCount) ); if (vettedSigningKeysCountAfter == vettedSigningKeysCountBefore) { @@ -454,7 +436,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { uint256 totalNodeOperatorsCount = getNodeOperatorsCount(); uint256 nodeOperatorId; - uint64 validatorsCount; + uint256 validatorsCount; uint256 _nodeOperatorIdsOffset; uint256 _stuckValidatorsCountsOffset; @@ -479,6 +461,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { _requireValidRange(nodeOperatorId < totalNodeOperatorsCount); _updateStuckValidatorsCount(nodeOperatorId, validatorsCount); } + _increaseValidatorsKeysNonce(); } /// @notice Called by StakingRouter to update the number of the validators in the EXITED state @@ -497,7 +480,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { uint256 totalNodeOperatorsCount = getNodeOperatorsCount(); uint256 nodeOperatorId; - uint64 validatorsCount; + uint256 validatorsCount; uint256 _nodeOperatorIdsOffset; uint256 _exitedValidatorsCountsOffset; /// @dev see comments for `updateStuckValidatorsCount` @@ -515,6 +498,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { _requireValidRange(nodeOperatorId < totalNodeOperatorsCount); _updateExitedValidatorsCount(nodeOperatorId, validatorsCount, false); } + _increaseValidatorsKeysNonce(); } /// @notice Updates the number of the refunded validators for node operator with the given id @@ -524,7 +508,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { _onlyExistedNodeOperator(_nodeOperatorId); _auth(STAKING_ROUTER_ROLE); - _updateRefundValidatorsKeysCount(_nodeOperatorId, uint64(_refundedValidatorsCount)); + _updateRefundValidatorsKeysCount(_nodeOperatorId, _refundedValidatorsCount); } /// @notice Called by StakingRouter after it finishes updating exited and stuck validators @@ -554,37 +538,43 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { _onlyExistedNodeOperator(_nodeOperatorId); _auth(STAKING_ROUTER_ROLE); - _updateExitedValidatorsCount(_nodeOperatorId, uint64(_exitedValidatorsCount), true /* _allowDecrease */ ); - _updateStuckValidatorsCount(_nodeOperatorId, uint64(_stuckValidatorsCount)); + _updateStuckValidatorsCount(_nodeOperatorId, _stuckValidatorsCount); + _updateExitedValidatorsCount(_nodeOperatorId, _exitedValidatorsCount, true /* _allowDecrease */ ); + _increaseValidatorsKeysNonce(); } - function _updateExitedValidatorsCount(uint256 _nodeOperatorId, uint64 _exitedValidatorsKeysCount, bool _allowDecrease) + function _updateExitedValidatorsCount(uint256 _nodeOperatorId, uint256 _exitedValidatorsCount, bool _allowDecrease) internal { Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); - int64 totalExitedValidatorsDelta = - int64(_exitedValidatorsKeysCount) - int64(signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET)); + uint256 oldExitedValidatorsCount = signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET); + if (_exitedValidatorsCount == oldExitedValidatorsCount) return; + require( + _allowDecrease || _exitedValidatorsCount > oldExitedValidatorsCount, + "EXITED_VALIDATORS_COUNT_DECREASED" + ); - if (totalExitedValidatorsDelta != 0) { - _requireValidRange(_exitedValidatorsKeysCount <= signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET)); - if (totalExitedValidatorsDelta < 0 && !_allowDecrease) { - revert("EXITED_VALIDATORS_COUNT_DECREASED"); - } + uint256 depositedValidatorsCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + uint256 stuckValidatorsCount = + _loadOperatorStuckPenaltyStats(_nodeOperatorId).get(STUCK_VALIDATORS_COUNT_OFFSET); - signingKeysStats.set(TOTAL_EXITED_KEYS_COUNT_OFFSET, _exitedValidatorsKeysCount); - _saveOperatorSigningKeysStats(_nodeOperatorId, signingKeysStats); - emit ExitedSigningKeysCountChanged(_nodeOperatorId, _exitedValidatorsKeysCount); + // sustain invariant exited + stuck <= deposited + assert(depositedValidatorsCount >= stuckValidatorsCount); + _requireValidRange(_exitedValidatorsCount <= depositedValidatorsCount - stuckValidatorsCount); - // upd totals - Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); - summarySigningKeysStats.set( - SUMMARY_EXITED_KEYS_COUNT_OFFSET, - uint64(int64(summarySigningKeysStats.get(SUMMARY_EXITED_KEYS_COUNT_OFFSET)) + totalExitedValidatorsDelta) - ); - _saveSummarySigningKeysStats(summarySigningKeysStats); + signingKeysStats.set(TOTAL_EXITED_KEYS_COUNT_OFFSET, _exitedValidatorsCount); + _saveOperatorSigningKeysStats(_nodeOperatorId, signingKeysStats); + emit ExitedSigningKeysCountChanged(_nodeOperatorId, _exitedValidatorsCount); - _updateSummaryMaxValidatorsCount(_nodeOperatorId); + Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); + uint256 exitedValidatorsAbsDiff = Math256.absDiff(_exitedValidatorsCount, oldExitedValidatorsCount); + if (_exitedValidatorsCount > oldExitedValidatorsCount) { + summarySigningKeysStats.add(SUMMARY_EXITED_KEYS_COUNT_OFFSET, exitedValidatorsAbsDiff); + } else { + summarySigningKeysStats.sub(SUMMARY_EXITED_KEYS_COUNT_OFFSET, exitedValidatorsAbsDiff); } + _saveSummarySigningKeysStats(summarySigningKeysStats); + _updateSummaryMaxValidatorsCount(_nodeOperatorId); } /// @notice Updates the limit of the validators that can be used for deposit by DAO @@ -598,31 +588,34 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { Packed64x4.Packed memory operatorTargetStats = _loadOperatorTargetValidatorsStats(_nodeOperatorId); operatorTargetStats.set(IS_TARGET_LIMIT_ACTIVE_OFFSET, _isTargetLimitActive ? 1 : 0); - operatorTargetStats.set(TARGET_VALIDATORS_COUNT_OFFSET, _isTargetLimitActive ? uint64(_targetLimit) : 0); + operatorTargetStats.set(TARGET_VALIDATORS_COUNT_OFFSET, _isTargetLimitActive ? _targetLimit : 0); _saveOperatorTargetValidatorsStats(_nodeOperatorId, operatorTargetStats); emit TargetValidatorsCountChanged(_nodeOperatorId, _targetLimit); _updateSummaryMaxValidatorsCount(_nodeOperatorId); + _increaseValidatorsKeysNonce(); } /** * @notice Set the stuck signings keys count */ - function _updateStuckValidatorsCount(uint256 _nodeOperatorId, uint64 _stuckValidatorsCount) internal { + function _updateStuckValidatorsCount(uint256 _nodeOperatorId, uint256 _stuckValidatorsCount) internal { Packed64x4.Packed memory stuckPenaltyStats = _loadOperatorStuckPenaltyStats(_nodeOperatorId); - uint64 curStuckValidatorsCount = stuckPenaltyStats.get(STUCK_VALIDATORS_COUNT_OFFSET); + uint256 curStuckValidatorsCount = stuckPenaltyStats.get(STUCK_VALIDATORS_COUNT_OFFSET); if (_stuckValidatorsCount == curStuckValidatorsCount) return; Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); - _requireValidRange( - _stuckValidatorsCount - <= signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET) - signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET) - ); + uint256 exitedValidatorsCount = signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET); + uint256 depositedValidatorsCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + + // sustain invariant exited + stuck <= deposited + assert(depositedValidatorsCount >= exitedValidatorsCount); + _requireValidRange(_stuckValidatorsCount <= depositedValidatorsCount - exitedValidatorsCount); - uint64 curRefundedValidatorsCount = stuckPenaltyStats.get(REFUNDED_VALIDATORS_COUNT_OFFSET); + uint256 curRefundedValidatorsCount = stuckPenaltyStats.get(REFUNDED_VALIDATORS_COUNT_OFFSET); if (_stuckValidatorsCount <= curRefundedValidatorsCount && curStuckValidatorsCount > curRefundedValidatorsCount) { - stuckPenaltyStats.set(STUCK_PENALTY_END_TIMESTAMP_OFFSET, uint64(block.timestamp + getStuckPenaltyDelay())); + stuckPenaltyStats.set(STUCK_PENALTY_END_TIMESTAMP_OFFSET, block.timestamp + getStuckPenaltyDelay()); } stuckPenaltyStats.set(STUCK_VALIDATORS_COUNT_OFFSET, _stuckValidatorsCount); @@ -637,17 +630,17 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { _updateSummaryMaxValidatorsCount(_nodeOperatorId); } - function _updateRefundValidatorsKeysCount(uint256 _nodeOperatorId, uint64 _refundedValidatorsCount) internal { + function _updateRefundValidatorsKeysCount(uint256 _nodeOperatorId, uint256 _refundedValidatorsCount) internal { Packed64x4.Packed memory stuckPenaltyStats = _loadOperatorStuckPenaltyStats(_nodeOperatorId); - uint64 curRefundedValidatorsCount = stuckPenaltyStats.get(REFUNDED_VALIDATORS_COUNT_OFFSET); + uint256 curRefundedValidatorsCount = stuckPenaltyStats.get(REFUNDED_VALIDATORS_COUNT_OFFSET); if (_refundedValidatorsCount == curRefundedValidatorsCount) return; Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); _requireValidRange(_refundedValidatorsCount <= signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET)); - uint64 curStuckValidatorsCount = stuckPenaltyStats.get(STUCK_VALIDATORS_COUNT_OFFSET); + uint256 curStuckValidatorsCount = stuckPenaltyStats.get(STUCK_VALIDATORS_COUNT_OFFSET); if (_refundedValidatorsCount >= curStuckValidatorsCount && curRefundedValidatorsCount < curStuckValidatorsCount) { - stuckPenaltyStats.set(STUCK_PENALTY_END_TIMESTAMP_OFFSET, uint64(block.timestamp + getStuckPenaltyDelay())); + stuckPenaltyStats.set(STUCK_PENALTY_END_TIMESTAMP_OFFSET, block.timestamp + getStuckPenaltyDelay()); } stuckPenaltyStats.set(REFUNDED_VALIDATORS_COUNT_OFFSET, _refundedValidatorsCount); @@ -662,17 +655,20 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { } // @dev Recalculate and update the max validator count for operator and summary stats - function _updateSummaryMaxValidatorsCount(uint256 _nodeOperatorId) internal returns (int64 maxSigningKeysDelta) { - maxSigningKeysDelta = _applyNodeOperatorLimits(_nodeOperatorId); - if (maxSigningKeysDelta != 0) { - Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); + function _updateSummaryMaxValidatorsCount(uint256 _nodeOperatorId) internal { + (uint256 oldMaxSigningKeysCount, uint256 newMaxSigningKeysCount) = _applyNodeOperatorLimits(_nodeOperatorId); - summarySigningKeysStats.set( - SUMMARY_MAX_VALIDATORS_COUNT_OFFSET, - uint64(int64(summarySigningKeysStats.get(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET)) + maxSigningKeysDelta) - ); - _saveSummarySigningKeysStats(summarySigningKeysStats); + if (newMaxSigningKeysCount == oldMaxSigningKeysCount) return; + + Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); + + uint256 maxSigningKeysCountAbsDiff = Math256.absDiff(newMaxSigningKeysCount, oldMaxSigningKeysCount); + if (newMaxSigningKeysCount > oldMaxSigningKeysCount) { + summarySigningKeysStats.add(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET, maxSigningKeysCountAbsDiff); + } else { + summarySigningKeysStats.sub(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET, maxSigningKeysCountAbsDiff); } + _saveSummarySigningKeysStats(summarySigningKeysStats); } /// @notice Invalidates all unused deposit data for all node operators @@ -695,16 +691,21 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { function _invalidateReadyToDepositKeysRange(uint256 _indexFrom, uint256 _indexTo) internal { _requireValidRange(_indexFrom <= _indexTo && _indexTo < getNodeOperatorsCount()); - uint64 trimmedKeysCount; - uint64 totalTrimmedKeysCount; + uint256 trimmedKeysCount; + uint256 totalTrimmedKeysCount; + uint256 totalSigningKeysCount; + uint256 depositedSigningKeysCount; Packed64x4.Packed memory signingKeysStats; - for (uint256 nodeOperatorId = _indexFrom; nodeOperatorId <= _indexTo; ++nodeOperatorId) { signingKeysStats = _loadOperatorSigningKeysStats(nodeOperatorId); - uint64 depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); - trimmedKeysCount = signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET) - depositedSigningKeysCount; - if (trimmedKeysCount == 0) continue; + totalSigningKeysCount = signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET); + depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + + if (totalSigningKeysCount == depositedSigningKeysCount) continue; + assert(totalSigningKeysCount > depositedSigningKeysCount); + + trimmedKeysCount = totalSigningKeysCount - depositedSigningKeysCount; totalTrimmedKeysCount += trimmedKeysCount; signingKeysStats.set(TOTAL_KEYS_COUNT_OFFSET, depositedSigningKeysCount); @@ -715,15 +716,12 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { emit TotalSigningKeysCountChanged(nodeOperatorId, depositedSigningKeysCount); emit VettedSigningKeysCountChanged(nodeOperatorId, depositedSigningKeysCount); - emit NodeOperatorTotalKeysTrimmed(nodeOperatorId, trimmedKeysCount); + emit NodeOperatorTotalKeysTrimmed(nodeOperatorId, uint64(trimmedKeysCount)); } if (totalTrimmedKeysCount > 0) { Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); - summarySigningKeysStats.set( - SUMMARY_TOTAL_KEYS_COUNT_OFFSET, - summarySigningKeysStats.get(SUMMARY_TOTAL_KEYS_COUNT_OFFSET) - totalTrimmedKeysCount - ); + summarySigningKeysStats.sub(SUMMARY_TOTAL_KEYS_COUNT_OFFSET, totalTrimmedKeysCount); _saveSummarySigningKeysStats(summarySigningKeysStats); _increaseValidatorsKeysNonce(); } @@ -761,7 +759,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { function _getNodeOperator(uint256 _nodeOperatorId) internal view - returns (uint64 maxSigningKeysCount, uint64 exitedSigningKeysCount, uint64 depositedSigningKeysCount) + returns (uint256 exitedSigningKeysCount, uint256 depositedSigningKeysCount, uint256 maxSigningKeysCount) { Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); Packed64x4.Packed memory operatorTargetStats = _loadOperatorTargetValidatorsStats(_nodeOperatorId); @@ -769,36 +767,48 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { exitedSigningKeysCount = signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET); depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); maxSigningKeysCount = operatorTargetStats.get(MAX_VALIDATORS_COUNT_OFFSET); + + // Validate data boundaries invariants here to not use SafeMath in caller methods + assert(maxSigningKeysCount >= depositedSigningKeysCount && depositedSigningKeysCount >= exitedSigningKeysCount); } - function _applyNodeOperatorLimits(uint256 _nodeOperatorId) internal returns (int64 maxSigningKeysDelta) { + function _applyNodeOperatorLimits(uint256 _nodeOperatorId) + internal + returns (uint256 oldMaxSigningKeysCount, uint256 newMaxSigningKeysCount) + { Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); Packed64x4.Packed memory operatorTargetStats = _loadOperatorTargetValidatorsStats(_nodeOperatorId); - uint64 exitedSigningKeysCount = signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET); - uint64 depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); - uint64 vettedSigningKeysCount = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); - - uint64 oldMaxSigningKeysCount = operatorTargetStats.get(MAX_VALIDATORS_COUNT_OFFSET); - uint64 newMaxSigningKeysCount = depositedSigningKeysCount; + uint256 depositedSigningKeysCount = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); - if (isOperatorPenaltyCleared(_nodeOperatorId)) { - if (operatorTargetStats.get(IS_TARGET_LIMIT_ACTIVE_OFFSET) == 0) { - newMaxSigningKeysCount = vettedSigningKeysCount; - } else { - // correct max count according to target if target is enabled - // targetLimit is limited to UINT64_MAX - uint256 targetLimit = Math256.min(uint256(exitedSigningKeysCount).add(operatorTargetStats.get(TARGET_VALIDATORS_COUNT_OFFSET)), UINT64_MAX); - if (targetLimit > depositedSigningKeysCount) { - newMaxSigningKeysCount = uint64(Math256.min(vettedSigningKeysCount, targetLimit)); - } - } - } // else newMaxSigningKeysCount = depositedSigningKeysCount, so depositable keys count = 0 + // It's expected that validators don't suffer from penalties most of the time, + // so optimistically, set the count of max validators equal to the vetted validators count. + newMaxSigningKeysCount = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); + + if (!isOperatorPenaltyCleared(_nodeOperatorId)) { + // when the node operator is penalized zeroing its depositable validators count + newMaxSigningKeysCount = depositedSigningKeysCount; + } else if (operatorTargetStats.get(IS_TARGET_LIMIT_ACTIVE_OFFSET) != 0) { + // apply target limit when it's active and the node operator is not penalized + newMaxSigningKeysCount = Math256.max( + // max validators count can't be less than the deposited validators count + // even when the target limit is less than the current active validators count + depositedSigningKeysCount, + Math256.min( + // max validators count can't be greater than the vetted validators count + newMaxSigningKeysCount, + // SafeMath.add() isn't used below because the sum is always + // less or equal to 2 * UINT64_MAX + signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET) + + operatorTargetStats.get(TARGET_VALIDATORS_COUNT_OFFSET) + ) + ); + } + oldMaxSigningKeysCount = operatorTargetStats.get(MAX_VALIDATORS_COUNT_OFFSET); if (oldMaxSigningKeysCount != newMaxSigningKeysCount) { operatorTargetStats.set(MAX_VALIDATORS_COUNT_OFFSET, newMaxSigningKeysCount); _saveOperatorTargetValidatorsStats(_nodeOperatorId, operatorTargetStats); - maxSigningKeysDelta = int64(newMaxSigningKeysCount) - int64(oldMaxSigningKeysCount); } } @@ -819,7 +829,8 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { uint256 exitedSigningKeysCount; for (uint256 nodeOperatorId; nodeOperatorId < nodeOperatorsCount; ++nodeOperatorId) { - (maxSigningKeysCount, exitedSigningKeysCount, depositedSigningKeysCount) = _getNodeOperator(nodeOperatorId); + (exitedSigningKeysCount, depositedSigningKeysCount, maxSigningKeysCount) + = _getNodeOperator(nodeOperatorId); // the node operator has no available signing keys if (depositedSigningKeysCount == maxSigningKeysCount) continue; @@ -842,10 +853,10 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { } allocatedKeysCount = - MinFirstAllocationStrategy.allocate(activeKeyCountsAfterAllocation, activeKeysCapacities, uint64(_keysCount)); + MinFirstAllocationStrategy.allocate(activeKeyCountsAfterAllocation, activeKeysCapacities, _keysCount); /// @dev method NEVER allocates more keys than was requested - assert(allocatedKeysCount <= _keysCount); + assert(_keysCount >= allocatedKeysCount); } function _loadAllocatedSigningKeys( @@ -856,19 +867,27 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { (pubkeys, signatures) = SigningKeys.initKeysSigsBuf(_keysCountToLoad); uint256 loadedKeysCount = 0; - uint64 depositedSigningKeysCountBefore; - uint64 depositedSigningKeysCountAfter; + uint256 depositedSigningKeysCountBefore; + uint256 depositedSigningKeysCountAfter; uint256 keysCount; Packed64x4.Packed memory signingKeysStats; for (uint256 i; i < _nodeOperatorIds.length; ++i) { signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorIds[i]); depositedSigningKeysCountBefore = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); depositedSigningKeysCountAfter = - signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET) + uint64(_activeKeyCountsAfterAllocation[i]); + signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET) + _activeKeyCountsAfterAllocation[i]; - keysCount = depositedSigningKeysCountAfter.sub(depositedSigningKeysCountBefore); - if (keysCount == 0) continue; + if (depositedSigningKeysCountAfter == depositedSigningKeysCountBefore) continue; + // For gas savings SafeMath.add() wasn't used on depositedSigningKeysCountAfter + // calculation, so below we check that operation finished without overflow + // In case of overflow: + // depositedSigningKeysCountAfter < signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET) + // what violates invariant: + // depositedSigningKeysCount >= exitedSigningKeysCount + assert(depositedSigningKeysCountAfter > depositedSigningKeysCountBefore); + + keysCount = depositedSigningKeysCountAfter - depositedSigningKeysCountBefore; SIGNING_KEYS_MAPPING_NAME.loadKeysSigs( _nodeOperatorIds[i], depositedSigningKeysCountBefore, keysCount, pubkeys, signatures, loadedKeysCount ); @@ -883,10 +902,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { assert(loadedKeysCount == _keysCountToLoad); Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); - summarySigningKeysStats.set( - SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET, - summarySigningKeysStats.get(SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET).add(uint64(loadedKeysCount)) - ); + summarySigningKeysStats.add(SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET, loadedKeysCount); _saveSummarySigningKeysStats(summarySigningKeysStats); } @@ -900,10 +916,10 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { bool active, string name, address rewardAddress, - uint64 stakingLimit, - uint64 stoppedValidators, - uint64 totalSigningKeys, - uint64 usedSigningKeys + uint64 totalVettedValidators, + uint64 totalExitedValidators, + uint64 totalAddedValidators, + uint64 totalDepositedValidators ) { _onlyExistedNodeOperator(_nodeOperatorId); @@ -916,10 +932,10 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); - stakingLimit = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); - stoppedValidators = signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET); - totalSigningKeys = signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET); - usedSigningKeys = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + totalVettedValidators = uint64(signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET)); + totalExitedValidators = uint64(signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET)); + totalAddedValidators = uint64(signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET)); + totalDepositedValidators = uint64(signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET)); } /// @notice Returns the rewards distribution proportional to the effective stake for each node operator. @@ -938,13 +954,21 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { uint256 idx = 0; uint256 totalActiveValidatorsCount = 0; + Packed64x4.Packed memory signingKeysStats; for (uint256 operatorId; operatorId < nodeOperatorCount; ++operatorId) { if (!getNodeOperatorIsActive(operatorId)) continue; - Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(operatorId); - uint256 activeValidatorsCount = - signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET) - signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET); - totalActiveValidatorsCount = totalActiveValidatorsCount.add(activeValidatorsCount); + signingKeysStats = _loadOperatorSigningKeysStats(operatorId); + uint256 totalExitedValidators = signingKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET); + uint256 totalDepositedValidators = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + + // validate invariant to not use SafeMath.sub() + assert(totalDepositedValidators >= totalExitedValidators); + uint256 activeValidatorsCount = totalDepositedValidators - totalExitedValidators; + + // SafeMath.add() isn't used below because the following is always true: + // totalActiveValidatorsCount <= MAX_NODE_OPERATORS_COUNT * UINT64_MAX + totalActiveValidatorsCount += activeValidatorsCount; recipients[idx] = _nodeOperators[operatorId].rewardAddress; // prefill shares array with 'key share' for recipient, see below @@ -1011,14 +1035,12 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { emit TotalSigningKeysCountChanged(_nodeOperatorId, totalSigningKeysCount); - signingKeysStats.set(TOTAL_KEYS_COUNT_OFFSET, uint64(totalSigningKeysCount)); + signingKeysStats.set(TOTAL_KEYS_COUNT_OFFSET, totalSigningKeysCount); _saveOperatorSigningKeysStats(_nodeOperatorId, signingKeysStats); // upd totals Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); - summarySigningKeysStats.set( - SUMMARY_TOTAL_KEYS_COUNT_OFFSET, summarySigningKeysStats.get(SUMMARY_TOTAL_KEYS_COUNT_OFFSET).add(uint64(_keysCount)) - ); + summarySigningKeysStats.add(SUMMARY_TOTAL_KEYS_COUNT_OFFSET, _keysCount); _saveSummarySigningKeysStats(summarySigningKeysStats); _increaseValidatorsKeysNonce(); @@ -1066,28 +1088,28 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); uint256 totalSigningKeysCount = signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET); - // comapring _fromIndex.add(_keysCount) <= totalSigningKeysCount is enough as totalSigningKeysCount is always less than MAX_UINT64 - _requireValidRange(_fromIndex >= signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET) && _fromIndex.add(_keysCount) <= totalSigningKeysCount); + // comparing _fromIndex.add(_keysCount) <= totalSigningKeysCount is enough as totalSigningKeysCount is always less than UINT64_MAX + _requireValidRange( + _fromIndex >= signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET) + && _fromIndex.add(_keysCount) <= totalSigningKeysCount + ); totalSigningKeysCount = SIGNING_KEYS_MAPPING_NAME.removeKeysSigs(_nodeOperatorId, _fromIndex, _keysCount, totalSigningKeysCount); - signingKeysStats.set(TOTAL_KEYS_COUNT_OFFSET, uint64(totalSigningKeysCount)); + signingKeysStats.set(TOTAL_KEYS_COUNT_OFFSET, totalSigningKeysCount); emit TotalSigningKeysCountChanged(_nodeOperatorId, totalSigningKeysCount); - uint64 vettedSigningKeysCount = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); + uint256 vettedSigningKeysCount = signingKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET); if (_fromIndex < vettedSigningKeysCount) { // decreasing the staking limit so the key at _index can't be used anymore - signingKeysStats.set(TOTAL_VETTED_KEYS_COUNT_OFFSET, uint64(_fromIndex)); + signingKeysStats.set(TOTAL_VETTED_KEYS_COUNT_OFFSET, _fromIndex); emit VettedSigningKeysCountChanged(_nodeOperatorId, _fromIndex); } _saveOperatorSigningKeysStats(_nodeOperatorId, signingKeysStats); // upd totals Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); - summarySigningKeysStats.set( - SUMMARY_TOTAL_KEYS_COUNT_OFFSET, - summarySigningKeysStats.get(SUMMARY_TOTAL_KEYS_COUNT_OFFSET).sub(uint64(_keysCount)) - ); + summarySigningKeysStats.sub(SUMMARY_TOTAL_KEYS_COUNT_OFFSET, _keysCount); _saveSummarySigningKeysStats(summarySigningKeysStats); _updateSummaryMaxValidatorsCount(_nodeOperatorId); @@ -1106,7 +1128,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { _onlyExistedNodeOperator(_nodeOperatorId); Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); - return signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET) - signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + return signingKeysStats.get(TOTAL_KEYS_COUNT_OFFSET).sub(signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET)); } /// @notice Returns n-th signing key of the node operator #`_nodeOperatorId` @@ -1165,7 +1187,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); totalExitedValidators = summarySigningKeysStats.get(SUMMARY_EXITED_KEYS_COUNT_OFFSET); totalDepositedValidators = summarySigningKeysStats.get(SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET); - depositableValidatorsCount = summarySigningKeysStats.get(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET) - totalDepositedValidators; + depositableValidatorsCount = summarySigningKeysStats.get(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET).sub(totalDepositedValidators); } function getNodeOperatorSummary(uint256 _nodeOperatorId) @@ -1202,7 +1224,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { uint256 depositableValidatorsCount ) { uint256 totalMaxValidators; - (totalMaxValidators, totalExitedValidators, totalDepositedValidators) = _getNodeOperator(_nodeOperatorId); + (totalExitedValidators, totalDepositedValidators, totalMaxValidators) = _getNodeOperator(_nodeOperatorId); depositableValidatorsCount = totalMaxValidators - totalDepositedValidators; } @@ -1222,7 +1244,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { return !_isOperatorPenalized(stuckPenaltyStats) && stuckPenaltyStats.get(STUCK_PENALTY_END_TIMESTAMP_OFFSET) == 0; } - function clearNodeOperatorPenalty(uint256 _nodeOperatorId) public returns (bool) { + function clearNodeOperatorPenalty(uint256 _nodeOperatorId) external returns (bool) { Packed64x4.Packed memory stuckPenaltyStats = _loadOperatorStuckPenaltyStats(_nodeOperatorId); require( !_isOperatorPenalized(stuckPenaltyStats) && stuckPenaltyStats.get(STUCK_PENALTY_END_TIMESTAMP_OFFSET) != 0, @@ -1231,6 +1253,7 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { stuckPenaltyStats.set(STUCK_PENALTY_END_TIMESTAMP_OFFSET, 0); _saveOperatorStuckPenaltyStats(_nodeOperatorId, stuckPenaltyStats); _updateSummaryMaxValidatorsCount(_nodeOperatorId); + _increaseValidatorsKeysNonce(); } /// @notice Returns total number of node operators @@ -1404,7 +1427,8 @@ contract NodeOperatorsRegistry is AragonApp, Versioned { function _onlyNodeOperatorManager(address _sender, uint256 _nodeOperatorId) internal view { bool isRewardAddress = _sender == _nodeOperators[_nodeOperatorId].rewardAddress; - _requireAuth(isRewardAddress || canPerform(_sender, MANAGE_SIGNING_KEYS, arr(_nodeOperatorId))); + bool isActive = _nodeOperators[_nodeOperatorId].active; + _requireAuth((isRewardAddress && isActive) || canPerform(_sender, MANAGE_SIGNING_KEYS, arr(_nodeOperatorId))); } function _onlyExistedNodeOperator(uint256 _nodeOperatorId) internal view { diff --git a/contracts/0.4.24/test_helpers/NodeOperatorsRegistryMock.sol b/contracts/0.4.24/test_helpers/NodeOperatorsRegistryMock.sol index 1fd6a7b88..68df9e5f0 100644 --- a/contracts/0.4.24/test_helpers/NodeOperatorsRegistryMock.sol +++ b/contracts/0.4.24/test_helpers/NodeOperatorsRegistryMock.sol @@ -40,7 +40,7 @@ contract NodeOperatorsRegistryMock is NodeOperatorsRegistry { _onlyExistedNodeOperator(_nodeOperatorId); // NodeOperator storage nodeOperator = _nodeOperators[_nodeOperatorId]; Packed64x4.Packed memory signingKeysStats = _loadOperatorSigningKeysStats(_nodeOperatorId); - uint64 depositedSigningKeysCountBefore = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); + uint256 depositedSigningKeysCountBefore = signingKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET); if (_depositedSigningKeysCount == depositedSigningKeysCountBefore) { return; } @@ -100,12 +100,12 @@ contract NodeOperatorsRegistryMock is NodeOperatorsRegistry { emit NodeOperatorAdded(id, _name, _rewardAddress, 0); - Packed64x4.Packed memory totalSigningKeysStats = _loadSummarySigningKeysStats(); - totalSigningKeysStats.set(TOTAL_VETTED_KEYS_COUNT_OFFSET, totalSigningKeysStats.get(TOTAL_VETTED_KEYS_COUNT_OFFSET).add(vettedSigningKeysCount)); - totalSigningKeysStats.set(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET, totalSigningKeysStats.get(TOTAL_DEPOSITED_KEYS_COUNT_OFFSET).add(depositedSigningKeysCount)); - totalSigningKeysStats.set(TOTAL_EXITED_KEYS_COUNT_OFFSET, totalSigningKeysStats.get(TOTAL_EXITED_KEYS_COUNT_OFFSET).add(exitedSigningKeysCount)); - totalSigningKeysStats.set(TOTAL_KEYS_COUNT_OFFSET, totalSigningKeysStats.get(TOTAL_KEYS_COUNT_OFFSET).add(totalSigningKeysCount)); - _saveSummarySigningKeysStats(totalSigningKeysStats); + Packed64x4.Packed memory summarySigningKeysStats = _loadSummarySigningKeysStats(); + summarySigningKeysStats.add(SUMMARY_MAX_VALIDATORS_COUNT_OFFSET, vettedSigningKeysCount); + summarySigningKeysStats.add(SUMMARY_EXITED_KEYS_COUNT_OFFSET, exitedSigningKeysCount); + summarySigningKeysStats.add(SUMMARY_TOTAL_KEYS_COUNT_OFFSET, totalSigningKeysCount); + summarySigningKeysStats.add(SUMMARY_DEPOSITED_KEYS_COUNT_OFFSET, depositedSigningKeysCount); + _saveSummarySigningKeysStats(summarySigningKeysStats); } function testing_setNodeOperatorLimits( @@ -191,7 +191,7 @@ contract NodeOperatorsRegistryMock is NodeOperatorsRegistry { } function testing_getNodeOperator(uint256 operatorId) external view - returns (uint64 maxSigningKeysCount, uint64 exitedSigningKeysCount, uint64 depositedSigningKeysCount) + returns (uint256 exitedSigningKeysCount, uint256 depositedSigningKeysCount, uint256 maxSigningKeysCount) { return _getNodeOperator(operatorId); } @@ -201,4 +201,24 @@ contract NodeOperatorsRegistryMock is NodeOperatorsRegistry { function testing_distributeRewards() external returns (uint256) { return _distributeRewards(); } + + function testing_setNodeOperatorPenalty( + uint256 _nodeOperatorId, + uint256 _refundedValidatorsCount, + uint256 _stuckValidatorsCount, + uint256 _stuckPenaltyEndTimestamp + ) external { + _requireValidRange(_refundedValidatorsCount <= UINT64_MAX); + _requireValidRange(_stuckValidatorsCount <= UINT64_MAX); + _requireValidRange(_stuckPenaltyEndTimestamp <= UINT64_MAX); + Packed64x4.Packed memory stuckPenaltyStats = _loadOperatorStuckPenaltyStats( + _nodeOperatorId + ); + + stuckPenaltyStats.set(REFUNDED_VALIDATORS_COUNT_OFFSET, uint64(_refundedValidatorsCount)); + stuckPenaltyStats.set(STUCK_VALIDATORS_COUNT_OFFSET, uint64(_stuckValidatorsCount)); + stuckPenaltyStats.set(STUCK_PENALTY_END_TIMESTAMP_OFFSET, uint64(_stuckPenaltyEndTimestamp)); + _saveOperatorStuckPenaltyStats(_nodeOperatorId, stuckPenaltyStats); + _updateSummaryMaxValidatorsCount(_nodeOperatorId); + } } diff --git a/contracts/0.4.24/test_helpers/StETHMock.sol b/contracts/0.4.24/test_helpers/StETHMock.sol index de24a2676..599fe5b9b 100644 --- a/contracts/0.4.24/test_helpers/StETHMock.sol +++ b/contracts/0.4.24/test_helpers/StETHMock.sol @@ -14,7 +14,13 @@ contract StETHMock is StETH { constructor() public payable{ _resume(); - _bootstrapInitialHolder(); + // _bootstrapInitialHolder + uint256 balance = address(this).balance; + assert(balance != 0); + + // address(0xdead) is a holder for initial shares + setTotalPooledEther(balance); + _mintInitialShares(balance); } function _getTotalPooledEther() internal view returns (uint256) { @@ -47,9 +53,4 @@ contract StETHMock is StETH { function burnShares(address _account, uint256 _sharesAmount) public returns (uint256 newTotalShares) { return _burnShares(_account, _sharesAmount); } - - function _emitTransferAfterMintingShares(address _to, uint256 _sharesAmount) internal { - emit Transfer(address(0), _to, getPooledEthByShares(_sharesAmount)); - emit TransferShares(address(0), _to, _sharesAmount); - } } diff --git a/contracts/0.4.24/test_helpers/StakeLimitUtilsMock.sol b/contracts/0.4.24/test_helpers/StakeLimitUtilsMock.sol index 224cb0a69..133eca288 100644 --- a/contracts/0.4.24/test_helpers/StakeLimitUtilsMock.sol +++ b/contracts/0.4.24/test_helpers/StakeLimitUtilsMock.sol @@ -67,13 +67,16 @@ contract StakeLimitUtilsMock { return STAKING_STATE_POSITION.getStorageStakeLimitStruct().isStakingLimitSet(); } - function setStakingLimit(uint256 _slotValue, uint256 _maxStakeLimit, uint256 _stakeLimitIncreasePerBlock) public view { + function setStakingLimit( + uint256 _slotValue, uint256 _maxStakeLimit, uint256 _stakeLimitIncreasePerBlock + ) public view returns (uint256) { STAKING_STATE_POSITION.setStorageUint256(_slotValue); STAKING_STATE_POSITION.setStorageStakeLimitStruct( STAKING_STATE_POSITION.getStorageStakeLimitStruct().setStakingLimit( _maxStakeLimit, _stakeLimitIncreasePerBlock ) ); + return STAKING_STATE_POSITION.getStorageUint256(); } function removeStakingLimit(uint256 _slotValue) public view returns(uint256) { diff --git a/contracts/0.8.9/DepositSecurityModule.sol b/contracts/0.8.9/DepositSecurityModule.sol index 1de248148..4e0059bd4 100644 --- a/contracts/0.8.9/DepositSecurityModule.sol +++ b/contracts/0.8.9/DepositSecurityModule.sol @@ -54,7 +54,7 @@ contract DepositSecurityModule { error DuplicateAddress(address addr); error NotAnOwner(address caller); error InvalidSignature(); - error SignatureNotSorted(); + error SignaturesNotSorted(); error DepositNoQuorum(); error DepositRootChanged(); error DepositInactiveModule(); @@ -402,8 +402,8 @@ contract DepositSecurityModule { * 5. block.number - StakingModule.getLastDepositBlock() < minDepositBlockDistance. * 6. blockhash(blockNumber) != blockHash. * - * Signatures must be sorted in ascending order by index of the guardian. Each signature must - * be produced for keccak256 hash of the following message (each component taking 32 bytes): + * Signatures must be sorted in ascending order by address of the guardian. Each signature must + * be produced for the keccak256 hash of the following message (each component taking 32 bytes): * * | ATTEST_MESSAGE_PREFIX | blockNumber | blockHash | depositRoot | stakingModuleId | nonce | */ @@ -452,7 +452,7 @@ contract DepositSecurityModule { for (uint256 i = 0; i < sigs.length; ++i) { address signerAddr = ECDSA.recover(msgHash, sigs[i].r, sigs[i].vs); if (!_isGuardian(signerAddr)) revert InvalidSignature(); - if (signerAddr <= prevSignerAddr) revert SignatureNotSorted(); + if (signerAddr <= prevSignerAddr) revert SignaturesNotSorted(); prevSignerAddr = signerAddr; } } diff --git a/contracts/0.8.9/EIP712StETH.sol b/contracts/0.8.9/EIP712StETH.sol index 4e7055ef0..5002d0cc8 100644 --- a/contracts/0.8.9/EIP712StETH.sol +++ b/contracts/0.8.9/EIP712StETH.sol @@ -51,8 +51,8 @@ contract EIP712StETH is IEIP712StETH { constructor(address _stETH) { if (_stETH == address(0)) { revert ZeroStETHAddress(); } - bytes32 hashedName = keccak256(bytes("Liquid staked Ether 2.0")); - bytes32 hashedVersion = keccak256(bytes("2")); + bytes32 hashedName = keccak256("Liquid staked Ether 2.0"); + bytes32 hashedVersion = keccak256("2"); bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); diff --git a/contracts/0.8.9/StakingRouter.sol b/contracts/0.8.9/StakingRouter.sol index 6af21bba1..0e2404864 100644 --- a/contracts/0.8.9/StakingRouter.sol +++ b/contracts/0.8.9/StakingRouter.sol @@ -41,6 +41,10 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version error DirectETHTransfer(); error InvalidReportData(uint256 code); error ExitedValidatorsCountCannotDecrease(); + error ReportedExitedValidatorsExceedDeposited( + uint256 reportedExitedValidatorsCount, + uint256 depositedValidatorsCount + ); error StakingModulesLimitExceeded(); error StakingModuleUnregistered(); error AppAuthLidoFailed(); @@ -124,7 +128,8 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version uint256 public constant FEE_PRECISION_POINTS = 10 ** 20; // 100 * 10 ** 18 uint256 public constant TOTAL_BASIS_POINTS = 10000; uint256 public constant MAX_STAKING_MODULES_COUNT = 32; - uint256 public constant MAX_STAKING_MODULE_NAME_LENGTH = 32; + /// @dev restrict the name size with 31 bytes to storage in a single slot + uint256 public constant MAX_STAKING_MODULE_NAME_LENGTH = 31; constructor(address _depositContract) BeaconChainDepositor(_depositContract) {} @@ -319,7 +324,7 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version /// @param _stakingModuleIds Ids of the staking modules to be updated. /// @param _exitedValidatorsCounts New counts of exited validators for the specified staking modules. /// - /// @return The total increase in the aggregate number of exited validators accross all updated modules. + /// @return The total increase in the aggregate number of exited validators across all updated modules. /// /// The total numbers are stored in the staking router and can differ from the totals obtained by calling /// `IStakingModule.getStakingModuleSummary()`. The overall process of updating validator counts is the following: @@ -329,19 +334,19 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version /// distribute new stake and staking fees between the modules. There can only be single call of this function /// per oracle reporting frame. /// - /// 2. In the first part of the second data submittion phase, the oracle calls + /// 2. In the first part of the second data submission phase, the oracle calls /// `StakingRouter.reportStakingModuleStuckValidatorsCountByNodeOperator` on the staking router which passes the /// counts by node operator to the staking module by calling `IStakingModule.updateStuckValidatorsCount`. /// This can be done multiple times for the same module, passing data for different subsets of node operators. /// - /// 3. In the second part of the second data submittion phase, the oracle calls + /// 3. In the second part of the second data submission phase, the oracle calls /// `StakingRouter.reportStakingModuleExitedValidatorsCountByNodeOperator` on the staking router which passes /// the counts by node operator to the staking module by calling `IStakingModule.updateExitedValidatorsCount`. /// This can be done multiple times for the same module, passing data for different subsets of node /// operators. /// - /// 4. At the end of the second data submission phase, it's expected for the aggragate exited validators count - /// accross all module's node operators (stored in the module) to match the total count for this module + /// 4. At the end of the second data submission phase, it's expected for the aggregate exited validators count + /// across all module's node operators (stored in the module) to match the total count for this module /// (stored in the staking router). However, it might happen that the second phase of data submission doesn't /// finish until the new oracle reporting frame is started, in which case staking router will emit a warning /// event `StakingModuleExitedValidatorsIncompleteReporting` when the first data submission phase is performed @@ -349,7 +354,7 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version /// the exited and maybe stuck validator counts during the whole reporting frame. Handling this condition is /// the responsibility of each staking module. /// - /// 5. When the second reporting phase is finshed, i.e. when the oracle submitted the complete data on the stuck + /// 5. When the second reporting phase is finished, i.e. when the oracle submitted the complete data on the stuck /// and exited validator counts per node operator for the current reporting frame, the oracle calls /// `StakingRouter.onValidatorsCountsByNodeOperatorReportingFinished` which, in turn, calls /// `IStakingModule.onExitedAndStuckValidatorsCountsUpdated` on all modules. @@ -377,19 +382,26 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version revert ExitedValidatorsCountCannotDecrease(); } - newlyExitedValidatorsCount += _exitedValidatorsCounts[i] - prevReportedExitedValidatorsCount; - ( - uint256 totalExitedValidatorsCount, - /* uint256 totalDepositedValidators */, + uint256 totalExitedValidators, + uint256 totalDepositedValidators, /* uint256 depositableValidatorsCount */ ) = IStakingModule(stakingModule.stakingModuleAddress).getStakingModuleSummary(); - if (totalExitedValidatorsCount < prevReportedExitedValidatorsCount) { + if (_exitedValidatorsCounts[i] > totalDepositedValidators) { + revert ReportedExitedValidatorsExceedDeposited( + _exitedValidatorsCounts[i], + totalDepositedValidators + ); + } + + newlyExitedValidatorsCount += _exitedValidatorsCounts[i] - prevReportedExitedValidatorsCount; + + if (totalExitedValidators < prevReportedExitedValidatorsCount) { // not all of the exited validators were async reported to the module emit StakingModuleExitedValidatorsIncompleteReporting( stakingModuleId, - prevReportedExitedValidatorsCount - totalExitedValidatorsCount + prevReportedExitedValidatorsCount - totalExitedValidators ); } @@ -482,18 +494,18 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version uint256 stuckValidatorsCount, /* uint256 refundedValidatorsCount */, /* uint256 stuckPenaltyEndTimestamp */, - uint256 totalExitedValidatorsCount, + uint256 totalExitedValidators, /* uint256 totalDepositedValidators */, /* uint256 depositableValidatorsCount */ ) = IStakingModule(stakingModule.stakingModuleAddress).getNodeOperatorSummary(_nodeOperatorId); if (_correction.currentModuleExitedValidatorsCount != stakingModule.exitedValidatorsCount || - _correction.currentNodeOperatorExitedValidatorsCount != totalExitedValidatorsCount || + _correction.currentNodeOperatorExitedValidatorsCount != totalExitedValidators || _correction.currentNodeOperatorStuckValidatorsCount != stuckValidatorsCount ) { revert UnexpectedCurrentValidatorsCount( stakingModule.exitedValidatorsCount, - totalExitedValidatorsCount, + totalExitedValidators, stuckValidatorsCount ); } @@ -912,13 +924,13 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version { StakingModule storage stakingModule = _getStakingModuleById(_stakingModuleId); ( - uint256 totalExitedValidatorsCount, - uint256 totalDepositedValidatorsCount, + uint256 totalExitedValidators, + uint256 totalDepositedValidators, /* uint256 depositableValidatorsCount */ ) = IStakingModule(stakingModule.stakingModuleAddress).getStakingModuleSummary(); - activeValidatorsCount = totalDepositedValidatorsCount - Math256.max( - stakingModule.exitedValidatorsCount, totalExitedValidatorsCount + activeValidatorsCount = totalDepositedValidators - Math256.max( + stakingModule.exitedValidatorsCount, totalExitedValidators ); } @@ -1000,9 +1012,9 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version uint96 stakingModuleFee; for (uint256 i; i < stakingModulesCount; ) { - stakingModuleIds[rewardedStakingModulesCount] = stakingModulesCache[i].stakingModuleId; /// @dev skip staking modules which have no active validators if (stakingModulesCache[i].activeValidatorsCount > 0) { + stakingModuleIds[rewardedStakingModulesCount] = stakingModulesCache[i].stakingModuleId; stakingModuleValidatorsShare = ((stakingModulesCache[i].activeValidatorsCount * precisionPoints) / totalActiveValidators); recipients[rewardedStakingModulesCount] = address(stakingModulesCache[i].stakingModuleAddress); @@ -1031,11 +1043,10 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version /// @dev shrink arrays if (rewardedStakingModulesCount < stakingModulesCount) { - uint256 trim = stakingModulesCount - rewardedStakingModulesCount; assembly { - mstore(stakingModuleIds, sub(mload(stakingModuleIds), trim)) - mstore(recipients, sub(mload(recipients), trim)) - mstore(stakingModuleFees, sub(mload(stakingModuleFees), trim)) + mstore(stakingModuleIds, rewardedStakingModulesCount) + mstore(recipients, rewardedStakingModulesCount) + mstore(stakingModuleFees, rewardedStakingModulesCount) } } } @@ -1047,10 +1058,9 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version /// reduced, 1e4 precision. function getTotalFeeE4Precision() external view returns (uint16 totalFee) { /// @dev The logic is placed here but in Lido contract to save Lido bytecode - uint256 E4_BASIS_POINTS = 10000; // Corresponds to Lido.TOTAL_BASIS_POINTS (, , , uint96 totalFeeInHighPrecision, uint256 precision) = getStakingRewardsDistribution(); // Here we rely on (totalFeeInHighPrecision <= precision) - totalFee = uint16((totalFeeInHighPrecision * E4_BASIS_POINTS) / precision); + totalFee = _toE4Precision(totalFeeInHighPrecision, precision); } /// @notice Helper for Lido contract (DEPRECATED) @@ -1061,15 +1071,14 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version returns (uint16 modulesFee, uint16 treasuryFee) { /// @dev The logic is placed here but in Lido contract to save Lido bytecode - uint256 E4_BASIS_POINTS = 10000; // Corresponds to Lido.TOTAL_BASIS_POINTS ( uint256 modulesFeeHighPrecision, uint256 treasuryFeeHighPrecision, uint256 precision ) = getStakingFeeAggregateDistribution(); // Here we rely on ({modules,treasury}FeeHighPrecision <= precision) - modulesFee = uint16((modulesFeeHighPrecision * E4_BASIS_POINTS) / precision); - treasuryFee = uint16((treasuryFeeHighPrecision * E4_BASIS_POINTS) / precision); + modulesFee = _toE4Precision(modulesFeeHighPrecision, precision); + treasuryFee = _toE4Precision(treasuryFeeHighPrecision, precision); } /// @notice returns new deposits allocation after the distribution of the `_depositsCount` deposits @@ -1304,4 +1313,8 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version result.slot := position } } + + function _toE4Precision(uint256 _value, uint256 _precision) internal pure returns (uint16) { + return uint16((_value * TOTAL_BASIS_POINTS) / _precision); + } } diff --git a/contracts/0.8.9/WithdrawalQueue.sol b/contracts/0.8.9/WithdrawalQueue.sol index 162c5fed6..23caa00f6 100644 --- a/contracts/0.8.9/WithdrawalQueue.sol +++ b/contracts/0.8.9/WithdrawalQueue.sol @@ -95,7 +95,6 @@ abstract contract WithdrawalQueue is AccessControlEnumerable, PausableUntil, Wit /// @notice Resume withdrawal requests placement and finalization function resume() external { - _checkPaused(); _checkRole(RESUME_ROLE, msg.sender); _resume(); } diff --git a/contracts/0.8.9/WithdrawalQueueERC721.sol b/contracts/0.8.9/WithdrawalQueueERC721.sol index e22d8201f..67a2f1c08 100644 --- a/contracts/0.8.9/WithdrawalQueueERC721.sol +++ b/contracts/0.8.9/WithdrawalQueueERC721.sol @@ -95,7 +95,7 @@ contract WithdrawalQueueERC721 is IERC721Metadata, WithdrawalQueue { } /// @dev Se_toBytes321Metadata-name}. - function name() external view returns (string memory) { + function name() external view override returns (string memory) { return _toString(NAME); } @@ -230,7 +230,7 @@ contract WithdrawalQueueERC721 is IERC721Metadata, WithdrawalQueue { ) revert NotOwnerOrApproved(msgSender); delete _getTokenApprovals()[_requestId]; - request.owner = payable(_to); + request.owner = _to; assert(_getRequestsByOwner()[_from].remove(_requestId)); assert(_getRequestsByOwner()[_to].add(_requestId)); diff --git a/contracts/0.8.9/interfaces/IStakingModule.sol b/contracts/0.8.9/interfaces/IStakingModule.sol index f48f4a474..416f89da4 100644 --- a/contracts/0.8.9/interfaces/IStakingModule.sol +++ b/contracts/0.8.9/interfaces/IStakingModule.sol @@ -55,6 +55,9 @@ interface IStakingModule { /// 4. a node operator was activated/deactivated /// 5. a node operator's deposit data is used for the deposit /// Note: Depending on the StakingModule implementation above list might be extended + /// @dev In some scenarios, it's allowed to update nonce without actual change of the deposit + /// data subset, but it MUST NOT lead to the DOS of the staking module via continuous + /// update of the nonce by the malicious actor function getNonce() external view returns (uint256); /// @notice Returns total number of node operators @@ -130,10 +133,11 @@ interface IStakingModule { /// contract /// @dev The method MUST revert when the staking module has not enough deposit data items /// @param _depositsCount Number of deposits to be done - /// @param _calldata Staking module defined data encoded as bytes + /// @param _depositCalldata Staking module defined data encoded as bytes. + /// IMPORTANT: _depositCalldata MUST NOT modify the deposit data set of the staking module /// @return publicKeys Batch of the concatenated public validators keys /// @return signatures Batch of the concatenated deposit signatures for returned public keys - function obtainDepositData(uint256 _depositsCount, bytes calldata _calldata) + function obtainDepositData(uint256 _depositsCount, bytes calldata _depositCalldata) external returns (bytes memory publicKeys, bytes memory signatures); diff --git a/contracts/0.8.9/lib/PositiveTokenRebaseLimiter.sol b/contracts/0.8.9/lib/PositiveTokenRebaseLimiter.sol index a5e6bd052..7324c1118 100644 --- a/contracts/0.8.9/lib/PositiveTokenRebaseLimiter.sol +++ b/contracts/0.8.9/lib/PositiveTokenRebaseLimiter.sol @@ -27,6 +27,7 @@ struct TokenRebaseLimiterData { uint256 preTotalShares; // pre-rebase total shares uint256 currentTotalPooledEther; // intermediate total pooled ether amount while token rebase is in progress uint256 positiveRebaseLimit; // positive rebase limit (target value) with 1e9 precision (`LIMITER_PRECISION_BASE`) + uint256 maxTotalPooledEther; // maximum total pooled ether that still fits into the positive rebase limit (cached) } /** @@ -93,6 +94,11 @@ library PositiveTokenRebaseLimiter { limiterState.currentTotalPooledEther = limiterState.preTotalPooledEther = _preTotalPooledEther; limiterState.preTotalShares = _preTotalShares; limiterState.positiveRebaseLimit = _rebaseLimit; + + limiterState.maxTotalPooledEther = (_rebaseLimit == UNLIMITED_REBASE) + ? type(uint256).max + : limiterState.preTotalPooledEther + + (limiterState.positiveRebaseLimit * limiterState.preTotalPooledEther) / LIMITER_PRECISION_BASE; } /** @@ -101,17 +107,7 @@ library PositiveTokenRebaseLimiter { * @return true if limit is reached */ function isLimitReached(TokenRebaseLimiterData memory _limiterState) internal pure returns (bool) { - if (_limiterState.positiveRebaseLimit == UNLIMITED_REBASE) return false; - if (_limiterState.currentTotalPooledEther < _limiterState.preTotalPooledEther) return false; - - uint256 accumulatedEther = _limiterState.currentTotalPooledEther - _limiterState.preTotalPooledEther; - uint256 accumulatedRebase; - - if (_limiterState.preTotalPooledEther > 0) { - accumulatedRebase = accumulatedEther * LIMITER_PRECISION_BASE / _limiterState.preTotalPooledEther; - } - - return accumulatedRebase >= _limiterState.positiveRebaseLimit; + return _limiterState.currentTotalPooledEther >= _limiterState.maxTotalPooledEther; } /** @@ -147,11 +143,8 @@ library PositiveTokenRebaseLimiter { uint256 prevPooledEther = _limiterState.currentTotalPooledEther; _limiterState.currentTotalPooledEther += _etherAmount; - uint256 maxTotalPooledEther = _limiterState.preTotalPooledEther + - (_limiterState.positiveRebaseLimit * _limiterState.preTotalPooledEther) / LIMITER_PRECISION_BASE; - _limiterState.currentTotalPooledEther - = Math256.min(_limiterState.currentTotalPooledEther, maxTotalPooledEther); + = Math256.min(_limiterState.currentTotalPooledEther, _limiterState.maxTotalPooledEther); assert(_limiterState.currentTotalPooledEther >= prevPooledEther); diff --git a/contracts/0.8.9/lib/UnstructuredRefStorage.sol b/contracts/0.8.9/lib/UnstructuredRefStorage.sol index 322e9e51c..175981810 100644 --- a/contracts/0.8.9/lib/UnstructuredRefStorage.sol +++ b/contracts/0.8.9/lib/UnstructuredRefStorage.sol @@ -4,18 +4,6 @@ pragma solidity 0.8.9; library UnstructuredRefStorage { - function storageAddressArray(bytes32 _position) internal pure returns ( - address[] storage result - ) { - assembly { result.slot := _position } - } - - function storageMapAddressUint256(bytes32 _position) internal pure returns ( - mapping(address => uint256) storage result - ) { - assembly { result.slot := _position } - } - function storageMapUint256Address(bytes32 _position) internal pure returns ( mapping(uint256 => address) storage result ) { diff --git a/contracts/0.8.9/oracle/AccountingOracle.sol b/contracts/0.8.9/oracle/AccountingOracle.sol index 8f38f82bd..14dce0d59 100644 --- a/contracts/0.8.9/oracle/AccountingOracle.sol +++ b/contracts/0.8.9/oracle/AccountingOracle.sol @@ -258,11 +258,11 @@ contract AccountingOracle is BaseOracle { bool isBunkerMode; /// - /// Extra data — the oracle information that can be processed asynchronously in chunks - /// after the main data is processed. The oracle doesn't enforce that extra data attached - /// to some data report is processed in full before the processing deadline expires or a - /// new data report starts being processed, but enforces that no processing of extra data - /// for a report is possible after its processing deadline passes or a new data report + /// Extra data — the oracle information that allows asynchronous processing, potentially in + /// chunks, after the main data is processed. The oracle doesn't enforce that extra data + /// attached to some data report is processed in full before the processing deadline expires + /// or a new data report starts being processed, but enforces that no processing of extra + /// data for a report is possible after its processing deadline passes or a new data report /// arrives. /// /// Extra data is an array of items, each item being encoded as follows: @@ -441,7 +441,7 @@ contract AccountingOracle is BaseOracle { ConsensusReport memory report = _storageConsensusReport().value; result.currentFrameRefSlot = _getCurrentRefSlot(); - if (result.currentFrameRefSlot != report.refSlot) { + if (report.hash == bytes32(0) || result.currentFrameRefSlot != report.refSlot) { return result; } @@ -449,7 +449,7 @@ contract AccountingOracle is BaseOracle { result.mainDataHash = report.hash; uint256 processingRefSlot = LAST_PROCESSING_REF_SLOT_POSITION.getStorageUint256(); - result.mainDataSubmitted = report.hash != bytes32(0) && report.refSlot == processingRefSlot; + result.mainDataSubmitted = report.refSlot == processingRefSlot; if (!result.mainDataSubmitted) { return result; } @@ -687,12 +687,15 @@ contract AccountingOracle is BaseOracle { internal view { _checkMsgSenderIsAllowedToSubmitData(); - _checkProcessingDeadline(); - if (procState.refSlot != LAST_PROCESSING_REF_SLOT_POSITION.getStorageUint256()) { + ConsensusReport memory report = _storageConsensusReport().value; + + if (report.hash == bytes32(0) || procState.refSlot != report.refSlot) { revert CannotSubmitExtraDataBeforeMainData(); } + _checkProcessingDeadline(); + if (procState.dataFormat != format) { revert UnexpectedExtraDataFormat(procState.dataFormat, format); } diff --git a/contracts/0.8.9/oracle/BaseOracle.sol b/contracts/0.8.9/oracle/BaseOracle.sol index e44057cfc..0cfbead9c 100644 --- a/contracts/0.8.9/oracle/BaseOracle.sol +++ b/contracts/0.8.9/oracle/BaseOracle.sol @@ -39,19 +39,22 @@ abstract contract BaseOracle is IReportAsyncProcessor, AccessControlEnumerable, error AddressCannotBeSame(); error VersionCannotBeSame(); error UnexpectedChainConfig(); - error OnlyConsensusContractCanSubmitReport(); + error SenderIsNotTheConsensusContract(); error InitialRefSlotCannotBeLessThanProcessingOne(uint256 initialRefSlot, uint256 processingRefSlot); error RefSlotMustBeGreaterThanProcessingOne(uint256 refSlot, uint256 processingRefSlot); error RefSlotCannotDecrease(uint256 refSlot, uint256 prevRefSlot); + error NoConsensusReportToProcess(); error ProcessingDeadlineMissed(uint256 deadline); error RefSlotAlreadyProcessing(); error UnexpectedRefSlot(uint256 consensusRefSlot, uint256 dataRefSlot); error UnexpectedConsensusVersion(uint256 expectedVersion, uint256 receivedVersion); + error HashCannotBeZero(); error UnexpectedDataHash(bytes32 consensusHash, bytes32 receivedHash); event ConsensusHashContractSet(address indexed addr, address indexed prevAddr); event ConsensusVersionSet(uint256 indexed version, uint256 indexed prevVersion); event ReportSubmitted(uint256 indexed refSlot, bytes32 hash, uint256 processingDeadlineTime); + event ReportDiscarded(uint256 indexed refSlot, bytes32 hash); event ProcessingStarted(uint256 indexed refSlot, bytes32 hash); event WarnProcessingMissed(uint256 indexed refSlot); @@ -156,15 +159,14 @@ abstract contract BaseOracle is IReportAsyncProcessor, AccessControlEnumerable, /// @notice Called by HashConsensus contract to push a consensus report for processing. /// - /// Note that submitting the report doesn't require the oracle to start processing it - /// right away, this can happen later. Until the processing is started, HashConsensus is - /// free to reach consensus on another report for the same reporting frame and submit it - /// using this same function. + /// Note that submitting the report doesn't require the processor to start processing it right + /// away, this can happen later (see `getLastProcessingRefSlot`). Until processing is started, + /// HashConsensus is free to reach consensus on another report for the same reporting frame an + /// submit it using this same function, or to lose the consensus on the submitted report, + /// notifying the processor via `discardConsensusReport`. /// function submitConsensusReport(bytes32 reportHash, uint256 refSlot, uint256 deadline) external { - if (_msgSender() != CONSENSUS_CONTRACT_POSITION.getStorageAddress()) { - revert OnlyConsensusContractCanSubmitReport(); - } + _checkSenderIsConsensusContract(); uint256 prevSubmittedRefSlot = _storageConsensusReport().value.refSlot; if (refSlot < prevSubmittedRefSlot) { @@ -176,10 +178,18 @@ abstract contract BaseOracle is IReportAsyncProcessor, AccessControlEnumerable, revert RefSlotMustBeGreaterThanProcessingOne(refSlot, prevProcessingRefSlot); } + if (_getTime() > deadline) { + revert ProcessingDeadlineMissed(deadline); + } + if (refSlot != prevSubmittedRefSlot && prevProcessingRefSlot != prevSubmittedRefSlot) { emit WarnProcessingMissed(prevSubmittedRefSlot); } + if (reportHash == bytes32(0)) { + revert HashCannotBeZero(); + } + emit ReportSubmitted(refSlot, reportHash, deadline); ConsensusReport memory report = ConsensusReport({ @@ -192,6 +202,41 @@ abstract contract BaseOracle is IReportAsyncProcessor, AccessControlEnumerable, _handleConsensusReport(report, prevSubmittedRefSlot, prevProcessingRefSlot); } + /// @notice Called by HashConsensus contract to notify that the report for the given ref. slot + /// is not a conensus report anymore and should be discarded. This can happen when a member + /// changes their report, is removed from the set, or when the quorum value gets increased. + /// + /// Only called when, for the given reference slot: + /// + /// 1. there previously was a consensus report; AND + /// 1. processing of the consensus report hasn't started yet; AND + /// 2. report processing deadline is not expired yet; AND + /// 3. there's no consensus report now (otherwise, `submitConsensusReport` is called instead). + /// + /// Can be called even when there's no submitted non-discarded consensus report for the current + /// reference slot, i.e. can be called multiple times in succession. + /// + function discardConsensusReport(uint256 refSlot) external { + _checkSenderIsConsensusContract(); + + ConsensusReport memory submittedReport = _storageConsensusReport().value; + if (refSlot < submittedReport.refSlot) { + revert RefSlotCannotDecrease(refSlot, submittedReport.refSlot); + } else if (refSlot > submittedReport.refSlot) { + return; + } + + uint256 lastProcessingRefSlot = LAST_PROCESSING_REF_SLOT_POSITION.getStorageUint256(); + if (refSlot <= lastProcessingRefSlot) { + revert RefSlotAlreadyProcessing(); + } + + _storageConsensusReport().value.hash = bytes32(0); + _handleConsensusReportDiscarded(submittedReport); + + emit ReportDiscarded(submittedReport.refSlot, submittedReport.hash); + } + /// @notice Returns the last reference slot for which processing of the report was started. /// function getLastProcessingRefSlot() external view returns (uint256) { @@ -224,11 +269,12 @@ abstract contract BaseOracle is IReportAsyncProcessor, AccessControlEnumerable, return IConsensusContract(consensus).getIsMember(addr); } - /// @notice Called when oracle gets a new consensus report from the HashConsensus contract. + /// @notice Called when the oracle gets a new consensus report from the HashConsensus contract. /// /// Keep in mind that, until you call `_startProcessing`, the oracle committee is free to /// reach consensus on another report for the same reporting frame and re-submit it using - /// this function. + /// this function, or lose consensus on the report and ask to discard it by calling the + /// `_handleConsensusReportDiscarded` function. /// function _handleConsensusReport( ConsensusReport memory report, @@ -236,15 +282,18 @@ abstract contract BaseOracle is IReportAsyncProcessor, AccessControlEnumerable, uint256 prevProcessingRefSlot ) internal virtual; + /// @notice Called when the HashConsensus contract loses consensus on a previously submitted + /// report that is not processing yet and asks to discard this report. Only called if there is + /// no new consensus report at the moment; otherwise, `_handleConsensusReport` is called instead. + /// + function _handleConsensusReportDiscarded(ConsensusReport memory report) internal virtual {} + /// @notice May be called by a descendant contract to check if the received data matches - /// the currently submitted consensus report, and that processing deadline is not missed. - /// Reverts otherwise. + /// the currently submitted consensus report. Reverts otherwise. /// function _checkConsensusData(uint256 refSlot, uint256 consensusVersion, bytes32 hash) internal view { - _checkProcessingDeadline(); - ConsensusReport memory report = _storageConsensusReport().value; if (refSlot != report.refSlot) { revert UnexpectedRefSlot(report.refSlot, refSlot); @@ -269,9 +318,12 @@ abstract contract BaseOracle is IReportAsyncProcessor, AccessControlEnumerable, /// the consensus report for the current frame is guaranteed to remain the same. /// function _startProcessing() internal returns (uint256) { - _checkProcessingDeadline(); - ConsensusReport memory report = _storageConsensusReport().value; + if (report.hash == bytes32(0)) { + revert NoConsensusReportToProcess(); + } + + _checkProcessingDeadline(report.processingDeadlineTime); uint256 prevProcessingRefSlot = LAST_PROCESSING_REF_SLOT_POSITION.getStorageUint256(); if (prevProcessingRefSlot == report.refSlot) { @@ -287,8 +339,11 @@ abstract contract BaseOracle is IReportAsyncProcessor, AccessControlEnumerable, /// @notice Reverts if the processing deadline for the current consensus report is missed. /// function _checkProcessingDeadline() internal view { - uint256 deadline = _storageConsensusReport().value.processingDeadlineTime; - if (_getTime() > deadline) revert ProcessingDeadlineMissed(deadline); + _checkProcessingDeadline(_storageConsensusReport().value.processingDeadlineTime); + } + + function _checkProcessingDeadline(uint256 deadlineTime) internal view { + if (_getTime() > deadlineTime) revert ProcessingDeadlineMissed(deadlineTime); } /// @notice Returns the reference slot for the current frame. @@ -330,6 +385,12 @@ abstract contract BaseOracle is IReportAsyncProcessor, AccessControlEnumerable, emit ConsensusHashContractSet(addr, prevAddr); } + function _checkSenderIsConsensusContract() internal view { + if (_msgSender() != CONSENSUS_CONTRACT_POSITION.getStorageAddress()) { + revert SenderIsNotTheConsensusContract(); + } + } + function _getTime() internal virtual view returns (uint256) { return block.timestamp; // solhint-disable-line not-rely-on-time } diff --git a/contracts/0.8.9/oracle/HashConsensus.sol b/contracts/0.8.9/oracle/HashConsensus.sol index 4974f6070..d2c81aa39 100644 --- a/contracts/0.8.9/oracle/HashConsensus.sol +++ b/contracts/0.8.9/oracle/HashConsensus.sol @@ -14,8 +14,9 @@ import { AccessControlEnumerable } from "../utils/access/AccessControlEnumerable /// HashConsensus doesn't expect any specific behavior from a report processor, and guarantees /// the following: /// -/// 1. HashConsensus won't submit reports via `IReportAsyncProcessor.submitConsensusReport` for the -/// slot returned from `IReportAsyncProcessor.getLastProcessingRefSlot` and any slot preceding it. +/// 1. HashConsensus won't submit reports via `IReportAsyncProcessor.submitConsensusReport` or ask +/// to discard reports via `IReportAsyncProcessor.discardConsensusReport` for any slot up to (and +/// including) the slot returned from `IReportAsyncProcessor.getLastProcessingRefSlot`. /// /// 2. HashConsensus won't accept member reports (and thus won't include such reports in calculating /// the consensus) that have `consensusVersion` argument of the `HashConsensus.submitReport` call @@ -25,13 +26,30 @@ import { AccessControlEnumerable } from "../utils/access/AccessControlEnumerable interface IReportAsyncProcessor { /// @notice Submits a consensus report for processing. /// - /// Note that submitting the report doesn't require the processor to start processing it - /// right away, this can happen later. Until the processing is started, HashConsensus is - /// free to reach consensus on another report for the same reporting frame and submit it - /// using this same function. + /// Note that submitting the report doesn't require the processor to start processing it right + /// away, this can happen later (see `getLastProcessingRefSlot`). Until processing is started, + /// HashConsensus is free to reach consensus on another report for the same reporting frame an + /// submit it using this same function, or to lose the consensus on the submitted report, + /// notifying the processor via `discardConsensusReport`. /// function submitConsensusReport(bytes32 report, uint256 refSlot, uint256 deadline) external; + /// @notice Notifies that the report for the given ref. slot is not a conensus report anymore + /// and should be discarded. This can happen when a member changes their report, is removed + /// from the set, or when the quorum value gets increased. + /// + /// Only called when, for the given reference slot: + /// + /// 1. there previously was a consensus report; AND + /// 1. processing of the consensus report hasn't started yet; AND + /// 2. report processing deadline is not expired yet; AND + /// 3. there's no consensus report now (otherwise, `submitConsensusReport` is called instead). + /// + /// Can be called even when there's no submitted non-discarded consensus report for the current + /// reference slot, i.e. can be called multiple times in succession. + /// + function discardConsensusReport(uint256 refSlot) external; + /// @notice Returns the last reference slot for which processing of the report was started. /// /// HashConsensus won't submit reports for any slot less than or equal to this slot. @@ -70,6 +88,7 @@ interface IReportAsyncProcessor { contract HashConsensus is AccessControlEnumerable { using SafeCast for uint256; + error InvalidChainConfig(); error NumericOverflow(); error AdminCannotBeZero(); error ReportProcessorCannotBeZero(); @@ -98,6 +117,7 @@ contract HashConsensus is AccessControlEnumerable { event QuorumSet(uint256 newQuorum, uint256 totalMembers, uint256 prevQuorum); event ReportReceived(uint256 indexed refSlot, address indexed member, bytes32 report); event ConsensusReached(uint256 indexed refSlot, bytes32 report, uint256 support); + event ConsensusLost(uint256 indexed refSlot); event ReportProcessorSet(address indexed processor, address indexed prevProcessor); struct FrameConfig { @@ -106,14 +126,21 @@ contract HashConsensus is AccessControlEnumerable { uint64 fastLaneLengthSlots; } - /// @dev Oracle reporting is divided into frames, each lasting the same number of slots + /// @dev Oracle reporting is divided into frames, each lasting the same number of slots. + /// + /// The start slot of the next frame is always the next slot after the end slot of the previous + /// frame. + /// + /// Each frame also has a reference slot: if the oracle report contains any data derived from + /// onchain data, the onchain data should be sampled at the reference slot. + /// struct ConsensusFrame { // frame index; increments by 1 with each frame but resets to zero on frame size change uint256 index; // the slot at which to read the state around which consensus is being reached; // if the slot contains a block, the state should include all changes from that block uint256 refSlot; - // the last slot at which a report can be processed + // the last slot at which a report can be reported and processed uint256 reportProcessingDeadlineSlot; } @@ -171,6 +198,12 @@ contract HashConsensus is AccessControlEnumerable { uint256 internal constant UNREACHABLE_QUORUM = type(uint256).max; bytes32 internal constant ZERO_HASH = bytes32(0); + /// @dev An offset from the processing deadline slot of the previous frame (i.e. the last slot + /// at which a report for the prev. frame can be submitted and its processing started) to the + /// reference slot of the next frame (equal to the last slot of the previous frame). + /// frame[i].reportProcessingDeadlineSlot := frame[i + 1].refSlot - DEADLINE_SLOT_OFFSET + uint256 internal constant DEADLINE_SLOT_OFFSET = 0; + /// @dev Reporting frame configuration FrameConfig internal _frameConfig; @@ -213,6 +246,9 @@ contract HashConsensus is AccessControlEnumerable { address admin, address reportProcessor ) { + if (slotsPerEpoch == 0) revert InvalidChainConfig(); + if (secondsPerSlot == 0) revert InvalidChainConfig(); + SLOTS_PER_EPOCH = slotsPerEpoch.toUint64(); SECONDS_PER_SLOT = secondsPerSlot.toUint64(); GENESIS_TIME = genesisTime.toUint64(); @@ -606,11 +642,7 @@ contract HashConsensus is AccessControlEnumerable { } function _getCurrentFrame() internal view returns (ConsensusFrame memory) { - return _getCurrentFrame(_frameConfig); - } - - function _getCurrentFrame(FrameConfig memory config) internal view returns (ConsensusFrame memory) { - return _getFrameAtTimestamp(_getTime(), config); + return _getFrameAtTimestamp(_getTime(), _frameConfig); } function _getInitialFrame() internal view returns (ConsensusFrame memory) { @@ -633,7 +665,7 @@ contract HashConsensus is AccessControlEnumerable { return ConsensusFrame({ index: frameIndex, refSlot: uint64(frameStartSlot - 1), - reportProcessingDeadlineSlot: uint64(nextFrameStartSlot - 1) + reportProcessingDeadlineSlot: uint64(nextFrameStartSlot - 1 - DEADLINE_SLOT_OFFSET) }); } @@ -739,14 +771,17 @@ contract HashConsensus is AccessControlEnumerable { emit MemberRemoved(addr, newTotalMembers, quorum); - ConsensusFrame memory frame = _getCurrentFrame(); + if (memberState.lastReportRefSlot > 0) { + // member reported at least once + ConsensusFrame memory frame = _getCurrentFrame(); - if (memberState.lastReportRefSlot == frame.refSlot && - _getLastProcessingRefSlot() < frame.refSlot - ) { - // member reported for the current ref. slot and the consensus report - // is not processing yet => need to cancel the member's report - --_reportVariants[memberState.lastReportVariantIndex].support; + if (memberState.lastReportRefSlot == frame.refSlot && + _getLastProcessingRefSlot() < frame.refSlot + ) { + // member reported for the current ref. slot and the consensus report + // is not processing yet => need to cancel the member's report + --_reportVariants[memberState.lastReportVariantIndex].support; + } } _setQuorumAndCheckConsensus(quorum, newTotalMembers); @@ -768,9 +803,13 @@ contract HashConsensus is AccessControlEnumerable { function _getFastLaneSubset(uint256 frameIndex, uint256 totalMembers) internal view returns (uint256 startIndex, uint256 pastEndIndex) { - if (totalMembers != 0) { + uint256 quorum = _quorum; + if (quorum >= totalMembers) { + startIndex = 0; + pastEndIndex = totalMembers; + } else { startIndex = frameIndex % totalMembers; - pastEndIndex = startIndex + _quorum; + pastEndIndex = startIndex + quorum; } } @@ -819,7 +858,9 @@ contract HashConsensus is AccessControlEnumerable { /// function _submitReport(uint256 slot, bytes32 report, uint256 consensusVersion) internal { + if (slot == 0) revert InvalidSlot(); if (slot > type(uint64).max) revert NumericOverflow(); + if (report == ZERO_HASH) revert EmptyReport(); uint256 memberIndex = _getMemberIndex(_msgSender()); MemberState memory memberState = _memberStates[memberIndex]; @@ -834,7 +875,6 @@ contract HashConsensus is AccessControlEnumerable { FrameConfig memory config = _frameConfig; ConsensusFrame memory frame = _getFrameAtTimestamp(timestamp, config); - if (report == ZERO_HASH) revert EmptyReport(); if (slot != frame.refSlot) revert InvalidSlot(); if (currentSlot > frame.reportProcessingDeadlineSlot) revert StaleReport(); @@ -866,7 +906,7 @@ contract HashConsensus is AccessControlEnumerable { } uint64 varIndex = 0; - uint64 support; + bool prevConsensusLost = false; while (varIndex < variantsLength && _reportVariants[varIndex].hash != report) { ++varIndex; @@ -878,10 +918,15 @@ contract HashConsensus is AccessControlEnumerable { if (varIndex == prevVarIndex) { revert DuplicateReport(); } else { - --_reportVariants[prevVarIndex].support; + uint256 support = --_reportVariants[prevVarIndex].support; + if (support == _quorum - 1) { + prevConsensusLost = true; + } } } + uint256 support; + if (varIndex < variantsLength) { support = ++_reportVariants[varIndex].support; } else { @@ -899,6 +944,8 @@ contract HashConsensus is AccessControlEnumerable { if (support >= _quorum) { _consensusReached(frame, report, varIndex, support); + } else if (prevConsensusLost) { + _consensusNotReached(frame); } } @@ -913,10 +960,16 @@ contract HashConsensus is AccessControlEnumerable { ) { _reportingState.lastConsensusRefSlot = uint64(frame.refSlot); _reportingState.lastConsensusVariantIndex = uint64(variantIndex); - + emit ConsensusReached(frame.refSlot, report, support); _submitReportForProcessing(frame, report); + } + } - emit ConsensusReached(frame.refSlot, report, support); + function _consensusNotReached(ConsensusFrame memory frame) internal { + if (_reportingState.lastConsensusRefSlot == frame.refSlot) { + _reportingState.lastConsensusRefSlot = 0; + emit ConsensusLost(frame.refSlot); + _cancelReportProcessing(frame); } } @@ -938,8 +991,7 @@ contract HashConsensus is AccessControlEnumerable { emit QuorumSet(quorum, totalMembers, prevQuorum); } - if (quorum < prevQuorum) { - // consensus can only change as the result of the quorum being decreased + if (_computeEpochAtTimestamp(_getTime()) >= _frameConfig.initialEpoch) { _checkConsensus(quorum); } } @@ -949,12 +1001,12 @@ contract HashConsensus is AccessControlEnumerable { ConsensusFrame memory frame = _getFrameAtTimestamp(timestamp, _frameConfig); if (_computeSlotAtTimestamp(timestamp) > frame.reportProcessingDeadlineSlot) { - // reference slot is not reportable anymore + // a report for the current ref. slot cannot be processed anymore return; } if (_getLastProcessingRefSlot() >= frame.refSlot) { - // consensus report for the current ref. slot already processing + // a consensus report for the current ref. slot is already being processed return; } @@ -963,6 +1015,8 @@ contract HashConsensus is AccessControlEnumerable { if (consensusVariantIndex >= 0) { _consensusReached(frame, consensusReport, uint256(consensusVariantIndex), support); + } else { + _consensusNotReached(frame); } } @@ -979,12 +1033,13 @@ contract HashConsensus is AccessControlEnumerable { report = ZERO_HASH; support = 0; - for (uint256 i = 0; i < variantsLength && report == ZERO_HASH; ++i) { + for (uint256 i = 0; i < variantsLength; ++i) { uint256 iSupport = _reportVariants[i].support; if (iSupport >= quorum) { variantIndex = int256(i); report = _reportVariants[i].hash; support = iSupport; + break; } } @@ -1031,6 +1086,10 @@ contract HashConsensus is AccessControlEnumerable { ); } + function _cancelReportProcessing(ConsensusFrame memory frame) internal { + IReportAsyncProcessor(_reportProcessor).discardConsensusReport(frame.refSlot); + } + function _getConsensusVersion() internal view returns (uint256) { return IReportAsyncProcessor(_reportProcessor).getConsensusVersion(); } diff --git a/contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol b/contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol index d55120563..1937aff61 100644 --- a/contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol +++ b/contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol @@ -163,9 +163,6 @@ contract ValidatorsExitBusOracle is BaseOracle, PausableUntil { /// @dev Total number of validator exit requests in this report. Must not be greater /// than limit checked in OracleReportSanityChecker.checkExitBusOracleReport. - /// - /// Cannot be zero: in the case there's no validator exit requests to submit, oracles - /// should skip submitting the report for the current reporting frame. uint256 requestsCount; /// @dev Format of the validator exit requests data. Currently, only the @@ -285,7 +282,7 @@ contract ValidatorsExitBusOracle is BaseOracle, PausableUntil { ConsensusReport memory report = _storageConsensusReport().value; result.currentFrameRefSlot = _getCurrentRefSlot(); - if (result.currentFrameRefSlot != report.refSlot) { + if (report.hash == bytes32(0) || result.currentFrameRefSlot != report.refSlot) { return result; } @@ -364,7 +361,7 @@ contract ValidatorsExitBusOracle is BaseOracle, PausableUntil { ); } - function _processExitRequestsList(bytes calldata data) internal returns (uint256) { + function _processExitRequestsList(bytes calldata data) internal { uint256 offset; uint256 offsetPastEnd; assembly { @@ -436,8 +433,6 @@ contract ValidatorsExitBusOracle is BaseOracle, PausableUntil { if (lastNodeOpKey != 0) { _storageLastRequestedValidatorIndices()[lastNodeOpKey] = lastRequestedVal; } - - return lastDataWithoutPubkey; } function _computeNodeOpKey(uint256 moduleId, uint256 nodeOpId) internal pure returns (uint256) { diff --git a/contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol b/contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol index 023c9654b..8ebccb9f3 100644 --- a/contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol +++ b/contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol @@ -102,8 +102,8 @@ contract OracleReportSanityChecker is AccessControlEnumerable { using PositiveTokenRebaseLimiter for TokenRebaseLimiterData; bytes32 public constant ALL_LIMITS_MANAGER_ROLE = keccak256("ALL_LIMITS_MANAGER_ROLE"); - bytes32 public constant CHURN_VALIDATORS_PER_DAY_LIMIT_MANGER_ROLE = - keccak256("CHURN_VALIDATORS_PER_DAY_LIMIT_MANGER_ROLE"); + bytes32 public constant CHURN_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE = + keccak256("CHURN_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE"); bytes32 public constant ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE = keccak256("ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE"); bytes32 public constant ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE = @@ -151,13 +151,14 @@ contract OracleReportSanityChecker is AccessControlEnumerable { LimitsList memory _limitsList, ManagersRoster memory _managersRoster ) { + if (_admin == address(0)) revert AdminCannotBeZero(); LIDO_LOCATOR = ILidoLocator(_lidoLocator); _updateLimits(_limitsList); _grantRole(DEFAULT_ADMIN_ROLE, _admin); _grantRole(ALL_LIMITS_MANAGER_ROLE, _managersRoster.allLimitsManagers); - _grantRole(CHURN_VALIDATORS_PER_DAY_LIMIT_MANGER_ROLE, _managersRoster.churnValidatorsPerDayLimitManagers); + _grantRole(CHURN_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE, _managersRoster.churnValidatorsPerDayLimitManagers); _grantRole(ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE, _managersRoster.oneOffCLBalanceDecreaseLimitManagers); _grantRole(ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE, _managersRoster.annualBalanceIncreaseLimitManagers); @@ -219,9 +220,8 @@ contract OracleReportSanityChecker is AccessControlEnumerable { /// @param _churnValidatorsPerDayLimit new churnValidatorsPerDayLimit value function setChurnValidatorsPerDayLimit(uint256 _churnValidatorsPerDayLimit) external - onlyRole(CHURN_VALIDATORS_PER_DAY_LIMIT_MANGER_ROLE) + onlyRole(CHURN_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE) { - _checkLimitValue(_churnValidatorsPerDayLimit, type(uint16).max); LimitsList memory limitsList = _limits.unpack(); limitsList.churnValidatorsPerDayLimit = _churnValidatorsPerDayLimit; _updateLimits(limitsList); @@ -233,7 +233,6 @@ contract OracleReportSanityChecker is AccessControlEnumerable { external onlyRole(ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE) { - _checkLimitValue(_oneOffCLBalanceDecreaseBPLimit, MAX_BASIS_POINTS); LimitsList memory limitsList = _limits.unpack(); limitsList.oneOffCLBalanceDecreaseBPLimit = _oneOffCLBalanceDecreaseBPLimit; _updateLimits(limitsList); @@ -245,7 +244,6 @@ contract OracleReportSanityChecker is AccessControlEnumerable { external onlyRole(ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE) { - _checkLimitValue(_annualBalanceIncreaseBPLimit, MAX_BASIS_POINTS); LimitsList memory limitsList = _limits.unpack(); limitsList.annualBalanceIncreaseBPLimit = _annualBalanceIncreaseBPLimit; _updateLimits(limitsList); @@ -257,7 +255,6 @@ contract OracleReportSanityChecker is AccessControlEnumerable { external onlyRole(SHARE_RATE_DEVIATION_LIMIT_MANAGER_ROLE) { - _checkLimitValue(_simulatedShareRateDeviationBPLimit, MAX_BASIS_POINTS); LimitsList memory limitsList = _limits.unpack(); limitsList.simulatedShareRateDeviationBPLimit = _simulatedShareRateDeviationBPLimit; _updateLimits(limitsList); @@ -269,7 +266,6 @@ contract OracleReportSanityChecker is AccessControlEnumerable { external onlyRole(MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT_ROLE) { - _checkLimitValue(_maxValidatorExitRequestsPerReport, type(uint16).max); LimitsList memory limitsList = _limits.unpack(); limitsList.maxValidatorExitRequestsPerReport = _maxValidatorExitRequestsPerReport; _updateLimits(limitsList); @@ -281,7 +277,6 @@ contract OracleReportSanityChecker is AccessControlEnumerable { external onlyRole(REQUEST_TIMESTAMP_MARGIN_MANAGER_ROLE) { - _checkLimitValue(_requestTimestampMargin, type(uint64).max); LimitsList memory limitsList = _limits.unpack(); limitsList.requestTimestampMargin = _requestTimestampMargin; _updateLimits(limitsList); @@ -298,7 +293,6 @@ contract OracleReportSanityChecker is AccessControlEnumerable { external onlyRole(MAX_POSITIVE_TOKEN_REBASE_MANAGER_ROLE) { - _checkLimitValue(_maxPositiveTokenRebase, type(uint64).max); LimitsList memory limitsList = _limits.unpack(); limitsList.maxPositiveTokenRebase = _maxPositiveTokenRebase; _updateLimits(limitsList); @@ -310,7 +304,6 @@ contract OracleReportSanityChecker is AccessControlEnumerable { external onlyRole(MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT_ROLE) { - _checkLimitValue(_maxAccountingExtraDataListItemsCount, type(uint16).max); LimitsList memory limitsList = _limits.unpack(); limitsList.maxAccountingExtraDataListItemsCount = _maxAccountingExtraDataListItemsCount; _updateLimits(limitsList); @@ -322,7 +315,6 @@ contract OracleReportSanityChecker is AccessControlEnumerable { external onlyRole(MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT_ROLE) { - _checkLimitValue(_maxNodeOperatorsPerExtraDataItemCount, type(uint16).max); LimitsList memory limitsList = _limits.unpack(); limitsList.maxNodeOperatorsPerExtraDataItemCount = _maxNodeOperatorsPerExtraDataItemCount; _updateLimits(limitsList); @@ -667,47 +659,47 @@ contract OracleReportSanityChecker is AccessControlEnumerable { function _updateLimits(LimitsList memory _newLimitsList) internal { LimitsList memory _oldLimitsList = _limits.unpack(); if (_oldLimitsList.churnValidatorsPerDayLimit != _newLimitsList.churnValidatorsPerDayLimit) { - _checkLimitValue(_newLimitsList.churnValidatorsPerDayLimit, type(uint16).max); + _checkLimitValue(_newLimitsList.churnValidatorsPerDayLimit, 0, type(uint16).max); emit ChurnValidatorsPerDayLimitSet(_newLimitsList.churnValidatorsPerDayLimit); } if (_oldLimitsList.oneOffCLBalanceDecreaseBPLimit != _newLimitsList.oneOffCLBalanceDecreaseBPLimit) { - _checkLimitValue(_newLimitsList.oneOffCLBalanceDecreaseBPLimit, MAX_BASIS_POINTS); + _checkLimitValue(_newLimitsList.oneOffCLBalanceDecreaseBPLimit, 0, MAX_BASIS_POINTS); emit OneOffCLBalanceDecreaseBPLimitSet(_newLimitsList.oneOffCLBalanceDecreaseBPLimit); } if (_oldLimitsList.annualBalanceIncreaseBPLimit != _newLimitsList.annualBalanceIncreaseBPLimit) { - _checkLimitValue(_newLimitsList.annualBalanceIncreaseBPLimit, MAX_BASIS_POINTS); + _checkLimitValue(_newLimitsList.annualBalanceIncreaseBPLimit, 0, MAX_BASIS_POINTS); emit AnnualBalanceIncreaseBPLimitSet(_newLimitsList.annualBalanceIncreaseBPLimit); } if (_oldLimitsList.simulatedShareRateDeviationBPLimit != _newLimitsList.simulatedShareRateDeviationBPLimit) { - _checkLimitValue(_newLimitsList.simulatedShareRateDeviationBPLimit, MAX_BASIS_POINTS); + _checkLimitValue(_newLimitsList.simulatedShareRateDeviationBPLimit, 0, MAX_BASIS_POINTS); emit SimulatedShareRateDeviationBPLimitSet(_newLimitsList.simulatedShareRateDeviationBPLimit); } if (_oldLimitsList.maxValidatorExitRequestsPerReport != _newLimitsList.maxValidatorExitRequestsPerReport) { - _checkLimitValue(_newLimitsList.maxValidatorExitRequestsPerReport, type(uint16).max); + _checkLimitValue(_newLimitsList.maxValidatorExitRequestsPerReport, 0, type(uint16).max); emit MaxValidatorExitRequestsPerReportSet(_newLimitsList.maxValidatorExitRequestsPerReport); } if (_oldLimitsList.maxAccountingExtraDataListItemsCount != _newLimitsList.maxAccountingExtraDataListItemsCount) { - _checkLimitValue(_newLimitsList.maxAccountingExtraDataListItemsCount, type(uint16).max); + _checkLimitValue(_newLimitsList.maxAccountingExtraDataListItemsCount, 0, type(uint16).max); emit MaxAccountingExtraDataListItemsCountSet(_newLimitsList.maxAccountingExtraDataListItemsCount); } if (_oldLimitsList.maxNodeOperatorsPerExtraDataItemCount != _newLimitsList.maxNodeOperatorsPerExtraDataItemCount) { - _checkLimitValue(_newLimitsList.maxNodeOperatorsPerExtraDataItemCount, type(uint16).max); + _checkLimitValue(_newLimitsList.maxNodeOperatorsPerExtraDataItemCount, 0, type(uint16).max); emit MaxNodeOperatorsPerExtraDataItemCountSet(_newLimitsList.maxNodeOperatorsPerExtraDataItemCount); } if (_oldLimitsList.requestTimestampMargin != _newLimitsList.requestTimestampMargin) { - _checkLimitValue(_newLimitsList.requestTimestampMargin, type(uint64).max); + _checkLimitValue(_newLimitsList.requestTimestampMargin, 0, type(uint64).max); emit RequestTimestampMarginSet(_newLimitsList.requestTimestampMargin); } if (_oldLimitsList.maxPositiveTokenRebase != _newLimitsList.maxPositiveTokenRebase) { - _checkLimitValue(_newLimitsList.maxPositiveTokenRebase, type(uint64).max); + _checkLimitValue(_newLimitsList.maxPositiveTokenRebase, 1, type(uint64).max); emit MaxPositiveTokenRebaseSet(_newLimitsList.maxPositiveTokenRebase); } _limits = _newLimitsList.pack(); } - function _checkLimitValue(uint256 _value, uint256 _maxAllowedValue) internal pure { - if (_value > _maxAllowedValue) { - revert IncorrectLimitValue(_value, _maxAllowedValue); + function _checkLimitValue(uint256 _value, uint256 _minAllowedValue, uint256 _maxAllowedValue) internal pure { + if (_value > _maxAllowedValue || _value < _minAllowedValue) { + revert IncorrectLimitValue(_value, _minAllowedValue, _maxAllowedValue); } } @@ -721,7 +713,7 @@ contract OracleReportSanityChecker is AccessControlEnumerable { event MaxNodeOperatorsPerExtraDataItemCountSet(uint256 maxNodeOperatorsPerExtraDataItemCount); event RequestTimestampMarginSet(uint256 requestTimestampMargin); - error IncorrectLimitValue(uint256 value, uint256 maxAllowedValue); + error IncorrectLimitValue(uint256 value, uint256 minAllowedValue, uint256 maxAllowedValue); error IncorrectWithdrawalsVaultBalance(uint256 actualWithdrawalVaultBalance); error IncorrectELRewardsVaultBalance(uint256 actualELRewardsVaultBalance); error IncorrectSharesRequestedToBurn(uint256 actualSharesToBurn); @@ -737,6 +729,7 @@ contract OracleReportSanityChecker is AccessControlEnumerable { error MaxAccountingExtraDataItemsCountExceeded(uint256 maxItemsCount, uint256 receivedItemsCount); error ExitedValidatorsLimitExceeded(uint256 limitPerDay, uint256 exitedPerDay); error TooManyNodeOpsPerExtraDataItem(uint256 itemIndex, uint256 nodeOpsCount); + error AdminCannotBeZero(); } library LimitsListPacker { diff --git a/contracts/0.8.9/test_helpers/StakingModuleMock.sol b/contracts/0.8.9/test_helpers/StakingModuleMock.sol index 718a12a6e..05ede6be6 100644 --- a/contracts/0.8.9/test_helpers/StakingModuleMock.sol +++ b/contracts/0.8.9/test_helpers/StakingModuleMock.sol @@ -30,7 +30,7 @@ contract StakingModuleMock is IStakingModule { uint256 depositableValidatorsCount ) { totalExitedValidators = _exitedValidatorsCount; - totalDepositedValidators = _activeValidatorsCount; + totalDepositedValidators = _exitedValidatorsCount + _activeValidatorsCount; depositableValidatorsCount = _availableValidatorsCount; } diff --git a/contracts/0.8.9/test_helpers/oracle/BaseOracleTimeTravellable.sol b/contracts/0.8.9/test_helpers/oracle/BaseOracleTimeTravellable.sol index 82f7d7981..11097844b 100644 --- a/contracts/0.8.9/test_helpers/oracle/BaseOracleTimeTravellable.sol +++ b/contracts/0.8.9/test_helpers/oracle/BaseOracleTimeTravellable.sol @@ -2,8 +2,8 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.9; -import {UnstructuredStorage} from "../../lib/UnstructuredStorage.sol"; -import {BaseOracle} from "../../oracle/BaseOracle.sol"; +import { UnstructuredStorage } from "../../lib/UnstructuredStorage.sol"; +import { BaseOracle } from "../../oracle/BaseOracle.sol"; struct ConsensusReport { bytes32 hash; @@ -17,7 +17,6 @@ contract BaseOracleTimeTravellable is BaseOracle { event MockStartProcessingResult(uint256 prevProcessingRefSlot); - struct HandleConsensusReportLastCall { ConsensusReport report; uint256 prevSubmittedRefSlot; @@ -25,14 +24,26 @@ contract BaseOracleTimeTravellable is BaseOracle { uint256 callCount; } HandleConsensusReportLastCall internal _handleConsensusReportLastCall; + ConsensusReport public lastDiscardedReport; - constructor(uint256 secondsPerSlot, uint256 genesisTime, address admin) BaseOracle(secondsPerSlot, genesisTime) { + constructor( + uint256 secondsPerSlot, + uint256 genesisTime, + address admin + ) BaseOracle(secondsPerSlot, genesisTime) { _setupRole(DEFAULT_ADMIN_ROLE, admin); CONTRACT_VERSION_POSITION.setStorageUint256(0); - require(genesisTime <= _time, "GENESIS_TIME_CANNOT_BE_MORE_THAN_MOCK_TIME"); + require( + genesisTime <= _time, + "GENESIS_TIME_CANNOT_BE_MORE_THAN_MOCK_TIME" + ); } - function initialize(address consensusContract, uint256 consensusVersion, uint256 lastProcessingRefSlot) external { + function initialize( + address consensusContract, + uint256 consensusVersion, + uint256 lastProcessingRefSlot + ) external { _initialize(consensusContract, consensusVersion, lastProcessingRefSlot); } @@ -58,12 +69,24 @@ contract BaseOracleTimeTravellable is BaseOracle { uint256 prevProcessingRefSlot ) internal virtual override { _handleConsensusReportLastCall.report = report; - _handleConsensusReportLastCall.prevSubmittedRefSlot = prevSubmittedRefSlot; - _handleConsensusReportLastCall.prevProcessingRefSlot = prevProcessingRefSlot; + _handleConsensusReportLastCall + .prevSubmittedRefSlot = prevSubmittedRefSlot; + _handleConsensusReportLastCall + .prevProcessingRefSlot = prevProcessingRefSlot; ++_handleConsensusReportLastCall.callCount; } - function getConsensusReportLastCall() external view returns (HandleConsensusReportLastCall memory) { + function _handleConsensusReportDiscarded( + ConsensusReport memory report + ) internal override { + lastDiscardedReport = report; + } + + function getConsensusReportLastCall() + external + view + returns (HandleConsensusReportLastCall memory) + { return _handleConsensusReportLastCall; } @@ -76,11 +99,19 @@ contract BaseOracleTimeTravellable is BaseOracle { return _isConsensusMember(addr); } - function getCurrentRefSlot() external view returns (uint256) { + function getCurrentRefSlot() external view returns (uint256) { return _getCurrentRefSlot(); } - function checkConsensusData(uint256 refSlot, uint256 consensusVersion, bytes32 hash) external view { + function checkConsensusData( + uint256 refSlot, + uint256 consensusVersion, + bytes32 hash + ) external view { _checkConsensusData(refSlot, consensusVersion, hash); } + + function checkProcessingDeadline() external view { + _checkProcessingDeadline(); + } } diff --git a/contracts/0.8.9/test_helpers/oracle/MockConsensusContract.sol b/contracts/0.8.9/test_helpers/oracle/MockConsensusContract.sol index 5e8a36916..12a9375dd 100644 --- a/contracts/0.8.9/test_helpers/oracle/MockConsensusContract.sol +++ b/contracts/0.8.9/test_helpers/oracle/MockConsensusContract.sol @@ -61,14 +61,26 @@ contract MockConsensusContract is IConsensusContract { return _memberIndices1b[addr] != 0; } - function getCurrentFrame() external view returns (uint256 refSlot, uint256 reportProcessingDeadlineSlot) { - return (_consensusFrame.refSlot, _consensusFrame.reportProcessingDeadlineSlot); + function getCurrentFrame() + external + view + returns (uint256 refSlot, uint256 reportProcessingDeadlineSlot) + { + return ( + _consensusFrame.refSlot, + _consensusFrame.reportProcessingDeadlineSlot + ); } - function setCurrentFrame(uint256 index, uint256 refSlot, uint256 reportProcessingDeadlineSlot) external { + function setCurrentFrame( + uint256 index, + uint256 refSlot, + uint256 reportProcessingDeadlineSlot + ) external { _consensusFrame.index = index; _consensusFrame.refSlot = refSlot; - _consensusFrame.reportProcessingDeadlineSlot = reportProcessingDeadlineSlot; + _consensusFrame + .reportProcessingDeadlineSlot = reportProcessingDeadlineSlot; } function setInitialRefSlot(uint256 initialRefSlot) external { @@ -78,12 +90,20 @@ contract MockConsensusContract is IConsensusContract { function getChainConfig() external view - returns (uint256 slotsPerEpoch, uint256 secondsPerSlot, uint256 genesisTime) + returns ( + uint256 slotsPerEpoch, + uint256 secondsPerSlot, + uint256 genesisTime + ) { return (SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME); } - function getFrameConfig() external view returns (uint256 initialEpoch, uint256 epochsPerFrame) { + function getFrameConfig() + external + view + returns (uint256 initialEpoch, uint256 epochsPerFrame) + { return (_frameConfig.initialEpoch, _frameConfig.epochsPerFrame); } @@ -91,8 +111,16 @@ contract MockConsensusContract is IConsensusContract { return _initialRefSlot; } - function _setFrameConfig(uint256 initialEpoch, uint256 epochsPerFrame, uint256 fastLaneLengthSlots) internal { - _frameConfig = FrameConfig(initialEpoch.toUint64(), epochsPerFrame.toUint64(), fastLaneLengthSlots.toUint64()); + function _setFrameConfig( + uint256 initialEpoch, + uint256 epochsPerFrame, + uint256 fastLaneLengthSlots + ) internal { + _frameConfig = FrameConfig( + initialEpoch.toUint64(), + epochsPerFrame.toUint64(), + fastLaneLengthSlots.toUint64() + ); } // @@ -103,7 +131,19 @@ contract MockConsensusContract is IConsensusContract { _reportProcessor = reportProcessor; } - function submitReportAsConsensus(bytes32 reportHash, uint256 refSlot, uint256 deadline) external { - IReportAsyncProcessor(_reportProcessor).submitConsensusReport(reportHash, refSlot, deadline); + function submitReportAsConsensus( + bytes32 reportHash, + uint256 refSlot, + uint256 deadline + ) external { + IReportAsyncProcessor(_reportProcessor).submitConsensusReport( + reportHash, + refSlot, + deadline + ); + } + + function discardReportAsConsensus(uint256 refSlot) external { + IReportAsyncProcessor(_reportProcessor).discardConsensusReport(refSlot); } } diff --git a/contracts/0.8.9/test_helpers/oracle/MockLidoForAccountingOracle.sol b/contracts/0.8.9/test_helpers/oracle/MockLidoForAccountingOracle.sol index 80bc498b4..96de85df8 100644 --- a/contracts/0.8.9/test_helpers/oracle/MockLidoForAccountingOracle.sol +++ b/contracts/0.8.9/test_helpers/oracle/MockLidoForAccountingOracle.sol @@ -17,7 +17,7 @@ interface IPostTokenRebaseReceiver { } contract MockLidoForAccountingOracle is ILido { - address legacyOracle; + address internal legacyOracle; struct HandleOracleReportLastCall { uint256 currentReportTimestamp; diff --git a/contracts/0.8.9/test_helpers/oracle/MockReportProcessor.sol b/contracts/0.8.9/test_helpers/oracle/MockReportProcessor.sol index 78fdea7c7..29893dd5d 100644 --- a/contracts/0.8.9/test_helpers/oracle/MockReportProcessor.sol +++ b/contracts/0.8.9/test_helpers/oracle/MockReportProcessor.sol @@ -7,14 +7,20 @@ import { IReportAsyncProcessor } from "../../oracle/HashConsensus.sol"; contract MockReportProcessor is IReportAsyncProcessor { uint256 internal _consensusVersion; - struct SubmitReportLastCall { + struct SubmitReportCall { bytes32 report; uint256 refSlot; uint256 deadline; uint256 callCount; } - SubmitReportLastCall internal _submitReportLastCall; + struct DiscardReportCall { + uint256 refSlot; + uint256 callCount; + } + + SubmitReportCall internal _submitReportLastCall; + DiscardReportCall internal _discardReportLastCall; uint256 internal _lastProcessingRefSlot; constructor(uint256 consensusVersion) { @@ -29,10 +35,14 @@ contract MockReportProcessor is IReportAsyncProcessor { _lastProcessingRefSlot = refSlot; } - function getLastCall_submitReport() external view returns (SubmitReportLastCall memory) { + function getLastCall_submitReport() external view returns (SubmitReportCall memory) { return _submitReportLastCall; } + function getLastCall_discardReport() external view returns (DiscardReportCall memory) { + return _discardReportLastCall; + } + function startReportProcessing() external { _lastProcessingRefSlot = _submitReportLastCall.refSlot; } @@ -52,6 +62,11 @@ contract MockReportProcessor is IReportAsyncProcessor { ++_submitReportLastCall.callCount; } + function discardConsensusReport(uint256 refSlot) external { + _discardReportLastCall.refSlot = refSlot; + ++_discardReportLastCall.callCount; + } + function getLastProcessingRefSlot() external view returns (uint256) { return _lastProcessingRefSlot; } diff --git a/contracts/common/lib/Math256.sol b/contracts/common/lib/Math256.sol index f5f958417..366a014cf 100644 --- a/contracts/common/lib/Math256.sol +++ b/contracts/common/lib/Math256.sol @@ -8,11 +8,6 @@ pragma solidity >=0.4.24 <0.9.0; library Math256 { - /// @dev Returns the absolute unsigned value of a signed value. - function abs(int256 n) internal pure returns (uint256) { - return uint256(n >= 0 ? n : -n); - } - /// @dev Returns the largest of two numbers. function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; @@ -41,4 +36,9 @@ library Math256 { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } + + /// @dev Returns absolute difference of two numbers. + function absDiff(uint256 a, uint256 b) internal pure returns (uint256) { + return a > b ? a - b : b - a; + } } diff --git a/contracts/common/lib/SignatureUtils.sol b/contracts/common/lib/SignatureUtils.sol index 4fd309cc4..efb6beef6 100644 --- a/contracts/common/lib/SignatureUtils.sol +++ b/contracts/common/lib/SignatureUtils.sol @@ -38,7 +38,7 @@ library SignatureUtils { // Solidity <0.5 generates a regular CALL instruction even if the function being called // is marked as `view`, and the only way to perform a STATICCALL is to use assembly bytes memory data = abi.encodeWithSelector(ERC1271_IS_VALID_SIGNATURE_SELECTOR, msgHash, sig); - bytes4 retval; + bytes32 retval; /// @solidity memory-safe-assembly assembly { // allocate memory for storing the return value @@ -46,11 +46,11 @@ library SignatureUtils { mstore(0x40, add(outDataOffset, 32)) // issue a static call and load the result if the call succeeded let success := staticcall(gas(), signer, add(data, 32), mload(data), outDataOffset, 32) - if eq(success, 1) { + if and(eq(success, 1), eq(returndatasize(), 32)) { retval := mload(outDataOffset) } } - return retval == ERC1271_IS_VALID_SIGNATURE_SELECTOR; + return retval == bytes32(ERC1271_IS_VALID_SIGNATURE_SELECTOR); } else { return ECDSA.recover(msgHash, v, r, s) == signer; } diff --git a/contracts/common/test_helpers/ERC1271SignerDumbMock.sol b/contracts/common/test_helpers/ERC1271SignerDumbMock.sol index 5b02e2fa8..5b875ddcd 100644 --- a/contracts/common/test_helpers/ERC1271SignerDumbMock.sol +++ b/contracts/common/test_helpers/ERC1271SignerDumbMock.sol @@ -8,7 +8,7 @@ contract ERC1271SignerDumbMock { error InvalidSignature(); struct Config { - bytes4 retval; + bytes retval; bool reverts; } @@ -20,6 +20,9 @@ contract ERC1271SignerDumbMock { function isValidSignature(bytes32 /* hash */, bytes memory /* sig */) external view returns (bytes4) { if (_config.reverts) revert InvalidSignature(); - return _config.retval; + bytes memory retval = _config.retval; + assembly { + return(add(retval, 32), mload(retval)) + } } } diff --git a/lib/abi/AccessControl.json b/lib/abi/AccessControl.json deleted file mode 100644 index b0fe35193..000000000 --- a/lib/abi/AccessControl.json +++ /dev/null @@ -1 +0,0 @@ -[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/AccessControlEnumerable.json b/lib/abi/AccessControlEnumerable.json deleted file mode 100644 index f1c58c582..000000000 --- a/lib/abi/AccessControlEnumerable.json +++ /dev/null @@ -1 +0,0 @@ -[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/AccountingOracle.json b/lib/abi/AccountingOracle.json deleted file mode 100644 index 5f583046f..000000000 --- a/lib/abi/AccountingOracle.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"lidoLocator","type":"address"},{"internalType":"address","name":"lido","type":"address"},{"internalType":"address","name":"legacyOracle","type":"address"},{"internalType":"uint256","name":"secondsPerSlot","type":"uint256"},{"internalType":"uint256","name":"genesisTime","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressCannotBeSame","type":"error"},{"inputs":[],"name":"AddressCannotBeZero","type":"error"},{"inputs":[],"name":"AdminCannotBeZero","type":"error"},{"inputs":[],"name":"CannotSubmitExtraDataBeforeMainData","type":"error"},{"inputs":[],"name":"ExtraDataAlreadyProcessed","type":"error"},{"inputs":[],"name":"ExtraDataHashCannotBeZeroForNonEmptyData","type":"error"},{"inputs":[],"name":"ExtraDataItemsCountCannotBeZeroForNonEmptyData","type":"error"},{"inputs":[],"name":"ExtraDataListOnlySupportsSingleTx","type":"error"},{"inputs":[{"internalType":"uint256","name":"code","type":"uint256"}],"name":"IncorrectOracleMigration","type":"error"},{"inputs":[{"internalType":"uint256","name":"initialRefSlot","type":"uint256"},{"internalType":"uint256","name":"processingRefSlot","type":"uint256"}],"name":"InitialRefSlotCannotBeLessThanProcessingOne","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[],"name":"InvalidExitedValidatorsData","type":"error"},{"inputs":[{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"name":"InvalidExtraDataItem","type":"error"},{"inputs":[{"internalType":"uint256","name":"itemIndex","type":"uint256"}],"name":"InvalidExtraDataSortOrder","type":"error"},{"inputs":[],"name":"LegacyOracleCannotBeZero","type":"error"},{"inputs":[],"name":"LidoCannotBeZero","type":"error"},{"inputs":[],"name":"LidoLocatorCannotBeZero","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[],"name":"OnlyConsensusContractCanSubmitReport","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ProcessingDeadlineMissed","type":"error"},{"inputs":[],"name":"RefSlotAlreadyProcessing","type":"error"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"prevRefSlot","type":"uint256"}],"name":"RefSlotCannotDecrease","type":"error"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"processingRefSlot","type":"uint256"}],"name":"RefSlotMustBeGreaterThanProcessingOne","type":"error"},{"inputs":[],"name":"SenderNotAllowed","type":"error"},{"inputs":[],"name":"UnexpectedChainConfig","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedVersion","type":"uint256"},{"internalType":"uint256","name":"receivedVersion","type":"uint256"}],"name":"UnexpectedConsensusVersion","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[{"internalType":"bytes32","name":"consensusHash","type":"bytes32"},{"internalType":"bytes32","name":"receivedHash","type":"bytes32"}],"name":"UnexpectedDataHash","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedFormat","type":"uint256"},{"internalType":"uint256","name":"receivedFormat","type":"uint256"}],"name":"UnexpectedExtraDataFormat","type":"error"},{"inputs":[{"internalType":"bytes32","name":"consensusHash","type":"bytes32"},{"internalType":"bytes32","name":"receivedHash","type":"bytes32"}],"name":"UnexpectedExtraDataHash","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedIndex","type":"uint256"},{"internalType":"uint256","name":"receivedIndex","type":"uint256"}],"name":"UnexpectedExtraDataIndex","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedCount","type":"uint256"},{"internalType":"uint256","name":"receivedCount","type":"uint256"}],"name":"UnexpectedExtraDataItemsCount","type":"error"},{"inputs":[{"internalType":"uint256","name":"consensusRefSlot","type":"uint256"},{"internalType":"uint256","name":"dataRefSlot","type":"uint256"}],"name":"UnexpectedRefSlot","type":"error"},{"inputs":[{"internalType":"uint256","name":"format","type":"uint256"}],"name":"UnsupportedExtraDataFormat","type":"error"},{"inputs":[{"internalType":"uint256","name":"itemIndex","type":"uint256"},{"internalType":"uint256","name":"dataType","type":"uint256"}],"name":"UnsupportedExtraDataType","type":"error"},{"inputs":[],"name":"VersionCannotBeSame","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"prevAddr","type":"address"}],"name":"ConsensusHashContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"version","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"prevVersion","type":"uint256"}],"name":"ConsensusVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"itemsProcessed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"itemsCount","type":"uint256"}],"name":"ExtraDataSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"ProcessingStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"}],"name":"ReportSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"processedItemsCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"itemsCount","type":"uint256"}],"name":"WarnExtraDataIncompleteProcessing","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"}],"name":"WarnProcessingMissed","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTRA_DATA_FORMAT_EMPTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTRA_DATA_FORMAT_LIST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTRA_DATA_TYPE_EXITED_VALIDATORS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXTRA_DATA_TYPE_STUCK_VALIDATORS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GENESIS_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LEGACY_ORACLE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LOCATOR","outputs":[{"internalType":"contract ILidoLocator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_CONSENSUS_CONTRACT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_CONSENSUS_VERSION_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECONDS_PER_SLOT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUBMIT_DATA_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusReport","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"},{"internalType":"bool","name":"processingStarted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastProcessingRefSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProcessingState","outputs":[{"components":[{"internalType":"uint256","name":"currentFrameRefSlot","type":"uint256"},{"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"},{"internalType":"bytes32","name":"mainDataHash","type":"bytes32"},{"internalType":"bool","name":"mainDataSubmitted","type":"bool"},{"internalType":"bytes32","name":"extraDataHash","type":"bytes32"},{"internalType":"uint256","name":"extraDataFormat","type":"uint256"},{"internalType":"bool","name":"extraDataSubmitted","type":"bool"},{"internalType":"uint256","name":"extraDataItemsCount","type":"uint256"},{"internalType":"uint256","name":"extraDataItemsSubmitted","type":"uint256"}],"internalType":"struct AccountingOracle.ProcessingState","name":"result","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"consensusContract","type":"address"},{"internalType":"uint256","name":"consensusVersion","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"consensusContract","type":"address"},{"internalType":"uint256","name":"consensusVersion","type":"uint256"},{"internalType":"uint256","name":"lastProcessingRefSlot","type":"uint256"}],"name":"initializeWithoutMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setConsensusContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"version","type":"uint256"}],"name":"setConsensusVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"reportHash","type":"bytes32"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"submitConsensusReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"consensusVersion","type":"uint256"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"numValidators","type":"uint256"},{"internalType":"uint256","name":"clBalanceGwei","type":"uint256"},{"internalType":"uint256[]","name":"stakingModuleIdsWithNewlyExitedValidators","type":"uint256[]"},{"internalType":"uint256[]","name":"numExitedValidatorsByStakingModule","type":"uint256[]"},{"internalType":"uint256","name":"withdrawalVaultBalance","type":"uint256"},{"internalType":"uint256","name":"elRewardsVaultBalance","type":"uint256"},{"internalType":"uint256","name":"sharesRequestedToBurn","type":"uint256"},{"internalType":"uint256[]","name":"withdrawalFinalizationBatches","type":"uint256[]"},{"internalType":"uint256","name":"simulatedShareRate","type":"uint256"},{"internalType":"bool","name":"isBunkerMode","type":"bool"},{"internalType":"uint256","name":"extraDataFormat","type":"uint256"},{"internalType":"bytes32","name":"extraDataHash","type":"bytes32"},{"internalType":"uint256","name":"extraDataItemsCount","type":"uint256"}],"internalType":"struct AccountingOracle.ReportData","name":"data","type":"tuple"},{"internalType":"uint256","name":"contractVersion","type":"uint256"}],"name":"submitReportData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"submitReportExtraDataEmpty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"items","type":"bytes"}],"name":"submitReportExtraDataList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/BaseOracle.json b/lib/abi/BaseOracle.json deleted file mode 100644 index bf2b9de68..000000000 --- a/lib/abi/BaseOracle.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"name":"AddressCannotBeSame","type":"error"},{"inputs":[],"name":"AddressCannotBeZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"initialRefSlot","type":"uint256"},{"internalType":"uint256","name":"processingRefSlot","type":"uint256"}],"name":"InitialRefSlotCannotBeLessThanProcessingOne","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[],"name":"OnlyConsensusContractCanSubmitReport","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ProcessingDeadlineMissed","type":"error"},{"inputs":[],"name":"RefSlotAlreadyProcessing","type":"error"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"prevRefSlot","type":"uint256"}],"name":"RefSlotCannotDecrease","type":"error"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"processingRefSlot","type":"uint256"}],"name":"RefSlotMustBeGreaterThanProcessingOne","type":"error"},{"inputs":[],"name":"UnexpectedChainConfig","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedVersion","type":"uint256"},{"internalType":"uint256","name":"receivedVersion","type":"uint256"}],"name":"UnexpectedConsensusVersion","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[{"internalType":"bytes32","name":"consensusHash","type":"bytes32"},{"internalType":"bytes32","name":"receivedHash","type":"bytes32"}],"name":"UnexpectedDataHash","type":"error"},{"inputs":[{"internalType":"uint256","name":"consensusRefSlot","type":"uint256"},{"internalType":"uint256","name":"dataRefSlot","type":"uint256"}],"name":"UnexpectedRefSlot","type":"error"},{"inputs":[],"name":"VersionCannotBeSame","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"prevAddr","type":"address"}],"name":"ConsensusHashContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"version","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"prevVersion","type":"uint256"}],"name":"ConsensusVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"ProcessingStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"}],"name":"ReportSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"}],"name":"WarnProcessingMissed","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GENESIS_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_CONSENSUS_CONTRACT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_CONSENSUS_VERSION_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECONDS_PER_SLOT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusReport","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"},{"internalType":"bool","name":"processingStarted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastProcessingRefSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setConsensusContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"version","type":"uint256"}],"name":"setConsensusVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"reportHash","type":"bytes32"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"submitConsensusReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/BeaconChainDepositor.json b/lib/abi/BeaconChainDepositor.json deleted file mode 100644 index 9d8f718cd..000000000 --- a/lib/abi/BeaconChainDepositor.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_depositContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DepositContractZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidPublicKeysBatchLength","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidSignaturesBatchLength","type":"error"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/Burner.json b/lib/abi/Burner.json deleted file mode 100644 index 79487afc0..000000000 --- a/lib/abi/Burner.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_stETH","type":"address"},{"internalType":"uint256","name":"_totalCoverSharesBurnt","type":"uint256"},{"internalType":"uint256","name":"_totalNonCoverSharesBurnt","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AppAuthLidoFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"requestedAmount","type":"uint256"},{"internalType":"uint256","name":"actualAmount","type":"uint256"}],"name":"BurnAmountExceedsActual","type":"error"},{"inputs":[],"name":"DirectETHTransfer","type":"error"},{"inputs":[],"name":"StETHRecoveryWrongFunc","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroBurnAmount","type":"error"},{"inputs":[],"name":"ZeroRecoveryAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfShares","type":"uint256"}],"name":"ExcessStETHRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isCover","type":"bool"},{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfShares","type":"uint256"}],"name":"StETHBurnRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"isCover","type":"bool"},{"indexed":false,"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfShares","type":"uint256"}],"name":"StETHBurnt","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECOVER_ASSETS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REQUEST_BURN_MY_STETH_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REQUEST_BURN_SHARES_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sharesToBurn","type":"uint256"}],"name":"commitSharesToBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCoverSharesBurnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExcessStETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNonCoverSharesBurnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSharesRequestedToBurn","outputs":[{"internalType":"uint256","name":"coverShares","type":"uint256"},{"internalType":"uint256","name":"nonCoverShares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"recoverERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverExcessStETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stETHAmountToBurn","type":"uint256"}],"name":"requestBurnMyStETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stETHAmountToBurn","type":"uint256"}],"name":"requestBurnMyStETHForCover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_sharesAmountToBurn","type":"uint256"}],"name":"requestBurnShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_sharesAmountToBurn","type":"uint256"}],"name":"requestBurnSharesForCover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}] \ No newline at end of file diff --git a/lib/abi/DepositSecurityModule.json b/lib/abi/DepositSecurityModule.json deleted file mode 100644 index c443f1ea6..000000000 --- a/lib/abi/DepositSecurityModule.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_lido","type":"address"},{"internalType":"address","name":"_depositContract","type":"address"},{"internalType":"address","name":"_stakingRouter","type":"address"},{"internalType":"uint256","name":"_maxDepositsPerBlock","type":"uint256"},{"internalType":"uint256","name":"_minDepositBlockDistance","type":"uint256"},{"internalType":"uint256","name":"_pauseIntentValidityPeriodBlocks","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DepositInactiveModule","type":"error"},{"inputs":[],"name":"DepositNoQuorum","type":"error"},{"inputs":[],"name":"DepositNonceChanged","type":"error"},{"inputs":[],"name":"DepositRootChanged","type":"error"},{"inputs":[],"name":"DepositTooFrequent","type":"error"},{"inputs":[],"name":"DepositUnexpectedBlockHash","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"DuplicateAddress","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"NotAGuardian","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotAnOwner","type":"error"},{"inputs":[],"name":"PauseIntentExpired","type":"error"},{"inputs":[],"name":"SignatureNotSorted","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"inputs":[{"internalType":"string","name":"parameter","type":"string"}],"name":"ZeroParameter","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint24","name":"stakingModuleId","type":"uint24"}],"name":"DepositsUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"GuardianQuorumChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MaxDepositsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MinDepositBlockDistanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"PauseIntentValidityPeriodBlocksChanged","type":"event"},{"inputs":[],"name":"ATTEST_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"contract ILido","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_MESSAGE_PREFIX","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_ROUTER","outputs":[{"internalType":"contract IStakingRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addGuardians","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"canDeposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"depositRoot","type":"bytes32"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"depositCalldata","type":"bytes"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature[]","name":"sortedGuardianSignatures","type":"tuple[]"}],"name":"depositBufferedEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getGuardianIndex","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardianQuorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardians","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinDepositBlockDistance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseIntentValidityPeriodBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isGuardian","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct DepositSecurityModule.Signature","name":"sig","type":"tuple"}],"name":"pauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"removeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setGuardianQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMaxDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setMinDepositBlockDistance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setPauseIntentValidityPeriodBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"}],"name":"unpauseDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/EIP712StETH.json b/lib/abi/EIP712StETH.json deleted file mode 100644 index d811a60f0..000000000 --- a/lib/abi/EIP712StETH.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_stETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ZeroStETHAddress","type":"error"},{"inputs":[{"internalType":"address","name":"_stETH","type":"address"}],"name":"domainSeparatorV4","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stETH","type":"address"}],"name":"eip712Domain","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stETH","type":"address"},{"internalType":"bytes32","name":"_structHash","type":"bytes32"}],"name":"hashTypedDataV4","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/Finance.json b/lib/abi/Finance.json deleted file mode 100644 index fad0e6165..000000000 --- a/lib/abi/Finance.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CREATE_PAYMENTS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_receiver","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_initialPaymentTime","type":"uint64"},{"name":"_interval","type":"uint64"},{"name":"_maxExecutions","type":"uint64"},{"name":"_reference","type":"string"}],"name":"newScheduledPayment","outputs":[{"name":"paymentId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_paymentId","type":"uint256"}],"name":"executePayment","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_vault","type":"address"},{"name":"_periodDuration","type":"uint64"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"removeBudget","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"}],"name":"getBudget","outputs":[{"name":"budget","type":"uint256"},{"name":"hasBudget","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_paymentId","type":"uint256"},{"name":"_active","type":"bool"}],"name":"setPaymentStatus","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_paymentId","type":"uint256"}],"name":"getPayment","outputs":[{"name":"token","type":"address"},{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"},{"name":"initialPaymentTime","type":"uint64"},{"name":"interval","type":"uint64"},{"name":"maxExecutions","type":"uint64"},{"name":"inactive","type":"bool"},{"name":"executions","type":"uint64"},{"name":"createdBy","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_transactionId","type":"uint256"}],"name":"getTransaction","outputs":[{"name":"periodId","type":"uint64"},{"name":"amount","type":"uint256"},{"name":"paymentId","type":"uint256"},{"name":"paymentExecutionNumber","type":"uint64"},{"name":"token","type":"address"},{"name":"entity","type":"address"},{"name":"isIncoming","type":"bool"},{"name":"date","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHANGE_PERIOD_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHANGE_BUDGETS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_paymentId","type":"uint256"}],"name":"receiverExecutePayment","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_periodId","type":"uint64"}],"name":"getPeriod","outputs":[{"name":"isCurrent","type":"bool"},{"name":"startTime","type":"uint64"},{"name":"endTime","type":"uint64"},{"name":"firstTransactionId","type":"uint256"},{"name":"lastTransactionId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_periodDuration","type":"uint64"}],"name":"setPeriodDuration","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"periodsLength","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_amount","type":"uint256"}],"name":"setBudget","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"recoverToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"EXECUTE_PAYMENTS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentPeriodId","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_maxTransitions","type":"uint64"}],"name":"tryTransitionAccountingPeriod","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPeriodDuration","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_reference","type":"string"}],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_paymentId","type":"uint256"}],"name":"nextPaymentTime","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_periodId","type":"uint64"},{"name":"_token","type":"address"}],"name":"getPeriodTokenStatement","outputs":[{"name":"expenses","type":"uint256"},{"name":"income","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paymentsNextIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"},{"name":"_amount","type":"uint256"}],"name":"canMakePayment","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_PAYMENTS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"transactionsNextIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"}],"name":"getRemainingBudget","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_receiver","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_reference","type":"string"}],"name":"newImmediatePayment","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"vault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"periodId","type":"uint64"},{"indexed":false,"name":"periodStarts","type":"uint64"},{"indexed":false,"name":"periodEnds","type":"uint64"}],"name":"NewPeriod","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"hasBudget","type":"bool"}],"name":"SetBudget","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"paymentId","type":"uint256"},{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"maxExecutions","type":"uint64"},{"indexed":false,"name":"reference","type":"string"}],"name":"NewPayment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"transactionId","type":"uint256"},{"indexed":false,"name":"incoming","type":"bool"},{"indexed":true,"name":"entity","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"reference","type":"string"}],"name":"NewTransaction","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"paymentId","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"ChangePaymentState","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newDuration","type":"uint64"}],"name":"ChangePeriodDuration","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"paymentId","type":"uint256"}],"name":"PaymentFailure","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}] \ No newline at end of file diff --git a/lib/abi/HashConsensus.json b/lib/abi/HashConsensus.json deleted file mode 100644 index bcfd3fb91..000000000 --- a/lib/abi/HashConsensus.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"uint256","name":"slotsPerEpoch","type":"uint256"},{"internalType":"uint256","name":"secondsPerSlot","type":"uint256"},{"internalType":"uint256","name":"genesisTime","type":"uint256"},{"internalType":"uint256","name":"epochsPerFrame","type":"uint256"},{"internalType":"uint256","name":"fastLaneLengthSlots","type":"uint256"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"reportProcessor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressCannotBeZero","type":"error"},{"inputs":[],"name":"AdminCannotBeZero","type":"error"},{"inputs":[],"name":"ConsensusReportAlreadyProcessing","type":"error"},{"inputs":[],"name":"DuplicateMember","type":"error"},{"inputs":[],"name":"DuplicateReport","type":"error"},{"inputs":[],"name":"EmptyReport","type":"error"},{"inputs":[],"name":"EpochsPerFrameCannotBeZero","type":"error"},{"inputs":[],"name":"FastLanePeriodCannotBeLongerThanFrame","type":"error"},{"inputs":[],"name":"InitialEpochAlreadyArrived","type":"error"},{"inputs":[],"name":"InitialEpochIsYetToArrive","type":"error"},{"inputs":[],"name":"InitialEpochRefSlotCannotBeEarlierThanProcessingSlot","type":"error"},{"inputs":[],"name":"InvalidSlot","type":"error"},{"inputs":[],"name":"NewProcessorCannotBeTheSame","type":"error"},{"inputs":[],"name":"NonFastLaneMemberCannotReportWithinFastLaneInterval","type":"error"},{"inputs":[],"name":"NonMember","type":"error"},{"inputs":[],"name":"NumericOverflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"minQuorum","type":"uint256"},{"internalType":"uint256","name":"receivedQuorum","type":"uint256"}],"name":"QuorumTooSmall","type":"error"},{"inputs":[],"name":"ReportProcessorCannotBeZero","type":"error"},{"inputs":[],"name":"StaleReport","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedConsensusVersion","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"report","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"support","type":"uint256"}],"name":"ConsensusReached","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fastLaneLengthSlots","type":"uint256"}],"name":"FastLaneConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newInitialEpoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newEpochsPerFrame","type":"uint256"}],"name":"FrameConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"newTotalMembers","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"MemberAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"newTotalMembers","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"MemberRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newQuorum","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalMembers","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"prevQuorum","type":"uint256"}],"name":"QuorumSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"processor","type":"address"},{"indexed":true,"internalType":"address","name":"prevProcessor","type":"address"}],"name":"ReportProcessorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":true,"internalType":"address","name":"member","type":"address"},{"indexed":false,"internalType":"bytes32","name":"report","type":"bytes32"}],"name":"ReportReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISABLE_CONSENSUS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_FAST_LANE_CONFIG_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_FRAME_CONFIG_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_MEMBERS_AND_QUORUM_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_REPORT_PROCESSOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"quorum","type":"uint256"}],"name":"addMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableConsensus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChainConfig","outputs":[{"internalType":"uint256","name":"slotsPerEpoch","type":"uint256"},{"internalType":"uint256","name":"secondsPerSlot","type":"uint256"},{"internalType":"uint256","name":"genesisTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusState","outputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"bytes32","name":"consensusReport","type":"bytes32"},{"internalType":"bool","name":"isReportProcessing","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getConsensusStateForMember","outputs":[{"components":[{"internalType":"uint256","name":"currentFrameRefSlot","type":"uint256"},{"internalType":"bytes32","name":"currentFrameConsensusReport","type":"bytes32"},{"internalType":"bool","name":"isMember","type":"bool"},{"internalType":"bool","name":"isFastLane","type":"bool"},{"internalType":"bool","name":"canReport","type":"bool"},{"internalType":"uint256","name":"lastMemberReportRefSlot","type":"uint256"},{"internalType":"bytes32","name":"currentFrameMemberReport","type":"bytes32"}],"internalType":"struct HashConsensus.MemberConsensusState","name":"result","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentFrame","outputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"reportProcessingDeadlineSlot","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFastLaneMembers","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"lastReportedRefSlots","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFrameConfig","outputs":[{"internalType":"uint256","name":"initialEpoch","type":"uint256"},{"internalType":"uint256","name":"epochsPerFrame","type":"uint256"},{"internalType":"uint256","name":"fastLaneLengthSlots","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInitialRefSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getIsFastLaneMember","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getIsMember","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMembers","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"lastReportedRefSlots","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQuorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReportProcessor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReportVariants","outputs":[{"internalType":"bytes32[]","name":"variants","type":"bytes32[]"},{"internalType":"uint256[]","name":"support","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"quorum","type":"uint256"}],"name":"removeMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fastLaneLengthSlots","type":"uint256"}],"name":"setFastLaneLengthSlots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochsPerFrame","type":"uint256"},{"internalType":"uint256","name":"fastLaneLengthSlots","type":"uint256"}],"name":"setFrameConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quorum","type":"uint256"}],"name":"setQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newProcessor","type":"address"}],"name":"setReportProcessor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slot","type":"uint256"},{"internalType":"bytes32","name":"report","type":"bytes32"},{"internalType":"uint256","name":"consensusVersion","type":"uint256"}],"name":"submitReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"initialEpoch","type":"uint256"}],"name":"updateInitialEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IAccountingOracle.json b/lib/abi/IAccountingOracle.json deleted file mode 100644 index 80b555f98..000000000 --- a/lib/abi/IAccountingOracle.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"getConsensusContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IConsensusContract.json b/lib/abi/IConsensusContract.json deleted file mode 100644 index f579c86d0..000000000 --- a/lib/abi/IConsensusContract.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"name":"getChainConfig","outputs":[{"internalType":"uint256","name":"slotsPerEpoch","type":"uint256"},{"internalType":"uint256","name":"secondsPerSlot","type":"uint256"},{"internalType":"uint256","name":"genesisTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentFrame","outputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"reportProcessingDeadlineSlot","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFrameConfig","outputs":[{"internalType":"uint256","name":"initialEpoch","type":"uint256"},{"internalType":"uint256","name":"epochsPerFrame","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInitialRefSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getIsMember","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IDepositContract.json b/lib/abi/IDepositContract.json deleted file mode 100644 index bbbff4979..000000000 --- a/lib/abi/IDepositContract.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"name":"get_deposit_root","outputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IERC2612.json b/lib/abi/IERC2612.json deleted file mode 100644 index c2f4d2c91..000000000 --- a/lib/abi/IERC2612.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"nonces","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"},{"name":"value","type":"uint256"},{"name":"deadline","type":"uint256"},{"name":"v","type":"uint8"},{"name":"r","type":"bytes32"},{"name":"s","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IETHRegistrarController.json b/lib/abi/IETHRegistrarController.json deleted file mode 100644 index ea487d959..000000000 --- a/lib/abi/IETHRegistrarController.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[{"name":"name","type":"string"},{"name":"duration","type":"uint256"}],"name":"rentPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"owner","type":"address"},{"name":"duration","type":"uint256"},{"name":"secret","type":"bytes32"}],"name":"register","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"MIN_REGISTRATION_DURATION","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minCommitmentAge","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"}],"name":"valid","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"}],"name":"available","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxCommitmentAge","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"commitment","type":"bytes32"}],"name":"commit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"},{"name":"owner","type":"address"},{"name":"secret","type":"bytes32"}],"name":"makeCommitment","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IHashConsensus.json b/lib/abi/IHashConsensus.json deleted file mode 100644 index f35b2fc0e..000000000 --- a/lib/abi/IHashConsensus.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"getChainConfig","outputs":[{"name":"slotsPerEpoch","type":"uint256"},{"name":"secondsPerSlot","type":"uint256"},{"name":"genesisTime","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getFrameConfig","outputs":[{"name":"initialEpoch","type":"uint256"},{"name":"epochsPerFrame","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentFrame","outputs":[{"name":"refSlot","type":"uint256"},{"name":"reportProcessingDeadlineSlot","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IInterfaceResolver.json b/lib/abi/IInterfaceResolver.json deleted file mode 100644 index 26db06286..000000000 --- a/lib/abi/IInterfaceResolver.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[{"name":"node","type":"bytes32"},{"name":"interfaceID","type":"bytes4"}],"name":"interfaceImplementer","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/ILegacyOracle.json b/lib/abi/ILegacyOracle.json deleted file mode 100644 index ab33ae81d..000000000 --- a/lib/abi/ILegacyOracle.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"name":"getBeaconSpec","outputs":[{"internalType":"uint64","name":"epochsPerFrame","type":"uint64"},{"internalType":"uint64","name":"slotsPerEpoch","type":"uint64"},{"internalType":"uint64","name":"secondsPerSlot","type":"uint64"},{"internalType":"uint64","name":"genesisTime","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastCompletedEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"clBalance","type":"uint256"},{"internalType":"uint256","name":"clValidators","type":"uint256"}],"name":"handleConsensusLayerReport","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/ILido.json b/lib/abi/ILido.json deleted file mode 100644 index f79f48b65..000000000 --- a/lib/abi/ILido.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"uint256","name":"_currentReportTimestamp","type":"uint256"},{"internalType":"uint256","name":"_timeElapsedSeconds","type":"uint256"},{"internalType":"uint256","name":"_clValidators","type":"uint256"},{"internalType":"uint256","name":"_clBalance","type":"uint256"},{"internalType":"uint256","name":"_withdrawalVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_elRewardsVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_sharesRequestedToBurn","type":"uint256"},{"internalType":"uint256[]","name":"_withdrawalFinalizationBatches","type":"uint256[]"},{"internalType":"uint256","name":"_simulatedShareRate","type":"uint256"}],"name":"handleOracleReport","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/ILidoExecutionLayerRewardsVault.json b/lib/abi/ILidoExecutionLayerRewardsVault.json deleted file mode 100644 index 0c39b7d35..000000000 --- a/lib/abi/ILidoExecutionLayerRewardsVault.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":false,"inputs":[{"name":"_maxAmount","type":"uint256"}],"name":"withdrawRewards","outputs":[{"name":"amount","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/INFTDescriptor.json b/lib/abi/INFTDescriptor.json deleted file mode 100644 index c42b80ece..000000000 --- a/lib/abi/INFTDescriptor.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"constructTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IOracleReportSanityChecker.json b/lib/abi/IOracleReportSanityChecker.json deleted file mode 100644 index cfdd4d6b5..000000000 --- a/lib/abi/IOracleReportSanityChecker.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"uint256","name":"_exitRequestsCount","type":"uint256"}],"name":"checkExitBusOracleReport","outputs":[],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IPostTokenRebaseReceiver.json b/lib/abi/IPostTokenRebaseReceiver.json deleted file mode 100644 index 54053fa7c..000000000 --- a/lib/abi/IPostTokenRebaseReceiver.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":false,"inputs":[{"name":"_reportTimestamp","type":"uint256"},{"name":"_timeElapsed","type":"uint256"},{"name":"_preTotalShares","type":"uint256"},{"name":"_preTotalEther","type":"uint256"},{"name":"_postTotalShares","type":"uint256"},{"name":"_postTotalEther","type":"uint256"},{"name":"_sharesMintedAsFees","type":"uint256"}],"name":"handlePostTokenRebase","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IReportAsyncProcessor.json b/lib/abi/IReportAsyncProcessor.json deleted file mode 100644 index 03b0f7540..000000000 --- a/lib/abi/IReportAsyncProcessor.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"name":"getConsensusVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastProcessingRefSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"report","type":"bytes32"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"submitConsensusReport","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IStETH.json b/lib/abi/IStETH.json deleted file mode 100644 index 1713391c8..000000000 --- a/lib/abi/IStETH.json +++ /dev/null @@ -1 +0,0 @@ -[{"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":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"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pooledEthAmount","type":"uint256"}],"name":"getSharesByPooledEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IStakingRouter.json b/lib/abi/IStakingRouter.json deleted file mode 100644 index cc4b059f3..000000000 --- a/lib/abi/IStakingRouter.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"name":"onValidatorsCountsByNodeOperatorReportingFinished","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"exitedValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleExitedValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"stuckValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleStuckValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"moduleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"exitedValidatorsCounts","type":"uint256[]"}],"name":"updateExitedValidatorsCountByStakingModule","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IWithdrawalQueue.json b/lib/abi/IWithdrawalQueue.json deleted file mode 100644 index 4c65f3257..000000000 --- a/lib/abi/IWithdrawalQueue.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"}],"name":"getWithdrawalStatus","outputs":[{"components":[{"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"internalType":"uint256","name":"amountOfShares","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bool","name":"isFinalized","type":"bool"},{"internalType":"bool","name":"isClaimed","type":"bool"}],"internalType":"struct IWithdrawalQueue.WithdrawalRequestStatus[]","name":"statuses","type":"tuple[]"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IWithdrawalVault.json b/lib/abi/IWithdrawalVault.json deleted file mode 100644 index 1e17b4148..000000000 --- a/lib/abi/IWithdrawalVault.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"withdrawWithdrawals","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/IWstETH.json b/lib/abi/IWstETH.json deleted file mode 100644 index b034090cf..000000000 --- a/lib/abi/IWstETH.json +++ /dev/null @@ -1 +0,0 @@ -[{"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":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"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wstETHAmount","type":"uint256"}],"name":"getStETHByWstETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stETH","outputs":[{"internalType":"contract IStETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wstETHAmount","type":"uint256"}],"name":"unwrap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/LegacyOracle.json b/lib/abi/LegacyOracle.json deleted file mode 100644 index 6fd74b812..000000000 --- a/lib/abi/LegacyOracle.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getVersion","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_lidoLocator","type":"address"},{"name":"_accountingOracleConsensusContract","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_accountingOracle","type":"address"}],"name":"finalizeUpgrade_v4","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLastCompletedReportDelta","outputs":[{"name":"postTotalPooledEther","type":"uint256"},{"name":"preTotalPooledEther","type":"uint256"},{"name":"timeElapsed","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getLido","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentFrame","outputs":[{"name":"frameEpochId","type":"uint256"},{"name":"frameStartTime","type":"uint256"},{"name":"frameEndTime","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"","type":"uint256"},{"name":"timeElapsed","type":"uint256"},{"name":"","type":"uint256"},{"name":"preTotalEther","type":"uint256"},{"name":"postTotalShares","type":"uint256"},{"name":"postTotalEther","type":"uint256"},{"name":"","type":"uint256"}],"name":"handlePostTokenRebase","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLastCompletedEpochId","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getContractVersion","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_refSlot","type":"uint256"},{"name":"_clBalance","type":"uint256"},{"name":"_clValidators","type":"uint256"}],"name":"handleConsensusLayerReport","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAccountingOracle","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentEpochId","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBeaconSpec","outputs":[{"name":"epochsPerFrame","type":"uint64"},{"name":"slotsPerEpoch","type":"uint64"},{"name":"secondsPerSlot","type":"uint64"},{"name":"genesisTime","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"epochId","type":"uint256"},{"indexed":false,"name":"beaconBalance","type":"uint128"},{"indexed":false,"name":"beaconValidators","type":"uint128"}],"name":"Completed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"postTotalPooledEther","type":"uint256"},{"indexed":false,"name":"preTotalPooledEther","type":"uint256"},{"indexed":false,"name":"timeElapsed","type":"uint256"},{"indexed":false,"name":"totalShares","type":"uint256"}],"name":"PostTotalShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"}] \ No newline at end of file diff --git a/lib/abi/Lido.json b/lib/abi/Lido.json deleted file mode 100644 index c28e25b8b..000000000 --- a/lib/abi/Lido.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":false,"inputs":[],"name":"resume","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"STAKING_CONTROL_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_ethAmount","type":"uint256"}],"name":"getSharesByPooledEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isStakingPaused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"},{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_maxStakeLimit","type":"uint256"},{"name":"_stakeLimitIncreasePerBlock","type":"uint256"}],"name":"setStakingLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"RESUME_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_lidoLocator","type":"address"},{"name":"_eip712StETH","type":"address"}],"name":"finalizeUpgrade_v2","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalPooledEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newDepositedValidators","type":"uint256"}],"name":"unsafeChangeDepositedValidators","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"PAUSE_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getTreasury","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isStopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBufferedEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_lidoLocator","type":"address"},{"name":"_eip712StETH","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"receiveELRewards","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getWithdrawalCredentials","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentStakeLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStakeLimitFullInfo","outputs":[{"name":"isStakingPaused","type":"bool"},{"name":"isStakingLimitSet","type":"bool"},{"name":"currentStakeLimit","type":"uint256"},{"name":"maxStakeLimit","type":"uint256"},{"name":"maxStakeLimitGrowthBlocks","type":"uint256"},{"name":"prevStakeLimit","type":"uint256"},{"name":"prevStakeBlockNumber","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"},{"name":"_recipient","type":"address"},{"name":"_sharesAmount","type":"uint256"}],"name":"transferSharesFrom","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"resumeStaking","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getFeeDistribution","outputs":[{"name":"treasuryFeeBasisPoints","type":"uint16"},{"name":"insuranceFeeBasisPoints","type":"uint16"},{"name":"operatorsFeeBasisPoints","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"receiveWithdrawals","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_sharesAmount","type":"uint256"}],"name":"getPooledEthByShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"nonces","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOracle","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"eip712Domain","outputs":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getContractVersion","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_sharesAmount","type":"uint256"}],"name":"transferShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getEIP712StETH","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_referral","type":"address"}],"name":"submit","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_maxDepositsCount","type":"uint256"},{"name":"_stakingModuleId","type":"uint256"},{"name":"_depositCalldata","type":"bytes"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"UNSAFE_CHANGE_DEPOSITED_VALIDATORS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBeaconStat","outputs":[{"name":"depositedValidators","type":"uint256"},{"name":"beaconValidators","type":"uint256"},{"name":"beaconBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"removeStakingLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_reportTimestamp","type":"uint256"},{"name":"_timeElapsed","type":"uint256"},{"name":"_clValidators","type":"uint256"},{"name":"_clBalance","type":"uint256"},{"name":"_withdrawalVaultBalance","type":"uint256"},{"name":"_elRewardsVaultBalance","type":"uint256"},{"name":"_sharesRequestedToBurn","type":"uint256"},{"name":"_withdrawalFinalizationBatches","type":"uint256[]"},{"name":"_simulatedShareRate","type":"uint256"}],"name":"handleOracleReport","outputs":[{"name":"postRebaseAmounts","type":"uint256[4]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getFee","outputs":[{"name":"totalFee","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_deadline","type":"uint256"},{"name":"_v","type":"uint8"},{"name":"_r","type":"bytes32"},{"name":"_s","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getLidoLocator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"canDeposit","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"STAKING_PAUSE_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getDepositableEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"sharesOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pauseStaking","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getTotalELRewardsCollected","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[],"name":"StakingPaused","type":"event"},{"anonymous":false,"inputs":[],"name":"StakingResumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"maxStakeLimit","type":"uint256"},{"indexed":false,"name":"stakeLimitIncreasePerBlock","type":"uint256"}],"name":"StakingLimitSet","type":"event"},{"anonymous":false,"inputs":[],"name":"StakingLimitRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"reportTimestamp","type":"uint256"},{"indexed":false,"name":"preCLValidators","type":"uint256"},{"indexed":false,"name":"postCLValidators","type":"uint256"}],"name":"CLValidatorsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"depositedValidators","type":"uint256"}],"name":"DepositedValidatorsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"reportTimestamp","type":"uint256"},{"indexed":false,"name":"preCLBalance","type":"uint256"},{"indexed":false,"name":"postCLBalance","type":"uint256"},{"indexed":false,"name":"withdrawalsWithdrawn","type":"uint256"},{"indexed":false,"name":"executionLayerRewardsWithdrawn","type":"uint256"},{"indexed":false,"name":"postBufferedEther","type":"uint256"}],"name":"ETHDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"reportTimestamp","type":"uint256"},{"indexed":false,"name":"timeElapsed","type":"uint256"},{"indexed":false,"name":"preTotalShares","type":"uint256"},{"indexed":false,"name":"preTotalEther","type":"uint256"},{"indexed":false,"name":"postTotalShares","type":"uint256"},{"indexed":false,"name":"postTotalEther","type":"uint256"},{"indexed":false,"name":"sharesMintedAsFees","type":"uint256"}],"name":"TokenRebased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"lidoLocator","type":"address"}],"name":"LidoLocatorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"ELRewardsReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"WithdrawalsReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"referral","type":"address"}],"name":"Submitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Unbuffered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"eip712StETH","type":"address"}],"name":"EIP712StETHInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"sharesValue","type":"uint256"}],"name":"TransferShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"preRebaseTokenAmount","type":"uint256"},{"indexed":false,"name":"postRebaseTokenAmount","type":"uint256"},{"indexed":false,"name":"sharesAmount","type":"uint256"}],"name":"SharesBurnt","type":"event"},{"anonymous":false,"inputs":[],"name":"Stopped","type":"event"},{"anonymous":false,"inputs":[],"name":"Resumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"}] \ No newline at end of file diff --git a/lib/abi/LidoExecutionLayerRewardsVault.json b/lib/abi/LidoExecutionLayerRewardsVault.json deleted file mode 100644 index 41f734ac5..000000000 --- a/lib/abi/LidoExecutionLayerRewardsVault.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_lido","type":"address"},{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ETHReceived","type":"event"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"recoverERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxAmount","type":"uint256"}],"name":"withdrawRewards","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}] \ No newline at end of file diff --git a/lib/abi/LidoLocator.json b/lib/abi/LidoLocator.json deleted file mode 100644 index f2145f2d8..000000000 --- a/lib/abi/LidoLocator.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"components":[{"internalType":"address","name":"accountingOracle","type":"address"},{"internalType":"address","name":"depositSecurityModule","type":"address"},{"internalType":"address","name":"elRewardsVault","type":"address"},{"internalType":"address","name":"legacyOracle","type":"address"},{"internalType":"address","name":"lido","type":"address"},{"internalType":"address","name":"oracleReportSanityChecker","type":"address"},{"internalType":"address","name":"postTokenRebaseReceiver","type":"address"},{"internalType":"address","name":"burner","type":"address"},{"internalType":"address","name":"stakingRouter","type":"address"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"validatorsExitBusOracle","type":"address"},{"internalType":"address","name":"withdrawalQueue","type":"address"},{"internalType":"address","name":"withdrawalVault","type":"address"},{"internalType":"address","name":"oracleDaemonConfig","type":"address"}],"internalType":"struct LidoLocator.Config","name":"_config","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"accountingOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coreComponents","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositSecurityModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"elRewardsVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"legacyOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lido","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleDaemonConfig","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleReportComponentsForLido","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleReportSanityChecker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"postTokenRebaseReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorsExitBusOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalQueue","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/LidoTemplate.json b/lib/abi/LidoTemplate.json deleted file mode 100644 index 5d959bf93..000000000 --- a/lib/abi/LidoTemplate.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":false,"inputs":[{"name":"_tokenName","type":"string"},{"name":"_tokenSymbol","type":"string"},{"name":"_votingSettings","type":"uint64[4]"},{"name":"_oracle","type":"address"}],"name":"newDAO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_daoName","type":"string"},{"name":"_unvestedTokensAmount","type":"uint256"}],"name":"finalizeDAO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_initialSemanticVersion","type":"uint16[3]"},{"name":"_lidoImplAddress","type":"address"},{"name":"_lidoContentURI","type":"bytes"},{"name":"_nodeOperatorsRegistryImplAddress","type":"address"},{"name":"_nodeOperatorsRegistryContentURI","type":"bytes"}],"name":"createRepos","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tld","type":"bytes32"},{"name":"_label","type":"bytes32"}],"name":"deployLidoAPM","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_holders","type":"address[]"},{"name":"_amounts","type":"uint256[]"},{"name":"_vestingStart","type":"uint64"},{"name":"_vestingCliff","type":"uint64"},{"name":"_vestingEnd","type":"uint64"},{"name":"_vestingRevokable","type":"bool"},{"name":"_expectedFinalTotalSupply","type":"uint256"}],"name":"issueTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"_to","type":"address"}],"name":"cancelAndTransferDomain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getConfig","outputs":[{"name":"_owner","type":"address"},{"name":"_daoFactory","type":"address"},{"name":"_ens","type":"address"},{"name":"_miniMeFactory","type":"address"},{"name":"_aragonID","type":"address"},{"name":"_apmRegistryFactory","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_owner","type":"address"},{"name":"_daoFactory","type":"address"},{"name":"_ens","type":"address"},{"name":"_miniMeFactory","type":"address"},{"name":"_aragonID","type":"address"},{"name":"_apmRegistryFactory","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"apm","type":"address"}],"name":"TmplAPMDeployed","type":"event"},{"anonymous":false,"inputs":[],"name":"TmplReposCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"appProxy","type":"address"},{"indexed":false,"name":"appId","type":"bytes32"}],"name":"TmplAppInstalled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"dao","type":"address"},{"indexed":false,"name":"token","type":"address"}],"name":"TmplDAOAndTokenDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"totalAmount","type":"uint256"}],"name":"TmplTokensIssued","type":"event"},{"anonymous":false,"inputs":[],"name":"TmplDaoFinalized","type":"event"}] \ No newline at end of file diff --git a/lib/abi/NodeOperatorsRegistry.json b/lib/abi/NodeOperatorsRegistry.json deleted file mode 100644 index 846e58f1a..000000000 --- a/lib/abi/NodeOperatorsRegistry.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_keysCount","type":"uint256"},{"name":"_publicKeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getType","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"clearNodeOperatorPenalty","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_offset","type":"uint256"},{"name":"_limit","type":"uint256"}],"name":"getNodeOperatorIds","outputs":[{"name":"nodeOperatorIds","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_offset","type":"uint256"},{"name":"_limit","type":"uint256"}],"name":"getSigningKeys","outputs":[{"name":"pubkeys","type":"bytes"},{"name":"signatures","type":"bytes"},{"name":"used","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fromIndex","type":"uint256"},{"name":"_keysCount","type":"uint256"}],"name":"removeSigningKeysOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorIsActive","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_name","type":"string"}],"name":"setNodeOperatorName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_totalRewardShares","type":"uint256"}],"name":"getRewardsDistribution","outputs":[{"name":"recipients","type":"address[]"},{"name":"shares","type":"uint256[]"},{"name":"penalized","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_indexFrom","type":"uint256"},{"name":"_indexTo","type":"uint256"}],"name":"invalidateReadyToDepositKeysRange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_locator","type":"address"},{"name":"_type","type":"bytes32"},{"name":"_stuckPenaltyDelay","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_delay","type":"uint256"}],"name":"setStuckPenaltyDelay","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStuckPenaltyDelay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fromIndex","type":"uint256"},{"name":"_keysCount","type":"uint256"}],"name":"removeSigningKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"isOperatorPenalized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"deactivateNodeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"STAKING_ROUTER_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_keysCount","type":"uint256"},{"name":"_publicKeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeysOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getActiveNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_rewardAddress","type":"address"}],"name":"addNodeOperator","outputs":[{"name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getContractVersion","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getUnusedSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"onRewardsMinted","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_NODE_OPERATOR_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"onWithdrawalCredentialsChanged","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"activateNodeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_rewardAddress","type":"address"}],"name":"setNodeOperatorRewardAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_fullInfo","type":"bool"}],"name":"getNodeOperator","outputs":[{"name":"active","type":"bool"},{"name":"name","type":"string"},{"name":"rewardAddress","type":"address"},{"name":"stakingLimit","type":"uint64"},{"name":"stoppedValidators","type":"uint64"},{"name":"totalSigningKeys","type":"uint64"},{"name":"usedSigningKeys","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_locator","type":"address"},{"name":"_type","type":"bytes32"},{"name":"_stuckPenaltyDelay","type":"uint256"}],"name":"finalizeUpgrade_v2","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStakingModuleSummary","outputs":[{"name":"totalExitedValidators","type":"uint256"},{"name":"totalDepositedValidators","type":"uint256"},{"name":"depositableValidatorsCount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorIds","type":"bytes"},{"name":"_exitedValidatorsCounts","type":"bytes"}],"name":"updateExitedValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorIds","type":"bytes"},{"name":"_stuckValidatorsCounts","type":"bytes"}],"name":"updateStuckValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_refundedValidatorsCount","type":"uint256"}],"name":"updateRefundedValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_isTargetLimitActive","type":"bool"},{"name":"_targetLimit","type":"uint256"}],"name":"updateTargetValidatorsLimits","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_vettedSigningKeysCount","type":"uint64"}],"name":"setNodeOperatorStakingLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorSummary","outputs":[{"name":"isTargetLimitActive","type":"bool"},{"name":"targetValidatorsCount","type":"uint256"},{"name":"stuckValidatorsCount","type":"uint256"},{"name":"refundedValidatorsCount","type":"uint256"},{"name":"stuckPenaltyEndTimestamp","type":"uint256"},{"name":"totalExitedValidators","type":"uint256"},{"name":"totalDepositedValidators","type":"uint256"},{"name":"depositableValidatorsCount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"getSigningKey","outputs":[{"name":"key","type":"bytes"},{"name":"depositSignature","type":"bytes"},{"name":"used","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_NODE_OPERATOR_NAME_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_depositsCount","type":"uint256"},{"name":"","type":"bytes"}],"name":"obtainDepositData","outputs":[{"name":"publicKeys","type":"bytes"},{"name":"signatures","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getKeysOpIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNonce","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getLocator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SET_NODE_OPERATOR_LIMIT_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"getTotalSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_STUCK_PENALTY_DELAY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"onExitedAndStuckValidatorsCountsUpdated","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_NODE_OPERATORS_COUNT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKeyOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nodeOperatorId","type":"uint256"},{"name":"_exitedValidatorsCount","type":"uint256"},{"name":"_stuckValidatorsCount","type":"uint256"}],"name":"unsafeUpdateValidatorsCount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_SIGNING_KEYS","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_nodeOperatorId","type":"uint256"}],"name":"isOperatorPenaltyCleared","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"rewardAddress","type":"address"},{"indexed":false,"name":"stakingLimit","type":"uint64"}],"name":"NodeOperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"NodeOperatorActiveSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"name","type":"string"}],"name":"NodeOperatorNameSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"rewardAddress","type":"address"}],"name":"NodeOperatorRewardAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"totalKeysTrimmed","type":"uint64"}],"name":"NodeOperatorTotalKeysTrimmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"keysOpIndex","type":"uint256"}],"name":"KeysOpIndexSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"moduleType","type":"bytes32"}],"name":"StakingModuleTypeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"rewardAddress","type":"address"},{"indexed":false,"name":"sharesAmount","type":"uint256"}],"name":"RewardsDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"locatorAddress","type":"address"}],"name":"LocatorContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"approvedValidatorsCount","type":"uint256"}],"name":"VettedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"depositedValidatorsCount","type":"uint256"}],"name":"DepositedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"exitedValidatorsCount","type":"uint256"}],"name":"ExitedSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"totalValidatorsCount","type":"uint256"}],"name":"TotalSigningKeysCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"nonce","type":"uint256"}],"name":"NonceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"stuckPenaltyDelay","type":"uint256"}],"name":"StuckPenaltyDelayChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"stuckValidatorsCount","type":"uint256"},{"indexed":false,"name":"refundedValidatorsCount","type":"uint256"},{"indexed":false,"name":"stuckPenaltyEndTimestamp","type":"uint256"}],"name":"StuckPenaltyStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"targetValidatorsCount","type":"uint256"}],"name":"TargetValidatorsCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipientAddress","type":"address"},{"indexed":false,"name":"sharesPenalizedAmount","type":"uint256"}],"name":"NodeOperatorPenalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}] \ No newline at end of file diff --git a/lib/abi/OracleDaemonConfig.json b/lib/abi/OracleDaemonConfig.json deleted file mode 100644 index 431f79df1..000000000 --- a/lib/abi/OracleDaemonConfig.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address[]","name":"_configManagers","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"key","type":"string"}],"name":"EmptyValue","type":"error"},{"inputs":[{"internalType":"string","name":"key","type":"string"}],"name":"ValueDoesntExist","type":"error"},{"inputs":[{"internalType":"string","name":"key","type":"string"}],"name":"ValueExists","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"key","type":"string"},{"indexed":false,"internalType":"bytes","name":"value","type":"bytes"}],"name":"ConfigValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"key","type":"string"}],"name":"ConfigValueUnset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"key","type":"string"},{"indexed":false,"internalType":"bytes","name":"value","type":"bytes"}],"name":"ConfigValueUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"CONFIG_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_key","type":"string"}],"name":"get","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string[]","name":"_keys","type":"string[]"}],"name":"getList","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_key","type":"string"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_key","type":"string"}],"name":"unset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_key","type":"string"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/OracleReportSanityChecker.json b/lib/abi/OracleReportSanityChecker.json deleted file mode 100644 index c58226d77..000000000 --- a/lib/abi/OracleReportSanityChecker.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_lidoLocator","type":"address"},{"internalType":"address","name":"_admin","type":"address"},{"components":[{"internalType":"uint256","name":"churnValidatorsPerDayLimit","type":"uint256"},{"internalType":"uint256","name":"oneOffCLBalanceDecreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"annualBalanceIncreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"simulatedShareRateDeviationBPLimit","type":"uint256"},{"internalType":"uint256","name":"maxValidatorExitRequestsPerReport","type":"uint256"},{"internalType":"uint256","name":"maxAccountingExtraDataListItemsCount","type":"uint256"},{"internalType":"uint256","name":"maxNodeOperatorsPerExtraDataItemCount","type":"uint256"},{"internalType":"uint256","name":"requestTimestampMargin","type":"uint256"},{"internalType":"uint256","name":"maxPositiveTokenRebase","type":"uint256"}],"internalType":"struct LimitsList","name":"_limitsList","type":"tuple"},{"components":[{"internalType":"address[]","name":"allLimitsManagers","type":"address[]"},{"internalType":"address[]","name":"churnValidatorsPerDayLimitManagers","type":"address[]"},{"internalType":"address[]","name":"oneOffCLBalanceDecreaseLimitManagers","type":"address[]"},{"internalType":"address[]","name":"annualBalanceIncreaseLimitManagers","type":"address[]"},{"internalType":"address[]","name":"shareRateDeviationLimitManagers","type":"address[]"},{"internalType":"address[]","name":"maxValidatorExitRequestsPerReportManagers","type":"address[]"},{"internalType":"address[]","name":"maxAccountingExtraDataListItemsCountManagers","type":"address[]"},{"internalType":"address[]","name":"maxNodeOperatorsPerExtraDataItemCountManagers","type":"address[]"},{"internalType":"address[]","name":"requestTimestampMarginManagers","type":"address[]"},{"internalType":"address[]","name":"maxPositiveTokenRebaseManagers","type":"address[]"}],"internalType":"struct OracleReportSanityChecker.ManagersRoster","name":"_managersRoster","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ActualShareRateIsZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"limitPerDay","type":"uint256"},{"internalType":"uint256","name":"exitedPerDay","type":"uint256"}],"name":"ExitedValidatorsLimitExceeded","type":"error"},{"inputs":[{"internalType":"uint256","name":"churnLimit","type":"uint256"}],"name":"IncorrectAppearedValidators","type":"error"},{"inputs":[{"internalType":"uint256","name":"oneOffCLBalanceDecreaseBP","type":"uint256"}],"name":"IncorrectCLBalanceDecrease","type":"error"},{"inputs":[{"internalType":"uint256","name":"annualBalanceDiff","type":"uint256"}],"name":"IncorrectCLBalanceIncrease","type":"error"},{"inputs":[{"internalType":"uint256","name":"actualELRewardsVaultBalance","type":"uint256"}],"name":"IncorrectELRewardsVaultBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"churnLimit","type":"uint256"}],"name":"IncorrectExitedValidators","type":"error"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"maxAllowedValue","type":"uint256"}],"name":"IncorrectLimitValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxRequestsCount","type":"uint256"}],"name":"IncorrectNumberOfExitRequestsPerReport","type":"error"},{"inputs":[{"internalType":"uint256","name":"requestCreationBlock","type":"uint256"}],"name":"IncorrectRequestFinalization","type":"error"},{"inputs":[{"internalType":"uint256","name":"actualSharesToBurn","type":"uint256"}],"name":"IncorrectSharesRequestedToBurn","type":"error"},{"inputs":[{"internalType":"uint256","name":"actualWithdrawalVaultBalance","type":"uint256"}],"name":"IncorrectWithdrawalsVaultBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxItemsCount","type":"uint256"},{"internalType":"uint256","name":"receivedItemsCount","type":"uint256"}],"name":"MaxAccountingExtraDataItemsCountExceeded","type":"error"},{"inputs":[],"name":"NegativeTotalPooledEther","type":"error"},{"inputs":[{"internalType":"uint256","name":"simulatedShareRate","type":"uint256"},{"internalType":"uint256","name":"actualShareRate","type":"uint256"}],"name":"TooHighSimulatedShareRate","type":"error"},{"inputs":[],"name":"TooHighTokenRebaseLimit","type":"error"},{"inputs":[{"internalType":"uint256","name":"simulatedShareRate","type":"uint256"},{"internalType":"uint256","name":"actualShareRate","type":"uint256"}],"name":"TooLowSimulatedShareRate","type":"error"},{"inputs":[],"name":"TooLowTokenRebaseLimit","type":"error"},{"inputs":[{"internalType":"uint256","name":"itemIndex","type":"uint256"},{"internalType":"uint256","name":"nodeOpsCount","type":"uint256"}],"name":"TooManyNodeOpsPerExtraDataItem","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"annualBalanceIncreaseBPLimit","type":"uint256"}],"name":"AnnualBalanceIncreaseBPLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"churnValidatorsPerDayLimit","type":"uint256"}],"name":"ChurnValidatorsPerDayLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxAccountingExtraDataListItemsCount","type":"uint256"}],"name":"MaxAccountingExtraDataListItemsCountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxNodeOperatorsPerExtraDataItemCount","type":"uint256"}],"name":"MaxNodeOperatorsPerExtraDataItemCountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxPositiveTokenRebase","type":"uint256"}],"name":"MaxPositiveTokenRebaseSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxValidatorExitRequestsPerReport","type":"uint256"}],"name":"MaxValidatorExitRequestsPerReportSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oneOffCLBalanceDecreaseBPLimit","type":"uint256"}],"name":"OneOffCLBalanceDecreaseBPLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestTimestampMargin","type":"uint256"}],"name":"RequestTimestampMarginSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"simulatedShareRateDeviationBPLimit","type":"uint256"}],"name":"SimulatedShareRateDeviationBPLimitSet","type":"event"},{"inputs":[],"name":"ALL_LIMITS_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHURN_VALIDATORS_PER_DAY_LIMIT_MANGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ACCOUNTING_EXTRA_DATA_LIST_ITEMS_COUNT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NODE_OPERATORS_PER_EXTRA_DATA_ITEM_COUNT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_POSITIVE_TOKEN_REBASE_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VALIDATOR_EXIT_REQUESTS_PER_REPORT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REQUEST_TIMESTAMP_MARGIN_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SHARE_RATE_DEVIATION_LIMIT_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_extraDataListItemsCount","type":"uint256"}],"name":"checkAccountingExtraDataListItemsCount","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timeElapsed","type":"uint256"},{"internalType":"uint256","name":"_preCLBalance","type":"uint256"},{"internalType":"uint256","name":"_postCLBalance","type":"uint256"},{"internalType":"uint256","name":"_withdrawalVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_elRewardsVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_sharesRequestedToBurn","type":"uint256"},{"internalType":"uint256","name":"_preCLValidators","type":"uint256"},{"internalType":"uint256","name":"_postCLValidators","type":"uint256"}],"name":"checkAccountingOracleReport","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_exitRequestsCount","type":"uint256"}],"name":"checkExitBusOracleReport","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_exitedValidatorsCount","type":"uint256"}],"name":"checkExitedValidatorsRatePerDay","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_itemIndex","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorsCount","type":"uint256"}],"name":"checkNodeOperatorsPerExtraDataItemCount","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_postTotalPooledEther","type":"uint256"},{"internalType":"uint256","name":"_postTotalShares","type":"uint256"},{"internalType":"uint256","name":"_etherLockedOnWithdrawalQueue","type":"uint256"},{"internalType":"uint256","name":"_sharesBurntDueToWithdrawals","type":"uint256"},{"internalType":"uint256","name":"_simulatedShareRate","type":"uint256"}],"name":"checkSimulatedShareRate","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastFinalizableRequestId","type":"uint256"},{"internalType":"uint256","name":"_reportTimestamp","type":"uint256"}],"name":"checkWithdrawalQueueOracleReport","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLidoLocator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxPositiveTokenRebase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracleReportLimits","outputs":[{"components":[{"internalType":"uint256","name":"churnValidatorsPerDayLimit","type":"uint256"},{"internalType":"uint256","name":"oneOffCLBalanceDecreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"annualBalanceIncreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"simulatedShareRateDeviationBPLimit","type":"uint256"},{"internalType":"uint256","name":"maxValidatorExitRequestsPerReport","type":"uint256"},{"internalType":"uint256","name":"maxAccountingExtraDataListItemsCount","type":"uint256"},{"internalType":"uint256","name":"maxNodeOperatorsPerExtraDataItemCount","type":"uint256"},{"internalType":"uint256","name":"requestTimestampMargin","type":"uint256"},{"internalType":"uint256","name":"maxPositiveTokenRebase","type":"uint256"}],"internalType":"struct LimitsList","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_annualBalanceIncreaseBPLimit","type":"uint256"}],"name":"setAnnualBalanceIncreaseBPLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_churnValidatorsPerDayLimit","type":"uint256"}],"name":"setChurnValidatorsPerDayLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxAccountingExtraDataListItemsCount","type":"uint256"}],"name":"setMaxAccountingExtraDataListItemsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxValidatorExitRequestsPerReport","type":"uint256"}],"name":"setMaxExitRequestsPerOracleReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxNodeOperatorsPerExtraDataItemCount","type":"uint256"}],"name":"setMaxNodeOperatorsPerExtraDataItemCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxPositiveTokenRebase","type":"uint256"}],"name":"setMaxPositiveTokenRebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_oneOffCLBalanceDecreaseBPLimit","type":"uint256"}],"name":"setOneOffCLBalanceDecreaseBPLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"churnValidatorsPerDayLimit","type":"uint256"},{"internalType":"uint256","name":"oneOffCLBalanceDecreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"annualBalanceIncreaseBPLimit","type":"uint256"},{"internalType":"uint256","name":"simulatedShareRateDeviationBPLimit","type":"uint256"},{"internalType":"uint256","name":"maxValidatorExitRequestsPerReport","type":"uint256"},{"internalType":"uint256","name":"maxAccountingExtraDataListItemsCount","type":"uint256"},{"internalType":"uint256","name":"maxNodeOperatorsPerExtraDataItemCount","type":"uint256"},{"internalType":"uint256","name":"requestTimestampMargin","type":"uint256"},{"internalType":"uint256","name":"maxPositiveTokenRebase","type":"uint256"}],"internalType":"struct LimitsList","name":"_limitsList","type":"tuple"}],"name":"setOracleReportLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestTimestampMargin","type":"uint256"}],"name":"setRequestTimestampMargin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_simulatedShareRateDeviationBPLimit","type":"uint256"}],"name":"setSimulatedShareRateDeviationBPLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_preTotalPooledEther","type":"uint256"},{"internalType":"uint256","name":"_preTotalShares","type":"uint256"},{"internalType":"uint256","name":"_preCLBalance","type":"uint256"},{"internalType":"uint256","name":"_postCLBalance","type":"uint256"},{"internalType":"uint256","name":"_withdrawalVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_elRewardsVaultBalance","type":"uint256"},{"internalType":"uint256","name":"_sharesRequestedToBurn","type":"uint256"},{"internalType":"uint256","name":"_etherToLockForWithdrawals","type":"uint256"},{"internalType":"uint256","name":"_newSharesToBurnForWithdrawals","type":"uint256"}],"name":"smoothenTokenRebase","outputs":[{"internalType":"uint256","name":"withdrawals","type":"uint256"},{"internalType":"uint256","name":"elRewards","type":"uint256"},{"internalType":"uint256","name":"simulatedSharesToBurn","type":"uint256"},{"internalType":"uint256","name":"sharesToBurn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/OssifiableProxy.json b/lib/abi/OssifiableProxy.json deleted file mode 100644 index 731606988..000000000 --- a/lib/abi/OssifiableProxy.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"implementation_","type":"address"},{"internalType":"address","name":"admin_","type":"address"},{"internalType":"bytes","name":"data_","type":"bytes"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotAdmin","type":"error"},{"inputs":[],"name":"ProxyIsOssified","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[],"name":"ProxyOssified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"newAdmin_","type":"address"}],"name":"proxy__changeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxy__getAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxy__getImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxy__getIsOssified","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxy__ossify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation_","type":"address"}],"name":"proxy__upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation_","type":"address"},{"internalType":"bytes","name":"setupCalldata_","type":"bytes"},{"internalType":"bool","name":"forceCall_","type":"bool"}],"name":"proxy__upgradeToAndCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}] \ No newline at end of file diff --git a/lib/abi/PositiveTokenRebaseLimiter.json b/lib/abi/PositiveTokenRebaseLimiter.json deleted file mode 100644 index f3c22b8f6..000000000 --- a/lib/abi/PositiveTokenRebaseLimiter.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"name":"NegativeTotalPooledEther","type":"error"},{"inputs":[],"name":"TooHighTokenRebaseLimit","type":"error"},{"inputs":[],"name":"TooLowTokenRebaseLimit","type":"error"},{"inputs":[],"name":"LIMITER_PRECISION_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNLIMITED_REBASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/SigningKeys.json b/lib/abi/SigningKeys.json deleted file mode 100644 index 365e3221d..000000000 --- a/lib/abi/SigningKeys.json +++ /dev/null @@ -1 +0,0 @@ -[{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"pubkey","type":"bytes"}],"name":"SigningKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nodeOperatorId","type":"uint256"},{"indexed":false,"name":"pubkey","type":"bytes"}],"name":"SigningKeyRemoved","type":"event"}] \ No newline at end of file diff --git a/lib/abi/StETH.json b/lib/abi/StETH.json deleted file mode 100644 index a03c73292..000000000 --- a/lib/abi/StETH.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_ethAmount","type":"uint256"}],"name":"getSharesByPooledEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"},{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getTotalPooledEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isStopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"},{"name":"_recipient","type":"address"},{"name":"_sharesAmount","type":"uint256"}],"name":"transferSharesFrom","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sharesAmount","type":"uint256"}],"name":"getPooledEthByShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_sharesAmount","type":"uint256"}],"name":"transferShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getTotalShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"sharesOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"sharesValue","type":"uint256"}],"name":"TransferShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"preRebaseTokenAmount","type":"uint256"},{"indexed":false,"name":"postRebaseTokenAmount","type":"uint256"},{"indexed":false,"name":"sharesAmount","type":"uint256"}],"name":"SharesBurnt","type":"event"},{"anonymous":false,"inputs":[],"name":"Stopped","type":"event"},{"anonymous":false,"inputs":[],"name":"Resumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}] \ No newline at end of file diff --git a/lib/abi/StETHPermit.json b/lib/abi/StETHPermit.json deleted file mode 100644 index b3ae6e2cc..000000000 --- a/lib/abi/StETHPermit.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_ethAmount","type":"uint256"}],"name":"getSharesByPooledEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"},{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalPooledEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isStopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"},{"name":"_recipient","type":"address"},{"name":"_sharesAmount","type":"uint256"}],"name":"transferSharesFrom","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sharesAmount","type":"uint256"}],"name":"getPooledEthByShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"nonces","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"eip712Domain","outputs":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_sharesAmount","type":"uint256"}],"name":"transferShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getEIP712StETH","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getTotalShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_deadline","type":"uint256"},{"name":"_v","type":"uint8"},{"name":"_r","type":"bytes32"},{"name":"_s","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"sharesOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"eip712StETH","type":"address"}],"name":"EIP712StETHInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"sharesValue","type":"uint256"}],"name":"TransferShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"preRebaseTokenAmount","type":"uint256"},{"indexed":false,"name":"postRebaseTokenAmount","type":"uint256"},{"indexed":false,"name":"sharesAmount","type":"uint256"}],"name":"SharesBurnt","type":"event"},{"anonymous":false,"inputs":[],"name":"Stopped","type":"event"},{"anonymous":false,"inputs":[],"name":"Resumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}] \ No newline at end of file diff --git a/lib/abi/StakingRouter.json b/lib/abi/StakingRouter.json deleted file mode 100644 index 88b6ba986..000000000 --- a/lib/abi/StakingRouter.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_depositContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AppAuthLidoFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"firstArrayLength","type":"uint256"},{"internalType":"uint256","name":"secondArrayLength","type":"uint256"}],"name":"ArraysLengthMismatch","type":"error"},{"inputs":[],"name":"DepositContractZeroAddress","type":"error"},{"inputs":[],"name":"DirectETHTransfer","type":"error"},{"inputs":[],"name":"EmptyWithdrawalsCredentials","type":"error"},{"inputs":[],"name":"ExitedValidatorsCountCannotDecrease","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[{"internalType":"uint256","name":"etherValue","type":"uint256"},{"internalType":"uint256","name":"depositsCount","type":"uint256"}],"name":"InvalidDepositsValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidPublicKeysBatchLength","type":"error"},{"inputs":[{"internalType":"uint256","name":"code","type":"uint256"}],"name":"InvalidReportData","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidSignaturesBatchLength","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[],"name":"StakingModuleAddressExists","type":"error"},{"inputs":[],"name":"StakingModuleNotActive","type":"error"},{"inputs":[],"name":"StakingModuleNotPaused","type":"error"},{"inputs":[],"name":"StakingModuleStatusTheSame","type":"error"},{"inputs":[],"name":"StakingModuleUnregistered","type":"error"},{"inputs":[],"name":"StakingModuleWrongName","type":"error"},{"inputs":[],"name":"StakingModulesLimitExceeded","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOpExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOpStuckValidatorsCount","type":"uint256"}],"name":"UnexpectedCurrentValidatorsCount","type":"error"},{"inputs":[],"name":"UnrecoverableModuleError","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ValueOver100Percent","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"ExitedAndStuckValidatorsCountsUpdateFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"RewardsMintedReportFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"address","name":"stakingModule","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"createdBy","type":"address"}],"name":"StakingModuleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unreportedExitedValidatorsCount","type":"uint256"}],"name":"StakingModuleExitedValidatorsIncompleteReporting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakingModuleFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"treasuryFee","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleFeesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"enum StakingRouter.StakingModuleStatus","name":"status","type":"uint8"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleStatusSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"targetShare","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleTargetShareSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakingRouterETHDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"withdrawalCredentials","type":"bytes32"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"WithdrawalCredentialsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"WithdrawalsCredentialsChangeFailed","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_PRECISION_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_WITHDRAWAL_CREDENTIALS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STAKING_MODULES_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STAKING_MODULE_NAME_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REPORT_EXITED_VALIDATORS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REPORT_REWARDS_MINTED_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_MANAGE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_PAUSE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_RESUME_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNSAFE_SET_EXITED_VALIDATORS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_stakingModuleAddress","type":"address"},{"internalType":"uint256","name":"_targetShare","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleFee","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"addStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositsCount","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_depositCalldata","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getAllNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllStakingModuleDigests","outputs":[{"components":[{"internalType":"uint256","name":"nodeOperatorsCount","type":"uint256"},{"internalType":"uint256","name":"activeNodeOperatorsCount","type":"uint256"},{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule","name":"state","type":"tuple"},{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.StakingModuleDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositsCount","type":"uint256"}],"name":"getDepositsAllocation","outputs":[{"internalType":"uint256","name":"allocated","type":"uint256"},{"internalType":"uint256[]","name":"allocations","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLido","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256[]","name":"_nodeOperatorIds","type":"uint256[]"}],"name":"getNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"digests","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorSummary","outputs":[{"components":[{"internalType":"bool","name":"isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingFeeAggregateDistribution","outputs":[{"internalType":"uint96","name":"modulesFee","type":"uint96"},{"internalType":"uint96","name":"treasuryFee","type":"uint96"},{"internalType":"uint256","name":"basePrecision","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingFeeAggregateDistributionE4Precision","outputs":[{"internalType":"uint16","name":"modulesFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModule","outputs":[{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleActiveValidatorsCount","outputs":[{"internalType":"uint256","name":"activeValidatorsCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"}],"name":"getStakingModuleDigests","outputs":[{"components":[{"internalType":"uint256","name":"nodeOperatorsCount","type":"uint256"},{"internalType":"uint256","name":"activeNodeOperatorsCount","type":"uint256"},{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule","name":"state","type":"tuple"},{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.StakingModuleDigest[]","name":"digests","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModuleIds","outputs":[{"internalType":"uint256[]","name":"stakingModuleIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsDepositsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsStopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleLastDepositBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_maxDepositsValue","type":"uint256"}],"name":"getStakingModuleMaxDepositsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleStatus","outputs":[{"internalType":"enum StakingRouter.StakingModuleStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleSummary","outputs":[{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModules","outputs":[{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"targetShare","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModule[]","name":"res","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModulesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingRewardsDistribution","outputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"stakingModuleIds","type":"uint256[]"},{"internalType":"uint96[]","name":"stakingModuleFees","type":"uint96[]"},{"internalType":"uint96","name":"totalFee","type":"uint96"},{"internalType":"uint256","name":"precisionPoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalFeeE4Precision","outputs":[{"internalType":"uint16","name":"totalFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalCredentials","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"hasStakingModule","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_lido","type":"address"},{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"onValidatorsCountsByNodeOperatorReportingFinished","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"pauseStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_totalShares","type":"uint256[]"}],"name":"reportRewardsMinted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"_exitedValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleExitedValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"_stuckValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleStuckValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"resumeStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"enum StakingRouter.StakingModuleStatus","name":"_status","type":"uint8"}],"name":"setStakingModuleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"}],"name":"setWithdrawalCredentials","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"bool","name":"_triggerUpdateFinish","type":"bool"},{"components":[{"internalType":"uint256","name":"currentModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOperatorExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOperatorStuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newNodeOperatorExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newNodeOperatorStuckValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.ValidatorsCountsCorrection","name":"_correction","type":"tuple"}],"name":"unsafeSetExitedValidatorsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_exitedValidatorsCounts","type":"uint256[]"}],"name":"updateExitedValidatorsCountByStakingModule","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"uint256","name":"_refundedValidatorsCount","type":"uint256"}],"name":"updateRefundedValidatorsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_targetShare","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleFee","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"updateStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"bool","name":"_isTargetLimitActive","type":"bool"},{"internalType":"uint256","name":"_targetLimit","type":"uint256"}],"name":"updateTargetValidatorsLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}] \ No newline at end of file diff --git a/lib/abi/TokenManager.json b/lib/abi/TokenManager.json deleted file mode 100644 index a560030c1..000000000 --- a/lib/abi/TokenManager.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_VESTINGS_PER_ADDRESS","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_holder","type":"address"}],"name":"spendableBalanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_receiver","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_start","type":"uint64"},{"name":"_cliff","type":"uint64"},{"name":"_vested","type":"uint64"},{"name":"_revokable","type":"bool"}],"name":"assignVested","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_recipient","type":"address"},{"name":"_vestingId","type":"uint256"}],"name":"getVesting","outputs":[{"name":"amount","type":"uint256"},{"name":"start","type":"uint64"},{"name":"cliff","type":"uint64"},{"name":"vesting","type":"uint64"},{"name":"revokable","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_receiver","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"onTransfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_holder","type":"address"},{"name":"_time","type":"uint256"}],"name":"transferableBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ISSUE_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"vestingsLengths","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_holder","type":"address"},{"name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ASSIGN_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BURN_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_receiver","type":"address"},{"name":"_amount","type":"uint256"}],"name":"assign","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"","type":"bytes"}],"name":"canForward","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"issue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_evmScript","type":"bytes"}],"name":"forward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"onApprove","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_transferable","type":"bool"},{"name":"_maxAccountTokens","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MINT_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxAccountTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"REVOKE_VESTINGS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"","type":"address"}],"name":"proxyPayment","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_holder","type":"address"},{"name":"_vestingId","type":"uint256"}],"name":"revokeVesting","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isForwarder","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"receiver","type":"address"},{"indexed":false,"name":"vestingId","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"NewVesting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"receiver","type":"address"},{"indexed":false,"name":"vestingId","type":"uint256"},{"indexed":false,"name":"nonVestedAmount","type":"uint256"}],"name":"RevokeVesting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}] \ No newline at end of file diff --git a/lib/abi/ValidatorsExitBusOracle.json b/lib/abi/ValidatorsExitBusOracle.json deleted file mode 100644 index 580e95171..000000000 --- a/lib/abi/ValidatorsExitBusOracle.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"uint256","name":"secondsPerSlot","type":"uint256"},{"internalType":"uint256","name":"genesisTime","type":"uint256"},{"internalType":"address","name":"lidoLocator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressCannotBeSame","type":"error"},{"inputs":[],"name":"AddressCannotBeZero","type":"error"},{"inputs":[],"name":"AdminCannotBeZero","type":"error"},{"inputs":[],"name":"ArgumentOutOfBounds","type":"error"},{"inputs":[{"internalType":"uint256","name":"initialRefSlot","type":"uint256"},{"internalType":"uint256","name":"processingRefSlot","type":"uint256"}],"name":"InitialRefSlotCannotBeLessThanProcessingOne","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[],"name":"InvalidRequestsData","type":"error"},{"inputs":[],"name":"InvalidRequestsDataLength","type":"error"},{"inputs":[],"name":"InvalidRequestsDataSortOrder","type":"error"},{"inputs":[{"internalType":"uint256","name":"moduleId","type":"uint256"},{"internalType":"uint256","name":"nodeOpId","type":"uint256"},{"internalType":"uint256","name":"prevRequestedValidatorIndex","type":"uint256"},{"internalType":"uint256","name":"requestedValidatorIndex","type":"uint256"}],"name":"NodeOpValidatorIndexMustIncrease","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[],"name":"OnlyConsensusContractCanSubmitReport","type":"error"},{"inputs":[],"name":"PauseUntilMustBeInFuture","type":"error"},{"inputs":[],"name":"PausedExpected","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ProcessingDeadlineMissed","type":"error"},{"inputs":[],"name":"RefSlotAlreadyProcessing","type":"error"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"prevRefSlot","type":"uint256"}],"name":"RefSlotCannotDecrease","type":"error"},{"inputs":[{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"processingRefSlot","type":"uint256"}],"name":"RefSlotMustBeGreaterThanProcessingOne","type":"error"},{"inputs":[],"name":"ResumedExpected","type":"error"},{"inputs":[],"name":"SenderNotAllowed","type":"error"},{"inputs":[],"name":"UnexpectedChainConfig","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedVersion","type":"uint256"},{"internalType":"uint256","name":"receivedVersion","type":"uint256"}],"name":"UnexpectedConsensusVersion","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[{"internalType":"bytes32","name":"consensusHash","type":"bytes32"},{"internalType":"bytes32","name":"receivedHash","type":"bytes32"}],"name":"UnexpectedDataHash","type":"error"},{"inputs":[{"internalType":"uint256","name":"consensusRefSlot","type":"uint256"},{"internalType":"uint256","name":"dataRefSlot","type":"uint256"}],"name":"UnexpectedRefSlot","type":"error"},{"inputs":[],"name":"UnexpectedRequestsDataLength","type":"error"},{"inputs":[{"internalType":"uint256","name":"format","type":"uint256"}],"name":"UnsupportedRequestsDataFormat","type":"error"},{"inputs":[],"name":"VersionCannotBeSame","type":"error"},{"inputs":[],"name":"ZeroPauseDuration","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"prevAddr","type":"address"}],"name":"ConsensusHashContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"version","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"prevVersion","type":"uint256"}],"name":"ConsensusVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"ProcessingStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"}],"name":"ReportSubmitted","type":"event"},{"anonymous":false,"inputs":[],"name":"Resumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nodeOperatorId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"validatorIndex","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"validatorPubkey","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ValidatorExitRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestsProcessed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestsCount","type":"uint256"}],"name":"WarnDataIncompleteProcessing","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"refSlot","type":"uint256"}],"name":"WarnProcessingMissed","type":"event"},{"inputs":[],"name":"DATA_FORMAT_LIST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GENESIS_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_CONSENSUS_CONTRACT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_CONSENSUS_VERSION_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_INFINITELY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESUME_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECONDS_PER_SLOT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUBMIT_DATA_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusReport","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"},{"internalType":"bool","name":"processingStarted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastProcessingRefSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"moduleId","type":"uint256"},{"internalType":"uint256[]","name":"nodeOpIds","type":"uint256[]"}],"name":"getLastRequestedValidatorIndices","outputs":[{"internalType":"int256[]","name":"","type":"int256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProcessingState","outputs":[{"components":[{"internalType":"uint256","name":"currentFrameRefSlot","type":"uint256"},{"internalType":"uint256","name":"processingDeadlineTime","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bool","name":"dataSubmitted","type":"bool"},{"internalType":"uint256","name":"dataFormat","type":"uint256"},{"internalType":"uint256","name":"requestsCount","type":"uint256"},{"internalType":"uint256","name":"requestsSubmitted","type":"uint256"}],"internalType":"struct ValidatorsExitBusOracle.ProcessingState","name":"result","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getResumeSinceTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalRequestsProcessed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"consensusContract","type":"address"},{"internalType":"uint256","name":"consensusVersion","type":"uint256"},{"internalType":"uint256","name":"lastProcessingRefSlot","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"pauseFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pauseUntilInclusive","type":"uint256"}],"name":"pauseUntil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resume","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setConsensusContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"version","type":"uint256"}],"name":"setConsensusVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"reportHash","type":"bytes32"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"submitConsensusReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"consensusVersion","type":"uint256"},{"internalType":"uint256","name":"refSlot","type":"uint256"},{"internalType":"uint256","name":"requestsCount","type":"uint256"},{"internalType":"uint256","name":"dataFormat","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ValidatorsExitBusOracle.ReportData","name":"data","type":"tuple"},{"internalType":"uint256","name":"contractVersion","type":"uint256"}],"name":"submitReportData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/Vault.json b/lib/abi/Vault.json deleted file mode 100644 index e64508583..000000000 --- a/lib/abi/Vault.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"TRANSFER_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_value","type":"uint256"}],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"isDepositable","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"}],"name":"balance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"token","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"VaultTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"token","type":"address"},{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"VaultDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}] \ No newline at end of file diff --git a/lib/abi/Versioned.json b/lib/abi/Versioned.json deleted file mode 100644 index b6bca8f6f..000000000 --- a/lib/abi/Versioned.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/Voting.json b/lib/abi/Voting.json deleted file mode 100644 index 9caca0ac0..000000000 --- a/lib/abi/Voting.json +++ /dev/null @@ -1 +0,0 @@ -[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_objectionPhaseTime","type":"uint64"}],"name":"unsafelyChangeObjectionPhaseTime","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_supportRequiredPct","type":"uint64"},{"name":"_minAcceptQuorumPct","type":"uint64"},{"name":"_voteTime","type":"uint64"},{"name":"_objectionPhaseTime","type":"uint64"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"UNSAFELY_MODIFY_VOTE_TIME_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_voteTime","type":"uint64"}],"name":"unsafelyChangeVoteTime","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MODIFY_QUORUM_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"objectionPhaseTime","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"},{"name":"_voter","type":"address"}],"name":"getVoterState","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"getVote","outputs":[{"name":"open","type":"bool"},{"name":"executed","type":"bool"},{"name":"startDate","type":"uint64"},{"name":"snapshotBlock","type":"uint64"},{"name":"supportRequired","type":"uint64"},{"name":"minAcceptQuorum","type":"uint64"},{"name":"yea","type":"uint256"},{"name":"nay","type":"uint256"},{"name":"votingPower","type":"uint256"},{"name":"script","type":"bytes"},{"name":"phase","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_minAcceptQuorumPct","type":"uint64"}],"name":"changeMinAcceptQuorumPct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MODIFY_SUPPORT_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_supportRequiredPct","type":"uint64"}],"name":"changeSupportRequiredPct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"voteTime","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CREATE_VOTES_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"","type":"bytes"}],"name":"canForward","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"canExecute","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"},{"name":"_voter","type":"address"}],"name":"canVote","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_executionScript","type":"bytes"},{"name":"_metadata","type":"string"}],"name":"newVote","outputs":[{"name":"voteId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_evmScript","type":"bytes"}],"name":"forward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"minAcceptQuorumPct","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"votesLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_voteId","type":"uint256"},{"name":"_supports","type":"bool"},{"name":"_executesIfDecided_deprecated","type":"bool"}],"name":"vote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_executionScript","type":"bytes"},{"name":"_metadata","type":"string"},{"name":"_castVote","type":"bool"},{"name":"_executesIfDecided_deprecated","type":"bool"}],"name":"newVote","outputs":[{"name":"voteId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"getVotePhase","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"executeVote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"supportRequiredPct","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PCT_BASE","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isForwarder","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"},{"indexed":true,"name":"creator","type":"address"},{"indexed":false,"name":"metadata","type":"string"}],"name":"StartVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"},{"indexed":true,"name":"voter","type":"address"},{"indexed":false,"name":"supports","type":"bool"},{"indexed":false,"name":"stake","type":"uint256"}],"name":"CastVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"},{"indexed":true,"name":"voter","type":"address"},{"indexed":false,"name":"stake","type":"uint256"}],"name":"CastObjection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"}],"name":"ExecuteVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"supportRequiredPct","type":"uint64"}],"name":"ChangeSupportRequired","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minAcceptQuorumPct","type":"uint64"}],"name":"ChangeMinQuorum","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"voteTime","type":"uint64"}],"name":"ChangeVoteTime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"objectionPhaseTime","type":"uint64"}],"name":"ChangeObjectionPhaseTime","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}] \ No newline at end of file diff --git a/lib/abi/WithdrawalQueue.json b/lib/abi/WithdrawalQueue.json deleted file mode 100644 index e0520efe9..000000000 --- a/lib/abi/WithdrawalQueue.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"name":"AdminZeroAddress","type":"error"},{"inputs":[],"name":"BatchesAreNotSorted","type":"error"},{"inputs":[],"name":"CantSendValueRecipientMayHaveReverted","type":"error"},{"inputs":[],"name":"EmptyBatches","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[{"internalType":"uint256","name":"_hint","type":"uint256"}],"name":"InvalidHint","type":"error"},{"inputs":[],"name":"InvalidReportTimestamp","type":"error"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"InvalidRequestId","type":"error"},{"inputs":[{"internalType":"uint256","name":"startId","type":"uint256"},{"internalType":"uint256","name":"endId","type":"uint256"}],"name":"InvalidRequestIdRange","type":"error"},{"inputs":[],"name":"InvalidState","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[],"name":"NotEnoughEther","type":"error"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"NotOwner","type":"error"},{"inputs":[],"name":"PauseUntilMustBeInFuture","type":"error"},{"inputs":[],"name":"PausedExpected","type":"error"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"RequestAlreadyClaimed","type":"error"},{"inputs":[{"internalType":"uint256","name":"_amountOfStETH","type":"uint256"}],"name":"RequestAmountTooLarge","type":"error"},{"inputs":[{"internalType":"uint256","name":"_amountOfStETH","type":"uint256"}],"name":"RequestAmountTooSmall","type":"error"},{"inputs":[],"name":"RequestIdsNotSorted","type":"error"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"RequestNotFoundOrNotFinalized","type":"error"},{"inputs":[],"name":"ResumedExpected","type":"error"},{"inputs":[{"internalType":"uint256","name":"sent","type":"uint256"},{"internalType":"uint256","name":"maxExpected","type":"uint256"}],"name":"TooMuchEtherToFinalize","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[],"name":"ZeroAmountOfETH","type":"error"},{"inputs":[],"name":"ZeroPauseDuration","type":"error"},{"inputs":[],"name":"ZeroRecipient","type":"error"},{"inputs":[],"name":"ZeroShareRate","type":"error"},{"inputs":[],"name":"ZeroTimestamp","type":"error"},{"anonymous":false,"inputs":[],"name":"BunkerModeDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sinceTimestamp","type":"uint256"}],"name":"BunkerModeEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_admin","type":"address"}],"name":"InitializedV1","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[],"name":"Resumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfETH","type":"uint256"}],"name":"WithdrawalClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"requestor","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfShares","type":"uint256"}],"name":"WithdrawalRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"from","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"to","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfETHLocked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sharesToBurn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalsFinalized","type":"event"},{"inputs":[],"name":"BUNKER_MODE_DISABLED_TIMESTAMP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FINALIZE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BATCHES_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STETH_WITHDRAWAL_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_STETH_WITHDRAWAL_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_INFINITELY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESUME_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH","outputs":[{"internalType":"contract IStETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WSTETH","outputs":[{"internalType":"contract IWstETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bunkerModeSinceTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxShareRate","type":"uint256"},{"internalType":"uint256","name":"_maxTimestamp","type":"uint256"},{"internalType":"uint256","name":"_maxRequestsPerCall","type":"uint256"},{"components":[{"internalType":"uint256","name":"remainingEthBudget","type":"uint256"},{"internalType":"bool","name":"finished","type":"bool"},{"internalType":"uint256[36]","name":"batches","type":"uint256[36]"},{"internalType":"uint256","name":"batchesLength","type":"uint256"}],"internalType":"struct WithdrawalQueueBase.BatchesCalculationState","name":"_state","type":"tuple"}],"name":"calculateFinalizationBatches","outputs":[{"components":[{"internalType":"uint256","name":"remainingEthBudget","type":"uint256"},{"internalType":"bool","name":"finished","type":"bool"},{"internalType":"uint256[36]","name":"batches","type":"uint256[36]"},{"internalType":"uint256","name":"batchesLength","type":"uint256"}],"internalType":"struct WithdrawalQueueBase.BatchesCalculationState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"claimWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_hints","type":"uint256[]"}],"name":"claimWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_hints","type":"uint256[]"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"claimWithdrawalsTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_batches","type":"uint256[]"},{"internalType":"uint256","name":"_maxShareRate","type":"uint256"}],"name":"finalize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"},{"internalType":"uint256","name":"_firstIndex","type":"uint256"},{"internalType":"uint256","name":"_lastIndex","type":"uint256"}],"name":"findCheckpointHints","outputs":[{"internalType":"uint256[]","name":"hintIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_hints","type":"uint256[]"}],"name":"getClaimableEther","outputs":[{"internalType":"uint256[]","name":"claimableEthValues","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastCheckpointIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastFinalizedRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLockedEtherAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getResumeSinceTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getWithdrawalRequests","outputs":[{"internalType":"uint256[]","name":"requestsIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"}],"name":"getWithdrawalStatus","outputs":[{"components":[{"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"internalType":"uint256","name":"amountOfShares","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bool","name":"isFinalized","type":"bool"},{"internalType":"bool","name":"isClaimed","type":"bool"}],"internalType":"struct WithdrawalQueueBase.WithdrawalRequestStatus[]","name":"statuses","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isBunkerModeActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_isBunkerModeNow","type":"bool"},{"internalType":"uint256","name":"_bunkerStartTimestamp","type":"uint256"},{"internalType":"uint256","name":"_currentReportTimestamp","type":"uint256"}],"name":"onOracleReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"pauseFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pauseUntilInclusive","type":"uint256"}],"name":"pauseUntil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_batches","type":"uint256[]"},{"internalType":"uint256","name":"_maxShareRate","type":"uint256"}],"name":"prefinalize","outputs":[{"internalType":"uint256","name":"ethToLock","type":"uint256"},{"internalType":"uint256","name":"sharesToBurn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"_owner","type":"address"}],"name":"requestWithdrawals","outputs":[{"internalType":"uint256[]","name":"requestIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"address","name":"_owner","type":"address"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct WithdrawalQueue.PermitInput","name":"_permit","type":"tuple"}],"name":"requestWithdrawalsWithPermit","outputs":[{"internalType":"uint256[]","name":"requestIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"_owner","type":"address"}],"name":"requestWithdrawalsWstETH","outputs":[{"internalType":"uint256[]","name":"requestIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"address","name":"_owner","type":"address"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct WithdrawalQueue.PermitInput","name":"_permit","type":"tuple"}],"name":"requestWithdrawalsWstETHWithPermit","outputs":[{"internalType":"uint256[]","name":"requestIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resume","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unfinalizedRequestNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unfinalizedStETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/WithdrawalQueueBase.json b/lib/abi/WithdrawalQueueBase.json deleted file mode 100644 index 8038b4052..000000000 --- a/lib/abi/WithdrawalQueueBase.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[],"name":"BatchesAreNotSorted","type":"error"},{"inputs":[],"name":"CantSendValueRecipientMayHaveReverted","type":"error"},{"inputs":[],"name":"EmptyBatches","type":"error"},{"inputs":[{"internalType":"uint256","name":"_hint","type":"uint256"}],"name":"InvalidHint","type":"error"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"InvalidRequestId","type":"error"},{"inputs":[{"internalType":"uint256","name":"startId","type":"uint256"},{"internalType":"uint256","name":"endId","type":"uint256"}],"name":"InvalidRequestIdRange","type":"error"},{"inputs":[],"name":"InvalidState","type":"error"},{"inputs":[],"name":"NotEnoughEther","type":"error"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"NotOwner","type":"error"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"RequestAlreadyClaimed","type":"error"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"RequestNotFoundOrNotFinalized","type":"error"},{"inputs":[{"internalType":"uint256","name":"sent","type":"uint256"},{"internalType":"uint256","name":"maxExpected","type":"uint256"}],"name":"TooMuchEtherToFinalize","type":"error"},{"inputs":[],"name":"ZeroAmountOfETH","type":"error"},{"inputs":[],"name":"ZeroShareRate","type":"error"},{"inputs":[],"name":"ZeroTimestamp","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfETH","type":"uint256"}],"name":"WithdrawalClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"requestor","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfShares","type":"uint256"}],"name":"WithdrawalRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"from","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"to","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfETHLocked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sharesToBurn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalsFinalized","type":"event"},{"inputs":[],"name":"MAX_BATCHES_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxShareRate","type":"uint256"},{"internalType":"uint256","name":"_maxTimestamp","type":"uint256"},{"internalType":"uint256","name":"_maxRequestsPerCall","type":"uint256"},{"components":[{"internalType":"uint256","name":"remainingEthBudget","type":"uint256"},{"internalType":"bool","name":"finished","type":"bool"},{"internalType":"uint256[36]","name":"batches","type":"uint256[36]"},{"internalType":"uint256","name":"batchesLength","type":"uint256"}],"internalType":"struct WithdrawalQueueBase.BatchesCalculationState","name":"_state","type":"tuple"}],"name":"calculateFinalizationBatches","outputs":[{"components":[{"internalType":"uint256","name":"remainingEthBudget","type":"uint256"},{"internalType":"bool","name":"finished","type":"bool"},{"internalType":"uint256[36]","name":"batches","type":"uint256[36]"},{"internalType":"uint256","name":"batchesLength","type":"uint256"}],"internalType":"struct WithdrawalQueueBase.BatchesCalculationState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastCheckpointIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastFinalizedRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLockedEtherAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_batches","type":"uint256[]"},{"internalType":"uint256","name":"_maxShareRate","type":"uint256"}],"name":"prefinalize","outputs":[{"internalType":"uint256","name":"ethToLock","type":"uint256"},{"internalType":"uint256","name":"sharesToBurn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unfinalizedRequestNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unfinalizedStETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/WithdrawalQueueERC721.json b/lib/abi/WithdrawalQueueERC721.json deleted file mode 100644 index b8193930f..000000000 --- a/lib/abi/WithdrawalQueueERC721.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"address","name":"_wstETH","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AdminZeroAddress","type":"error"},{"inputs":[],"name":"ApprovalToOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BatchesAreNotSorted","type":"error"},{"inputs":[],"name":"CantSendValueRecipientMayHaveReverted","type":"error"},{"inputs":[],"name":"EmptyBatches","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[{"internalType":"uint256","name":"_hint","type":"uint256"}],"name":"InvalidHint","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"InvalidOwnerAddress","type":"error"},{"inputs":[],"name":"InvalidReportTimestamp","type":"error"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"InvalidRequestId","type":"error"},{"inputs":[{"internalType":"uint256","name":"startId","type":"uint256"},{"internalType":"uint256","name":"endId","type":"uint256"}],"name":"InvalidRequestIdRange","type":"error"},{"inputs":[],"name":"InvalidState","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[],"name":"NotEnoughEther","type":"error"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"NotOwner","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"NotOwnerOrApproved","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"NotOwnerOrApprovedForAll","type":"error"},{"inputs":[],"name":"PauseUntilMustBeInFuture","type":"error"},{"inputs":[],"name":"PausedExpected","type":"error"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"RequestAlreadyClaimed","type":"error"},{"inputs":[{"internalType":"uint256","name":"_amountOfStETH","type":"uint256"}],"name":"RequestAmountTooLarge","type":"error"},{"inputs":[{"internalType":"uint256","name":"_amountOfStETH","type":"uint256"}],"name":"RequestAmountTooSmall","type":"error"},{"inputs":[],"name":"RequestIdsNotSorted","type":"error"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"RequestNotFoundOrNotFinalized","type":"error"},{"inputs":[],"name":"ResumedExpected","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"inputs":[{"internalType":"uint256","name":"sent","type":"uint256"},{"internalType":"uint256","name":"maxExpected","type":"uint256"}],"name":"TooMuchEtherToFinalize","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"realOwner","type":"address"}],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferFromZeroAddress","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"TransferToNonIERC721Receiver","type":"error"},{"inputs":[],"name":"TransferToThemselves","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[],"name":"ZeroAmountOfETH","type":"error"},{"inputs":[],"name":"ZeroMetadata","type":"error"},{"inputs":[],"name":"ZeroPauseDuration","type":"error"},{"inputs":[],"name":"ZeroRecipient","type":"error"},{"inputs":[],"name":"ZeroShareRate","type":"error"},{"inputs":[],"name":"ZeroTimestamp","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"BaseURISet","type":"event"},{"anonymous":false,"inputs":[],"name":"BunkerModeDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_sinceTimestamp","type":"uint256"}],"name":"BunkerModeEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_admin","type":"address"}],"name":"InitializedV1","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftDescriptorAddress","type":"address"}],"name":"NftDescriptorAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[],"name":"Resumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfETH","type":"uint256"}],"name":"WithdrawalClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":true,"internalType":"address","name":"requestor","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfShares","type":"uint256"}],"name":"WithdrawalRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"from","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"to","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfETHLocked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sharesToBurn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawalsFinalized","type":"event"},{"inputs":[],"name":"BUNKER_MODE_DISABLED_TIMESTAMP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FINALIZE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_TOKEN_URI_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BATCHES_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STETH_WITHDRAWAL_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_STETH_WITHDRAWAL_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_INFINITELY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESUME_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH","outputs":[{"internalType":"contract IStETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WSTETH","outputs":[{"internalType":"contract IWstETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bunkerModeSinceTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxShareRate","type":"uint256"},{"internalType":"uint256","name":"_maxTimestamp","type":"uint256"},{"internalType":"uint256","name":"_maxRequestsPerCall","type":"uint256"},{"components":[{"internalType":"uint256","name":"remainingEthBudget","type":"uint256"},{"internalType":"bool","name":"finished","type":"bool"},{"internalType":"uint256[36]","name":"batches","type":"uint256[36]"},{"internalType":"uint256","name":"batchesLength","type":"uint256"}],"internalType":"struct WithdrawalQueueBase.BatchesCalculationState","name":"_state","type":"tuple"}],"name":"calculateFinalizationBatches","outputs":[{"components":[{"internalType":"uint256","name":"remainingEthBudget","type":"uint256"},{"internalType":"bool","name":"finished","type":"bool"},{"internalType":"uint256[36]","name":"batches","type":"uint256[36]"},{"internalType":"uint256","name":"batchesLength","type":"uint256"}],"internalType":"struct WithdrawalQueueBase.BatchesCalculationState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"claimWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_hints","type":"uint256[]"}],"name":"claimWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_hints","type":"uint256[]"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"claimWithdrawalsTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_batches","type":"uint256[]"},{"internalType":"uint256","name":"_maxShareRate","type":"uint256"}],"name":"finalize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"},{"internalType":"uint256","name":"_firstIndex","type":"uint256"},{"internalType":"uint256","name":"_lastIndex","type":"uint256"}],"name":"findCheckpointHints","outputs":[{"internalType":"uint256[]","name":"hintIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_hints","type":"uint256[]"}],"name":"getClaimableEther","outputs":[{"internalType":"uint256[]","name":"claimableEthValues","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastCheckpointIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastFinalizedRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLockedEtherAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNFTDescriptorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getResumeSinceTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getWithdrawalRequests","outputs":[{"internalType":"uint256[]","name":"requestsIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"}],"name":"getWithdrawalStatus","outputs":[{"components":[{"internalType":"uint256","name":"amountOfStETH","type":"uint256"},{"internalType":"uint256","name":"amountOfShares","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bool","name":"isFinalized","type":"bool"},{"internalType":"bool","name":"isClaimed","type":"bool"}],"internalType":"struct WithdrawalQueueBase.WithdrawalRequestStatus[]","name":"statuses","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBunkerModeActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_isBunkerModeNow","type":"bool"},{"internalType":"uint256","name":"_bunkerStartTimestamp","type":"uint256"},{"internalType":"uint256","name":"_currentReportTimestamp","type":"uint256"}],"name":"onOracleReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"pauseFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pauseUntilInclusive","type":"uint256"}],"name":"pauseUntil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_batches","type":"uint256[]"},{"internalType":"uint256","name":"_maxShareRate","type":"uint256"}],"name":"prefinalize","outputs":[{"internalType":"uint256","name":"ethToLock","type":"uint256"},{"internalType":"uint256","name":"sharesToBurn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"_owner","type":"address"}],"name":"requestWithdrawals","outputs":[{"internalType":"uint256[]","name":"requestIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"address","name":"_owner","type":"address"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct WithdrawalQueue.PermitInput","name":"_permit","type":"tuple"}],"name":"requestWithdrawalsWithPermit","outputs":[{"internalType":"uint256[]","name":"requestIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"_owner","type":"address"}],"name":"requestWithdrawalsWstETH","outputs":[{"internalType":"uint256[]","name":"requestIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"address","name":"_owner","type":"address"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct WithdrawalQueue.PermitInput","name":"_permit","type":"tuple"}],"name":"requestWithdrawalsWstETHWithPermit","outputs":[{"internalType":"uint256[]","name":"requestIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resume","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftDescriptorAddress","type":"address"}],"name":"setNFTDescriptorAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unfinalizedRequestNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unfinalizedStETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/abi/WithdrawalVault.json b/lib/abi/WithdrawalVault.json deleted file mode 100644 index cf8287e26..000000000 --- a/lib/abi/WithdrawalVault.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"contract ILido","name":"_lido","type":"address"},{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[],"name":"LidoZeroAddress","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"requested","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"NotEnoughEther","type":"error"},{"inputs":[],"name":"NotLido","type":"error"},{"inputs":[],"name":"TreasuryZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestedBy","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721Recovered","type":"event"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"contract ILido","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"recoverERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/lib/abi/WstETH.json b/lib/abi/WstETH.json deleted file mode 100644 index 0550c891e..000000000 --- a/lib/abi/WstETH.json +++ /dev/null @@ -1 +0,0 @@ -[{"inputs":[{"internalType":"contract IStETH","name":"_stETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":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"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wstETHAmount","type":"uint256"}],"name":"getStETHByWstETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stETHAmount","type":"uint256"}],"name":"getWstETHByStETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stETH","outputs":[{"internalType":"contract IStETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stEthPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensPerStEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wstETHAmount","type":"uint256"}],"name":"unwrap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stETHAmount","type":"uint256"}],"name":"wrap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}] \ No newline at end of file diff --git a/package.json b/package.json index 9947dc151..bc2d27009 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,11 @@ "test:forge": "forge test", "test": "yarn run test:unit", "test-sequential": "yarn run test:unit-sequential", - "test:unit": "hardhat test --parallel --network hardhat", - "test:unit-sequential": "hardhat test --network hardhat", - "test:gas": "REPORT_GAS=true hardhat test --network hardhat", - "test:coverage": "hardhat coverage --testfiles test", - "test:e2e": "npm run compile && ava -T 1000000 -v", + "test:unit": "yarn compile && hardhat test --parallel --network hardhat", + "test:unit-sequential": "yarn compile && hardhat test --network hardhat", + "test:gas": "yarn compile && REPORT_GAS=true hardhat test --network hardhat", + "test:coverage": "yarn compile && hardhat coverage --testfiles test", + "test:e2e": "yarn compile && ava -T 1000000 -v", "estimate-deposit-loop-gas": "yarn run test:unit ./estimate_deposit_loop_gas.js", "compile": "hardhat compile && yarn extract-abi", "clean": "hardhat clean", diff --git a/test/0.4.24/node-operators-registry-happy-path.test.js b/test/0.4.24/node-operators-registry-happy-path.test.js index 380a1c9c3..f01046a5c 100644 --- a/test/0.4.24/node-operators-registry-happy-path.test.js +++ b/test/0.4.24/node-operators-registry-happy-path.test.js @@ -106,7 +106,7 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re const keysCount = +(await nor.getTotalSigningKeyCount(operatorId)) const unusedKeysCount = +(await nor.getUnusedSigningKeyCount(operatorId)) - assert.equals(+operatorBefore.totalSigningKeys + keys.count, operator.totalSigningKeys) + assert.equals(+operatorBefore.totalAddedValidators + keys.count, operator.totalAddedValidators) assert.equals(keysCountBefore + keys.count, keysCount) assert.equals(unusedKeysCountBefore + keys.count, unusedKeysCount) @@ -128,10 +128,10 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re const operator = await nor.getNodeOperator(operatorId, true) const summary = await nor.getNodeOperatorSummary(operatorId) const stakingModuleSummary = await nor.getStakingModuleSummary() - const expectedLimit = +operatorBefore.stakingLimit + stakingLimit + const expectedLimit = +operatorBefore.totalVettedValidators + stakingLimit const expectedDepositable = +summaryBefore.depositableValidatorsCount + stakingLimit - assert.equals(operator.stakingLimit, expectedLimit) + assert.equals(operator.totalVettedValidators, expectedLimit) assert.equals(summary.depositableValidatorsCount, expectedDepositable) assert.equals( +stakingModuleSummaryBefore.depositableValidatorsCount + stakingLimit, @@ -160,7 +160,11 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re async function assertOperatorDeposits(operatorData, deposited, keysLeft) { const operator = await nor.getNodeOperator(operatorData.id, true) const summary = await nor.getNodeOperatorSummary(operatorData.id) - assert.equals(operator.usedSigningKeys, deposited, `${operatorData.name} usedSigningKeys asserting to ${deposited}`) + assert.equals( + operator.totalDepositedValidators, + deposited, + `${operatorData.name} totalDepositedValidators asserting to ${deposited}` + ) assert.equals( summary.totalDepositedValidators, deposited, @@ -254,14 +258,14 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re assert.isFalse(await nor.getNodeOperatorIsActive(operatorId)) assert.equals(+activeOperatorsBefore - 1, +activeOperatorsAfter) assert.emits(tx, 'NodeOperatorActiveSet', { nodeOperatorId: operatorId, active: false }) - if (+operatorBefore.stakingLimit - +operatorBefore.usedSigningKeys > 0) { + if (+operatorBefore.totalVettedValidators - +operatorBefore.totalDepositedValidators > 0) { assert.emits(tx, 'VettedSigningKeysCountChanged', { nodeOperatorId: operatorId, - approvedValidatorsCount: operator.usedSigningKeys, + approvedValidatorsCount: operator.totalDepositedValidators, }) } assert.equals(summary.depositableValidatorsCount, 0) - assert.equals(operator.stakingLimit, operator.usedSigningKeys) + assert.equals(operator.totalVettedValidators, operator.totalDepositedValidators) assert.equals( +stakingModuleSummaryBefore.depositableValidatorsCount - keysToCut, stakingModuleSummary.depositableValidatorsCount @@ -339,10 +343,10 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re assert.isTrue(operator.active) assert.equals(operator.name, initialName) assert.equals(operator.rewardAddress, operatorData.rewardAddressInitial) - assert.equals(operator.stakingLimit, 0) - assert.equals(operator.stoppedValidators, 0) - assert.equals(operator.totalSigningKeys, 0) - assert.equals(operator.usedSigningKeys, 0) + assert.equals(operator.totalVettedValidators, 0) + assert.equals(operator.totalExitedValidators, 0) + assert.equals(operator.totalAddedValidators, 0) + assert.equals(operator.totalDepositedValidators, 0) }) assert.equals(await nor.getNodeOperatorsCount(), NODE_OPERATORS.length) @@ -396,7 +400,7 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re const unusedKeysCountBefore = await nor.getUnusedSigningKeyCount(operatorData.id) const keyIdxToRemove = 1 const keyBefore = await nor.getSigningKey(operatorData.id, keyIdxToRemove) - assert.equals(operatorBefore.stakingLimit, operatorData.vettedSigningKeysCount) + assert.equals(operatorBefore.totalVettedValidators, operatorData.vettedSigningKeysCount) await nor.removeSigningKey(operatorData.id, keyIdxToRemove, { from: voting.address }) @@ -406,8 +410,8 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re const unusedKeysCountAfter = await nor.getUnusedSigningKeyCount(operatorData.id) const keyAfter = await nor.getSigningKey(operatorData.id, keyIdxToRemove) - assert.equals(operatorAfter.stakingLimit, keyIdxToRemove) - assert.equals(+operatorBefore.totalSigningKeys - 1, +operatorAfter.totalSigningKeys) + assert.equals(operatorAfter.totalVettedValidators, keyIdxToRemove) + assert.equals(+operatorBefore.totalAddedValidators - 1, +operatorAfter.totalAddedValidators) assert.equals(+keysCountBefore - 1, +keysCountAfter) assert.equals(+unusedKeysCountBefore - 1, +unusedKeysCountAfter) assert.equals(summaryBefore.depositableValidatorsCount, operatorData.vettedSigningKeysCount) @@ -424,7 +428,7 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re }) const summary = await nor.getNodeOperatorSummary(operatorData.id) const operator = await nor.getNodeOperator(operatorData.id, true) - assert.equals(operator.stakingLimit, operatorData.vettedSigningKeysCount) + assert.equals(operator.totalVettedValidators, operatorData.vettedSigningKeysCount) assert.equals(summary.depositableValidatorsCount, operatorData.vettedSigningKeysCount) }) @@ -619,7 +623,7 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re it('Operator summaries after exit/stuck report', async () => { const operator1 = await nor.getNodeOperator(Operator1.id, true) const summaryOperator1 = await nor.getNodeOperatorSummary(Operator1.id) - assert.equals(operator1.stoppedValidators, 2) + assert.equals(operator1.totalExitedValidators, 2) assert.equals(summaryOperator1.totalExitedValidators, 2) assert.equals(summaryOperator1.depositableValidatorsCount, 4) @@ -715,12 +719,12 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re const summaryBefore = await nor.getNodeOperatorSummary(operatorData.id) const keysCountBefore = await nor.getTotalSigningKeyCount(operatorData.id) const unusedKeysCountBefore = await nor.getUnusedSigningKeyCount(operatorData.id) - const keyIdxToRemove = +operatorBefore.usedSigningKeys + 1 + const keyIdxToRemove = +operatorBefore.totalDepositedValidators + 1 const keysCountToRemove = 2 const key1Before = await nor.getSigningKey(operatorData.id, keyIdxToRemove) const key2Before = await nor.getSigningKey(operatorData.id, keyIdxToRemove + 1) - assert.equals(operatorBefore.stakingLimit, operatorData.vettedSigningKeysCount) + assert.equals(operatorBefore.totalVettedValidators, operatorData.vettedSigningKeysCount) await nor.removeSigningKeys(operatorData.id, keyIdxToRemove, keysCountToRemove, { from: voting.address }) @@ -731,14 +735,14 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re const key1After = await nor.getSigningKey(operatorData.id, keyIdxToRemove) const key2After = await nor.getSigningKey(operatorData.id, keyIdxToRemove + 1) - assert.equals(operatorAfter.stakingLimit, keyIdxToRemove) - assert.equals(+operatorBefore.totalSigningKeys - keysCountToRemove, +operatorAfter.totalSigningKeys) + assert.equals(operatorAfter.totalVettedValidators, keyIdxToRemove) + assert.equals(+operatorBefore.totalAddedValidators - keysCountToRemove, +operatorAfter.totalAddedValidators) assert.equals(+keysCountBefore - keysCountToRemove, +keysCountAfter) assert.equals(+unusedKeysCountBefore - keysCountToRemove, +unusedKeysCountAfter) assert.equals( Math.min( +summaryBefore.depositableValidatorsCount - keysCountToRemove, - +operatorAfter.stakingLimit - +operatorAfter.usedSigningKeys + +operatorAfter.totalVettedValidators - +operatorAfter.totalDepositedValidators ), +summaryAfter.depositableValidatorsCount ) @@ -820,7 +824,7 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re assert.isTrue(await nor.getNodeOperatorIsActive(operatorData.id)) assert.equals(+activeOperatorsBefore + 1, +activeOperatorsAfter) assert.emits(tx, 'NodeOperatorActiveSet', { nodeOperatorId: operatorData.id, active: true }) - assert.equals(operator.stakingLimit, operator.usedSigningKeys) + assert.equals(operator.totalVettedValidators, operator.totalDepositedValidators) }) it('Set operator 4 staking limit', async () => { @@ -859,7 +863,6 @@ contract('NodeOperatorsRegistry', ([appManager, rewards1, rewards2, rewards3, re withdrawalCredentials = '0x'.padEnd(66, '5678') await stakingRouter.setWithdrawalCredentials(withdrawalCredentials, { from: voting.address }) const summary = await nor.getStakingModuleSummary() - console.log(summary, summaryBefore) assert.equals(summaryBefore.totalExitedValidators, summary.totalExitedValidators) assert.equals(summaryBefore.totalDepositedValidators, summary.totalDepositedValidators) diff --git a/test/0.4.24/node-operators-registry.test.js b/test/0.4.24/node-operators-registry.test.js index ffbb88620..639f52eeb 100644 --- a/test/0.4.24/node-operators-registry.test.js +++ b/test/0.4.24/node-operators-registry.test.js @@ -212,10 +212,10 @@ contract('NodeOperatorsRegistry', (addresses) => { for (let i = 0; i < NODE_OPERATORS.length; ++i) { const nodeOperator = await app.getNodeOperator(i, false) - assert.equals(nodeOperator.totalSigningKeys.toNumber(), NODE_OPERATORS[i].totalSigningKeysCount) - assert.equals(nodeOperator.stakingLimit.toNumber(), NODE_OPERATORS[i].vettedSigningKeysCount) - assert.equals(nodeOperator.usedSigningKeys.toNumber(), NODE_OPERATORS[i].depositedSigningKeysCount) - assert.equals(nodeOperator.stoppedValidators.toNumber(), NODE_OPERATORS[i].exitedSigningKeysCount) + assert.equals(nodeOperator.totalAddedValidators.toNumber(), NODE_OPERATORS[i].totalSigningKeysCount) + assert.equals(nodeOperator.totalVettedValidators.toNumber(), NODE_OPERATORS[i].vettedSigningKeysCount) + assert.equals(nodeOperator.totalDepositedValidators.toNumber(), NODE_OPERATORS[i].depositedSigningKeysCount) + assert.equals(nodeOperator.totalExitedValidators.toNumber(), NODE_OPERATORS[i].exitedSigningKeysCount) const nodeOperatorLimits = await app.getNodeOperatorSummary(i) assert.equals(nodeOperatorLimits.stuckValidatorsCount.toNumber(), NODE_OPERATORS[i].stuckValidatorsCount) @@ -242,7 +242,7 @@ contract('NodeOperatorsRegistry', (addresses) => { assert.equals(totalSigningKeysStatsAfter.exitedSigningKeysCount.toNumber(), exitedSigningKeysCount) }) - it("trims vettedSigningKeys if it's greater than totalSigningKeys", async () => { + it("trims vettedSigningKeys if it's greater than totalAddedValidators", async () => { const config = { name: 'test', rewardAddress: ADDRESS_1, @@ -271,14 +271,14 @@ contract('NodeOperatorsRegistry', (addresses) => { ) let nodeOperator = await app.getNodeOperator(0, false) - assert.equals(nodeOperator.stakingLimit.toNumber(), config.vettedSigningKeysCount) - assert.equals(nodeOperator.totalSigningKeys.toNumber(), config.totalSigningKeysCount) + assert.equals(nodeOperator.totalVettedValidators.toNumber(), config.vettedSigningKeysCount) + assert.equals(nodeOperator.totalAddedValidators.toNumber(), config.totalSigningKeysCount) await app.finalizeUpgrade_v2(locator.address, CURATED_TYPE, PENALTY_DELAY) nodeOperator = await app.getNodeOperator(0, false) - assert.equals(nodeOperator.stakingLimit.toNumber(), config.totalSigningKeysCount) - assert.equals(nodeOperator.totalSigningKeys.toNumber(), config.totalSigningKeysCount) + assert.equals(nodeOperator.totalVettedValidators.toNumber(), config.totalSigningKeysCount) + assert.equals(nodeOperator.totalAddedValidators.toNumber(), config.totalSigningKeysCount) }) it("trims vettedSigningKeys if it's greater than depositedSigningKeysCount", async () => { @@ -311,15 +311,15 @@ contract('NodeOperatorsRegistry', (addresses) => { ) let nodeOperator = await app.getNodeOperator(0, false) - assert.equals(nodeOperator.stakingLimit.toNumber(), config.vettedSigningKeysCount) - assert.equals(nodeOperator.totalSigningKeys.toNumber(), config.totalSigningKeysCount) + assert.equals(nodeOperator.totalVettedValidators.toNumber(), config.vettedSigningKeysCount) + assert.equals(nodeOperator.totalAddedValidators.toNumber(), config.totalSigningKeysCount) await app.finalizeUpgrade_v2(locator.address, CURATED_TYPE, PENALTY_DELAY) nodeOperator = await app.getNodeOperator(0, false) - assert.equals(nodeOperator.stakingLimit.toNumber(), config.depositedSigningKeysCount) - assert.equals(nodeOperator.totalSigningKeys.toNumber(), config.totalSigningKeysCount) + assert.equals(nodeOperator.totalVettedValidators.toNumber(), config.depositedSigningKeysCount) + assert.equals(nodeOperator.totalAddedValidators.toNumber(), config.totalSigningKeysCount) }) it('emits ContractVersionSet event with correct params', async () => { @@ -423,10 +423,10 @@ contract('NodeOperatorsRegistry', (addresses) => { assert.isTrue(nodeOperator.active) assert.equals(nodeOperator.name, name) assert.equals(nodeOperator.rewardAddress, ADDRESS_1) - assert.equals(nodeOperator.stakingLimit, 0) - assert.equals(nodeOperator.stoppedValidators, 0) - assert.equals(nodeOperator.totalSigningKeys, 0) - assert.equals(nodeOperator.usedSigningKeys, 0) + assert.equals(nodeOperator.totalVettedValidators, 0) + assert.equals(nodeOperator.totalExitedValidators, 0) + assert.equals(nodeOperator.totalAddedValidators, 0) + assert.equals(nodeOperator.totalDepositedValidators, 0) }) it('returns correct node operator id', async () => { @@ -718,17 +718,17 @@ contract('NodeOperatorsRegistry', (addresses) => { const activeNodeOperatorId = await nodeOperators.findNodeOperatorId(app, (operator) => operator.active) assert.notEqual(activeNodeOperatorId, -1, `Invariant: active node operator not found`) - const { usedSigningKeys, stakingLimit } = await app.getNodeOperator(activeNodeOperatorId, false) + const { totalDepositedValidators, totalVettedValidators } = await app.getNodeOperator(activeNodeOperatorId, false) assert.isTrue( - stakingLimit.toNumber() > usedSigningKeys.toString(), + totalVettedValidators.toNumber() > totalDepositedValidators.toString(), 'invariant failed: readyToDepositValidatorsKeysCountBefore <= depositedSigningKeysCount' ) const receipt = await app.deactivateNodeOperator(activeNodeOperatorId, { from: nodeOperatorsManager }) assert.emits(receipt, 'VettedSigningKeysCountChanged', { nodeOperatorId: activeNodeOperatorId, - approvedValidatorsCount: usedSigningKeys, + approvedValidatorsCount: totalDepositedValidators, }) }) @@ -990,23 +990,23 @@ contract('NodeOperatorsRegistry', (addresses) => { it('newStakingLimit < depositedSigningKeys :: sets staking limit to deposited signing keys count', async () => { await app.setNodeOperatorStakingLimit(firstNodeOperatorId, 10, { from: limitsManager }) const nodeOperator = await app.getNodeOperator(firstNodeOperatorId, false) - assert.equals(nodeOperator.stakingLimit, 20) + assert.equals(nodeOperator.totalVettedValidators, 20) }) it('newStakingLimit > totalSigningKeysCount :: sets staking limit to total signing keys count', async () => { await app.setNodeOperatorStakingLimit(secondNodeOperatorId, 1000, { from: limitsManager }) const nodeOperator = await app.getNodeOperator(secondNodeOperatorId, false) - assert.equals(nodeOperator.stakingLimit, 50) + assert.equals(nodeOperator.totalVettedValidators, 50) }) it('depositedSigningKeys <= newStakingLimit <= totalSigningKeysCount :: sets staking limit to passed value', async () => { await app.setNodeOperatorStakingLimit(firstNodeOperatorId, 75, { from: limitsManager }) const nodeOperator = await app.getNodeOperator(firstNodeOperatorId, false) - assert.equals(nodeOperator.stakingLimit, 75) + assert.equals(nodeOperator.totalVettedValidators, 75) }) it("doesn't change state & doesn't emit events when new staking limit is the same", async () => { - const [{ stakingLimit: stakingLimitBefore }, nonceBefore, keysOpIndexBefore] = await Promise.all([ + const [{ totalVettedValidators: stakingLimitBefore }, nonceBefore, keysOpIndexBefore] = await Promise.all([ app.getNodeOperator(firstNodeOperatorId, false), app.getNonce(), app.getKeysOpIndex(), @@ -1015,7 +1015,7 @@ contract('NodeOperatorsRegistry', (addresses) => { from: limitsManager, }) assert.notEmits(receipt, 'VettedSigningKeysCountChanged') - const [{ stakingLimit: stakingLimitAfter }, nonceAfter, keysOpIndexAfter] = await Promise.all([ + const [{ totalVettedValidators: stakingLimitAfter }, nonceAfter, keysOpIndexAfter] = await Promise.all([ app.getNodeOperator(firstNodeOperatorId, false), app.getNonce(), app.getKeysOpIndex(), @@ -1067,12 +1067,12 @@ contract('NodeOperatorsRegistry', (addresses) => { }) it("doesn't affect other node operators staking limits", async () => { - const { stakingLimit: secondNodeOperatorStakingLimitBefore } = await app.getNodeOperator( + const { totalVettedValidators: secondNodeOperatorStakingLimitBefore } = await app.getNodeOperator( secondNodeOperatorId, true ) await app.setNodeOperatorRewardAddress(firstNodeOperatorId, ADDRESS_4, { from: nodeOperatorsManager }) - const { stakingLimit: secondNodeOperatorStakingLimitAfter } = await app.getNodeOperator( + const { totalVettedValidators: secondNodeOperatorStakingLimitAfter } = await app.getNodeOperator( secondNodeOperatorId, true ) @@ -1080,6 +1080,36 @@ contract('NodeOperatorsRegistry', (addresses) => { }) }) + describe('updateStuckValidatorsCount()', () => { + const firstNodeOperatorId = 0 + const secondNodeOperatorId = 1 + + beforeEach(async () => { + await nodeOperators.addNodeOperator(app, { ...NODE_OPERATORS[0], exitedSigningKeysCount: 3 }, { from: admin }) + await nodeOperators.addNodeOperator(app, NODE_OPERATORS[1], { from: admin }) + }) + + it('updates nonce & keysOpIndex', async () => { + const { operatorIds, keysCounts } = prepIdsCountsPayload([firstNodeOperatorId, secondNodeOperatorId], [1, 2]) + const [nonceBefore, keysOpIndexBefore] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + await app.updateStuckValidatorsCount(operatorIds, keysCounts, { from: stakingRouter }) + const [nonceAfter, keysOpIndexAfter] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + assert.equals(nonceAfter, wei(nonceBefore) + 1n) + assert.equals(keysOpIndexAfter, wei(keysOpIndexBefore) + 1n) + }) + + it('emits KeysOpIndexSet & NonceChanged events', async () => { + const { operatorIds, keysCounts } = prepIdsCountsPayload([firstNodeOperatorId, secondNodeOperatorId], [1, 2]) + const keysOpIndexBefore = await app.getKeysOpIndex() + const tx = await app.updateStuckValidatorsCount(operatorIds, keysCounts, { + from: stakingRouter, + }) + const nonceAfter = await app.getNonce() + assert.emits(tx, 'KeysOpIndexSet', { keysOpIndex: wei(keysOpIndexBefore) + 1n }) + assert.emits(tx, 'NonceChanged', { nonce: nonceAfter }) + }) + }) + describe('updateExitedValidatorsCount()', () => { const firstNodeOperatorId = 0 const secondNodeOperatorId = 1 @@ -1111,13 +1141,13 @@ contract('NodeOperatorsRegistry', (addresses) => { }) it("doesn't change the state when new value is equal to the previous one", async () => { - const { stoppedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( firstNodeOperatorId, false ) const { operatorIds, keysCounts } = prepIdsCountsPayload(firstNodeOperatorId, exitedValidatorsKeysCountBefore) await app.updateExitedValidatorsCount(operatorIds, keysCounts, { from: stakingRouter }) - const { stoppedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( firstNodeOperatorId, false ) @@ -1125,7 +1155,7 @@ contract('NodeOperatorsRegistry', (addresses) => { }) it("doesn't emit ExitedSigningKeysCountChanged event when new value is equal to the previous one", async () => { - const { stoppedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( firstNodeOperatorId, false ) @@ -1137,7 +1167,7 @@ contract('NodeOperatorsRegistry', (addresses) => { it('reverts with "OUT_OF_RANGE" error when new exitedValidatorsKeysCount > depositedSigningKeysCount', async () => { const newExitedValidatorsCount = 1000 const nodeOperator = await app.getNodeOperator(firstNodeOperatorId, false) - assert(newExitedValidatorsCount > nodeOperator.usedSigningKeys.toNumber()) + assert(newExitedValidatorsCount > nodeOperator.totalDepositedValidators.toNumber()) const { operatorIds, keysCounts } = prepIdsCountsPayload(firstNodeOperatorId, newExitedValidatorsCount) await assert.reverts( app.updateExitedValidatorsCount(operatorIds, keysCounts, { from: stakingRouter }), @@ -1147,8 +1177,8 @@ contract('NodeOperatorsRegistry', (addresses) => { it('reverts with "EXITED_VALIDATORS_COUNT_DECREASED" error when new exitedValidatorsKeysCount less then current one', async () => { const nodeOperator = await app.getNodeOperator(firstNodeOperatorId, false) - assert(nodeOperator.stoppedValidators.toNumber() > 0, 'invariant failed: no exited validators') - const newExitedValidatorsKeysCount = nodeOperator.stoppedValidators.toNumber() - 1 + assert(nodeOperator.totalExitedValidators.toNumber() > 0, 'invariant failed: no exited validators') + const newExitedValidatorsKeysCount = nodeOperator.totalExitedValidators.toNumber() - 1 const { operatorIds, keysCounts } = prepIdsCountsPayload(firstNodeOperatorId, newExitedValidatorsKeysCount) await assert.reverts( app.updateExitedValidatorsCount(operatorIds, keysCounts, { from: stakingRouter }), @@ -1158,14 +1188,14 @@ contract('NodeOperatorsRegistry', (addresses) => { it('increases exited signing keys count of node operator', async () => { const newExitedValidatorsCount = 5 - const { stoppedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( secondNodeOperatorId, false ) assert.notEquals(exitedValidatorsKeysCountBefore, newExitedValidatorsCount) const { operatorIds, keysCounts } = prepIdsCountsPayload(secondNodeOperatorId, newExitedValidatorsCount) await app.updateExitedValidatorsCount(operatorIds, keysCounts, { from: stakingRouter }) - const { stoppedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( secondNodeOperatorId, false ) @@ -1175,7 +1205,7 @@ contract('NodeOperatorsRegistry', (addresses) => { it('increases the total exited signing keys count', async () => { const newExitedValidatorsCount = 4 const [ - { stoppedValidators: exitedValidatorsKeysCountBefore }, + { totalExitedValidators: exitedValidatorsKeysCountBefore }, { exitedSigningKeysCount: exitedSigningKeysCountBefore }, ] = await Promise.all([ await app.getNodeOperator(firstNodeOperatorId, false), @@ -1203,15 +1233,48 @@ contract('NodeOperatorsRegistry', (addresses) => { it("doesn't change the exited signing keys count of other node operators", async () => { const newExitedValidatorsCount = 4 - const { stakingLimit: secondNodeOperatorStakingLimitBefore } = await app.getNodeOperator( + const { totalVettedValidators: secondNodeOperatorStakingLimitBefore } = await app.getNodeOperator( firstNodeOperatorId, true ) const { operatorIds, keysCounts } = prepIdsCountsPayload(secondNodeOperatorId, newExitedValidatorsCount) await app.updateExitedValidatorsCount(operatorIds, keysCounts, { from: stakingRouter }) - const { stakingLimit: secondNodeOperatorStakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, true) + const { totalVettedValidators: secondNodeOperatorStakingLimitAfter } = await app.getNodeOperator( + firstNodeOperatorId, + true + ) assert.equals(secondNodeOperatorStakingLimitAfter, secondNodeOperatorStakingLimitBefore) }) + + it('updates nonce & keysOpIndex', async () => { + const { operatorIds, keysCounts } = prepIdsCountsPayload( + [firstNodeOperatorId, secondNodeOperatorId], + [ + NODE_OPERATORS[firstNodeOperatorId].exitedSigningKeysCount + 4, + NODE_OPERATORS[secondNodeOperatorId].exitedSigningKeysCount + 2, + ] + ) + const [nonceBefore, keysOpIndexBefore] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + await app.updateExitedValidatorsCount(operatorIds, keysCounts, { from: stakingRouter }) + const [nonceAfter, keysOpIndexAfter] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + assert.equals(nonceAfter, wei(nonceBefore) + 1n) + assert.equals(keysOpIndexAfter, wei(keysOpIndexBefore) + 1n) + }) + + it('emits KeysOpIndexSet & NonceChanged events', async () => { + const { operatorIds, keysCounts } = prepIdsCountsPayload( + [firstNodeOperatorId, secondNodeOperatorId], + [ + NODE_OPERATORS[firstNodeOperatorId].exitedSigningKeysCount + 4, + NODE_OPERATORS[secondNodeOperatorId].exitedSigningKeysCount + 2, + ] + ) + const keysOpIndexBefore = await app.getKeysOpIndex() + const tx = await app.updateExitedValidatorsCount(operatorIds, keysCounts, { from: stakingRouter }) + const nonceAfter = await app.getNonce() + assert.emits(tx, 'KeysOpIndexSet', { keysOpIndex: wei(keysOpIndexBefore) + 1n }) + assert.emits(tx, 'NonceChanged', { nonce: nonceAfter }) + }) }) describe('unsafeUpdateValidatorsCount(): exited validators update', () => { @@ -1336,7 +1399,7 @@ contract('NodeOperatorsRegistry', (addresses) => { }) it("doesn't change the state when new value is equal to the previous one", async () => { - const { stoppedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( firstNodeOperatorId, false ) @@ -1346,7 +1409,7 @@ contract('NodeOperatorsRegistry', (addresses) => { stuckValidatorsCount, { from: stakingRouter } ) - const { stoppedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( firstNodeOperatorId, false ) @@ -1354,7 +1417,7 @@ contract('NodeOperatorsRegistry', (addresses) => { }) it("doesn't emit ExitedSigningKeysCountChanged event when new value is equal to the previous one", async () => { - const { stoppedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( firstNodeOperatorId, false ) @@ -1372,7 +1435,7 @@ contract('NodeOperatorsRegistry', (addresses) => { it('reverts with "OUT_OF_RANGE" error when new exitedValidatorsKeysCount > depositedSigningKeysCount', async () => { const newExitedValidatorsCount = 1000 const nodeOperator = await app.getNodeOperator(firstNodeOperatorId, false) - assert(newExitedValidatorsCount > nodeOperator.usedSigningKeys.toNumber()) + assert(newExitedValidatorsCount > nodeOperator.totalDepositedValidators.toNumber()) await assert.reverts( app.unsafeUpdateValidatorsCount(firstNodeOperatorId, newExitedValidatorsCount, stuckValidatorsCount, { from: stakingRouter, @@ -1384,7 +1447,7 @@ contract('NodeOperatorsRegistry', (addresses) => { it('decreases the exited validators count when new value is less then previous one', async () => { const newExitedValidatorsCount = 1 const newStuckValidatorsCount = 0 - const { stoppedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( firstNodeOperatorId, false ) @@ -1392,7 +1455,7 @@ contract('NodeOperatorsRegistry', (addresses) => { await app.unsafeUpdateValidatorsCount(firstNodeOperatorId, newExitedValidatorsCount, newStuckValidatorsCount, { from: stakingRouter, }) - const { stoppedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( firstNodeOperatorId, false ) @@ -1401,7 +1464,7 @@ contract('NodeOperatorsRegistry', (addresses) => { it('increases the exited validators count when new value is greater then previous one', async () => { const newExitedValidatorsCount = 3 - const { stoppedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountBefore } = await app.getNodeOperator( secondNodeOperatorId, false ) @@ -1409,7 +1472,7 @@ contract('NodeOperatorsRegistry', (addresses) => { await app.unsafeUpdateValidatorsCount(secondNodeOperatorId, newExitedValidatorsCount, stuckValidatorsCount, { from: stakingRouter, }) - const { stoppedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( + const { totalExitedValidators: exitedValidatorsKeysCountAfter } = await app.getNodeOperator( secondNodeOperatorId, false ) @@ -1419,7 +1482,7 @@ contract('NodeOperatorsRegistry', (addresses) => { it('decreases the total exited signing keys count when new value is less then previous one', async () => { const newExitedValidatorsCount = 1 const [ - { stoppedValidators: exitedValidatorsKeysCountBefore }, + { totalExitedValidators: exitedValidatorsKeysCountBefore }, { exitedSigningKeysCount: exitedSigningKeysCountBefore }, ] = await Promise.all([app.getNodeOperator(firstNodeOperatorId, false), app.testing_getTotalSigningKeysStats()]) assert(newExitedValidatorsCount < exitedValidatorsKeysCountBefore.toNumber()) @@ -1438,7 +1501,7 @@ contract('NodeOperatorsRegistry', (addresses) => { const newExitedValidatorsCount = 5 const newStuckValidatorsCount = 0 const [ - { stoppedValidators: exitedValidatorsKeysCountBefore }, + { totalExitedValidators: exitedValidatorsKeysCountBefore }, { exitedSigningKeysCount: exitedSigningKeysCountBefore }, ] = await Promise.all([app.getNodeOperator(firstNodeOperatorId, false), app.testing_getTotalSigningKeysStats()]) assert(newExitedValidatorsCount > exitedValidatorsKeysCountBefore.toNumber()) @@ -1469,7 +1532,7 @@ contract('NodeOperatorsRegistry', (addresses) => { it("doesn't change the exited signing keys count of other node operators", async () => { const newExitedValidatorsCount = 4 - const { stakingLimit: secondNodeOperatorStakingLimitBefore } = await app.getNodeOperator( + const { totalVettedValidators: secondNodeOperatorStakingLimitBefore } = await app.getNodeOperator( firstNodeOperatorId, true ) @@ -1479,9 +1542,39 @@ contract('NodeOperatorsRegistry', (addresses) => { await app.unsafeUpdateValidatorsCount(secondNodeOperatorId, newExitedValidatorsCount, stuckValidatorsCount, { from: stakingRouter, }) - const { stakingLimit: secondNodeOperatorStakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, true) + const { totalVettedValidators: secondNodeOperatorStakingLimitAfter } = await app.getNodeOperator( + firstNodeOperatorId, + true + ) assert.equals(secondNodeOperatorStakingLimitAfter, secondNodeOperatorStakingLimitBefore) }) + + it('updates nonce & keysOpIndex', async () => { + const newExitedValidatorsCount = 4 + const [nonceBefore, keysOpIndexBefore] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + await app.unsafeUpdateValidatorsCount(secondNodeOperatorId, newExitedValidatorsCount, stuckValidatorsCount, { + from: stakingRouter, + }) + const [nonceAfter, keysOpIndexAfter] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + assert.equals(nonceAfter, wei(nonceBefore) + 1n) + assert.equals(keysOpIndexAfter, wei(keysOpIndexBefore) + 1n) + }) + + it('emits KeysOpIndexSet & NonceChanged events', async () => { + const newExitedValidatorsCount = 4 + const keysOpIndexBefore = await app.getKeysOpIndex() + const tx = await app.unsafeUpdateValidatorsCount( + secondNodeOperatorId, + newExitedValidatorsCount, + stuckValidatorsCount, + { + from: stakingRouter, + } + ) + const nonceAfter = await app.getNonce() + assert.emits(tx, 'KeysOpIndexSet', { keysOpIndex: wei(keysOpIndexBefore) + 1n }) + assert.emits(tx, 'NonceChanged', { nonce: nonceAfter }) + }) }) describe('updateTargetValidatorsLimits()', () => { @@ -1582,8 +1675,8 @@ contract('NodeOperatorsRegistry', (addresses) => { for (let i = 0; i < allNodeOperatorsBefore.length; ++i) { const nodeOperatorBefore = allNodeOperatorsBefore[i] const nodeOperatorAfter = allNodeOperatorsAfter[i] - assert.equals(nodeOperatorAfter.stakingLimit, nodeOperatorBefore.usedSigningKeys) - assert.equals(nodeOperatorAfter.totalSigningKeys, nodeOperatorBefore.usedSigningKeys) + assert.equals(nodeOperatorAfter.totalVettedValidators, nodeOperatorBefore.totalDepositedValidators) + assert.equals(nodeOperatorAfter.totalAddedValidators, nodeOperatorBefore.totalDepositedValidators) } }) @@ -1594,14 +1687,16 @@ contract('NodeOperatorsRegistry', (addresses) => { for (let i = 0; i < allNodeOperatorsBefore.length; ++i) { const nodeOperatorBefore = allNodeOperatorsBefore[i] const nodeOperatorAfter = allNodeOperatorsAfter[i] - if (nodeOperatorBefore.totalSigningKeys.toNumber() !== nodeOperatorAfter.usedSigningKeys.toNumber()) { + if ( + nodeOperatorBefore.totalAddedValidators.toNumber() !== nodeOperatorAfter.totalDepositedValidators.toNumber() + ) { assert.emits(receipt, 'TotalSigningKeysCountChanged', { nodeOperatorId: i, - totalValidatorsCount: nodeOperatorAfter.usedSigningKeys, + totalValidatorsCount: nodeOperatorAfter.totalDepositedValidators, }) assert.emits(receipt, 'VettedSigningKeysCountChanged', { nodeOperatorId: i, - approvedValidatorsCount: nodeOperatorAfter.usedSigningKeys, + approvedValidatorsCount: nodeOperatorAfter.totalDepositedValidators, }) } else { assert.notEmits(receipt, 'TotalSigningKeysCountChanged', { nodeOperatorId: i }) @@ -1617,11 +1712,14 @@ contract('NodeOperatorsRegistry', (addresses) => { for (let i = 0; i < allNodeOperatorsBefore.length; ++i) { const nodeOperatorBefore = allNodeOperatorsBefore[i] const nodeOperatorAfter = allNodeOperatorsAfter[i] - if (nodeOperatorBefore.totalSigningKeys.toNumber() !== nodeOperatorAfter.usedSigningKeys.toNumber()) { + if ( + nodeOperatorBefore.totalAddedValidators.toNumber() !== nodeOperatorAfter.totalDepositedValidators.toNumber() + ) { assert.emits(receipt, 'NodeOperatorTotalKeysTrimmed', { nodeOperatorId: i, totalKeysTrimmed: - nodeOperatorBefore.totalSigningKeys.toNumber() - nodeOperatorAfter.usedSigningKeys.toNumber(), + nodeOperatorBefore.totalAddedValidators.toNumber() - + nodeOperatorAfter.totalDepositedValidators.toNumber(), }) } else { assert.notEmits(receipt, 'NodeOperatorTotalKeysTrimmed', { nodeOperatorId: i }) @@ -1735,8 +1833,8 @@ contract('NodeOperatorsRegistry', (addresses) => { const allNodeOperatorsAfter = await nodeOperators.getAllNodeOperators(app) const nodeOperatorBefore = allNodeOperatorsBefore[nodeOperatorIndex] const nodeOperatorAfter = allNodeOperatorsAfter[nodeOperatorIndex] - assert.equals(nodeOperatorAfter.stakingLimit, nodeOperatorBefore.usedSigningKeys) - assert.equals(nodeOperatorAfter.totalSigningKeys, nodeOperatorBefore.usedSigningKeys) + assert.equals(nodeOperatorAfter.totalVettedValidators, nodeOperatorBefore.totalDepositedValidators) + assert.equals(nodeOperatorAfter.totalAddedValidators, nodeOperatorBefore.totalDepositedValidators) }) it('sets totalSigningKeysCount and vettedSigningKeysCount equal to depositedSigningKeys for each node operator in range', async () => { @@ -1748,8 +1846,8 @@ contract('NodeOperatorsRegistry', (addresses) => { for (let i = indexFrom; i <= indexTo; ++i) { const nodeOperatorBefore = allNodeOperatorsBefore[i] const nodeOperatorAfter = allNodeOperatorsAfter[i] - assert.equals(nodeOperatorAfter.stakingLimit, nodeOperatorBefore.usedSigningKeys) - assert.equals(nodeOperatorAfter.totalSigningKeys, nodeOperatorBefore.usedSigningKeys) + assert.equals(nodeOperatorAfter.totalVettedValidators, nodeOperatorBefore.totalDepositedValidators) + assert.equals(nodeOperatorAfter.totalAddedValidators, nodeOperatorBefore.totalDepositedValidators) } }) @@ -1762,9 +1860,9 @@ contract('NodeOperatorsRegistry', (addresses) => { for (let i = 0; i < indexTo; ++i) { const nodeOperatorBefore = allNodeOperatorsBefore[i] const nodeOperatorAfter = allNodeOperatorsAfter[i] - assert.equals(nodeOperatorAfter.stakingLimit, nodeOperatorBefore.stakingLimit) - assert.equals(nodeOperatorAfter.usedSigningKeys, nodeOperatorBefore.usedSigningKeys) - assert.equals(nodeOperatorAfter.totalSigningKeys, nodeOperatorBefore.totalSigningKeys) + assert.equals(nodeOperatorAfter.totalVettedValidators, nodeOperatorBefore.totalVettedValidators) + assert.equals(nodeOperatorAfter.totalDepositedValidators, nodeOperatorBefore.totalDepositedValidators) + assert.equals(nodeOperatorAfter.totalAddedValidators, nodeOperatorBefore.totalAddedValidators) } }) }) @@ -1872,6 +1970,22 @@ contract('NodeOperatorsRegistry', (addresses) => { // the second receives 4 deposits assert.equals(activeKeyCountsAfterAllocation[1], secondNodeOperatorActiveKeysCount + 4) }) + + it('updates nonce & keysOpIndex', async () => { + const [nonceBefore, keysOpIndexBefore] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + await app.updateTargetValidatorsLimits(firstNodeOperatorId, true, 4, { from: stakingRouter }) + const [nonceAfter, keysOpIndexAfter] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + assert.equals(nonceAfter, wei(nonceBefore) + 1n) + assert.equals(keysOpIndexAfter, wei(keysOpIndexBefore) + 1n) + }) + + it('emits KeysOpIndexSet & NonceChanged events', async () => { + const keysOpIndexBefore = await app.getKeysOpIndex() + const tx = await app.updateTargetValidatorsLimits(firstNodeOperatorId, true, 4, { from: stakingRouter }) + const nonceAfter = await app.getNonce() + assert.emits(tx, 'KeysOpIndexSet', { keysOpIndex: wei(keysOpIndexBefore) + 1n }) + assert.emits(tx, 'NonceChanged', { nonce: nonceAfter }) + }) }) describe('getSigningKeysAllocationData()', async () => { @@ -1920,8 +2034,8 @@ contract('NodeOperatorsRegistry', (addresses) => { app.getNodeOperator(firstNodeOperatorId, false), app.getNodeOperator(secondNodeOperatorId, false), ]) - assert.equals(firstNodeOperator.totalSigningKeys, firstNodeOperator.usedSigningKeys) - assert.equals(secondNodeOperator.totalSigningKeys, secondNodeOperator.usedSigningKeys) + assert.equals(firstNodeOperator.totalAddedValidators, firstNodeOperator.totalDepositedValidators) + assert.equals(secondNodeOperator.totalAddedValidators, secondNodeOperator.totalDepositedValidators) const { allocatedKeysCount, nodeOperatorIds, activeKeyCountsAfterAllocation } = await app.testing_getSigningKeysAllocationData(10) assert.equals(allocatedKeysCount, 0) @@ -1936,8 +2050,8 @@ contract('NodeOperatorsRegistry', (addresses) => { app.getNodeOperator(firstNodeOperatorId, false), app.getNodeOperator(secondNodeOperatorId, false), ]) - assert.equals(firstNodeOperator.usedSigningKeys, firstNodeOperator.stakingLimit) - assert.equals(secondNodeOperator.usedSigningKeys, secondNodeOperator.stakingLimit) + assert.equals(firstNodeOperator.totalDepositedValidators, firstNodeOperator.totalVettedValidators) + assert.equals(secondNodeOperator.totalDepositedValidators, secondNodeOperator.totalVettedValidators) const { allocatedKeysCount, nodeOperatorIds, activeKeyCountsAfterAllocation } = await app.testing_getSigningKeysAllocationData(10) assert.equals(allocatedKeysCount, 0) @@ -1952,8 +2066,10 @@ contract('NodeOperatorsRegistry', (addresses) => { app.getNodeOperator(secondNodeOperatorId, false), ]) - assert.equals(firstNodeOperator.stakingLimit, firstNodeOperator.usedSigningKeys) - assert.isTrue(secondNodeOperator.stakingLimit.toNumber() > secondNodeOperator.usedSigningKeys.toNumber()) + assert.equals(firstNodeOperator.totalVettedValidators, firstNodeOperator.totalDepositedValidators) + assert.isTrue( + secondNodeOperator.totalVettedValidators.toNumber() > secondNodeOperator.totalDepositedValidators.toNumber() + ) const keysToAllocate = 10 const { allocatedKeysCount, nodeOperatorIds, activeKeyCountsAfterAllocation } = await app.testing_getSigningKeysAllocationData(keysToAllocate) @@ -2291,10 +2407,13 @@ contract('NodeOperatorsRegistry', (addresses) => { assert.equals(nodeOperator.active, NODE_OPERATORS[secondNodeOperatorId].isActive !== false) assert.equals(nodeOperator.name, NODE_OPERATORS[secondNodeOperatorId].name) assert.equals(nodeOperator.rewardAddress, NODE_OPERATORS[secondNodeOperatorId].rewardAddress) - assert.equals(nodeOperator.stakingLimit, NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount) - assert.equals(nodeOperator.stoppedValidators, NODE_OPERATORS[secondNodeOperatorId].exitedSigningKeysCount) - assert.equals(nodeOperator.totalSigningKeys, NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount) - assert.equals(nodeOperator.usedSigningKeys, NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount) + assert.equals(nodeOperator.totalVettedValidators, NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount) + assert.equals(nodeOperator.totalExitedValidators, NODE_OPERATORS[secondNodeOperatorId].exitedSigningKeysCount) + assert.equals(nodeOperator.totalAddedValidators, NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount) + assert.equals( + nodeOperator.totalDepositedValidators, + NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount + ) }) it('returns empty name when _fullInfo is false', async () => { @@ -2472,11 +2591,14 @@ contract('NodeOperatorsRegistry', (addresses) => { }) it('increases node operator total signing keys counter correctly', async () => { - const { totalSigningKeys: totalSigningKeysCountBefore } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalAddedValidators: totalSigningKeysCountBefore } = await app.getNodeOperator( + firstNodeOperatorId, + false + ) await app.addSigningKeys(firstNodeOperatorId, firstNodeOperatorKeys.count, ...firstNodeOperatorKeys.slice(), { from: signingKeysManager, }) - const { totalSigningKeys: totalSigningKeysCountAfter } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalAddedValidators: totalSigningKeysCountAfter } = await app.getNodeOperator(firstNodeOperatorId, false) assert.equals( totalSigningKeysCountAfter.toNumber(), totalSigningKeysCountBefore.toNumber() + firstNodeOperatorKeys.count @@ -2484,11 +2606,17 @@ contract('NodeOperatorsRegistry', (addresses) => { }) it("doesn't modify total signing keys counter of other node operators", async () => { - const { totalSigningKeys: totalSigningKeysCountBefore } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalAddedValidators: totalSigningKeysCountBefore } = await app.getNodeOperator( + secondNodeOperatorId, + false + ) await app.addSigningKeys(firstNodeOperatorId, firstNodeOperatorKeys.count, ...firstNodeOperatorKeys.slice(), { from: signingKeysManager, }) - const { totalSigningKeys: totalSigningKeysCountAfter } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalAddedValidators: totalSigningKeysCountAfter } = await app.getNodeOperator( + secondNodeOperatorId, + false + ) assert.equals(totalSigningKeysCountBefore, totalSigningKeysCountAfter) }) @@ -2661,6 +2789,48 @@ contract('NodeOperatorsRegistry', (addresses) => { assert.equals(depositSignature, expectedSignature) } }) + + it('nonce should not change if operators are inactive', async () => { + const [nodeOperatorBefore, keysOpIndexBefore, nonceBefore] = await Promise.all([ + app.getNodeOperator(firstNodeOperatorId, false), + app.getKeysOpIndex(), + app.getNonce(), + ]) + assert.isTrue(nodeOperatorBefore.active) + + // nonce is increased only here + await app.deactivateNodeOperator(firstNodeOperatorId, { from: nodeOperatorsManager }) + + let [nodeOperatorAfter, keysOpIndexAfter, nonceAfter] = await Promise.all([ + app.getNodeOperator(firstNodeOperatorId, false), + app.getKeysOpIndex(), + app.getNonce(), + ]) + + assert.isFalse(nodeOperatorAfter.active) + assert.equals(+keysOpIndexBefore + 1, keysOpIndexAfter) + assert.equals(+nonceBefore + 1, nonceAfter) + + await assert.reverts( + app.addSigningKeysOperatorBH( + firstNodeOperatorId, + firstNodeOperatorKeys.count, + ...firstNodeOperatorKeys.slice(), + { + from: user1, + } + ), + 'APP_AUTH_FAILED' + ) + ;[nodeOperatorAfter, keysOpIndexAfter, nonceAfter] = await Promise.all([ + app.getNodeOperator(firstNodeOperatorId, false), + app.getKeysOpIndex(), + app.getNonce(), + ]) + + assert.equals(+keysOpIndexBefore + 1, keysOpIndexAfter) + assert.equals(+nonceBefore + 1, nonceAfter) + }) }) describe('removeSigningKey()', async () => { @@ -2720,9 +2890,9 @@ contract('NodeOperatorsRegistry', (addresses) => { it('decreases total signing keys counter for node operator', async () => { const keyIndex = NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount assert.isTrue(keyIndex <= NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount) - const { totalSigningKeys: totalSigningKeysBefore } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalAddedValidators: totalSigningKeysBefore } = await app.getNodeOperator(secondNodeOperatorId, false) await app.removeSigningKey(secondNodeOperatorId, keyIndex, { from: signingKeysManager }) - const { totalSigningKeys: totalSigningKeysAfter } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalAddedValidators: totalSigningKeysAfter } = await app.getNodeOperator(secondNodeOperatorId, false) assert.equals(totalSigningKeysAfter.toNumber(), totalSigningKeysBefore.toNumber() - 1) }) @@ -2738,18 +2908,18 @@ contract('NodeOperatorsRegistry', (addresses) => { it("doesn't change vetted signing keys counter if it greater than vetted keys counter", async () => { const keyIndex = NODE_OPERATORS[firstNodeOperatorId].vettedSigningKeysCount + 1 assert.isTrue(keyIndex <= NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount) - const { stakingLimit: stakingLimitBefore } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalVettedValidators: stakingLimitBefore } = await app.getNodeOperator(firstNodeOperatorId, false) await app.removeSigningKey(firstNodeOperatorId, keyIndex, { from: signingKeysManager }) - const { stakingLimit: stakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalVettedValidators: stakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, false) assert.equals(stakingLimitBefore, stakingLimitAfter) }) it("doesn't change vetted signing keys counter if it equal to vetted keys counter", async () => { const keyIndex = NODE_OPERATORS[firstNodeOperatorId].vettedSigningKeysCount assert.isTrue(keyIndex <= NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount) - const { stakingLimit: stakingLimitBefore } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalVettedValidators: stakingLimitBefore } = await app.getNodeOperator(firstNodeOperatorId, false) await app.removeSigningKey(firstNodeOperatorId, keyIndex, { from: signingKeysManager }) - const { stakingLimit: stakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalVettedValidators: stakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, false) assert.equals(stakingLimitBefore, stakingLimitAfter) }) @@ -2757,7 +2927,7 @@ contract('NodeOperatorsRegistry', (addresses) => { const keyIndex = NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount - 1 assert.isTrue(keyIndex <= NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount) await app.removeSigningKey(secondNodeOperatorId, keyIndex, { from: signingKeysManager }) - const { stakingLimit: stakingLimitAfter } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalVettedValidators: stakingLimitAfter } = await app.getNodeOperator(secondNodeOperatorId, false) assert.equals(stakingLimitAfter.toNumber(), keyIndex) }) @@ -2828,8 +2998,8 @@ contract('NodeOperatorsRegistry', (addresses) => { it('correctly removes the last unused signing key', async () => { const keyIndex = NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - 1 await app.removeSigningKey(firstNodeOperatorId, keyIndex, { from: signingKeysManager }) - const { totalSigningKeys } = await app.getNodeOperator(firstNodeOperatorId, false) - for (let i = 0; i < totalSigningKeys.toNumber(); ++i) { + const { totalAddedValidators } = await app.getNodeOperator(firstNodeOperatorId, false) + for (let i = 0; i < totalAddedValidators.toNumber(); ++i) { const { key, depositSignature } = await app.getSigningKey(firstNodeOperatorId, i) const [expectedPublicKey, expectedSignature] = firstNodeOperatorKeys.get(i) assert.equals(key, expectedPublicKey) @@ -2852,8 +3022,8 @@ contract('NodeOperatorsRegistry', (addresses) => { const [expectedPublicKey, expectedSignature] = secondNodeOperatorKeys.get(secondNodeOperatorKeys.count - 1) assert.equals(key, expectedPublicKey) assert.equals(depositSignature, expectedSignature) - const { totalSigningKeys } = await app.getNodeOperator(secondNodeOperatorId, false) - for (let i = keyIndex + 1; i < totalSigningKeys.toNumber(); ++i) { + const { totalAddedValidators } = await app.getNodeOperator(secondNodeOperatorId, false) + for (let i = keyIndex + 1; i < totalAddedValidators.toNumber(); ++i) { const { key, depositSignature } = await app.getSigningKey(secondNodeOperatorId, i) const [expectedPublicKey, expectedSignature] = secondNodeOperatorKeys.get(i) assert.equals(key, expectedPublicKey) @@ -2871,16 +3041,19 @@ contract('NodeOperatorsRegistry', (addresses) => { from: signingKeysManager, }) } - const { totalSigningKeys, stakingLimit, usedSigningKeys } = await app.getNodeOperator(firstNodeOperatorId, false) - for (let i = 0; i < totalSigningKeys.toNumber(); ++i) { + const { totalAddedValidators, totalVettedValidators, totalDepositedValidators } = await app.getNodeOperator( + firstNodeOperatorId, + false + ) + for (let i = 0; i < totalAddedValidators.toNumber(); ++i) { const { key, depositSignature } = await app.getSigningKey(firstNodeOperatorId, i) const [expectedPublicKey, expectedSignature] = firstNodeOperatorKeys.get(i) assert.equals(key, expectedPublicKey) assert.equals(depositSignature, expectedSignature) } - assert.equals(stakingLimit, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) - assert.equals(usedSigningKeys, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) - assert.equals(totalSigningKeys, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) + assert.equals(totalVettedValidators, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) + assert.equals(totalDepositedValidators, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) + assert.equals(totalAddedValidators, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) }) it("doesn't modify keys of other node operators", async () => { @@ -2906,12 +3079,12 @@ contract('NodeOperatorsRegistry', (addresses) => { const keyIndex = NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount - 1 assert.isTrue(keyIndex <= NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount) await app.removeSigningKey(secondNodeOperatorId, keyIndex, { from: signingKeysManager }) - const { totalSigningKeys } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalAddedValidators } = await app.getNodeOperator(secondNodeOperatorId, false) const keysToAdd = new signingKeys.FakeValidatorKeys(1) await app.addSigningKeys(secondNodeOperatorId, keysToAdd.count, ...keysToAdd.slice(), { from: signingKeysManager, }) - const { key, depositSignature } = await app.getSigningKey(secondNodeOperatorId, totalSigningKeys.toNumber()) + const { key, depositSignature } = await app.getSigningKey(secondNodeOperatorId, totalAddedValidators.toNumber()) assert.equals(key, keysToAdd.get(0)[0]) assert.equals(depositSignature, keysToAdd.get(0)[1]) }) @@ -2997,8 +3170,8 @@ contract('NodeOperatorsRegistry', (addresses) => { it('returns earlier if keys count is 0', async () => { const keyIndex = NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount await app.removeSigningKeys(firstNodeOperatorId, keyIndex, 0, { from: signingKeysManager }) - const { totalSigningKeys } = await app.getNodeOperator(firstNodeOperatorId, false) - assert.equals(totalSigningKeys, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount) + const { totalAddedValidators } = await app.getNodeOperator(firstNodeOperatorId, false) + assert.equals(totalAddedValidators, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount) }) it('reverts with "OUT_OF_RANGE" error when called on non existent validator', async () => { @@ -3062,9 +3235,9 @@ contract('NodeOperatorsRegistry', (addresses) => { const keyIndex = NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount const keysCount = NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount - keyIndex assert(keysCount > 0) - const { totalSigningKeys: totalSigningKeysBefore } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalAddedValidators: totalSigningKeysBefore } = await app.getNodeOperator(secondNodeOperatorId, false) await app.removeSigningKeys(secondNodeOperatorId, keyIndex, keysCount, { from: signingKeysManager }) - const { totalSigningKeys: totalSigningKeysAfter } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalAddedValidators: totalSigningKeysAfter } = await app.getNodeOperator(secondNodeOperatorId, false) assert.equals(totalSigningKeysAfter.toNumber(), totalSigningKeysBefore.toNumber() - keysCount) }) @@ -3082,18 +3255,18 @@ contract('NodeOperatorsRegistry', (addresses) => { const keyIndex = NODE_OPERATORS[firstNodeOperatorId].vettedSigningKeysCount + 1 const keysCount = NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - keyIndex assert(keysCount > 0) - const { stakingLimit: stakingLimitBefore } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalVettedValidators: stakingLimitBefore } = await app.getNodeOperator(firstNodeOperatorId, false) await app.removeSigningKeys(firstNodeOperatorId, keyIndex, keysCount, { from: signingKeysManager }) - const { stakingLimit: stakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalVettedValidators: stakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, false) assert.equals(stakingLimitBefore, stakingLimitAfter) }) it("doesn't change vetted signing keys counter if fromIndex is equal to vetted keys counter", async () => { const keyIndex = NODE_OPERATORS[firstNodeOperatorId].vettedSigningKeysCount const keysCount = 1 - const { stakingLimit: stakingLimitBefore } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalVettedValidators: stakingLimitBefore } = await app.getNodeOperator(firstNodeOperatorId, false) await app.removeSigningKeys(firstNodeOperatorId, keyIndex, keysCount, { from: signingKeysManager }) - const { stakingLimit: stakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, false) + const { totalVettedValidators: stakingLimitAfter } = await app.getNodeOperator(firstNodeOperatorId, false) assert.equals(stakingLimitBefore, stakingLimitAfter) }) @@ -3102,7 +3275,7 @@ contract('NodeOperatorsRegistry', (addresses) => { const keysCount = NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount - keyIndex assert(keysCount > 0) await app.removeSigningKeys(secondNodeOperatorId, keyIndex, keysCount, { from: signingKeysManager }) - const { stakingLimit: stakingLimitAfter } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalVettedValidators: stakingLimitAfter } = await app.getNodeOperator(secondNodeOperatorId, false) assert.equals(stakingLimitAfter.toNumber(), keyIndex) }) @@ -3166,10 +3339,10 @@ contract('NodeOperatorsRegistry', (addresses) => { const keysCount = NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount - keyIndex assert(keysCount > 0) await app.removeSigningKeys(secondNodeOperatorId, keyIndex, keysCount, { from: signingKeysManager }) - const { totalSigningKeys, stakingLimit } = await app.getNodeOperator(secondNodeOperatorId, false) - assert.equals(totalSigningKeys, NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount) - assert.equals(stakingLimit, NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount) - for (let i = 0; i < totalSigningKeys.toNumber(); ++i) { + const { totalAddedValidators, totalVettedValidators } = await app.getNodeOperator(secondNodeOperatorId, false) + assert.equals(totalAddedValidators, NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount) + assert.equals(totalVettedValidators, NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount) + for (let i = 0; i < totalAddedValidators.toNumber(); ++i) { const { key, depositSignature } = await app.getSigningKey(secondNodeOperatorId, i) const [expectedPublicKey, expectedSignature] = secondNodeOperatorKeys.get(i) assert.equals(key, expectedPublicKey) @@ -3182,14 +3355,14 @@ contract('NodeOperatorsRegistry', (addresses) => { const keysCount = NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount - keyIndex assert(keysCount > 0) await app.removeSigningKeys(secondNodeOperatorId, keyIndex, keysCount, { from: signingKeysManager }) - const { totalSigningKeys, stakingLimit } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalAddedValidators, totalVettedValidators } = await app.getNodeOperator(secondNodeOperatorId, false) assert.equals( - totalSigningKeys, + totalAddedValidators, NODE_OPERATORS[secondNodeOperatorId].totalSigningKeysCount - (NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount - NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount) ) - assert.equals(stakingLimit, NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount) + assert.equals(totalVettedValidators, NODE_OPERATORS[secondNodeOperatorId].depositedSigningKeysCount) // the deposited keys must stay untouched for (let i = 0; i < keyIndex; ++i) { @@ -3208,7 +3381,7 @@ contract('NodeOperatorsRegistry', (addresses) => { assert.equals(depositSignature, expectedSignature) } // the rest of the batch stays same - for (let i = keyIndex + keysCount; i < totalSigningKeys.toNumber(); ++i) { + for (let i = keyIndex + keysCount; i < totalAddedValidators.toNumber(); ++i) { const { key, depositSignature } = await app.getSigningKey(secondNodeOperatorId, i) const [expectedPublicKey, expectedSignature] = secondNodeOperatorKeys.get(i) assert.equals(key, expectedPublicKey) @@ -3221,9 +3394,9 @@ contract('NodeOperatorsRegistry', (addresses) => { const keysCount = NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - keyIndex - 1 assert(keysCount > 0) await app.removeSigningKeys(firstNodeOperatorId, keyIndex, keysCount, { from: signingKeysManager }) - const { totalSigningKeys, stakingLimit } = await app.getNodeOperator(firstNodeOperatorId, false) - assert.equals(totalSigningKeys, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - keysCount) - assert.equals(stakingLimit, keyIndex) + const { totalAddedValidators, totalVettedValidators } = await app.getNodeOperator(firstNodeOperatorId, false) + assert.equals(totalAddedValidators, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - keysCount) + assert.equals(totalVettedValidators, keyIndex) for (let i = 0; i < keyIndex; ++i) { const { key, depositSignature } = await app.getSigningKey(firstNodeOperatorId, i) const [expectedPublicKey, expectedSignature] = firstNodeOperatorKeys.get(i) @@ -3239,7 +3412,7 @@ contract('NodeOperatorsRegistry', (addresses) => { assert.equals(depositSignature, expectedSignature) } // in this case we removed all keys except the last one - assert.equals(totalSigningKeys, keyIndex + 1) + assert.equals(totalAddedValidators, keyIndex + 1) // the last key stays on the same place const [expectedPublicKey, expectedSignature] = firstNodeOperatorKeys.get(firstNodeOperatorKeys.count - 1) const { key, depositSignature } = await app.getSigningKey(firstNodeOperatorId, keyIndex) @@ -3254,16 +3427,19 @@ contract('NodeOperatorsRegistry', (addresses) => { NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount assert(unusedKeysCount > 0) await app.removeSigningKeys(firstNodeOperatorId, keyIndex, unusedKeysCount, { from: signingKeysManager }) - const { totalSigningKeys, stakingLimit, usedSigningKeys } = await app.getNodeOperator(firstNodeOperatorId, false) - for (let i = 0; i < totalSigningKeys.toNumber(); ++i) { + const { totalAddedValidators, totalVettedValidators, totalDepositedValidators } = await app.getNodeOperator( + firstNodeOperatorId, + false + ) + for (let i = 0; i < totalAddedValidators.toNumber(); ++i) { const { key, depositSignature } = await app.getSigningKey(firstNodeOperatorId, i) const [expectedPublicKey, expectedSignature] = firstNodeOperatorKeys.get(i) assert.equals(key, expectedPublicKey) assert.equals(depositSignature, expectedSignature) } - assert.equals(stakingLimit, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) - assert.equals(usedSigningKeys, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) - assert.equals(totalSigningKeys, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) + assert.equals(totalVettedValidators, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) + assert.equals(totalDepositedValidators, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) + assert.equals(totalAddedValidators, NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount) }) it("doesn't modify keys of other node operators", async () => { @@ -3286,12 +3462,12 @@ contract('NodeOperatorsRegistry', (addresses) => { const keyIndex = NODE_OPERATORS[secondNodeOperatorId].vettedSigningKeysCount - 1 const keysCount = 2 await app.removeSigningKeys(secondNodeOperatorId, keyIndex, keysCount, { from: signingKeysManager }) - const { totalSigningKeys } = await app.getNodeOperator(secondNodeOperatorId, false) + const { totalAddedValidators } = await app.getNodeOperator(secondNodeOperatorId, false) const keysToAdd = new signingKeys.FakeValidatorKeys(1) await app.addSigningKeys(secondNodeOperatorId, keysToAdd.count, ...keysToAdd.slice(), { from: signingKeysManager, }) - const { key, depositSignature } = await app.getSigningKey(secondNodeOperatorId, totalSigningKeys.toNumber()) + const { key, depositSignature } = await app.getSigningKey(secondNodeOperatorId, totalAddedValidators.toNumber()) assert.equals(key, keysToAdd.get(0)[0]) assert.equals(depositSignature, keysToAdd.get(0)[1]) }) @@ -3391,8 +3567,8 @@ contract('NodeOperatorsRegistry', (addresses) => { it('reward address can remove signing keys', async () => { const keyIndex = NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount await app.removeSigningKeyOperatorBH(firstNodeOperatorId, keyIndex, { from: rewardAddress }) - const { totalSigningKeys } = await app.getNodeOperator(firstNodeOperatorId, false) - assert.equals(totalSigningKeys, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - 1) + const { totalAddedValidators } = await app.getNodeOperator(firstNodeOperatorId, false) + assert.equals(totalAddedValidators, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - 1) }) }) @@ -3445,8 +3621,8 @@ contract('NodeOperatorsRegistry', (addresses) => { const keyIndex = NODE_OPERATORS[firstNodeOperatorId].depositedSigningKeysCount const keysCount = NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - keyIndex await app.removeSigningKeysOperatorBH(firstNodeOperatorId, keyIndex, keysCount, { from: rewardAddress }) - const { totalSigningKeys } = await app.getNodeOperator(firstNodeOperatorId, false) - assert.equals(totalSigningKeys, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - keysCount) + const { totalAddedValidators } = await app.getNodeOperator(firstNodeOperatorId, false) + assert.equals(totalAddedValidators, NODE_OPERATORS[firstNodeOperatorId].totalSigningKeysCount - keysCount) }) }) @@ -3698,6 +3874,47 @@ contract('NodeOperatorsRegistry', (addresses) => { }) }) + describe('clearNodeOperatorPenalty', () => { + const firstNodeOperatorId = 0 + const nonExistentNodeOperatorId = 3 + + beforeEach(async () => { + await nodeOperators.addNodeOperator(app, { ...NODE_OPERATORS[0], exitedSigningKeysCount: 3 }, { from: admin }) + const refundedValidatorsCount = 4 + const stuckValidatorsCount = 3 + const stuckPenaltyEndTimestamp = 1 // dumb data, we only need some time in past + await app.testing_setNodeOperatorPenalty( + firstNodeOperatorId, + refundedValidatorsCount, + stuckValidatorsCount, + stuckPenaltyEndTimestamp + ) + }) + + it('reverts with message "CANT_CLEAR_PENALTY" called with non existed node operator id', async () => { + await assert.reverts( + app.clearNodeOperatorPenalty(nonExistentNodeOperatorId, { from: stakingRouter }), + 'CANT_CLEAR_PENALTY' + ) + }) + + it('updates nonce & keysOpIndex', async () => { + const [nonceBefore, keysOpIndexBefore] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + await app.clearNodeOperatorPenalty(firstNodeOperatorId, { from: stakingRouter }) + const [nonceAfter, keysOpIndexAfter] = await Promise.all([app.getNonce(), app.getKeysOpIndex()]) + assert.equals(nonceAfter, wei(nonceBefore) + 1n) + assert.equals(keysOpIndexAfter, wei(keysOpIndexBefore) + 1n) + }) + + it('emits KeysOpIndexSet & NonceChanged events', async () => { + const keysOpIndexBefore = await app.getKeysOpIndex() + const tx = await app.clearNodeOperatorPenalty(firstNodeOperatorId, { from: stakingRouter }) + const nonceAfter = await app.getNonce() + assert.emits(tx, 'KeysOpIndexSet', { keysOpIndex: wei(keysOpIndexBefore) + 1n }) + assert.emits(tx, 'NonceChanged', { nonce: nonceAfter }) + }) + }) + describe('setStuckPenaltyDelay()', () => { it('reverts with error "APP_AUTH_FAILED" when called by sender without MANAGE_NODE_OPERATOR_ROLE', async () => { const hasPermission = await dao.hasPermission(nobody, app, 'MANAGE_NODE_OPERATOR_ROLE') diff --git a/test/0.4.24/signingkey-lib.test.js b/test/0.4.24/signingkey-lib.test.js index b83231908..dbef3cee9 100644 --- a/test/0.4.24/signingkey-lib.test.js +++ b/test/0.4.24/signingkey-lib.test.js @@ -8,6 +8,8 @@ const signingKeys = require('../helpers/signing-keys') const SigningKeysMock = artifacts.require('SigningKeysMock') const SigningKeys = artifacts.require('SigningKeys') +const UINT64_MAX_BN = toBN('0xffffffffffffffff') + const nodeOpId1 = 1 const nodeOpId2 = 2 @@ -34,6 +36,40 @@ contract('SigningKeys', () => { }) describe('saveKeysSigs()', () => { + it('reverts with INVALID_KEYS_COUNT error when start index == UINT64_MAX', async () => { + const keysCount = 1 + const [publicKeys, signatures] = firstNodeOperatorKeys.slice(0, keysCount) + await assert.reverts( + app.saveKeysSigs(firstNodeOperatorId, UINT64_MAX_BN, keysCount, publicKeys, signatures), + 'INVALID_KEYS_COUNT' + ) + }) + + it('works correctly when when start index == UINT64_MAX - 1 and keys count == 1', async () => { + const keysCount = 1 + const startIndex = UINT64_MAX_BN.sub(toBN(1)) + const [publicKeys, signatures] = firstNodeOperatorKeys.slice(0, keysCount) + await app.saveKeysSigs(firstNodeOperatorId, startIndex, keysCount, publicKeys, signatures) + + const { pubkeys: actualPublicKey, signatures: actualSignature } = await app.loadKeysSigs( + firstNodeOperatorId, + startIndex, + 1 + ) + const [expectedPublicKey, expectedSignature] = firstNodeOperatorKeys.get(0) + assert.equal(actualPublicKey, expectedPublicKey) + assert.equal(actualSignature, expectedSignature) + }) + + it('reverts with INVALID_KEYS_COUNT error when start index == UINT64_MAX', async () => { + const keysCount = 1 + const [publicKeys, signatures] = firstNodeOperatorKeys.slice(0, keysCount) + await assert.reverts( + app.saveKeysSigs(firstNodeOperatorId, UINT64_MAX_BN, keysCount, publicKeys, signatures), + 'INVALID_KEYS_COUNT' + ) + }) + it('reverts with INVALID_KEYS_COUNT error when keys count > UINT64_MAX', async () => { const keysCount = toBN('0x10000000000000001') await assert.reverts( diff --git a/test/0.4.24/staking-limit.test.js b/test/0.4.24/staking-limit.test.js index 0b3d7e14a..cc49d8c2c 100644 --- a/test/0.4.24/staking-limit.test.js +++ b/test/0.4.24/staking-limit.test.js @@ -50,29 +50,29 @@ contract('StakingLimits', ([account1]) => { it('check staking pause at start', async () => { const slot = await limits.setStorageStakeLimitStruct(0, 0, 0, 0) const paused = await limits.isStakingPaused(slot) - assert.equal(paused, true, 'staking not paused') + assert.equals(paused, true, 'staking not paused') }) it('check staking pause with block number', async () => { const prevStakeBlockNumber = 10 const slot2 = await limits.setStorageStakeLimitStruct(prevStakeBlockNumber, 0, 0, 0) const paused2 = await limits.isStakingPaused(slot2) - assert.equal(paused2, false, 'staking paused') + assert.equals(paused2, false, 'staking paused') }) it('check staking pause/unpause', async () => { let paused const slot = await limits.setStorageStakeLimitStruct(1, 1, 1, 1) paused = await limits.isStakingPaused(slot) - assert.equal(paused, false, 'staking paused') + assert.equals(paused, false, 'staking paused') const slot2 = await limits.setStakeLimitPauseState(slot, true) paused = await limits.isStakingPaused(slot2) - assert.equal(paused, true, 'staking not paused') + assert.equals(paused, true, 'staking not paused') const slot3 = await limits.setStakeLimitPauseState(slot, false) paused = await limits.isStakingPaused(slot3) - assert.equal(paused, false, 'staking paused') + assert.equals(paused, false, 'staking paused') }) it('check staking rate limit', async () => { @@ -80,16 +80,16 @@ contract('StakingLimits', ([account1]) => { const slot = await limits.setStorageStakeLimitStruct(0, 0, 0, 0) limited = await limits.isStakingLimitSet(slot) - assert.equal(limited, false, 'limits are limited') + assert.equals(limited, false, 'limits are limited') const maxStakeLimit = 10 const slot2 = await limits.setStorageStakeLimitStruct(0, 0, 0, maxStakeLimit) limited = await limits.isStakingLimitSet(slot2) - assert.equal(limited, true, 'limits are not limited') + assert.equals(limited, true, 'limits are not limited') const slot3 = await limits.removeStakingLimit(slot2) limited = await limits.isStakingLimitSet(slot3) - assert.equal(limited, false, 'limits are limited') + assert.equals(limited, false, 'limits are limited') }) it('stake limit increase > max stake', async () => { @@ -140,12 +140,12 @@ contract('StakingLimits', ([account1]) => { assert.equals(currentStakeLimit2, 0) const block2 = await waitBlocks(1) - assert.equal(block2.number, block.number + 1) + assert.equals(block2.number, block.number + 1) const currentStakeLimit3 = await limits.calculateCurrentStakeLimit(slot) assert.equals(currentStakeLimit3, 50) const block3 = await waitBlocks(3) - assert.equal(block3.number, block.number + 1 + 3) + assert.equals(block3.number, block.number + 1 + 3) const currentStakeLimit4 = await limits.calculateCurrentStakeLimit(slot) assert.equals(currentStakeLimit4, 100) }) @@ -159,11 +159,11 @@ contract('StakingLimits', ([account1]) => { const slot = await limits.setStorageStakeLimitStruct(block.number, 0, maxStakeLimitGrowthBlocks, maxStakeLimit) const decodedSlot = await limits.getStorageStakeLimit(slot) - assert.equal(decodedSlot.prevStakeBlockNumber, block.number) - assert.equal(decodedSlot.prevStakeLimit, 0) + assert.equals(decodedSlot.prevStakeBlockNumber, block.number) + assert.equals(decodedSlot.prevStakeLimit, 0) const block2 = await waitBlocks(3) - assert.equal(block2.number, block.number + 3) + assert.equals(block2.number, block.number + 3) const currentStakeLimit2 = await limits.calculateCurrentStakeLimit(slot) assert.equals(currentStakeLimit2, maxStakeLimit) @@ -171,8 +171,8 @@ contract('StakingLimits', ([account1]) => { const deposit = 87 const newSlot = await limits.updatePrevStakeLimit(slot, currentStakeLimit2 - deposit) const decodedNewSlot = await limits.getStorageStakeLimit(newSlot) - assert.equal(decodedNewSlot.prevStakeBlockNumber, block2.number) - assert.equal(decodedNewSlot.prevStakeLimit, 13) + assert.equals(decodedNewSlot.prevStakeBlockNumber, block2.number) + assert.equals(decodedNewSlot.prevStakeLimit, 13) // checking staking recovery await waitBlocks(1) @@ -240,4 +240,48 @@ contract('StakingLimits', ([account1]) => { assert.equals(currentBlock, referenceBlock + i + 1) } }) + + it('setStakingLimit resets prev stake limit to the new max', async () => { + const block = await web3.eth.getBlock('latest') + const maxStakeLimit = 10000 + const maxStakeLimitGrowthBlocks = 100 + const prevStakeLimit = 5000 + + // set initial values + let slot = await limits.setStorageStakeLimitStruct( + block.number, + prevStakeLimit, + maxStakeLimitGrowthBlocks, + maxStakeLimit + ) + + // check their correctness + let decodedRaw = await limits.getStorageStakeLimit(slot) + assert.equals(decodedRaw.maxStakeLimit, maxStakeLimit) + assert.equals(decodedRaw.maxStakeLimitGrowthBlocks, maxStakeLimitGrowthBlocks) + assert.equals(decodedRaw.prevStakeLimit, prevStakeLimit) + assert.equals(decodedRaw.prevStakeBlockNumber, block.number) + + // pause stake + slot = await limits.setStakeLimitPauseState(slot, true) + assert.isTrue(await limits.isStakingPaused(slot)) + + // setStakeLimit again + slot = await limits.setStakingLimit(slot, maxStakeLimit, maxStakeLimit / maxStakeLimitGrowthBlocks) + decodedRaw = await limits.getStorageStakeLimit(slot) + assert.equals(decodedRaw.prevStakeLimit, maxStakeLimit) + + // set unlimited + slot = await limits.removeStakingLimit(slot) + + // setStakeLimit again + slot = await limits.setStakingLimit(slot, maxStakeLimit * 2, 10) + decodedRaw = await limits.getStorageStakeLimit(slot) + assert.equals(decodedRaw.prevStakeLimit, maxStakeLimit * 2) + + // set stake limit lower than before + slot = await limits.setStakingLimit(slot, maxStakeLimit / 2, 100) + decodedRaw = await limits.getStorageStakeLimit(slot) + assert.equals(decodedRaw.prevStakeLimit, maxStakeLimit / 2) + }) }) diff --git a/test/0.8.9/deposit-security-module.test.js b/test/0.8.9/deposit-security-module.test.js index 1e6ccc061..39adee6b8 100644 --- a/test/0.8.9/deposit-security-module.test.js +++ b/test/0.8.9/deposit-security-module.test.js @@ -479,7 +479,7 @@ contract('DepositSecurityModule', ([owner, stranger, guardian]) => { signatures, { from: stranger } ), - 'SignatureNotSorted()' + 'SignaturesNotSorted()' ) }) @@ -500,7 +500,7 @@ contract('DepositSecurityModule', ([owner, stranger, guardian]) => { signatures, { from: stranger } ), - 'SignatureNotSorted()' + 'SignaturesNotSorted()' ) }) diff --git a/test/0.8.9/oracle-report-sanity-checker.test.js b/test/0.8.9/oracle-report-sanity-checker.test.js index efe1bea14..2be6b557b 100644 --- a/test/0.8.9/oracle-report-sanity-checker.test.js +++ b/test/0.8.9/oracle-report-sanity-checker.test.js @@ -1,5 +1,5 @@ const { artifacts, contract, ethers } = require('hardhat') -const { ETH } = require('../helpers/utils') +const { ETH, ZERO_ADDRESS } = require('../helpers/utils') const { assert } = require('../helpers/assert') const { getCurrentBlockTimestamp, EvmSnapshot } = require('../helpers/blockchain') @@ -90,6 +90,21 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa await snapshot.rollback() }) + it('constructor reverts if admin address is zero', async () => { + await assert.reverts( + OracleReportSanityChecker.new( + lidoLocatorMock.address, + ZERO_ADDRESS, + Object.values(defaultLimitsList), + Object.values(managersRoster), + { + from: deployer, + } + ), + 'AdminCannotBeZero()' + ) + }) + describe('getLidoLocator()', () => { it('retrieves correct locator address', async () => { assert.equals(await oracleReportSanityChecker.getLidoLocator(), lidoLocatorMock.address) @@ -914,8 +929,8 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa preTotalShares: ETH('1000000'), preCLBalance: ETH('1000000'), postCLBalance: ETH('1000000'), - elRewardsVaultBalance: ETH(500), withdrawalVaultBalance: ETH(500), + elRewardsVaultBalance: ETH(500), sharesRequestedToBurn: ETH(0), etherToLockForWithdrawals: ETH(40000), newSharesToBurnForWithdrawals: ETH(40000), @@ -929,6 +944,33 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa assert.equals(simulatedSharesToBurn, ETH(0)) assert.equals(sharesToBurn, '39960039960039960039960') // ETH(1000000 - 961000. / 1.001) }) + + it('rounding case from Görli', async () => { + const newRebaseLimit = 750_000 // 0.075% or 7.5 basis points + await oracleReportSanityChecker.setMaxPositiveTokenRebase(newRebaseLimit, { + from: managersRoster.maxPositiveTokenRebaseManagers[0], + }) + + const rebaseParams = { + preTotalPooledEther: '125262263468962792235936', + preTotalShares: '120111767594397261197918', + preCLBalance: '113136253352529000000000', + postCLBalance: '113134996436274000000000', + withdrawalVaultBalance: '129959459000000000', + elRewardsVaultBalance: '6644376444653811679390', + sharesRequestedToBurn: '15713136097768852533', + etherToLockForWithdrawals: '0', + newSharesToBurnForWithdrawals: '0', + } + + const { withdrawals, elRewards, simulatedSharesToBurn, sharesToBurn } = + await oracleReportSanityChecker.smoothenTokenRebase(...Object.values(rebaseParams)) + + assert.equals(withdrawals, '129959459000000000') + assert.equals(elRewards, '95073654397722094176') + assert.equals(simulatedSharesToBurn, '0') + assert.equals(sharesToBurn, '0') + }) }) describe('churn limit', () => { @@ -947,7 +989,7 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa await assert.revertsOZAccessControl( oracleReportSanityChecker.setChurnValidatorsPerDayLimit(newChurnLimit, { from: deployer }), deployer, - 'CHURN_VALIDATORS_PER_DAY_LIMIT_MANGER_ROLE' + 'CHURN_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE' ) const tx = await oracleReportSanityChecker.setChurnValidatorsPerDayLimit(newChurnLimit, { @@ -1129,7 +1171,8 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa from: managersRoster.allLimitsManagers[0], } ), - `IncorrectLimitValue(${INVALID_BASIS_POINTS}, ${MAX_BASIS_POINTS})` + 'IncorrectLimitValue', + [INVALID_BASIS_POINTS, 0, MAX_BASIS_POINTS] ) await assert.reverts( @@ -1139,7 +1182,8 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa from: managersRoster.allLimitsManagers[0], } ), - `IncorrectLimitValue(${INVALID_BASIS_POINTS}, ${MAX_BASIS_POINTS})` + 'IncorrectLimitValue', + [INVALID_BASIS_POINTS, 0, MAX_BASIS_POINTS] ) await assert.reverts( @@ -1149,7 +1193,8 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa from: managersRoster.allLimitsManagers[0], } ), - `IncorrectLimitValue(${INVALID_BASIS_POINTS}, ${MAX_BASIS_POINTS})` + 'IncorrectLimitValue', + [INVALID_BASIS_POINTS, 0, MAX_BASIS_POINTS] ) }) @@ -1164,7 +1209,8 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa from: managersRoster.allLimitsManagers[0], } ), - `IncorrectLimitValue(${INVALID_VALUE}, ${MAX_UINT_16})` + 'IncorrectLimitValue', + [INVALID_VALUE, 0, MAX_UINT_16] ) await assert.reverts( @@ -1174,7 +1220,8 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa from: managersRoster.allLimitsManagers[0], } ), - `IncorrectLimitValue(${INVALID_VALUE}, ${MAX_UINT_16})` + 'IncorrectLimitValue', + [INVALID_VALUE, 0, MAX_UINT_16] ) await assert.reverts( @@ -1184,7 +1231,8 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa from: managersRoster.allLimitsManagers[0], } ), - `IncorrectLimitValue(${INVALID_VALUE}, ${MAX_UINT_16})` + 'IncorrectLimitValue', + [INVALID_VALUE, 0, MAX_UINT_16] ) await assert.reverts( @@ -1194,7 +1242,8 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa from: managersRoster.allLimitsManagers[0], } ), - `IncorrectLimitValue(${INVALID_VALUE}, ${MAX_UINT_16})` + 'IncorrectLimitValue', + [INVALID_VALUE, 0, MAX_UINT_16] ) }) @@ -1209,7 +1258,8 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa from: managersRoster.allLimitsManagers[0], } ), - `IncorrectLimitValue(${INVALID_VALUE.toString()}, ${MAX_UINT_64.toString()})` + 'IncorrectLimitValue', + [INVALID_VALUE.toString(), 0, MAX_UINT_64.toString()] ) await assert.reverts( @@ -1219,7 +1269,21 @@ contract('OracleReportSanityChecker', ([deployer, admin, withdrawalVault, elRewa from: managersRoster.allLimitsManagers[0], } ), - `IncorrectLimitValue(${INVALID_VALUE.toString()}, ${MAX_UINT_64.toString()})` + 'IncorrectLimitValue', + [INVALID_VALUE.toString(), 1, MAX_UINT_64.toString()] + ) + }) + + it('value must be greater than zero', async () => { + const MAX_UINT_64 = BigInt(2) ** 64n - 1n + const INVALID_VALUE = 0 + + await assert.reverts( + oracleReportSanityChecker.setMaxPositiveTokenRebase(0, { + from: managersRoster.maxPositiveTokenRebaseManagers[0], + }), + 'IncorrectLimitValue', + [INVALID_VALUE, 1, MAX_UINT_64.toString()] ) }) }) diff --git a/test/0.8.9/oracle/accounting-oracle-access-control.test.js b/test/0.8.9/oracle/accounting-oracle-access-control.test.js index 9f6976448..b2ddae258 100644 --- a/test/0.8.9/oracle/accounting-oracle-access-control.test.js +++ b/test/0.8.9/oracle/accounting-oracle-access-control.test.js @@ -105,9 +105,7 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra }) it('should allow calling from a member', async () => { - await consensus.addMember(member2, 2) - - const tx = await oracle.submitReportData(reportItems, CONSENSUS_VERSION, { from: member2 }) + const tx = await oracle.submitReportData(reportItems, CONSENSUS_VERSION, { from: member1 }) assert.emits(tx, 'ProcessingStarted', { refSlot: reportFields.refSlot }) }) }) @@ -131,12 +129,11 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra }) it('should allow calling from a member', async () => { - await consensus.addMember(member2, 2) const deadline = (await oracle.getConsensusReport()).processingDeadlineTime await consensus.setTime(deadline) - await oracle.submitReportData(reportItems, CONSENSUS_VERSION, { from: member2 }) - const tx = await oracle.submitReportExtraDataList(extraDataList, { from: member2 }) + await oracle.submitReportData(reportItems, CONSENSUS_VERSION, { from: member1 }) + const tx = await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) assert.emits(tx, 'ExtraDataSubmitted', { refSlot: reportFields.refSlot }) }) @@ -161,12 +158,11 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra }) it('should allow calling from a member', async () => { - await consensus.addMember(member2, 2) const deadline = (await oracle.getConsensusReport()).processingDeadlineTime await consensus.setTime(deadline) - await oracle.submitReportData(reportItems, CONSENSUS_VERSION, { from: member2 }) - const tx = await oracle.submitReportExtraDataEmpty({ from: member2 }) + await oracle.submitReportData(reportItems, CONSENSUS_VERSION, { from: member1 }) + const tx = await oracle.submitReportExtraDataEmpty({ from: member1 }) assert.emits(tx, 'ExtraDataSubmitted', { refSlot: reportFields.refSlot }) }) diff --git a/test/0.8.9/oracle/accounting-oracle-submit-report-data.test.js b/test/0.8.9/oracle/accounting-oracle-submit-report-data.test.js index fb91dc5fa..49581646e 100644 --- a/test/0.8.9/oracle/accounting-oracle-submit-report-data.test.js +++ b/test/0.8.9/oracle/accounting-oracle-submit-report-data.test.js @@ -1,6 +1,7 @@ -const { contract, web3 } = require('hardhat') +const { contract, web3, ethers } = require('hardhat') const { assert } = require('../../helpers/assert') const { e9, e18, e27, toNum } = require('../../helpers/utils') +const { EvmSnapshot } = require('../../helpers/blockchain') const AccountingOracleAbi = require('../../../lib/abi/AccountingOracle.json') @@ -21,11 +22,12 @@ const { HASH_1, } = require('./accounting-oracle-deploy.test') -contract('AccountingOracle', ([admin, member1]) => { +contract('AccountingOracle', ([admin, member1, member2]) => { let consensus = null let oracle = null let reportItems = null let reportFields = null + let reportHash = null let extraDataList = null let extraDataHash = null let extraDataItems = null @@ -37,6 +39,7 @@ contract('AccountingOracle', ([admin, member1]) => { let oracleReportSanityChecker = null let mockLegacyOracle = null let mockWithdrawalQueue = null + let snapshot = null const getReportFields = (override = {}) => ({ consensusVersion: CONSENSUS_VERSION, @@ -57,6 +60,7 @@ contract('AccountingOracle', ([admin, member1]) => { }) const deploy = async (options = undefined) => { + snapshot = new EvmSnapshot(ethers.provider) const deployed = await deployAndConfigureAccountingOracle(admin) const { refSlot } = await deployed.consensus.getCurrentFrame() @@ -79,7 +83,7 @@ contract('AccountingOracle', ([admin, member1]) => { refSlot: +refSlot, }) reportItems = getAccountingReportDataItems(reportFields) - const reportHash = calcAccountingReportDataHash(reportItems) + reportHash = calcAccountingReportDataHash(reportItems) await deployed.consensus.addMember(member1, 1, { from: admin }) await deployed.consensus.submitReport(refSlot, reportHash, CONSENSUS_VERSION, { from: member1 }) @@ -93,6 +97,12 @@ contract('AccountingOracle', ([admin, member1]) => { oracleReportSanityChecker = deployed.oracleReportSanityChecker mockLegacyOracle = deployed.legacyOracle mockWithdrawalQueue = deployed.withdrawalQueue + + await snapshot.make() + } + + async function rollback() { + await snapshot.rollback() } async function prepareNextReport(newReportFields) { @@ -119,9 +129,10 @@ contract('AccountingOracle', ([admin, member1]) => { }) return next } + before(deploy) context('deploying', () => { - before(deploy) + after(rollback) it('deploying accounting oracle', async () => { assert.isNotNull(oracle) @@ -138,8 +149,34 @@ contract('AccountingOracle', ([admin, member1]) => { }) }) + context('discarded report prevents data submit', () => { + after(rollback) + + it('report is discarded', async () => { + const { refSlot } = await consensus.getCurrentFrame() + const tx = await consensus.addMember(member2, 2, { from: admin }) + assert.emits(tx, 'ReportDiscarded', { refSlot, hash: reportHash }, { abi: AccountingOracleAbi }) + }) + + it('processing state reverts to pre-report state ', async () => { + const state = await oracle.getProcessingState() + assert.equals(state.mainDataHash, ZERO_HASH) + assert.equals(state.extraDataHash, ZERO_HASH) + assert.equals(state.extraDataFormat, 0) + assert.equals(state.mainDataSubmitted, false) + assert.equals(state.extraDataFormat, 0) + assert.equals(state.extraDataSubmitted, false) + assert.equals(state.extraDataItemsCount, 0) + assert.equals(state.extraDataItemsSubmitted, 0) + }) + + it('reverts on trying to submit the discarded report', async () => { + await assert.reverts(oracle.submitReportData(reportItems, oracleVersion, { from: member1 })) + }) + }) + context('submitReportData', () => { - beforeEach(deploy) + afterEach(rollback) context('checks contract version', () => { it('should revert if incorrect contract version', async () => { diff --git a/test/0.8.9/oracle/accounting-oracle-submit-report-extra-data.test.js b/test/0.8.9/oracle/accounting-oracle-submit-report-extra-data.test.js index 2b32fd6a7..d5246d251 100644 --- a/test/0.8.9/oracle/accounting-oracle-submit-report-extra-data.test.js +++ b/test/0.8.9/oracle/accounting-oracle-submit-report-extra-data.test.js @@ -96,31 +96,15 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra } } - async function prepareNextReport({ extraData, extraDataItems, reportFields = {} } = {}) { - const data = getReportData({ extraData, extraDataItems, reportFields }) - - await consensus.submitReport(data.reportFields.refSlot, data.reportHash, CONSENSUS_VERSION, { from: member1 }) - await oracle.submitReportData(data.reportItems, oracleVersion, { from: member1 }) - - const deadline = (await oracle.getConsensusReport()).processingDeadlineTime - - return { - ...data, - deadline, - } + async function prepareReport({ extraData, extraDataItems, reportFields = {} } = {}) { + const { refSlot } = await consensus.getCurrentFrame() + return getReportData({ extraData, extraDataItems, reportFields: { ...reportFields, refSlot } }) } - async function prepareNextReportInNextFrame({ reportFields = {}, ...prepareArgs } = {}) { - await consensus.advanceTimeToNextFrameStart() - const { refSlot } = await consensus.getCurrentFrame() - const next = await prepareNextReport({ - ...prepareArgs, - reportFields: { - ...reportFields, - refSlot, - }, - }) - return next + async function submitReportHash({ extraData, extraDataItems, reportFields = {} } = {}) { + const data = await prepareReport({ extraData, extraDataItems, reportFields }) + await consensus.submitReport(data.reportFields.refSlot, data.reportHash, CONSENSUS_VERSION, { from: member1 }) + return data } context('deploying', () => { @@ -138,7 +122,10 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra context('enforces the deadline', () => { it('reverts with ProcessingDeadlineMissed if deadline missed', async () => { - const { extraDataList, deadline } = await prepareNextReportInNextFrame() + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash() + const deadline = (await oracle.getConsensusReport()).processingDeadlineTime + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await consensus.advanceTimeToNextFrameStart() await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), @@ -147,7 +134,10 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra }) it('pass successfully if time is equals exactly to deadline value', async () => { - const { extraDataList, deadline, reportFields } = await prepareNextReportInNextFrame() + await consensus.advanceTimeToNextFrameStart() + const { extraDataList, reportFields, reportItems } = await submitReportHash() + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) + const deadline = (await oracle.getConsensusReport()).processingDeadlineTime await consensus.setTime(deadline) const tx = await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) assert.emits(tx, 'ExtraDataSubmitted', { refSlot: reportFields.refSlot }) @@ -179,7 +169,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra context('checks extra data hash', () => { it('reverts with UnexpectedDataHash if hash did not match', async () => { - const { extraDataHash } = await prepareNextReportInNextFrame() + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataHash } = await submitReportHash() + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) const incorrectExtraData = getDefaultExtraData() ++incorrectExtraData.stuckKeys[0].nodeOpIds[0] const incorrectExtraDataItems = encodeExtraDataItems(incorrectExtraData) @@ -192,7 +184,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra }) it('pass successfully if data hash matches', async () => { - const { extraDataList, reportFields } = await prepareNextReportInNextFrame() + await consensus.advanceTimeToNextFrameStart() + const { extraDataList, reportFields, reportItems } = await submitReportHash() + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) const tx = await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) assert.emits(tx, 'ExtraDataSubmitted', { refSlot: reportFields.refSlot }) }) @@ -204,7 +198,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra const reportFields = { extraDataItemsCount: wrongItemsCount, } - const { extraDataList, extraDataItems } = await prepareNextReportInNextFrame({ reportFields }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList, extraDataItems } = await submitReportHash({ reportFields }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `UnexpectedExtraDataItemsCount(${reportFields.extraDataItemsCount}, ${extraDataItems.length})` @@ -219,7 +215,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra extraDataFormat: EXTRA_DATA_FORMAT_EMPTY, extraDataItemsCount: 0, } - const { extraDataList } = await prepareNextReportInNextFrame({ reportFields }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ reportFields }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `UnexpectedExtraDataFormat(${EXTRA_DATA_FORMAT_EMPTY}, ${EXTRA_DATA_FORMAT_LIST})` @@ -241,7 +239,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra ], } - const { extraDataList } = await prepareNextReportInNextFrame({ extraData: invalidExtraData }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData: invalidExtraData }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { @@ -262,7 +262,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra ], } - const { extraDataList } = await prepareNextReportInNextFrame({ extraData: invalidExtraData }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData: invalidExtraData }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { @@ -287,7 +289,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra ], } - const { extraDataList, reportFields } = await prepareNextReportInNextFrame({ extraData: invalidExtraData }) + await consensus.advanceTimeToNextFrameStart() + const { reportFields, reportItems, extraDataList } = await submitReportHash({ extraData: invalidExtraData }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) const tx = await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) assert.emits(tx, 'ExtraDataSubmitted', { refSlot: reportFields.refSlot }) @@ -318,7 +322,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra it('if first item index is not zero', async () => { const { extraData, extraDataItems, lastIndexDefault, lastIndexCustom } = getExtraWithCustomLastIndex(1, 1) - const { extraDataList } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `UnexpectedExtraDataIndex(${lastIndexDefault}, ${lastIndexCustom})` @@ -327,7 +333,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra it('if next index is greater than previous for more than +1', async () => { const { extraData, extraDataItems, lastIndexDefault, lastIndexCustom } = getExtraWithCustomLastIndex(2, 2) - const { extraDataList } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `UnexpectedExtraDataIndex(${lastIndexDefault}, ${lastIndexCustom})` @@ -336,7 +344,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra it('if next index equals to previous', async () => { const { extraData, extraDataItems, lastIndexDefault, lastIndexCustom } = getExtraWithCustomLastIndex(3, 1) - const { extraDataList } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `UnexpectedExtraDataIndex(${lastIndexDefault}, ${lastIndexCustom})` @@ -345,7 +355,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra it('if next index less than previous', async () => { const { extraData, extraDataItems, lastIndexDefault, lastIndexCustom } = getExtraWithCustomLastIndex(3, 0) - const { extraDataList } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `UnexpectedExtraDataIndex(${lastIndexDefault}, ${lastIndexCustom})` @@ -354,7 +366,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra it('succeeds if indexes were passed sequentially', async () => { const { extraData, extraDataItems } = getExtraWithCustomLastIndex(3, 2) - const { extraDataList, reportFields } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportFields, reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) const tx = await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) assert.emits(tx, 'ExtraDataSubmitted', { refSlot: reportFields.refSlot }) }) @@ -380,7 +394,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra it('if type `0` was passed', async () => { const { extraData, extraDataItems, wrongTypedIndex, typeCustom } = getExtraWithCustomType(0) - const { extraDataList } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `UnsupportedExtraDataType(${wrongTypedIndex}, ${typeCustom})` @@ -389,7 +405,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra it('if type `3` was passed', async () => { const { extraData, extraDataItems, wrongTypedIndex, typeCustom } = getExtraWithCustomType(3) - const { extraDataList } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `UnsupportedExtraDataType(${wrongTypedIndex}, ${typeCustom})` @@ -398,14 +416,18 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra it('succeeds if `1` was passed', async () => { const { extraData, extraDataItems } = getExtraWithCustomType(1) - const { extraDataList, reportFields } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportFields, reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) const tx = await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) assert.emits(tx, 'ExtraDataSubmitted', { refSlot: reportFields.refSlot }) }) it('succeeds if `2` was passed', async () => { const { extraData, extraDataItems } = getExtraWithCustomType(2) - const { extraDataList, reportFields } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportFields, reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) const tx = await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) assert.emits(tx, 'ExtraDataSubmitted', { refSlot: reportFields.refSlot }) }) @@ -419,7 +441,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra exitedKeys: [], } const problematicItemsCount = extraData.stuckKeys[problematicItemIdx].nodeOpIds.length - const { extraDataList } = await prepareNextReportInNextFrame({ extraData }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await oracleReportSanityChecker.setMaxNodeOperatorsPerExtraDataItemCount(problematicItemsCount - 1) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), @@ -434,7 +458,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra exitedKeys: [], } const problematicItemsCount = extraData.stuckKeys[problematicItemIdx].nodeOpIds.length - const { extraDataList, reportFields } = await prepareNextReportInNextFrame({ extraData }) + await consensus.advanceTimeToNextFrameStart() + const { reportFields, reportItems, extraDataList } = await submitReportHash({ extraData }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await oracleReportSanityChecker.setMaxAccountingExtraDataListItemsCount(problematicItemsCount) const tx = await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) assert.emits(tx, 'ExtraDataSubmitted', { refSlot: reportFields.refSlot }) @@ -456,7 +482,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra // of `_processExtraDataItem` function, check on 776 line in AccountingOracle const cutStop = 36 extraDataItems[invalidItemIndex] = extraDataItems[invalidItemIndex].slice(0, cutStop) - const { extraDataList } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `InvalidExtraDataItem(${invalidItemIndex})` @@ -477,7 +505,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra // of `_processExtraDataItem` function, check on 812 line in AccountingOracle, first condition const cutStop = extraDataItems[invalidItemIndex].length - 2 extraDataItems[invalidItemIndex] = extraDataItems[invalidItemIndex].slice(0, cutStop) - const { extraDataList } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `InvalidExtraDataItem(${invalidItemIndex})` @@ -493,7 +523,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra ], exitedKeys: [], } - const { extraDataList } = await prepareNextReportInNextFrame({ extraData }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `InvalidExtraDataItem(${invalidItemIndex})` @@ -512,7 +544,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra exitedKeys: [], } const extraDataItems = encodeExtraDataItems(extraData) - const { extraDataList } = await prepareNextReportInNextFrame({ extraData, extraDataItems }) + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash({ extraData, extraDataItems }) + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await assert.reverts( oracle.submitReportExtraDataList(extraDataList, { from: member1 }), `InvalidExtraDataItem(${invalidItemIndex})` @@ -551,7 +585,10 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra context('delivers the data to staking router', () => { it('calls reportStakingModuleStuckValidatorsCountByNodeOperator on StakingRouter', async () => { - const { extraData, extraDataList } = await prepareNextReportInNextFrame() + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraData, extraDataList } = await submitReportHash() + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) + await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) const callsCount = await stakingRouter.totalCalls_reportStuckKeysByNodeOperator() @@ -567,7 +604,10 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra }) it('calls reportStakingModuleExitedValidatorsCountByNodeOperator on StakingRouter', async () => { - const { extraData, extraDataList } = await prepareNextReportInNextFrame() + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraData, extraDataList } = await submitReportHash() + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) + await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) const callsCount = await stakingRouter.totalCalls_reportExitedKeysByNodeOperator() @@ -583,7 +623,10 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra }) it('calls onValidatorsCountsByNodeOperatorReportingFinished on StakingRouter', async () => { - const { extraDataList } = await prepareNextReportInNextFrame() + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataList } = await submitReportHash() + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) + await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) const callsCount = await stakingRouter.totalCalls_onValidatorsCountsByNodeOperatorReportingFinished() assert.equals(callsCount, 1) @@ -591,7 +634,9 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra }) it('reverts if extraData has already been already processed', async () => { - const { extraDataItems, extraDataList } = await prepareNextReportInNextFrame() + await consensus.advanceTimeToNextFrameStart() + const { reportItems, extraDataItems, extraDataList } = await submitReportHash() + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) await oracle.submitReportExtraDataList(extraDataList, { from: member1 }) const state = await oracle.getExtraDataProcessingState() assert.equals(state.itemsCount, extraDataItems.length) @@ -604,17 +649,42 @@ contract('AccountingOracle', ([admin, account1, account2, member1, member2, stra it('reverts if main data has not been processed yet', async () => { await consensus.advanceTimeToNextFrameStart() - const { refSlot } = await consensus.getCurrentFrame() - const { reportFields, reportHash, extraDataList } = getReportData({ reportFields: { refSlot } }) - await consensus.submitReport(reportFields.refSlot, reportHash, CONSENSUS_VERSION, { from: member1 }) + const report1 = await prepareReport() + await assert.revertsWithCustomError( - oracle.submitReportExtraDataList(extraDataList, { from: member1 }), + oracle.submitReportExtraDataList(report1.extraDataList, { from: member1 }), + 'CannotSubmitExtraDataBeforeMainData()' + ) + + await consensus.submitReport(report1.reportFields.refSlot, report1.reportHash, CONSENSUS_VERSION, { + from: member1, + }) + + await assert.revertsWithCustomError( + oracle.submitReportExtraDataList(report1.extraDataList, { from: member1 }), + 'CannotSubmitExtraDataBeforeMainData()' + ) + + await oracle.submitReportData(report1.reportItems, oracleVersion, { from: member1 }) + + await consensus.advanceTimeToNextFrameStart() + const report2 = await submitReportHash() + + await assert.revertsWithCustomError( + oracle.submitReportExtraDataList(report1.extraDataList, { from: member1 }), + 'CannotSubmitExtraDataBeforeMainData()' + ) + + await assert.revertsWithCustomError( + oracle.submitReportExtraDataList(report2.extraDataList, { from: member1 }), 'CannotSubmitExtraDataBeforeMainData()' ) }) it('updates extra data processing state', async () => { - const { extraDataItems, extraDataHash, reportFields, extraDataList } = await prepareNextReportInNextFrame() + await consensus.advanceTimeToNextFrameStart() + const { reportItems, reportFields, extraDataItems, extraDataHash, extraDataList } = await submitReportHash() + await oracle.submitReportData(reportItems, oracleVersion, { from: member1 }) const stateBefore = await oracle.getExtraDataProcessingState() diff --git a/test/0.8.9/oracle/base-oracle-access-control.test.js b/test/0.8.9/oracle/base-oracle-access-control.test.js index ed526424e..9b14cdc88 100644 --- a/test/0.8.9/oracle/base-oracle-access-control.test.js +++ b/test/0.8.9/oracle/base-oracle-access-control.test.js @@ -1,5 +1,6 @@ -const { contract, web3, artifacts } = require('hardhat') +const { contract, web3, artifacts, ethers } = require('hardhat') const { assert } = require('../../helpers/assert') +const { EvmSnapshot } = require('../../helpers/blockchain') const { deployBaseOracle, @@ -19,17 +20,26 @@ const MockConsensusContract = artifacts.require('MockConsensusContract') contract('BaseOracle', ([admin, account1, account2, member1, member2]) => { let oracle = null let consensus = null + let snapshot = null const manageConsensusContractRoleKeccak156 = web3.utils.keccak256('MANAGE_CONSENSUS_CONTRACT_ROLE') const manageConsensusVersionRoleKeccak156 = web3.utils.keccak256('MANAGE_CONSENSUS_VERSION_ROLE') const deploy = async (options = undefined) => { + snapshot = new EvmSnapshot(ethers.provider) const deployed = await deployBaseOracle(admin, options) oracle = deployed.oracle consensus = deployed.consensusContract + await snapshot.make() } + const rollback = async () => { + await snapshot.rollback() + } + + before(deploy) + context('deploying', () => { - before(deploy) + after(rollback) it('deploying oracle', async () => { assert.isNotNull(oracle) @@ -38,7 +48,7 @@ contract('BaseOracle', ([admin, account1, account2, member1, member2]) => { }) context('MANAGE_CONSENSUS_CONTRACT_ROLE', () => { - beforeEach(deploy) + afterEach(rollback) context('setConsensusContract', () => { it('should revert without MANAGE_CONSENSUS_CONTRACT_ROLE role', async () => { @@ -72,7 +82,7 @@ contract('BaseOracle', ([admin, account1, account2, member1, member2]) => { }) context('MANAGE_CONSENSUS_VERSION_ROLE', () => { - beforeEach(deploy) + afterEach(rollback) context('setConsensusVersion', () => { it('should revert without MANAGE_CONSENSUS_VERSION_ROLE role', async () => { @@ -95,7 +105,7 @@ contract('BaseOracle', ([admin, account1, account2, member1, member2]) => { }) context('CONSENSUS_CONTRACT', () => { - beforeEach(deploy) + afterEach(rollback) context('submitConsensusReport', async () => { const initialRefSlot = +(await oracle.getTime()) @@ -103,7 +113,34 @@ contract('BaseOracle', ([admin, account1, account2, member1, member2]) => { it('should revert from not a consensus contract', async () => { await assert.revertsWithCustomError( oracle.submitConsensusReport(HASH_1, initialRefSlot, initialRefSlot, { from: account1 }), - 'OnlyConsensusContractCanSubmitReport()' + 'SenderIsNotTheConsensusContract()' + ) + + assert.equals((await oracle.getConsensusReportLastCall()).callCount, 0) + }) + + it('should allow calling from a consensus contract', async () => { + await consensus.submitReportAsConsensus(HASH_1, initialRefSlot, initialRefSlot + SLOTS_PER_FRAME) + + assert.equals((await oracle.getConsensusReportLastCall()).callCount, 1) + }) + }) + }) + + context('CONSENSUS_CONTRACT', () => { + afterEach(rollback) + + context('submitConsensusReport', () => { + let initialRefSlot = null + + before(async () => { + initialRefSlot = +(await oracle.getTime()) + }) + + it('should revert from not a consensus contract', async () => { + await assert.revertsWithCustomError( + oracle.submitConsensusReport(HASH_1, initialRefSlot, initialRefSlot, { from: account1 }), + 'SenderIsNotTheConsensusContract()' ) assert.equals((await oracle.getConsensusReportLastCall()).callCount, 0) @@ -114,6 +151,19 @@ contract('BaseOracle', ([admin, account1, account2, member1, member2]) => { assert.equals((await oracle.getConsensusReportLastCall()).callCount, 1) }) + + it('should allow to discard report from a consensus contract', async () => { + await consensus.submitReportAsConsensus(HASH_1, initialRefSlot, initialRefSlot + SLOTS_PER_FRAME) + assert.equals((await oracle.getConsensusReportLastCall()).callCount, 1) + await consensus.discardReportAsConsensus(initialRefSlot) + }) + + it('should revert on discard from stranger', async () => { + await assert.revertsWithCustomError( + oracle.discardConsensusReport(initialRefSlot), + 'SenderIsNotTheConsensusContract()' + ) + }) }) }) }) diff --git a/test/0.8.9/oracle/base-oracle-set-consensus.test.js b/test/0.8.9/oracle/base-oracle-set-consensus.test.js index eea85b00e..6b476687f 100644 --- a/test/0.8.9/oracle/base-oracle-set-consensus.test.js +++ b/test/0.8.9/oracle/base-oracle-set-consensus.test.js @@ -139,16 +139,6 @@ contract('BaseOracle', ([admin, member, notMember]) => { await consensus.submitReportAsConsensus(HASH_1, initialRefSlot, deadline) }) - it('deadline missed on current ref slot, reverts on any arguments', async () => { - const oldTime = await baseOracle.getTime() - await baseOracle.setTime(deadline + 10) - await assert.revertsWithCustomError( - baseOracle.checkConsensusData(initialRefSlot, CONSENSUS_VERSION, HASH_1), - `ProcessingDeadlineMissed(${deadline})` - ) - await baseOracle.setTime(oldTime) - }) - it('reverts on mismatched slot', async () => { await assert.revertsWithCustomError( baseOracle.checkConsensusData(initialRefSlot + 1, CONSENSUS_VERSION, HASH_1), @@ -175,6 +165,21 @@ contract('BaseOracle', ([admin, member, notMember]) => { }) }) + describe('_checkProcessingDeadline checks report processing deadline', () => { + before(rollback) + let deadline + + it('report is submitted', async () => { + deadline = computeDeadlineFromRefSlot(initialRefSlot) + await consensus.submitReportAsConsensus(HASH_1, initialRefSlot, deadline) + }) + + it('reverts if deadline is missed', async () => { + await baseOracle.setTime(deadline + 10) + await assert.revertsWithCustomError(baseOracle.checkProcessingDeadline(), `ProcessingDeadlineMissed(${deadline})`) + }) + }) + describe('_isConsensusMember correctly check address for consensus membership trough consensus contract', () => { before(rollback) diff --git a/test/0.8.9/oracle/base-oracle-submit-report.test.js b/test/0.8.9/oracle/base-oracle-submit-report.test.js index 1ebd65b75..132aa97a0 100644 --- a/test/0.8.9/oracle/base-oracle-submit-report.test.js +++ b/test/0.8.9/oracle/base-oracle-submit-report.test.js @@ -34,7 +34,22 @@ contract('BaseOracle', ([admin]) => { before(deployContract) describe('submitConsensusReport is called and changes the contract state', () => { - context('submitConsensusReport passes pre-conditions', () => { + context('submitConsensusReport rejects a report whose deadline has already passed', () => { + before(async () => { + await evmSnapshot.rollback() + }) + + it('the report is rejected', async () => { + const deadline = computeDeadlineFromRefSlot(initialRefSlot) + await baseOracle.setTime(deadline + 1) + await assert.revertsWithCustomError( + consensus.submitReportAsConsensus(HASH_1, initialRefSlot, deadline), + `ProcessingDeadlineMissed(${deadline})` + ) + }) + }) + + context('submitConsensusReport checks pre-conditions', () => { before(async () => { await evmSnapshot.rollback() }) @@ -42,7 +57,14 @@ contract('BaseOracle', ([admin]) => { it('only setConsensus contract can call submitConsensusReport', async () => { await assert.revertsWithCustomError( baseOracle.submitConsensusReport(HASH_1, initialRefSlot, computeDeadlineFromRefSlot(initialRefSlot)), - 'OnlyConsensusContractCanSubmitReport()' + 'SenderIsNotTheConsensusContract()' + ) + }) + + it('zero hash cannot be submitted as a report', async () => { + await assert.revertsWithCustomError( + consensus.submitReportAsConsensus(ZERO_HASH, initialRefSlot, computeDeadlineFromRefSlot(initialRefSlot)), + 'HashCannotBeZero()' ) }) @@ -126,6 +148,10 @@ contract('BaseOracle', ([admin]) => { assert(!report.processingStarted) }) + it('cannot start processing on empty state', async () => { + await assert.reverts(baseOracle.startProcessing(), 'NoConsensusReportToProcess()') + }) + it('initial report is submitted', async () => { await consensus.submitReportAsConsensus(HASH_1, initialRefSlot, computeDeadlineFromRefSlot(initialRefSlot)) const report = await baseOracle.getConsensusReport() @@ -188,7 +214,7 @@ contract('BaseOracle', ([admin]) => { }) it('initial contract state, no reports, cannot startProcessing', async () => { - await assert.revertsWithCustomError(baseOracle.startProcessing(), 'ProcessingDeadlineMissed(0)') + await assert.revertsWithCustomError(baseOracle.startProcessing(), 'NoConsensusReportToProcess()') }) it('submit first report for initial slot', async () => { @@ -217,4 +243,72 @@ contract('BaseOracle', ([admin]) => { await assert.revertsWithCustomError(baseOracle.startProcessing(), `ProcessingDeadlineMissed(${refSlot2Deadline})`) }) }) + + describe('discardConsensusReport', () => { + let nextRefSlot + + before(async () => { + await evmSnapshot.rollback() + nextRefSlot = computeNextRefSlotFromRefSlot(initialRefSlot) + }) + + it('noop if no report for this frame', async () => { + const tx = await consensus.discardReportAsConsensus(initialRefSlot) + assert.emitsNumberOfEvents(tx, 'ReportDiscarded', 0, { abi: baseOracleAbi }) + }) + + it('initial report', async () => { + await consensus.submitReportAsConsensus(HASH_1, initialRefSlot, computeDeadlineFromRefSlot(initialRefSlot)) + }) + + it('noop if discarding future report', async () => { + const tx = await consensus.discardReportAsConsensus(nextRefSlot) + assert.notEmits(tx, 'ReportDiscarded', { abi: baseOracleAbi }) + }) + + it('reverts for invalid slot', async () => { + await assert.revertsWithCustomError( + consensus.discardReportAsConsensus(initialRefSlot - 1), + `RefSlotCannotDecrease(${initialRefSlot - 1}, ${initialRefSlot})` + ) + }) + + it('discards report and throws events', async () => { + const tx = await consensus.discardReportAsConsensus(initialRefSlot) + assert.emits(tx, 'ReportDiscarded', { refSlot: initialRefSlot, hash: HASH_1 }, { abi: baseOracleAbi }) + const currentReport = await baseOracle.getConsensusReport() + assert.equals(currentReport.hash, ZERO_HASH) + assert.equals(currentReport.refSlot, initialRefSlot) + assert.equals(currentReport.processingDeadlineTime, computeDeadlineFromRefSlot(initialRefSlot)) + assert.equals(currentReport.processingStarted, false) + }) + + it('internal _handleConsensusReportDiscarded was called during discard', async () => { + const discardedReport = await baseOracle.lastDiscardedReport() + assert.equals(discardedReport.hash, HASH_1) + assert.equals(discardedReport.refSlot, initialRefSlot) + assert.equals(discardedReport.processingDeadlineTime, computeDeadlineFromRefSlot(initialRefSlot)) + }) + + it('cannot start processing on zero report', async () => { + await assert.reverts(baseOracle.startProcessing(), 'NoConsensusReportToProcess()') + }) + + it('report can be resubmitted after discard', async () => { + await consensus.submitReportAsConsensus(HASH_2, initialRefSlot, computeDeadlineFromRefSlot(initialRefSlot)) + const currentReport = await baseOracle.getConsensusReport() + assert.equals(currentReport.hash, HASH_2) + assert.equals(currentReport.refSlot, initialRefSlot) + assert.equals(currentReport.processingDeadlineTime, computeDeadlineFromRefSlot(initialRefSlot)) + assert.equals(currentReport.processingStarted, false) + await baseOracle.startProcessing() + }) + + it('reverts if processing started', async () => { + await assert.revertsWithCustomError( + consensus.discardReportAsConsensus(initialRefSlot), + `RefSlotAlreadyProcessing()` + ) + }) + }) }) diff --git a/test/0.8.9/oracle/hash-consensus-fast-lane-members.test.js b/test/0.8.9/oracle/hash-consensus-fast-lane-members.test.js index 7342f9bfe..589a137d7 100644 --- a/test/0.8.9/oracle/hash-consensus-fast-lane-members.test.js +++ b/test/0.8.9/oracle/hash-consensus-fast-lane-members.test.js @@ -1,6 +1,7 @@ const { contract } = require('hardhat') const { assert } = require('../../helpers/assert') const { toNum } = require('../../helpers/utils') +const { MAX_UINT256 } = require('../../helpers/constants') const { HASH_1, CONSENSUS_VERSION, deployHashConsensus } = require('./hash-consensus-deploy.test') @@ -150,13 +151,13 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, frames.forEach(testFrame) }) - context('Quorum size equal to total members', () => { + const testAllInFastLane = ({ quorumSize }) => { before(async () => { await deploy({ fastLaneLengthSlots: 10 }) - await consensus.addMember(member1, 3, { from: admin }) - await consensus.addMember(member2, 3, { from: admin }) - await consensus.addMember(member3, 3, { from: admin }) + await consensus.addMember(member1, quorumSize, { from: admin }) + await consensus.addMember(member2, quorumSize, { from: admin }) + await consensus.addMember(member3, quorumSize, { from: admin }) }) before(setTimeToFrame0) @@ -189,6 +190,10 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, }) Array.from({ length: 10 }, (_, i) => i).forEach(testFrame) - }) + } + + context('Quorum size equal to total members', () => testAllInFastLane({ quorumSize: 3 })) + context('Quorum size more than total members', () => testAllInFastLane({ quorumSize: 5 })) + context('Quorum is a max value', () => testAllInFastLane({ quorumSize: MAX_UINT256 })) }) }) diff --git a/test/0.8.9/oracle/hash-consensus-frames.test.js b/test/0.8.9/oracle/hash-consensus-frames.test.js index d1120ccbd..57e9ecec9 100644 --- a/test/0.8.9/oracle/hash-consensus-frames.test.js +++ b/test/0.8.9/oracle/hash-consensus-frames.test.js @@ -18,7 +18,7 @@ const { deployHashConsensus, } = require('./hash-consensus-deploy.test') -contract('HashConsensus', ([admin, member1, member2]) => { +contract('HashConsensus', ([admin, member1, member2, member3]) => { const TEST_INITIAL_EPOCH = 3 context('Frame methods', () => { @@ -156,17 +156,35 @@ contract('HashConsensus', ([admin, member1, member2]) => { assert.equals(initialRefSlot, TEST_INITIAL_EPOCH * SLOTS_PER_EPOCH - 1) }) - it('before the initial epoch arrives, members can be added and queried, and quorum increased', async () => { + it('before the initial epoch arrives, members can be added and queried, and quorum changed', async () => { await consensus.setTimeInEpochs(TEST_INITIAL_EPOCH - 1) + await consensus.addMember(member3, 1, { from: admin }) + assert.isTrue(await consensus.getIsMember(member3)) + assert.equals(await consensus.getQuorum(), 1) + + await consensus.removeMember(member3, 2) + assert.isFalse(await consensus.getIsMember(member3)) + assert.equals(await consensus.getQuorum(), 2) + await consensus.addMember(member1, 1, { from: admin }) await consensus.addMember(member2, 2, { from: admin }) - await consensus.setQuorum(3, { from: admin }) + await consensus.addMember(member3, 2, { from: admin }) + assert.equals(await consensus.getQuorum(), 2) + + await consensus.setQuorum(4, { from: admin }) + assert.equals(await consensus.getQuorum(), 4) + await consensus.setQuorum(3, { from: admin }) assert.equals(await consensus.getQuorum(), 3) + await consensus.removeMember(member3, 3) + assert.isTrue(await consensus.getIsMember(member1)) assert.isTrue(await consensus.getIsMember(member2)) + assert.isFalse(await consensus.getIsMember(member3)) + assert.equals(await consensus.getQuorum(), 3) + assert.isFalse(await consensus.getIsMember(admin)) const { addresses, lastReportedRefSlots } = await consensus.getMembers() @@ -178,10 +196,6 @@ contract('HashConsensus', ([admin, member1, member2]) => { }) it('but otherwise, the contract is dysfunctional', async () => { - await assert.reverts(consensus.removeMember(member2, 2), 'InitialEpochIsYetToArrive()') - await assert.reverts(consensus.removeMember(member2, 1), 'InitialEpochIsYetToArrive()') - await assert.reverts(consensus.setQuorum(2), 'InitialEpochIsYetToArrive()') - await assert.reverts(consensus.getCurrentFrame(), 'InitialEpochIsYetToArrive()') await assert.reverts(consensus.getConsensusState(), 'InitialEpochIsYetToArrive()') await assert.reverts(consensus.getConsensusStateForMember(member1), 'InitialEpochIsYetToArrive()') diff --git a/test/0.8.9/oracle/hash-consensus-happy-path.test.js b/test/0.8.9/oracle/hash-consensus-happy-path.test.js index afa3995e2..bcabed067 100644 --- a/test/0.8.9/oracle/hash-consensus-happy-path.test.js +++ b/test/0.8.9/oracle/hash-consensus-happy-path.test.js @@ -93,6 +93,7 @@ contract('HashConsensus', ([admin, member1, member2, member3, stranger]) => { assert.equal(consensusState.consensusReport, ZERO_HASH) assert.isFalse(consensusState.isReportProcessing) assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 0) + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 0) const memberInfo = await consensus.getConsensusStateForMember(member1) assert.equal(memberInfo.currentFrameConsensusReport, ZERO_HASH) @@ -121,6 +122,7 @@ contract('HashConsensus', ([admin, member1, member2, member3, stranger]) => { assert.equal(consensusState.consensusReport, ZERO_HASH) assert.isFalse(consensusState.isReportProcessing) assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 0) + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 0) const memberInfo = await consensus.getConsensusStateForMember(member1) assert.equal(memberInfo.currentFrameConsensusReport, ZERO_HASH) @@ -157,9 +159,11 @@ contract('HashConsensus', ([admin, member1, member2, member3, stranger]) => { assert.equal(submitReportLastCall.report, HASH_3) assert.equals(submitReportLastCall.refSlot, +frame.refSlot) assert.equals(submitReportLastCall.deadline, computeTimestampAtSlot(frame.reportProcessingDeadlineSlot)) + + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 0) }) - it('first member votes for hash 1', async () => { + it('first member re-votes for hash 1', async () => { await consensus.advanceTimeBy(SECONDS_PER_EPOCH + 5) assert.isTrue((await consensus.getConsensusStateForMember(member1)).canReport) @@ -190,6 +194,77 @@ contract('HashConsensus', ([admin, member1, member2, member3, stranger]) => { assert.equal(submitReportLastCall.report, HASH_1) assert.equals(submitReportLastCall.refSlot, +frame.refSlot) assert.equals(submitReportLastCall.deadline, computeTimestampAtSlot(frame.reportProcessingDeadlineSlot)) + + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 0) + }) + + it('second member re-votes for hash 2', async () => { + await consensus.advanceTimeBy(SECONDS_PER_EPOCH + 5) + + assert.isTrue((await consensus.getConsensusStateForMember(member2)).canReport) + + const tx = await consensus.submitReport(frame.refSlot, HASH_2, CONSENSUS_VERSION, { from: member2 }) + + assert.emits(tx, 'ReportReceived', { refSlot: frame.refSlot, member: member2, report: HASH_2 }) + assert.emits(tx, 'ConsensusLost', { refSlot: frame.refSlot }) + + const memberInfo = await consensus.getConsensusStateForMember(member2) + assert.isTrue(memberInfo.isMember) + assert.equals(memberInfo.lastMemberReportRefSlot, +frame.refSlot) + assert.equals(memberInfo.currentFrameRefSlot, +frame.refSlot) + assert.equal(memberInfo.currentFrameMemberReport, HASH_2) + assert.isTrue(memberInfo.canReport) + }) + + it('consensus is lost', async () => { + const consensusState = await consensus.getConsensusState() + assert.equal(consensusState.consensusReport, ZERO_HASH) + assert.isFalse(consensusState.isReportProcessing) + + const memberInfo = await consensus.getConsensusStateForMember(member1) + assert.equal(memberInfo.currentFrameConsensusReport, ZERO_HASH) + + const submitReportLastCall = await reportProcessor.getLastCall_submitReport() + assert.equals(submitReportLastCall.callCount, 2) + + const discardReportLastCall = await reportProcessor.getLastCall_discardReport() + assert.equals(discardReportLastCall.callCount, 1) + assert.equals(discardReportLastCall.refSlot, +frame.refSlot) + }) + + it('second member re-votes for hash 1', async () => { + await consensus.advanceTimeBy(SECONDS_PER_EPOCH + 5) + + assert.isTrue((await consensus.getConsensusStateForMember(member2)).canReport) + + const tx = await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) + + assert.emits(tx, 'ReportReceived', { refSlot: frame.refSlot, member: member2, report: HASH_1 }) + assert.emits(tx, 'ConsensusReached', { refSlot: frame.refSlot, report: HASH_1, support: 2 }) + + const memberInfo = await consensus.getConsensusStateForMember(member2) + assert.isTrue(memberInfo.isMember) + assert.equals(memberInfo.lastMemberReportRefSlot, +frame.refSlot) + assert.equals(memberInfo.currentFrameRefSlot, +frame.refSlot) + assert.equal(memberInfo.currentFrameMemberReport, HASH_1) + assert.isTrue(memberInfo.canReport) + }) + + it('consensus is reached again', async () => { + const consensusState = await consensus.getConsensusState() + assert.equal(consensusState.consensusReport, HASH_1) + assert.isFalse(consensusState.isReportProcessing) + + const memberInfo = await consensus.getConsensusStateForMember(member1) + assert.equal(memberInfo.currentFrameConsensusReport, HASH_1) + + const submitReportLastCall = await reportProcessor.getLastCall_submitReport() + assert.equals(submitReportLastCall.callCount, 3) + assert.equal(submitReportLastCall.report, HASH_1) + assert.equals(submitReportLastCall.refSlot, +frame.refSlot) + assert.equals(submitReportLastCall.deadline, computeTimestampAtSlot(frame.reportProcessingDeadlineSlot)) + + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 1) }) it('report processor starts processing the report', async () => { @@ -241,7 +316,8 @@ contract('HashConsensus', ([admin, member1, member2, member3, stranger]) => { await checkMember(member2) await checkMember(member3) - assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 2) + assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 3) + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 1) }) it('a member cannot submit report for the previous ref slot', async () => { @@ -284,7 +360,8 @@ contract('HashConsensus', ([admin, member1, member2, member3, stranger]) => { const consensusState = await consensus.getConsensusState() assert.equal(consensusState.consensusReport, ZERO_HASH) assert.isFalse(consensusState.isReportProcessing) - assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 2) + assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 3) + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 1) const memberInfo = await consensus.getConsensusStateForMember(member1) assert.equal(memberInfo.currentFrameConsensusReport, ZERO_HASH) diff --git a/test/0.8.9/oracle/hash-consensus-members.test.js b/test/0.8.9/oracle/hash-consensus-members.test.js index 6785bd9e9..fde187969 100644 --- a/test/0.8.9/oracle/hash-consensus-members.test.js +++ b/test/0.8.9/oracle/hash-consensus-members.test.js @@ -5,7 +5,7 @@ const { ZERO_ADDRESS } = require('../../helpers/constants') const { HASH_1, HASH_2, CONSENSUS_VERSION, deployHashConsensus, ZERO_HASH } = require('./hash-consensus-deploy.test') -contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, stranger]) => { +contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, member6, stranger]) => { context('Managing members and quorum', () => { let consensus @@ -46,6 +46,10 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, ) }) + it(`doesn't allow setting quorum to zero`, async () => { + await assert.reverts(consensus.addMember(member1, 0, { from: admin }), 'QuorumTooSmall(1, 0)') + }) + it('allows to add a member, setting the new quorum', async () => { const newQuorum = 1 const tx = await consensus.addMember(member1, newQuorum, { from: admin }) @@ -97,6 +101,12 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_1, support: 3 }) assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) }) + + it(`increasing the quorum might trigger consensus loss`, async () => { + const { refSlot } = await consensus.getCurrentFrame() + const tx = await consensus.addMember(member6, 4, { from: admin }) + assert.emits(tx, 'ConsensusLost', { refSlot }) + }) }) context('removeMember', () => { @@ -210,6 +220,29 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) }) + it(`removing a member who voted can trigger consensus loss`, async () => { + const { refSlot } = await consensus.getCurrentFrame() + await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member1 }) + await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member2 }) + await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member4 }) + + let tx = await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member5 }) + assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_2, support: 4 }) + assert.equal((await consensus.getConsensusState()).consensusReport, HASH_2) + + let reportVariants = await consensus.getReportVariants() + assert.sameOrderedMembers(reportVariants.variants, [HASH_2]) + assert.sameOrderedMembers(reportVariants.support.map(toNum), [4]) + + tx = await consensus.removeMember(member2, 4, { from: admin }) + assert.emits(tx, 'ConsensusLost', { refSlot }) + assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) + + reportVariants = await consensus.getReportVariants() + assert.sameOrderedMembers(reportVariants.variants, [HASH_2]) + assert.sameOrderedMembers(reportVariants.support.map(toNum), [3]) + }) + it(`allows to remove a member that's the only one who voted for a variant`, async () => { const { refSlot } = await consensus.getCurrentFrame() await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) @@ -230,18 +263,24 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, await consensus.addMember(member2, 2, { from: admin }) const { refSlot } = await consensus.getCurrentFrame() - await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) - let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') + + tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_1, support: 2 }) + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) tx = await consensus.addMember(member3, 3, { from: admin }) + assert.emits(tx, 'ConsensusLost', { refSlot }) assert.notEmits(tx, 'ConsensusReached') assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) tx = await consensus.removeMember(member3, 2, { from: admin }) - assert.notEmits(tx, 'ConsensusReached') + assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_1, support: 2 }) + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) }) @@ -250,18 +289,24 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, await consensus.addMember(member2, 2, { from: admin }) const { refSlot } = await consensus.getCurrentFrame() - await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) - let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') + + tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_1, support: 2 }) + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) tx = await consensus.addMember(member3, 2, { from: admin }) assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) tx = await consensus.removeMember(member3, 2, { from: admin }) assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) }) @@ -270,23 +315,28 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, await consensus.addMember(member2, 2, { from: admin }) const { refSlot } = await consensus.getCurrentFrame() - await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) - let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') + + tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_1, support: 2 }) + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) tx = await consensus.addMember(member3, 3, { from: admin }) + assert.emits(tx, 'ConsensusLost', { refSlot }) assert.notEmits(tx, 'ConsensusReached') - // TODO: is this really ok? assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member3 }) - assert.notEmits(tx, 'ConsensusReached') + assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_1, support: 3 }) assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) tx = await consensus.removeMember(member3, 2, { from: admin }) assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) }) @@ -297,27 +347,37 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, await consensus.addMember(member2, 2, { from: admin }) await consensus.addMember(member3, 2, { from: admin }) - await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) - let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) + let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') + tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_1, support: 2 }) + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) tx = await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member3 }) assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) - await consensus.addMember(member4, 3, { from: admin }) + tx = await consensus.addMember(member4, 3, { from: admin }) + assert.emits(tx, 'ConsensusLost', { refSlot }) assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) - await consensus.addMember(member5, 3, { from: admin }) + tx = await consensus.addMember(member5, 3, { from: admin }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) - await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member4 }) + tx = await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member4 }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) tx = await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member5 }) assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_2, support: 3 }) + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_2) }) @@ -328,30 +388,43 @@ contract('HashConsensus', ([admin, member1, member2, member3, member4, member5, await consensus.addMember(member2, 2, { from: admin }) await consensus.addMember(member3, 2, { from: admin }) - await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) - let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) + let tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') + tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_1, support: 2 }) + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) tx = await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member3 }) assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_1) - await consensus.addMember(member4, 3, { from: admin }) + tx = await consensus.addMember(member4, 3, { from: admin }) + assert.emits(tx, 'ConsensusLost', { refSlot }) + assert.notEmits(tx, 'ConsensusReached') assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) - await consensus.addMember(member5, 4, { from: admin }) + tx = await consensus.addMember(member5, 4, { from: admin }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) - await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member4 }) + tx = await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member4 }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) tx = await consensus.submitReport(refSlot, HASH_2, CONSENSUS_VERSION, { from: member5 }) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, ZERO_HASH) tx = await consensus.removeMember(member2, 3, { from: admin }) assert.emits(tx, 'ConsensusReached', { refSlot, report: HASH_2, support: 3 }) + assert.notEmits(tx, 'ConsensusLost') assert.equal((await consensus.getConsensusState()).consensusReport, HASH_2) }) }) diff --git a/test/0.8.9/oracle/hash-consensus-report-processor.test.js b/test/0.8.9/oracle/hash-consensus-report-processor.test.js index 9da7504a7..7629be84a 100644 --- a/test/0.8.9/oracle/hash-consensus-report-processor.test.js +++ b/test/0.8.9/oracle/hash-consensus-report-processor.test.js @@ -1,8 +1,9 @@ -const { contract, artifacts } = require('hardhat') +const { contract, artifacts, ethers } = require('hardhat') const { assert } = require('../../helpers/assert') const { ZERO_ADDRESS } = require('../../helpers/constants') +const { EvmSnapshot } = require('../../helpers/blockchain') -const { HASH_1, CONSENSUS_VERSION, deployHashConsensus } = require('./hash-consensus-deploy.test') +const { HASH_1, HASH_2, CONSENSUS_VERSION, deployHashConsensus } = require('./hash-consensus-deploy.test') const { toNum } = require('../../helpers/utils') const MockReportProcessor = artifacts.require('MockReportProcessor') @@ -12,16 +13,25 @@ contract('HashConsensus', ([admin, member1, member2, stranger]) => { let consensus let reportProcessor1 let reportProcessor2 + let snapshot const deploy = async (options = undefined) => { + snapshot = new EvmSnapshot(ethers.provider) const deployed = await deployHashConsensus(admin, options) consensus = deployed.consensus reportProcessor1 = deployed.reportProcessor reportProcessor2 = await MockReportProcessor.new(CONSENSUS_VERSION, { from: admin }) + await snapshot.make() } + const rollback = async () => { + await snapshot.rollback() + } + + before(deploy) + context('initial setup', () => { - beforeEach(deploy) + afterEach(rollback) it('properly set initial report processor', async () => { assert.addressEqual(await consensus.getReportProcessor(), reportProcessor1.address, 'processor address differs') @@ -29,7 +39,7 @@ contract('HashConsensus', ([admin, member1, member2, stranger]) => { }) context('method setReportProcessor', () => { - beforeEach(deploy) + afterEach(rollback) it('checks next processor is not zero', async () => { await assert.reverts(consensus.setReportProcessor(ZERO_ADDRESS), 'ReportProcessorCannotBeZero()') @@ -99,7 +109,7 @@ contract('HashConsensus', ([admin, member1, member2, stranger]) => { assert.equals((await reportProcessor2.getLastCall_submitReport()).callCount, 0) }) - it('do not submit report to next processor if there was no conensus', async () => { + it('do not submit report to next processor if there was no consensus', async () => { const frame = await consensus.getCurrentFrame() await consensus.addMember(member1, 1, { from: admin }) @@ -115,10 +125,25 @@ contract('HashConsensus', ([admin, member1, member2, stranger]) => { 'processor reported but there was no quorum' ) }) + + it('do not submit report to next processor if consensus was lost', async () => { + const frame = await consensus.getCurrentFrame() + + await consensus.addMember(member1, 1, { from: admin }) + await consensus.addMember(member2, 2, { from: admin }) + + await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) + await consensus.submitReport(frame.refSlot, HASH_2, CONSENSUS_VERSION, { from: member2 }) + assert.equals((await reportProcessor1.getLastCall_discardReport()).callCount, 1, 'report withdrawn') + + await consensus.setReportProcessor(reportProcessor2.address, { from: admin }) + assert.equals((await reportProcessor2.getLastCall_submitReport()).callCount, 0, 'no report submitted') + }) }) context('consensus version', () => { - beforeEach(deploy) + afterEach(rollback) it('equals to version of initial processor', async () => { assert.equal(await consensus.getConsensusVersion(), CONSENSUS_VERSION) @@ -133,7 +158,7 @@ contract('HashConsensus', ([admin, member1, member2, stranger]) => { }) context('method getReportVariants', () => { - beforeEach(deploy) + afterEach(rollback) it(`returns empty data if lastReportRefSlot != currentFrame.refSlot`, async () => { const { refSlot } = await consensus.getCurrentFrame() diff --git a/test/0.8.9/oracle/hash-consensus-set-quorum.test.js b/test/0.8.9/oracle/hash-consensus-set-quorum.test.js index 283f09480..5d0b0ce5b 100644 --- a/test/0.8.9/oracle/hash-consensus-set-quorum.test.js +++ b/test/0.8.9/oracle/hash-consensus-set-quorum.test.js @@ -1,6 +1,6 @@ -const { contract } = require('hardhat') +const { contract, ethers } = require('hardhat') const { assert } = require('../../helpers/assert') - +const { EvmSnapshot } = require('../../helpers/blockchain') const { ZERO_HASH, UNREACHABLE_QUORUM, @@ -12,15 +12,22 @@ const { contract('HashConsensus', ([admin, member1, member2, member3]) => { describe('setQuorum and addMember changes getQuorum', () => { let consensus + let snapshot const deployContract = async () => { + snapshot = new EvmSnapshot(ethers.provider) const deployed = await deployHashConsensus(admin, { initialEpoch: 1 }) consensus = deployed.consensus + await snapshot.make() } - context('at deploy quorum is zero and can be set to any number while event is fired on every change', () => { - before(deployContract) + const rollback = async () => { + await snapshot.rollback() + } + before(deployContract) + + context('at deploy quorum is zero and can be set to any number while event is fired on every change', () => { it('quorum is zero at deploy', async () => { assert.equals(await consensus.getQuorum(), 0) }) @@ -49,7 +56,7 @@ contract('HashConsensus', ([admin, member1, member2, member3]) => { }) context('as new members are added quorum is updated and cannot be set lower than members/2', () => { - before(deployContract) + before(rollback) it('addMember adds member and updates quorum', async () => { assert.equals(await consensus.getQuorum(), 0) @@ -83,7 +90,7 @@ contract('HashConsensus', ([admin, member1, member2, member3]) => { }) context('disableConsensus sets unreachable quorum value', () => { - before(deployContract) + before(rollback) it('disableConsensus updated quorum value and emits events', async () => { const tx = await consensus.disableConsensus() @@ -101,8 +108,10 @@ contract('HashConsensus', ([admin, member1, member2, member3]) => { let consensus let reportProcessor let frame + let snapshot const deployContractWithMembers = async () => { + snapshot = new EvmSnapshot(ethers.provider) const deployed = await deployHashConsensus(admin, { initialEpoch: 1 }) consensus = deployed.consensus reportProcessor = deployed.reportProcessor @@ -111,10 +120,17 @@ contract('HashConsensus', ([admin, member1, member2, member3]) => { await consensus.addMember(member2, 2, { from: admin }) await consensus.addMember(member3, 3, { from: admin }) frame = await consensus.getCurrentFrame() + await snapshot.make() } + const rollback = async () => { + await snapshot.rollback() + } + + before(deployContractWithMembers) + context('quorum increases and changes effective consensus', () => { - before(deployContractWithMembers) + after(rollback) it('consensus is reached at 2/3 for quorum of 2', async () => { await consensus.setQuorum(2) @@ -152,7 +168,7 @@ contract('HashConsensus', ([admin, member1, member2, member3]) => { }) context('setQuorum triggers consensus on decrease', () => { - before(deployContractWithMembers) + after(rollback) it('2/3 reports come in', async () => { const tx1 = await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) @@ -180,8 +196,8 @@ contract('HashConsensus', ([admin, member1, member2, member3]) => { }) }) - context('setQuorum does not re-trigger same consensus', () => { - before(deployContractWithMembers) + context('setQuorum can lead to consensus loss on quorum increase', () => { + after(rollback) it('2/3 members reach consensus with quorum of 2', async () => { await consensus.setQuorum(2) @@ -203,27 +219,31 @@ contract('HashConsensus', ([admin, member1, member2, member3]) => { assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 1) }) - it('quorum goes up and effective consensus changes to none', async () => { - await consensus.setQuorum(3) + it('quorum goes up to 3 and consensus is lost', async () => { + const tx = await consensus.setQuorum(3) + assert.emits(tx, 'ConsensusLost', { refSlot: frame.refSlot }) + const consensusState = await consensus.getConsensusState() assert.equal(consensusState.consensusReport, ZERO_HASH) assert.isFalse(consensusState.isReportProcessing) + + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 1) }) - it('quorum goes down but same consensus is not triggered and report is not submitted', async () => { + it('quorum goes down, the consensus is reached again', async () => { const tx = await consensus.setQuorum(2) - assert.notEmits(tx, 'ConsensusReached') + assert.emits(tx, 'ConsensusReached', { refSlot: frame.refSlot, report: HASH_1, support: 2 }) const consensusState = await consensus.getConsensusState() assert.equal(consensusState.consensusReport, HASH_1) assert.isFalse(consensusState.isReportProcessing) - assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 1) + assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 2) }) }) context('setQuorum does not re-trigger consensus if hash is already being processed', () => { - before(deployContractWithMembers) + after(rollback) it('2/3 members reach consensus with Quorum of 2', async () => { await consensus.setQuorum(2) @@ -252,15 +272,22 @@ contract('HashConsensus', ([admin, member1, member2, member3]) => { }) it('quorum increases while report is processing', async () => { - await consensus.setQuorum(3) + const tx = await consensus.setQuorum(3) + assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') + const consensusState = await consensus.getConsensusState() assert.isTrue(consensusState.isReportProcessing) + + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 0) }) it('quorum decreases but no consensus is triggered', async () => { const tx = await consensus.setQuorum(2) assert.notEmits(tx, 'ConsensusReached') + assert.notEmits(tx, 'ConsensusLost') assert.equals((await reportProcessor.getLastCall_submitReport()).callCount, 1) + assert.equals((await reportProcessor.getLastCall_discardReport()).callCount, 0) }) }) }) diff --git a/test/0.8.9/oracle/hash-consensus-submit-report.test.js b/test/0.8.9/oracle/hash-consensus-submit-report.test.js index 7aedf07a9..07d6bbdb1 100644 --- a/test/0.8.9/oracle/hash-consensus-submit-report.test.js +++ b/test/0.8.9/oracle/hash-consensus-submit-report.test.js @@ -1,71 +1,99 @@ -const { contract } = require('hardhat') +const { contract, ethers } = require('hardhat') const { assert } = require('../../helpers/assert') +const { EvmSnapshot } = require('../../helpers/blockchain') -const { deployHashConsensus, CONSENSUS_VERSION, ZERO_HASH, HASH_1 } = require('./hash-consensus-deploy.test') +const { deployHashConsensus, CONSENSUS_VERSION, ZERO_HASH, HASH_1, HASH_2 } = require('./hash-consensus-deploy.test') const CONSENSUS_VERSION_2 = 2 contract('HashConsensus', ([admin, member1, member2, stranger]) => { - context('Report Submitting', () => { - let consensus - let frame - let reportProcessor - - const deploy = async (options = { epochsPerFrame: 200 }) => { - const deployed = await deployHashConsensus(admin, options) - consensus = deployed.consensus - reportProcessor = deployed.reportProcessor - frame = await consensus.getCurrentFrame() - await consensus.addMember(member1, 1, { from: admin }) - } - - context('method sumbitReport', () => { - beforeEach(deploy) - - it('reverts with NumericOverflow', async () => { - await assert.reverts( - consensus.submitReport('20446744073709551615', HASH_1, CONSENSUS_VERSION, { from: member1 }), - 'NumericOverflow()' - ) - }) - - it('reverts with UnexpectedConsensusVersion', async () => { - await assert.reverts( - consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION_2, { from: member1 }), - `UnexpectedConsensusVersion(${CONSENSUS_VERSION}, ${CONSENSUS_VERSION_2})` - ) - }) - - it('reverts with EmptyReport', async () => { - await assert.reverts( - consensus.submitReport(frame.refSlot, ZERO_HASH, CONSENSUS_VERSION, { from: member1 }), - `EmptyReport()` - ) - }) - - it('reverts with ConsensusReportAlreadyProcessing', async () => { - await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) - await reportProcessor.startReportProcessing() - await assert.reverts( - consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }), - `ConsensusReportAlreadyProcessing()` - ) - }) - - it('does not reverts with ConsensusReportAlreadyProcessing if member hasn`t sent a report for this slot', async () => { - await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) - await reportProcessor.startReportProcessing() - await consensus.addMember(member2, 2, { from: admin }) - await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) - }) - - it('reverts with DuplicateReport', async () => { - await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) - await assert.reverts( - consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }), - `DuplicateReport()` - ) - }) + let consensus + let frame + let reportProcessor + let snapshot + + const deploy = async (options = { epochsPerFrame: 200 }) => { + snapshot = new EvmSnapshot(ethers.provider) + const deployed = await deployHashConsensus(admin, options) + consensus = deployed.consensus + reportProcessor = deployed.reportProcessor + frame = await consensus.getCurrentFrame() + await consensus.addMember(member1, 1, { from: admin }) + await snapshot.make() + } + + const rollback = async () => { + await snapshot.rollback() + } + + before(deploy) + + context('method submitReport', () => { + afterEach(rollback) + + it('reverts with NumericOverflow if slot is greater than max allowed', async () => { + await assert.reverts( + consensus.submitReport('20446744073709551615', HASH_1, CONSENSUS_VERSION, { from: member1 }), + 'NumericOverflow()' + ) + }) + + it('reverts with NumericOverflow if slot is greater than max allowed', async () => { + await assert.reverts( + consensus.submitReport('20446744073709551615', HASH_1, CONSENSUS_VERSION, { from: member1 }), + 'NumericOverflow()' + ) + }) + + it('reverts with InvalidSlot if slot is zero', async () => { + await assert.reverts(consensus.submitReport(0, HASH_1, CONSENSUS_VERSION, { from: member1 }), 'InvalidSlot()') + }) + + it('reverts with UnexpectedConsensusVersion', async () => { + await assert.reverts( + consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION_2, { from: member1 }), + `UnexpectedConsensusVersion(${CONSENSUS_VERSION}, ${CONSENSUS_VERSION_2})` + ) + }) + + it('reverts with EmptyReport', async () => { + await assert.reverts( + consensus.submitReport(frame.refSlot, ZERO_HASH, CONSENSUS_VERSION, { from: member1 }), + `EmptyReport()` + ) + }) + + it('reverts with ConsensusReportAlreadyProcessing', async () => { + await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + await reportProcessor.startReportProcessing() + await assert.reverts( + consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }), + `ConsensusReportAlreadyProcessing()` + ) + }) + + it('reverts with DuplicateReport', async () => { + await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + await assert.reverts( + consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }), + `DuplicateReport()` + ) + }) + + it('does not reverts with ConsensusReportAlreadyProcessing if member has not sent a report for this slot', async () => { + await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + await reportProcessor.startReportProcessing() + await consensus.addMember(member2, 2, { from: admin }) + await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) + }) + + it('consensus loss on conflicting report submit', async () => { + await consensus.addMember(member2, 2, { from: admin }) + await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member1 }) + const tx1 = await consensus.submitReport(frame.refSlot, HASH_1, CONSENSUS_VERSION, { from: member2 }) + assert.emitsNumberOfEvents(tx1, 'ConsensusReached', 1) + const tx2 = await consensus.submitReport(frame.refSlot, HASH_2, CONSENSUS_VERSION, { from: member2 }) + assert.emitsNumberOfEvents(tx2, 'ConsensusLost', 1) }) }) }) diff --git a/test/0.8.9/oracle/validators-exit-bus-oracle-submit-report-data.test.js b/test/0.8.9/oracle/validators-exit-bus-oracle-submit-report-data.test.js index 45f611c18..a83f8a597 100644 --- a/test/0.8.9/oracle/validators-exit-bus-oracle-submit-report-data.test.js +++ b/test/0.8.9/oracle/validators-exit-bus-oracle-submit-report-data.test.js @@ -1,5 +1,6 @@ -const { contract } = require('hardhat') +const { contract, ethers } = require('hardhat') const { assert } = require('../../helpers/assert') +const { EvmSnapshot } = require('../../helpers/blockchain') const { CONSENSUS_VERSION, @@ -12,6 +13,9 @@ const { ZERO_HASH, } = require('./validators-exit-bus-oracle-deploy.test') +const ValidatorExitBusAbi = require('../../../lib/abi/ValidatorsExitBusOracle.json') +const { HASH_1 } = require('./hash-consensus-deploy.test') + const PUBKEYS = [ '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', @@ -36,8 +40,10 @@ contract('ValidatorsExitBusOracle', ([admin, member1, member2, member3, stranger let oracle let oracleReportSanityChecker let oracleVersion + let snapshot - async function setup() { + async function deployAndSetup() { + snapshot = new EvmSnapshot(ethers.provider) const deployed = await deployExitBusOracle(admin, { lastProcessingRefSlot: LAST_PROCESSING_REF_SLOT, resumeAfterDeploy: true, @@ -52,6 +58,11 @@ contract('ValidatorsExitBusOracle', ([admin, member1, member2, member3, stranger await consensus.addMember(member1, 1, { from: admin }) await consensus.addMember(member2, 2, { from: admin }) await consensus.addMember(member3, 2, { from: admin }) + await snapshot.make() + } + + async function rollback() { + await snapshot.rollback() } async function triggerConsensusOnHash(hash) { @@ -96,12 +107,49 @@ contract('ValidatorsExitBusOracle', ([admin, member1, member2, member3, stranger return +(await oracle.getLastRequestedValidatorIndices(moduleId, [nodeOpId]))[0] } + before(deployAndSetup) + + context('discarded report prevents data submit', () => { + let reportItems = null + let reportHash = null + + after(rollback) + + it('report is discarded', async () => { + reportItems = await prepareReportAndSubmitHash() + reportHash = calcValidatorsExitBusReportDataHash(reportItems) + const { refSlot } = await consensus.getCurrentFrame() + + // change of mind + const tx = await consensus.submitReport(refSlot, HASH_1, CONSENSUS_VERSION, { from: member3 }) + assert.emits(tx, 'ReportDiscarded', { refSlot, hash: reportHash }, { abi: ValidatorExitBusAbi }) + }) + + it('processing state reverts to pre-report state ', async () => { + const state = await oracle.getProcessingState() + assert.equals(state.dataHash, ZERO_HASH) + assert.equals(state.dataSubmitted, false) + assert.equals(state.dataFormat, 0) + assert.equals(state.requestsCount, 0) + assert.equals(state.requestsSubmitted, 0) + }) + + it('reverts on trying to submit the discarded report', async () => { + await assert.reverts( + oracle.submitReportData(reportItems, oracleVersion, { from: member1 }), + `UnexpectedDataHash`, + [`"${ZERO_HASH}"`, `"${reportHash}"`] + ) + }) + }) + context('_handleConsensusReportData', () => { beforeEach(async () => { - await setup() await consensus.advanceTimeToNextFrameStart() }) + afterEach(rollback) + context('enforces data format', () => { it('dataFormat = 0 reverts', async () => { const dataFormatUnsupported = 0 @@ -313,7 +361,7 @@ contract('ValidatorsExitBusOracle', ([admin, member1, member2, member3, stranger }) context(`requires validator indices for the same node operator to increase`, () => { - before(setup) + after(rollback) it(`requesting NO 5-3 to exit validator 0`, async () => { await consensus.advanceTimeToNextFrameStart() @@ -405,7 +453,7 @@ contract('ValidatorsExitBusOracle', ([admin, member1, member2, member3, stranger }) context(`only consensus member or SUBMIT_DATA_ROLE can submit report on unpaused contract`, () => { - beforeEach(setup) + afterEach(rollback) it('reverts on stranger', async () => { const report = await prepareReportAndSubmitHash() @@ -436,7 +484,7 @@ contract('ValidatorsExitBusOracle', ([admin, member1, member2, member3, stranger }) context('invokes internal baseOracle checks', () => { - beforeEach(setup) + afterEach(rollback) it(`reverts on contract version mismatch`, async () => { const report = await prepareReportAndSubmitHash() @@ -470,7 +518,7 @@ contract('ValidatorsExitBusOracle', ([admin, member1, member2, member3, stranger }) context('getTotalRequestsProcessed reflects report history', () => { - before(setup) + after(rollback) let requestCount @@ -508,7 +556,7 @@ contract('ValidatorsExitBusOracle', ([admin, member1, member2, member3, stranger }) context('getProcessingState reflects state change', () => { - before(setup) + after(rollback) let report let hash diff --git a/test/0.8.9/positive-token-rebase-limiter.test.js b/test/0.8.9/positive-token-rebase-limiter.test.js index f30dd9bfe..7aecc9032 100644 --- a/test/0.8.9/positive-token-rebase-limiter.test.js +++ b/test/0.8.9/positive-token-rebase-limiter.test.js @@ -204,7 +204,8 @@ contract('PositiveTokenRebaseLimiter', () => { const preTotalShares = ETH('1000000') await limiter.initLimiterState(rebaseLimit, preTotalPooledEther, preTotalShares) - await limiter.increaseEther(ETH(1000)) + const appendedEther = await limiter.increaseEther.sendWithResult(ETH(1000)) + assert.equals(appendedEther, ETH(1000)) await limiter.decreaseEther(ETH(40000)) // withdrawal fulfillment assert.isFalse(await limiter.isLimitReached()) @@ -225,4 +226,20 @@ contract('PositiveTokenRebaseLimiter', () => { const rebase = e9.mul(postShareRate).div(preShareRate).sub(e9) assert.almostEqual(rebase, rebaseLimit, 1) }) + + it('limit is reachable when rounding happens', async () => { + const rebaseLimit = bn('750000') // 0.075% or 7.5 basis points + + const preTotalPooledEther = bn('101000') + const preTotalShares = bn('101000') + const etherIncrease = bn('100000') + + await limiter.initLimiterState(rebaseLimit, preTotalPooledEther, preTotalShares) + const appendedEther = await limiter.increaseEther.sendWithResult(etherIncrease) + + assert.notEquals(etherIncrease, appendedEther) + assert.equals(appendedEther, bn('75')) + assert.isTrue(await limiter.isLimitReached()) + assert.equals(await limiter.getSharesToBurnLimit(), bn(0)) + }) }) diff --git a/test/0.8.9/staking-router/digest.test.js b/test/0.8.9/staking-router/digest.test.js index 9da68189d..c9fe9e8ea 100644 --- a/test/0.8.9/staking-router/digest.test.js +++ b/test/0.8.9/staking-router/digest.test.js @@ -172,7 +172,7 @@ contract('StakingRouter', ([deployer, lido, admin, appManager, stranger]) => { }) it('getStakingModuleDigests([]uint256) - digests works', async () => { await module1.setTotalExitedValidatorsCount(11) - await module1.setActiveValidatorsCount(22) + await module1.setActiveValidatorsCount(21) await module1.setAvailableKeysCount(33) const digests = await router.getStakingModuleDigests([module1Id, module2Id]) @@ -195,7 +195,7 @@ contract('StakingRouter', ([deployer, lido, admin, appManager, stranger]) => { }), summary: Object.values({ totalExitedValidators: '11', - totalDepositedValidators: '22', + totalDepositedValidators: '32', // 11 exited + 21 active depositableValidatorsCount: '33', }), } diff --git a/test/0.8.9/staking-router/rewards-distribution.test.js b/test/0.8.9/staking-router/rewards-distribution.test.js index cf94c64ed..230013c53 100644 --- a/test/0.8.9/staking-router/rewards-distribution.test.js +++ b/test/0.8.9/staking-router/rewards-distribution.test.js @@ -88,7 +88,7 @@ contract('StakingRouter', ([deployer, admin, depositor, stranger]) => { name: 'test', rewardAddress: ADDRESS_1, totalSigningKeysCount: 13, - vettedSigningKeysCount: 4, + vettedSigningKeysCount: 7, depositedSigningKeysCount: 7, exitedSigningKeysCount: 5, } @@ -184,7 +184,7 @@ contract('StakingRouter', ([deployer, admin, depositor, stranger]) => { name: 'Solo3', rewardAddress: ADDRESS_3, totalSigningKeysCount: 13, - vettedSigningKeysCount: 4, + vettedSigningKeysCount: 12, depositedSigningKeysCount: 7, exitedSigningKeysCount: 5, } @@ -254,7 +254,7 @@ contract('StakingRouter', ([deployer, admin, depositor, stranger]) => { name: 'test', rewardAddress: ADDRESS_1, totalSigningKeysCount: 13, - vettedSigningKeysCount: 4, + vettedSigningKeysCount: 8, depositedSigningKeysCount: 7, exitedSigningKeysCount: 5, } @@ -342,7 +342,7 @@ contract('StakingRouter', ([deployer, admin, depositor, stranger]) => { name: 'Solo3', rewardAddress: ADDRESS_3, totalSigningKeysCount: 13, - vettedSigningKeysCount: 4, + vettedSigningKeysCount: 13, depositedSigningKeysCount: 7, exitedSigningKeysCount: 5, } diff --git a/test/0.8.9/staking-router/staking-router-keys-reporting.test.js b/test/0.8.9/staking-router/staking-router-keys-reporting.test.js index eaded7a53..a4abaa9fc 100644 --- a/test/0.8.9/staking-router/staking-router-keys-reporting.test.js +++ b/test/0.8.9/staking-router/staking-router-keys-reporting.test.js @@ -74,6 +74,8 @@ contract('StakingRouter', ([deployer, lido, admin, stranger]) => { { from: admin } ) module1Id = +(await router.getStakingModuleIds())[0] + + await module1.setActiveValidatorsCount(10) }) it('initially, router assumes no staking modules have exited validators', async () => { @@ -515,6 +517,20 @@ contract('StakingRouter', ([deployer, lido, admin, stranger]) => { 'UnrecoverableModuleError()' ) }) + + it( + 'updateExitedValidatorsCountByStakingModule reverts when reported ' + + 'exitedValidatorsCount exceeds deposited validators count', + async () => { + const { totalDepositedValidators } = await module1.getStakingModuleSummary() + const invalidExitedValidatorsCount = +totalDepositedValidators + 1 + await assert.reverts( + router.updateExitedValidatorsCountByStakingModule([1], [invalidExitedValidatorsCount], { from: admin }), + 'ReportedExitedValidatorsExceedDeposited', + [invalidExitedValidatorsCount, totalDepositedValidators] + ) + } + ) }) describe('two staking modules', async () => { @@ -532,6 +548,8 @@ contract('StakingRouter', ([deployer, lido, admin, stranger]) => { 5_000, // 50 % _treasuryFee { from: admin } ) + await module1.setActiveValidatorsCount(7) + await router.addStakingModule( 'module 2', module2.address, @@ -540,6 +558,8 @@ contract('StakingRouter', ([deployer, lido, admin, stranger]) => { 0, // 0 % _treasuryFee { from: admin } ) + await module2.setActiveValidatorsCount(11) + moduleIds = toNum(await router.getStakingModuleIds()) }) @@ -851,6 +871,26 @@ contract('StakingRouter', ([deployer, lido, admin, stranger]) => { assert.equal(callInfo2.updateStuckValidatorsCount.callCount, 1) } ) + + it( + 'updateExitedValidatorsCountByStakingModule reverts when reported ' + + 'exitedValidatorsCount exceeds deposited validators count', + async () => { + const { totalDepositedValidators } = await module2.getStakingModuleSummary() + const invalidExitedValidatorsCount = +totalDepositedValidators + 1 + await assert.reverts( + router.updateExitedValidatorsCountByStakingModule.sendWithResult( + moduleIds, + [3, invalidExitedValidatorsCount], + { + from: admin, + } + ), + 'ReportedExitedValidatorsExceedDeposited', + [invalidExitedValidatorsCount, totalDepositedValidators] + ) + } + ) }) }) @@ -912,6 +952,8 @@ contract('StakingRouter', ([deployer, lido, admin, stranger]) => { depositableValidatorsCount: 0, } + await module1.setActiveValidatorsCount(10) + // first correction const newlyExited = await router.updateExitedValidatorsCountByStakingModule.sendWithResult([module1Id], [10], { from: admin, diff --git a/test/0.8.9/staking-router/staking-router.test.js b/test/0.8.9/staking-router/staking-router.test.js index 68d808476..16fb1eddb 100644 --- a/test/0.8.9/staking-router/staking-router.test.js +++ b/test/0.8.9/staking-router/staking-router.test.js @@ -495,10 +495,10 @@ contract('StakingRouter', ([deployer, lido, admin, appManager, stranger]) => { `StakingModuleWrongName()` ) - // check length > 32 symbols + // check length > 31 symbols await assert.revertsWithCustomError( router.addStakingModule( - '#'.repeat(33), + '#'.repeat(32), stakingModule1.address, stakingModulesParams[0].targetShare, stakingModulesParams[0].stakingModuleFee, @@ -1158,12 +1158,12 @@ contract('StakingRouter', ([deployer, lido, admin, appManager, stranger]) => { module1Id = +(await router.getStakingModuleIds())[0] await module1.setTotalExitedValidatorsCount(11) - await module1.setActiveValidatorsCount(22) + await module1.setActiveValidatorsCount(12) await module1.setAvailableKeysCount(33) const summary = await router.getStakingModuleSummary(module1Id) assert.equal(summary.totalExitedValidators, 11) - assert.equal(summary.totalDepositedValidators, 22) + assert.equal(summary.totalDepositedValidators, 23) // 11 exited + 12 deposited assert.equal(summary.depositableValidatorsCount, 33) }) }) diff --git a/test/0.8.9/withdrawal-queue.test.js b/test/0.8.9/withdrawal-queue.test.js index 199a52963..80c09532b 100644 --- a/test/0.8.9/withdrawal-queue.test.js +++ b/test/0.8.9/withdrawal-queue.test.js @@ -144,8 +144,14 @@ contract('WithdrawalQueue', ([owner, stranger, daoAgent, user, pauser, resumer, await assert.reverts(withdrawalQueue.finalize([1], 0, { from: owner }), 'ResumedExpected()') }) + it('cant resume without resume role', async () => { + await assert.revertsOZAccessControl(withdrawalQueue.resume({ from: pauser }), pauser, 'RESUME_ROLE') + }) + it('cant resume if not paused', async () => { - await assert.reverts(withdrawalQueue.resume(), 'PausedExpected()') + const RESUME_ROLE = await withdrawalQueue.RESUME_ROLE() + await withdrawalQueue.grantRole(RESUME_ROLE, resumer, { from: daoAgent }) + await assert.reverts(withdrawalQueue.resume({ from: resumer }), 'PausedExpected()') }) }) diff --git a/test/common/lib/signature-utils.test.js b/test/common/lib/signature-utils.test.js index ee06c0c1f..6ff92d10c 100644 --- a/test/common/lib/signature-utils.test.js +++ b/test/common/lib/signature-utils.test.js @@ -1,7 +1,7 @@ const { artifacts, ethers, contract } = require('hardhat') const { assert } = require('../../helpers/assert') -const { toBN, hex, hexConcat } = require('../../helpers/utils') +const { toBN, hex, hexConcat, strip0x } = require('../../helpers/utils') const { EvmSnapshot } = require('../../helpers/blockchain') const { ecSign } = require('../../helpers/signatures') const { ACCOUNTS_AND_KEYS } = require('../../helpers/constants') @@ -17,6 +17,9 @@ testWithConsumer(SignatureUtilsConsumer_0_8_9, 'Solidity 0.8.9') function testWithConsumer(SignatureUtilsConsumer, desc) { const ERC1271_MAGIC_VALUE = '0x1626ba7e' + const ERC1271_MAGIC_VALUE_PLUS_1 = '0x1626ba7f' + + const hexPadRight = (s, byteLen) => '0x' + strip0x(s).padEnd(byteLen * 2, '0') contract(`SignatureUtils.isValidSignature, ${desc}`, () => { const msgHash = `0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef` @@ -78,19 +81,72 @@ function testWithConsumer(SignatureUtilsConsumer, desc) { await snapshot.make() }) - it(`returns true when the call returns the magic value`, async () => { - await signerContract.configure({ reverts: false, retval: ERC1271_MAGIC_VALUE }) + it(`returns true when the call returns the magic value right-padded to 32 bytes`, async () => { + await signerContract.configure({ reverts: false, retval: hexPadRight(ERC1271_MAGIC_VALUE, 32) }) assert.isTrue(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) }) - it(`returns false when the call returns any other value`, async () => { - await signerContract.configure({ reverts: false, retval: '0x' + hex(toBN(ERC1271_MAGIC_VALUE).addn(1), 4) }) + it(`returns false when the call returns any other 4-byte value right-padded to 32 bytes`, async () => { + await signerContract.configure({ reverts: false, retval: hexPadRight(ERC1271_MAGIC_VALUE_PLUS_1, 32) }) + assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + + await signerContract.configure({ reverts: false, retval: hexPadRight('0x12345678', 32) }) + assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + }) + + it(`returns false when the returned value is shorter than 4 bytes (before padding)`, async () => { + await signerContract.configure({ reverts: false, retval: hexPadRight(ERC1271_MAGIC_VALUE.slice(0, -2), 32) }) assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) - await signerContract.configure({ reverts: false, retval: '0x00000000' }) + await signerContract.configure({ reverts: false, retval: hexPadRight('0x00000000', 32) }) assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + }) + + it(`returns false when the returned value is longer than 4 bytes (before padding)`, async () => { + await signerContract.configure({ + reverts: false, + retval: hexPadRight(hexConcat(ERC1271_MAGIC_VALUE, '0x01'), 32), + }) + assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + }) + + it(`returns false when the returned value is shorter than 32 bytes (after padding)`, async () => { + await signerContract.configure({ reverts: false, retval: ERC1271_MAGIC_VALUE }) + assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + + await signerContract.configure({ reverts: false, retval: hexPadRight(ERC1271_MAGIC_VALUE, 31) }) + assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + }) - await signerContract.configure({ reverts: false, retval: '0x12345678' }) + it(`returns false when the returned value is longer than 32 bytes (after padding)`, async () => { + await signerContract.configure({ + reverts: false, + retval: hexConcat(hexPadRight(ERC1271_MAGIC_VALUE, 32), '0x00'), + }) + assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + + await signerContract.configure({ + reverts: false, + retval: hexConcat(hexPadRight(ERC1271_MAGIC_VALUE, 32), '0x01'), + }) + assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + + await signerContract.configure({ + reverts: false, + retval: hexConcat(hexPadRight(ERC1271_MAGIC_VALUE, 32), hexPadRight('0x00', 32)), + }) + assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + + await signerContract.configure({ + reverts: false, + retval: hexConcat(hexPadRight(ERC1271_MAGIC_VALUE, 32), ERC1271_MAGIC_VALUE), + }) + assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) + + await signerContract.configure({ + reverts: false, + retval: hexConcat(hexPadRight(ERC1271_MAGIC_VALUE, 32), hexPadRight(ERC1271_MAGIC_VALUE, 32)), + }) assert.isFalse(await sigUtils.isValidSignature(signerContract.address, msgHash, v, r, s)) }) diff --git a/test/helpers/assert.js b/test/helpers/assert.js index 5c077074c..d6bf5f146 100644 --- a/test/helpers/assert.js +++ b/test/helpers/assert.js @@ -12,7 +12,7 @@ chai.util.addMethod(chai.assert, 'emits', function (receipt, eventName, args = u if (args !== undefined) { chai.assert( findEventWithArgs(args, events) !== undefined, - () => `No '${eventName}' event was emitted with expected args ${JSON.stringify(args)}` + () => `No '${eventName}' event was emitted with expected args ${stringify(args)}` ) } }) @@ -21,7 +21,7 @@ chai.util.addMethod(chai.assert, 'emitsAt', function (receipt, eventName, index, const event = getEventAt(receipt, eventName, index, args, options.abi) chai.assert( event !== undefined, - () => `Event '${eventName}' at index ${index} with args ${JSON.stringify(args)} wasn't found` + () => `Event '${eventName}' at index ${index} with args ${stringify(args)} wasn't found` ) }) @@ -162,7 +162,7 @@ function findEventWithArgs(args, events) { } function normalizeArg(arg) { - if (isBn(arg) || Number.isFinite(arg)) { + if (isBn(arg) || Number.isFinite(arg) || typeof arg === 'bigint') { return arg.toString() } else if (isAddress(arg)) { return toChecksumAddress(arg) @@ -174,4 +174,9 @@ function normalizeArg(arg) { return arg } +function stringify(obj) { + // Helps overcome the problem with BigInt serialization. Details: https://github.com/GoogleChromeLabs/jsbi/issues/30 + return JSON.stringify(obj, (_, value) => (typeof value === 'bigint' ? value.toString() : value)) +} + module.exports = { assert: chai.assert } diff --git a/test/helpers/factories.js b/test/helpers/factories.js index a87939571..374073f43 100644 --- a/test/helpers/factories.js +++ b/test/helpers/factories.js @@ -328,7 +328,7 @@ async function oracleReportSanityCheckerFactory({ lidoLocator, voting, appManage to: voting.address, roles: [ 'ALL_LIMITS_MANAGER_ROLE', - 'CHURN_VALIDATORS_PER_DAY_LIMIT_MANGER_ROLE', + 'CHURN_VALIDATORS_PER_DAY_LIMIT_MANAGER_ROLE', 'ONE_OFF_CL_BALANCE_DECREASE_LIMIT_MANAGER_ROLE', 'ANNUAL_BALANCE_INCREASE_LIMIT_MANAGER_ROLE', 'SHARE_RATE_DEVIATION_LIMIT_MANAGER_ROLE', diff --git a/test/helpers/node-operators.js b/test/helpers/node-operators.js index 9e4e94e1e..bba526205 100644 --- a/test/helpers/node-operators.js +++ b/test/helpers/node-operators.js @@ -83,8 +83,8 @@ async function addNodeOperator(registry, config, txOptions) { const nodeOperator = await registry.getNodeOperator(newOperatorId, true) if (isActive) { - assert.equals(nodeOperator.stakingLimit, vettedSigningKeysCount) - assert.equals(nodeOperator.totalSigningKeys, totalSigningKeysCount) + assert.equals(nodeOperator.totalVettedValidators, vettedSigningKeysCount) + assert.equals(nodeOperator.totalAddedValidators, totalSigningKeysCount) assert.equals(nodeOperatorsSummary.totalExitedValidators, exitedSigningKeysCount) assert.equals(nodeOperatorsSummary.totalDepositedValidators, depositedSigningKeysCount) assert.equals(nodeOperatorsSummary.depositableValidatorsCount, vettedSigningKeysCount - depositedSigningKeysCount) diff --git a/test/scenario/lido_happy_path.test.js b/test/scenario/lido_happy_path.test.js index e1736a53e..f2a62df62 100644 --- a/test/scenario/lido_happy_path.test.js +++ b/test/scenario/lido_happy_path.test.js @@ -14,6 +14,13 @@ const { INITIAL_HOLDER } = require('../helpers/constants') const NodeOperatorsRegistry = artifacts.require('NodeOperatorsRegistry') const CURATED_MODULE_ID = 1 +const TOTAL_BASIS_POINTS = 10000 +const CURATED_MODULE_MODULE_FEE = 500 +const CURATED_MODULE_TREASURY_FEE = 500 + +// Fee and its distribution are in basis points, 10000 corresponding to 100% +// Total fee is 10% +const totalFeePoints = 0.1 * TOTAL_BASIS_POINTS contract('Lido: happy path', (addresses) => { const [ @@ -41,14 +48,14 @@ contract('Lido: happy path', (addresses) => { async () => { const deployed = await deployProtocol({ stakingModulesFactory: async (protocol) => { - const curatedModule = await setupNodeOperatorsRegistry(protocol) + const curatedModule = await setupNodeOperatorsRegistry(protocol, true) return [ { module: curatedModule, name: 'Curated', targetShares: 10000, - moduleFee: 500, - treasuryFee: 500, + moduleFee: CURATED_MODULE_MODULE_FEE, + treasuryFee: CURATED_MODULE_TREASURY_FEE, }, ] }, @@ -84,22 +91,6 @@ contract('Lido: happy path', (addresses) => { } ) - // Fee and its distribution are in basis points, 10000 corresponding to 100% - - // Total fee is 10% - const totalFeePoints = 0.1 * 10000 - - it.skip('voting sets fee and its distribution', async () => { - // Fee and distribution were set - assert.equals(await pool.getFee({ from: nobody }), totalFeePoints, 'total fee') - const distribution = await pool.getFeeDistribution({ from: nobody }) - console.log('distribution', distribution) - const treasuryFeePoints = 0 // TODO - const nodeOperatorsFeePoints = 0 // TODO - assert.equals(distribution.treasuryFeeBasisPoints, treasuryFeePoints, 'treasury fee') - assert.equals(distribution.operatorsFeeBasisPoints, nodeOperatorsFeePoints, 'node operators fee') - }) - it('voting sets withdrawal credentials', async () => { const wc = '0x'.padEnd(66, '1234') assert.equal(await pool.getWithdrawalCredentials({ from: nobody }), wc, 'withdrawal credentials') @@ -500,7 +491,7 @@ contract('Lido: happy path', (addresses) => { from: nodeOperator3.address, }) const nodeOperatorInfo = await nodeOperatorsRegistry.getNodeOperator(nodeOperator3.id, false) - assert.equals(nodeOperatorInfo.stakingLimit, 5) + assert.equals(nodeOperatorInfo.totalVettedValidators, 5) }) it('deposit to nodeOperator3 validators', async () => { @@ -537,13 +528,39 @@ contract('Lido: happy path', (addresses) => { let nodeOperatorInfo = await nodeOperatorsRegistry.getNodeOperator(nodeOperator3.id, false) // validate that only 5 signing keys used after key removing - assert.equals(nodeOperatorInfo.stakingLimit, nodeOperatorInfo.usedSigningKeys) - assert.equals(nodeOperatorInfo.totalSigningKeys, 9) + assert.equals(nodeOperatorInfo.totalVettedValidators, nodeOperatorInfo.totalDepositedValidators) + assert.equals(nodeOperatorInfo.totalAddedValidators, 9) // validate that all other validators used and pool still has buffered ether nodeOperatorInfo = await nodeOperatorsRegistry.getNodeOperator(nodeOperator1.id, false) - assert.equals(nodeOperatorInfo.totalSigningKeys, nodeOperatorInfo.usedSigningKeys) + assert.equals(nodeOperatorInfo.totalAddedValidators, nodeOperatorInfo.totalDepositedValidators) nodeOperatorInfo = await nodeOperatorsRegistry.getNodeOperator(nodeOperator2.id, false) - assert.equals(nodeOperatorInfo.totalSigningKeys, nodeOperatorInfo.usedSigningKeys) + assert.equals(nodeOperatorInfo.totalAddedValidators, nodeOperatorInfo.totalDepositedValidators) + }) + + it('getFee and getFeeDistribution works as expected', async () => { + // Need to have at least single deposited key, otherwise StakingRouter.getStakingRewardsDistribution + // will return zero fees because no modules with non-zero total active validators + // This is done in the changes in the tests above, but assuming there are no such changes + // one could use the following: + // await nodeOperatorsRegistry.increaseNodeOperatorDepositedSigningKeysCount(0, 1) + + function getFeeRelativeToTotalFee(absoluteFee) { + return (absoluteFee * TOTAL_BASIS_POINTS) / totalFeePoints + } + + assert.equals(await pool.getFee({ from: nobody }), totalFeePoints, 'total fee') + const distribution = await pool.getFeeDistribution({ from: nobody }) + assert.equals(distribution.insuranceFeeBasisPoints, 0, 'insurance fee') + assert.equals( + distribution.treasuryFeeBasisPoints, + getFeeRelativeToTotalFee(CURATED_MODULE_TREASURY_FEE), + 'treasury fee' + ) + assert.equals( + distribution.operatorsFeeBasisPoints, + getFeeRelativeToTotalFee(CURATED_MODULE_MODULE_FEE), + 'node operators fee' + ) }) })