From 7f69a0372d445d49c04f4a13a4c869d3b4b59edb Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 27 Jun 2023 11:18:25 +0300 Subject: [PATCH 01/13] Don't capitalize Ether "ether" is not capitalized on ethereum.org, so we should not too --- README.md | 6 ++-- contracts/0.4.24/Lido.sol | 14 ++++----- contracts/0.4.24/StETH.sol | 16 +++++----- contracts/0.4.24/StETHPermit.sol | 2 +- contracts/0.8.9/StakingRouter.sol | 2 +- test/0.4.24/lido.test.js | 2 +- .../lido-exec-layer-rewards-vault.test.js | 4 +-- ...tion_layer_rewards_after_the_merge.test.js | 30 +++++++++---------- .../lido_deposit_iteration_limit.test.js | 8 ++--- test/scenario/lido_happy_path.test.js | 14 ++++----- test/scenario/lido_penalties_slashing.test.js | 16 +++++----- 11 files changed, 57 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index f92c36826..3ace63eb2 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ [![Tests](https://github.com/lidofinance/lido-dao/workflows/Tests/badge.svg)](https://github.com/lidofinance/lido-dao/actions) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) -The Lido Ethereum Liquid Staking Protocol allows their users to earn staking rewards on the Beacon chain without locking Ether or maintaining staking infrastructure. +The Lido Ethereum Liquid Staking Protocol allows their users to earn staking rewards on the Beacon chain without locking ether or maintaining staking infrastru ether -Users can deposit Ether to the Lido smart contract and receive stETH tokens in return. The smart contract then stakes tokens with the DAO-picked node operators. Users' deposited funds are pooled by the DAO, node operators never have direct access to the users' assets. +Users can deposit ether to the Lido smart contract and receive stETH tokens in return. The smart contract then stakes tokens with the DAO-picked node operators. Users' deposited funds are pooled by the DAO, node operators never have direct access to the users' assets. -Unlike staked ether, the stETH token is free from the limitations associated with a lack of liquidity and can be transferred at any time. The stETH token balance corresponds to the amount of Ether that the holder could request to withdraw. +Unlike staked ether, the stETH token is free from the limitations associated with a lack of liquidity and can be transferred at any time. The stETH token balance corresponds to the amount of ether that the holder could request to withdraw. Before getting started with this repo, please read: diff --git a/contracts/0.4.24/Lido.sol b/contracts/0.4.24/Lido.sol index 520a9b4ae..42703c3a2 100644 --- a/contracts/0.4.24/Lido.sol +++ b/contracts/0.4.24/Lido.sol @@ -179,7 +179,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { /// @dev storage slot position of the staking rate limit structure bytes32 internal constant STAKING_STATE_POSITION = 0xa3678de4a579be090bed1177e0a24f77cc29d181ac22fd7688aca344d8938015; // keccak256("lido.Lido.stakeLimit"); - /// @dev amount of Ether (on the current Ethereum side) buffered on this smart contract balance + /// @dev amount of ether (on the current Ethereum side) buffered on this smart contract balance bytes32 internal constant BUFFERED_ETHER_POSITION = 0xed310af23f61f96daefbcd140b306c0bdbf8c178398299741687b90e794772b0; // keccak256("lido.Lido.bufferedEther"); /// @dev number of deposited validators (incrementing counter of deposit operations). @@ -314,9 +314,9 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @notice Stops accepting new Ether to the protocol + * @notice Stops accepting new ether to the protocol * - * @dev While accepting new Ether is stopped, calls to the `submit` function, + * @dev While accepting new ether is stopped, calls to the `submit` function, * as well as to the default payable function, will revert. * * Emits `StakingPaused` event. @@ -328,7 +328,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @notice Resumes accepting new Ether to the protocol (if `pauseStaking` was called previously) + * @notice Resumes accepting new ether to the protocol (if `pauseStaking` was called previously) * NB: Staking could be rate-limited by imposing a limit on the stake amount * at each moment in time, see `setStakingLimit()` and `removeStakingLimit()` * @@ -397,7 +397,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { /** - * @notice Returns how much Ether can be staked in the current block + * @notice Returns how much ether can be staked in the current block * @dev Special return values: * - 2^256 - 1 if staking is unlimited; * - 0 if staking is paused or if limit is exhausted. @@ -1078,7 +1078,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @dev Gets the amount of Ether temporary buffered on this contract balance + * @dev Gets the amount of ether temporary buffered on this contract balance */ function _getBufferedEther() internal view returns (uint256) { return BUFFERED_ETHER_POSITION.getStorageUint256(); @@ -1100,7 +1100,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @dev Gets the total amount of Ether controlled by the system + * @dev Gets the total amount of ether controlled by the system * @return total balance in wei */ function _getTotalPooledEther() internal view returns (uint256) { diff --git a/contracts/0.4.24/StETH.sol b/contracts/0.4.24/StETH.sol index 8a4b40ff6..48fe07307 100644 --- a/contracts/0.4.24/StETH.sol +++ b/contracts/0.4.24/StETH.sol @@ -17,7 +17,7 @@ import "./utils/Pausable.sol"; * the `_getTotalPooledEther` function. * * StETH balances are dynamic and represent the holder's share in the total amount - * of Ether controlled by the protocol. Account shares aren't normalized, so the + * of ether controlled by the protocol. Account shares aren't normalized, so the * contract also stores the sum of all shares to calculate each account's token balance * which equals to: * @@ -37,7 +37,7 @@ import "./utils/Pausable.sol"; * Since balances of all token holders change when the amount of total pooled Ether * changes, this token cannot fully implement ERC20 standard: it only emits `Transfer` * events upon explicit transfer between holders. In contrast, when total amount of - * pooled Ether increases, no `Transfer` events are generated: doing so would require + * pooled ether increases, no `Transfer` events are generated: doing so would require * emitting an event for each token holder and thus running an unbounded loop. * * The token inherits from `Pausable` and uses `whenNotStopped` modifier for methods @@ -55,7 +55,7 @@ contract StETH is IERC20, Pausable { /** * @dev StETH balances are dynamic and are calculated based on the accounts' shares - * and the total amount of Ether controlled by the protocol. Account shares aren't + * and the total amount of ether controlled by the protocol. Account shares aren't * normalized, so the contract also stores the sum of all shares to calculate * each account's token balance which equals to: * @@ -142,14 +142,14 @@ contract StETH is IERC20, Pausable { * @return the amount of tokens in existence. * * @dev Always equals to `_getTotalPooledEther()` since token amount - * is pegged to the total amount of Ether controlled by the protocol. + * is pegged to the total amount of ether controlled by the protocol. */ function totalSupply() external view returns (uint256) { return _getTotalPooledEther(); } /** - * @return the entire amount of Ether controlled by the protocol. + * @return the entire amount of ether controlled by the protocol. * * @dev The sum of all ETH balances in the protocol, equals to the total supply of stETH. */ @@ -161,7 +161,7 @@ contract StETH is IERC20, Pausable { * @return the amount of tokens owned by the `_account`. * * @dev Balances are dynamic and equal the `_account`'s share in the amount of the - * total Ether controlled by the protocol. See `sharesOf`. + * total ether controlled by the protocol. See `sharesOf`. */ function balanceOf(address _account) external view returns (uint256) { return getPooledEthByShares(_sharesOf(_account)); @@ -304,7 +304,7 @@ contract StETH is IERC20, Pausable { } /** - * @return the amount of Ether that corresponds to `_sharesAmount` token shares. + * @return the amount of ether that corresponds to `_sharesAmount` token shares. */ function getPooledEthByShares(uint256 _sharesAmount) public view returns (uint256) { return _sharesAmount @@ -361,7 +361,7 @@ contract StETH is IERC20, Pausable { } /** - * @return the total amount (in wei) of Ether controlled by the protocol. + * @return the total amount (in wei) of ether controlled by the protocol. * @dev This is used for calculating tokens from shares and vice versa. * @dev This function is required to be implemented in a derived contract. */ diff --git a/contracts/0.4.24/StETHPermit.sol b/contracts/0.4.24/StETHPermit.sol index b0105e58d..ad7cb05df 100644 --- a/contracts/0.4.24/StETHPermit.sol +++ b/contracts/0.4.24/StETHPermit.sol @@ -17,7 +17,7 @@ import {StETH} from "./StETH.sol"; * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't - * need to send a transaction, and thus is not required to hold Ether at all. + * need to send a transaction, and thus is not required to hold ether at all. */ interface IERC2612 { /** diff --git a/contracts/0.8.9/StakingRouter.sol b/contracts/0.8.9/StakingRouter.sol index adcb1d6bb..0c1f21794 100644 --- a/contracts/0.8.9/StakingRouter.sol +++ b/contracts/0.8.9/StakingRouter.sol @@ -112,7 +112,7 @@ contract StakingRouter is AccessControlEnumerable, BeaconChainDepositor, Version bytes32 internal constant LIDO_POSITION = keccak256("lido.StakingRouter.lido"); - /// @dev Credentials which allows the DAO to withdraw Ether on the 2.0 side + /// @dev Credentials which allows the DAO to withdraw ether on the 2.0 side bytes32 internal constant WITHDRAWAL_CREDENTIALS_POSITION = keccak256("lido.StakingRouter.withdrawalCredentials"); /// @dev total count of staking modules diff --git a/test/0.4.24/lido.test.js b/test/0.4.24/lido.test.js index 92137d8c0..71f09cb82 100644 --- a/test/0.4.24/lido.test.js +++ b/test/0.4.24/lido.test.js @@ -1219,7 +1219,7 @@ contract('Lido', ([appManager, , , , , , , , , , , , user1, user2, user3, nobody assert.equals(await app.totalSupply(), tokens(32)) // 30 remote (slashed) + 2 buffered = 32 await checkRewards({ treasury: 0, operator: 0 }) - // rewarded 200 Ether (was 30, became 230) + // rewarded 200 ether (was 30, became 230) await pushReport(1, ETH(130)) await checkStat({ depositedValidators: 1, beaconValidators: 1, beaconBalance: ETH(130) }) // Todo check reward effects diff --git a/test/0.8.9/lido-exec-layer-rewards-vault.test.js b/test/0.8.9/lido-exec-layer-rewards-vault.test.js index d7070dd95..744d44e40 100644 --- a/test/0.8.9/lido-exec-layer-rewards-vault.test.js +++ b/test/0.8.9/lido-exec-layer-rewards-vault.test.js @@ -36,14 +36,14 @@ contract('LidoExecutionLayerRewardsVault', ([deployer, anotherAccount]) => { await assert.reverts(elRewardsVault.withdrawRewards(12345, { from: appManager }), 'ONLY_LIDO_CAN_WITHDRAW') }) - it('Execution layer rewards vault can receive Ether by plain transfers (no call data)', async () => { + it('Execution layer rewards vault can receive ether by plain transfers (no call data)', async () => { const before = +(await web3.eth.getBalance(elRewardsVault.address)).toString() const amount = 0.02 await web3.eth.sendTransaction({ to: elRewardsVault.address, from: anotherAccount, value: ETH(amount) }) assert.equals(await web3.eth.getBalance(elRewardsVault.address), ETH(before + amount)) }) - it('Execution layer rewards vault refuses to receive Ether by transfers with call data', async () => { + it('Execution layer rewards vault refuses to receive ether by transfers with call data', async () => { const amount = 0.02 await assert.reverts( web3.eth.sendTransaction({ diff --git a/test/scenario/execution_layer_rewards_after_the_merge.test.js b/test/scenario/execution_layer_rewards_after_the_merge.test.js index 77dd30b8d..b95090a23 100644 --- a/test/scenario/execution_layer_rewards_after_the_merge.test.js +++ b/test/scenario/execution_layer_rewards_after_the_merge.test.js @@ -52,7 +52,7 @@ contract('Lido: merge acceptance', (addresses) => { // node operators operator_1, operator_2, - // users who deposit Ether to the pool + // users who deposit ether to the pool user1, user2, user3, @@ -250,14 +250,14 @@ contract('Lido: merge acceptance', (addresses) => { signatures ) - // No Ether was deposited yet to the validator contract + // No ether was deposited yet to the validator contract assert.equals(await depositContractMock.totalCalls(), 0) const ether2Stat = await pool.getBeaconStat() assert.equals(ether2Stat.depositedValidators, 0, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, 0, 'remote ether2') - // All Ether was buffered within the pool contract atm + // All ether was buffered within the pool contract atm // The contract's balance must be non-zero. When the contract is deployed, // it receives LIDO_INIT_BALANCE_ETH ETH in deployProtocol() function. @@ -315,7 +315,7 @@ contract('Lido: merge acceptance', (addresses) => { assert.equals(ether2Stat.depositedValidators, 1, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, 0, 'remote ether2') - // Some Ether remained buffered within the pool contract + // Some ether remained buffered within the pool contract // The contract's balance must be non-zero. When the contract is deployed, // it receives LIDO_INIT_BALANCE_ETH ETH in deployProtocol() function. @@ -449,7 +449,7 @@ contract('Lido: merge acceptance', (addresses) => { const elRewards = 9 - // Total pooled Ether increased + // Total pooled ether increased const newTotalPooledEther = await pool.getTotalPooledEther() assert.equals(newTotalPooledEther, ETH(LIDO_INIT_BALANCE_ETH + 3 + 30 + 64.35 + elRewards), 'total pooled ether') @@ -459,7 +459,7 @@ contract('Lido: merge acceptance', (addresses) => { assert.equals(ether2Stat.depositedValidators, 2, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, ETH(64.35), 'remote ether2') - // Buffered Ether amount changed on execution layer rewards + // Buffered ether amount changed on execution layer rewards assert.equals(await pool.getBufferedEther(), ETH(LIDO_INIT_BALANCE_ETH + 33 + elRewards), 'buffered ether') // New tokens was minted to distribute fee @@ -553,7 +553,7 @@ contract('Lido: merge acceptance', (addresses) => { const newTotalShares = await token.getTotalShares() assert.equals(newTotalShares, oldTotalShares, 'total shares') - // Total pooled Ether increased + // Total pooled ether increased const newTotalPooledEther = await pool.getTotalPooledEther() assert.equals(newTotalPooledEther, ETH(107.35 + 7), 'total pooled ether') @@ -564,7 +564,7 @@ contract('Lido: merge acceptance', (addresses) => { assert.equals(ether2Stat.depositedValidators, 2, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, ETH(64.35), 'remote ether2') - // Buffered Ether amount changed on execution layer rewards + // Buffered ether amount changed on execution layer rewards assert.equals(await pool.getBufferedEther(), ETH(LIDO_INIT_BALANCE_ETH + 42 + 7), 'buffered ether') assert.equals(await token.totalSupply(), tokens(114.35), 'token total supply') @@ -647,7 +647,7 @@ contract('Lido: merge acceptance', (addresses) => { const newTotalShares = await token.getTotalShares() assert.equals(newTotalShares, oldTotalShares, 'total shares') - // Total pooled Ether increased by 5ETH - 2ETH + // Total pooled ether increased by 5ETH - 2ETH const newTotalPooledEther = await pool.getTotalPooledEther() assert.equals(newTotalPooledEther, ETH(114.35 + 3), 'total pooled ether') @@ -656,7 +656,7 @@ contract('Lido: merge acceptance', (addresses) => { assert.equals(ether2Stat.depositedValidators, 2, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, ETH(62.35), 'remote ether2') - // Buffered Ether amount changed on execution layer rewards + // Buffered ether amount changed on execution layer rewards assert.equals(await pool.getBufferedEther(), ETH(LIDO_INIT_BALANCE_ETH + 49 + 5), 'buffered ether') assert.equals(await token.totalSupply(), tokens(114.35 + 3), 'token total supply') @@ -743,7 +743,7 @@ contract('Lido: merge acceptance', (addresses) => { assert.equals(ether2Stat.depositedValidators, 2, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, ETH(59.35), 'remote ether2') - // Buffered Ether amount changed on execution layer rewards + // Buffered ether amount changed on execution layer rewards assert.equals(await pool.getBufferedEther(), ETH(LIDO_INIT_BALANCE_ETH + 54 + 3), 'buffered ether') assert.equals(await token.totalSupply(), tokens(117.35), 'token total supply') @@ -805,7 +805,7 @@ contract('Lido: merge acceptance', (addresses) => { const newTotalShares = await token.getTotalShares() assert.equals(newTotalShares, oldTotalShares, 'total shares') - // Total pooled Ether decreased by 8ETH-2ETH + // Total pooled ether decreased by 8ETH-2ETH const newTotalPooledEther = await pool.getTotalPooledEther() assert.equals(newTotalPooledEther, ETH(111.35), 'total pooled ether') @@ -814,7 +814,7 @@ contract('Lido: merge acceptance', (addresses) => { assert.equals(ether2Stat.depositedValidators, 2, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, ETH(51.35), 'remote ether2') - // Buffered Ether amount changed on execution layer rewards + // Buffered ether amount changed on execution layer rewards assert.equals(await pool.getBufferedEther(), ETH(LIDO_INIT_BALANCE_ETH + 57 + 2), 'buffered ether') assert.equals(await token.totalSupply(), tokens(111.35), 'token total supply') @@ -906,7 +906,7 @@ contract('Lido: merge acceptance', (addresses) => { const newTotalShares = await token.getTotalShares() assert.equals(newTotalShares, new BN('99132944596694892595'), 'total shares') - // Total pooled Ether increased by 0.14ETH+3ETH + // Total pooled ether increased by 0.14ETH+3ETH const newTotalPooledEther = await pool.getTotalPooledEther() assert.equals(newTotalPooledEther, ETH(111.49 + 3), 'total pooled ether') @@ -915,7 +915,7 @@ contract('Lido: merge acceptance', (addresses) => { assert.equals(ether2Stat.depositedValidators, 2, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, ETH(51.49), 'remote ether2') - // Buffered Ether amount changed on execution layer rewards + // Buffered ether amount changed on execution layer rewards assert.equals(await pool.getBufferedEther(), ETH(LIDO_INIT_BALANCE_ETH + 59 + 3), 'buffered ether') assert.equals(await token.totalSupply(), tokens(111.49 + 3), 'token total supply') diff --git a/test/scenario/lido_deposit_iteration_limit.test.js b/test/scenario/lido_deposit_iteration_limit.test.js index 418b69592..01b3a0499 100644 --- a/test/scenario/lido_deposit_iteration_limit.test.js +++ b/test/scenario/lido_deposit_iteration_limit.test.js @@ -14,7 +14,7 @@ const CURATED_MODULE_ID = 1 contract('Lido: deposit loop iteration limit', ([user1, nobody, nodeOperator]) => { // Limits the number of validators assigned in a single transaction, regardless the amount - // of Ether submitted to/buffered in the contract and the number of spare validator keys. + // of ether submitted to/buffered in the contract and the number of spare validator keys. // This is needed to prevent the deposit loop from failing due to it using more gas than // available in a single block and to protect from possible attacks exploiting this. @@ -129,7 +129,7 @@ contract('Lido: deposit loop iteration limit', ([user1, nobody, nodeOperator]) = const ether2Stat = await pool.getBeaconStat() assert.equals(ether2Stat.depositedValidators, 10, 'deposited validators') - // the rest of the received Ether is still buffered in the pool + // the rest of the received ether is still buffered in the pool assert.equals(await pool.getBufferedEther(), ETH(15 * 32), 'buffered ether') }) @@ -246,7 +246,7 @@ contract('Lido: deposit loop iteration limit', ([user1, nobody, nodeOperator]) = const ether2Stat = await pool.getBeaconStat() assert.equals(ether2Stat.depositedValidators, 26, 'deposited validators') - // the rest of the received Ether is still buffered in the pool + // the rest of the received ether is still buffered in the pool assert.equals(await pool.getBufferedEther(), ETH(1 * 32), 'buffered ether') }) @@ -280,7 +280,7 @@ contract('Lido: deposit loop iteration limit', ([user1, nobody, nodeOperator]) = assert.equals(await depositContractMock.totalCalls(), 26, 'total validators assigned') - // the rest of the received Ether is still buffered in the pool + // the rest of the received ether is still buffered in the pool assert.equals(await pool.getBufferedEther(), ETH(1 * 32), 'buffered ether') }) }) diff --git a/test/scenario/lido_happy_path.test.js b/test/scenario/lido_happy_path.test.js index f2a62df62..5db11350a 100644 --- a/test/scenario/lido_happy_path.test.js +++ b/test/scenario/lido_happy_path.test.js @@ -28,7 +28,7 @@ contract('Lido: happy path', (addresses) => { operator_1, operator_2, operator_3, - // users who deposit Ether to the pool + // users who deposit ether to the pool user1, user2, user3, @@ -189,7 +189,7 @@ contract('Lido: happy path', (addresses) => { signatures ) - // No Ether was deposited yet to the validator contract + // No ether was deposited yet to the validator contract assert.equals(await depositContractMock.totalCalls(), 0) @@ -197,7 +197,7 @@ contract('Lido: happy path', (addresses) => { assert.equals(ether2Stat.depositedValidators, 0, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, 0, 'remote ether2') - // All Ether was buffered within the pool contract atm + // All ether was buffered within the pool contract atm assert.equals(await pool.getBufferedEther(), ETH(3), 'buffered ether') assert.equals(await pool.getTotalPooledEther(), ETH(3), 'total pooled ether') @@ -253,7 +253,7 @@ contract('Lido: happy path', (addresses) => { assert.equals(ether2Stat.depositedValidators, 1, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, 0, 'remote ether2') - // Some Ether remained buffered within the pool contract + // Some ether remained buffered within the pool contract assert.equals(await pool.getBufferedEther(), ETH(1), 'buffered ether') assert.equals(await pool.getTotalPooledEther(), ETH(1 + 32), 'total pooled ether') @@ -402,7 +402,7 @@ contract('Lido: happy path', (addresses) => { const newTotalShares = await token.getTotalShares() assert.equals(newTotalShares, '97031905270948112819', 'total shares') - // Total pooled Ether increased + // Total pooled ether increased const newTotalPooledEther = await pool.getTotalPooledEther() assert.equals(newTotalPooledEther, ETH(33 + 64.32), 'total pooled ether') @@ -413,7 +413,7 @@ contract('Lido: happy path', (addresses) => { assert.equals(ether2Stat.depositedValidators, 2, 'deposited ether2') assert.equals(ether2Stat.beaconBalance, ETH(64.32), 'remote ether2') - // Buffered Ether amount didn't change + // Buffered ether amount didn't change assert.equals(await pool.getBufferedEther(), ETH(33), 'buffered ether') @@ -437,7 +437,7 @@ contract('Lido: happy path', (addresses) => { assert.equalsDelta(await token.balanceOf(nodeOperatorsRegistry.address), 0, 1, 'staking module tokens') // The node operators' fee is distributed between all active node operators, - // proportional to their effective stake (the amount of Ether staked by the operator's + // proportional to their effective stake (the amount of ether staked by the operator's // used and non-stopped validators). // // In our case, both node operators received the same fee since they have the same diff --git a/test/scenario/lido_penalties_slashing.test.js b/test/scenario/lido_penalties_slashing.test.js index dfc27b072..659981a03 100644 --- a/test/scenario/lido_penalties_slashing.test.js +++ b/test/scenario/lido_penalties_slashing.test.js @@ -19,7 +19,7 @@ contract('Lido: penalties, slashing, operator stops', (addresses) => { // node operators operator_1, operator_2, - // users who deposit Ether to the pool + // users who deposit ether to the pool user1, // unrelated address nobody, @@ -184,7 +184,7 @@ contract('Lido: penalties, slashing, operator stops', (addresses) => { signatures ) - // No Ether was deposited yet to the validator contract + // No ether was deposited yet to the validator contract assert.equals(await depositContractMock.totalCalls(), 0, 'no validators registered yet') @@ -192,7 +192,7 @@ contract('Lido: penalties, slashing, operator stops', (addresses) => { assert.equals(ether2Stat.depositedValidators, 0, 'no validators have received the ether2') assert.equals(ether2Stat.beaconBalance, 0, 'remote ether2 not reported yet') - assert.equals(await pool.getBufferedEther(), ETH(33), `All Ether was buffered within the pool contract atm`) + assert.equals(await pool.getBufferedEther(), ETH(33), `All ether was buffered within the pool contract atm`) assert.equals(await pool.getTotalPooledEther(), ETH(33), 'total pooled ether') expectedUser1Balance = StETH(32) @@ -289,7 +289,7 @@ contract('Lido: penalties, slashing, operator stops', (addresses) => { 'Total shares stay the same because no fee shares are added' ) - assert.equals(await pool.getTotalPooledEther(), ETH(32), 'Total pooled Ether decreased') + assert.equals(await pool.getTotalPooledEther(), ETH(32), 'Total pooled ether decreased') const clStat = await pool.getBeaconStat() assert.equals(clStat.depositedValidators, 1, 'validators count') @@ -315,7 +315,7 @@ contract('Lido: penalties, slashing, operator stops', (addresses) => { assert.equals( await pool.getTotalPooledEther(), ETH(32), - 'Old total pooled Ether 31 ETH od previous report + 1 ETH initial' + 'Old total pooled ether 31 ETH od previous report + 1 ETH initial' ) // Reporting 2 ETH balance loss (31 => 29) @@ -326,13 +326,13 @@ contract('Lido: penalties, slashing, operator stops', (addresses) => { shares(33), `Total shares stay the same because no fee shares are added` ) - assert.equals(await pool.getTotalPooledEther(), ETH(30), 'Total pooled Ether decreased') + assert.equals(await pool.getTotalPooledEther(), ETH(30), 'Total pooled ether decreased') const ether2Stat = await pool.getBeaconStat() assert.equals(ether2Stat.depositedValidators, 1, 'deposited validators') assert.equals(ether2Stat.beaconBalance, ETH(29), 'Ether2 stat reported by the pool changed correspondingly') - assert.equals(await pool.getBufferedEther(), ETH(1), 'Buffered Ether amount didnt change') + assert.equals(await pool.getBufferedEther(), ETH(1), 'Buffered ether amount didnt change') assert.equals(await token.totalSupply(), StETH(30), 'Total supply accounts for penalties taken by the validator') expectedUser1Balance = bn(shares(32)).muln(30).divn(33) // New share price is 30/33 ETH/share @@ -469,7 +469,7 @@ contract('Lido: penalties, slashing, operator stops', (addresses) => { bn(shares(1)).add(expectedUser1Shares), 'Total shares stay the same because no fee shares are added' ) - assert.equals(await pool.getTotalPooledEther(), ETH(61), 'Total pooled Ether decreased') + assert.equals(await pool.getTotalPooledEther(), ETH(61), 'Total pooled ether decreased') const ether2Stat = await pool.getBeaconStat() assert.equals(ether2Stat.depositedValidators, 2, 'Another validator is deposited') From 07d647eed756f5bf4392727eb99aab9f072dff5b Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 27 Jun 2023 11:22:18 +0300 Subject: [PATCH 02/13] =?UTF-8?q?=F0=9F=93=9A:=20stETH=20allowance=20does?= =?UTF-8?q?=20not=20stopped=20on=20pause?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/0.4.24/StETH.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/0.4.24/StETH.sol b/contracts/0.4.24/StETH.sol index 48fe07307..0cf94d2f6 100644 --- a/contracts/0.4.24/StETH.sol +++ b/contracts/0.4.24/StETH.sol @@ -41,7 +41,7 @@ import "./utils/Pausable.sol"; * emitting an event for each token holder and thus running an unbounded loop. * * The token inherits from `Pausable` and uses `whenNotStopped` modifier for methods - * which change `shares` or `allowances`. `_stop` and `_resume` functions are overridden + * which change `shares`. `_stop` and `_resume` functions are overridden * in `Lido.sol` and might be called by an account with the `PAUSE_ROLE` assigned by the * DAO. This is useful for emergency scenarios, e.g. a protocol bug, where one might want * to freeze all token transfers and approvals until the emergency is resolved. From 798d1a0677ec906825429c1dc7da0772cd465824 Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 27 Jun 2023 11:23:12 +0300 Subject: [PATCH 03/13] =?UTF-8?q?=F0=9F=93=9A(StETH):=20more=20consistency?= =?UTF-8?q?=20for=20transfer*=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/0.4.24/StETH.sol | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/contracts/0.4.24/StETH.sol b/contracts/0.4.24/StETH.sol index 0cf94d2f6..29fdf4c14 100644 --- a/contracts/0.4.24/StETH.sol +++ b/contracts/0.4.24/StETH.sol @@ -176,7 +176,7 @@ contract StETH is IERC20, Pausable { * * Requirements: * - * - `_recipient` cannot be the zero address. + * - `_recipient` cannot be the zero address or stETH contract itself. * - the caller must have a balance of at least `_amount`. * - the contract must not be paused. * @@ -227,7 +227,8 @@ contract StETH is IERC20, Pausable { * * Requirements: * - * - `_sender` and `_recipient` cannot be the zero addresses. + * - `_sender` cannot be the zero addresses. + * - `_recipient` cannot be the zero addresses or stETH contract itself. * - `_sender` must have a balance of at least `_amount`. * - the caller must have allowance for `_sender`'s tokens of at least `_amount`. * - the contract must not be paused. @@ -321,7 +322,7 @@ contract StETH is IERC20, Pausable { * * Requirements: * - * - `_recipient` cannot be the zero address. + * - `_recipient` cannot be the zero address or stETH contract itself. * - the caller must have at least `_sharesAmount` shares. * - the contract must not be paused. * @@ -335,15 +336,19 @@ contract StETH is IERC20, Pausable { } /** - * @notice Moves `_sharesAmount` token shares from the `_sender` account to the `_recipient` account. + * @notice Moves `_sharesAmount` token shares from the `_sender` account to the `_recipient` using + * the allowance mechanism. The amount of tokens equivalent to `_sharesAmount` is then deducted + * from the caller's allowance. * * @return amount of transferred tokens. * Emits a `TransferShares` event. * Emits a `Transfer` event. + * Emits an `Approval` event indicating the updated allowance. * * Requirements: * - * - `_sender` and `_recipient` cannot be the zero addresses. + * - `_sender` cannot be the zero address. + * - `_recipient` cannot be the zero address or stETH contract itself. * - `_sender` must have at least `_sharesAmount` shares. * - the caller must have allowance for `_sender`'s tokens of at least `getPooledEthByShares(_sharesAmount)`. * - the contract must not be paused. From 63f996c568bcef2898f24594e075f4ffd97b05cf Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 27 Jun 2023 11:24:37 +0300 Subject: [PATCH 04/13] =?UTF-8?q?=F0=9F=93=9A(Lido):=20fix=20getLidoLocato?= =?UTF-8?q?r()=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/0.4.24/Lido.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/0.4.24/Lido.sol b/contracts/0.4.24/Lido.sol index 42703c3a2..8d481df9f 100644 --- a/contracts/0.4.24/Lido.sol +++ b/contracts/0.4.24/Lido.sol @@ -646,8 +646,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @notice Gets authorized oracle address - * @return address of oracle contract + * @notice address of LidoLocator */ function getLidoLocator() public view returns (ILidoLocator) { return ILidoLocator(LIDO_LOCATOR_POSITION.getStorageAddress()); From d941ba1f67f00da485453eab7c426785682375f8 Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 27 Jun 2023 11:25:23 +0300 Subject: [PATCH 05/13] =?UTF-8?q?=F0=9F=93=9A(Lido):=20various=20comment?= =?UTF-8?q?=20improvements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/0.4.24/Lido.sol | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/contracts/0.4.24/Lido.sol b/contracts/0.4.24/Lido.sol index 8d481df9f..dd7861888 100644 --- a/contracts/0.4.24/Lido.sol +++ b/contracts/0.4.24/Lido.sol @@ -602,13 +602,12 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @notice Unsafely change deposited validators + * @notice Unsafely change deposited validators counter * - * The method unsafely changes deposited validator counter. - * Can be required when onboarding external validators to Lido + * @dev Can be required when onboarding external validators to Lido * (i.e., had deposited before and rotated their type-0x00 withdrawal credentials to Lido) * - * @param _newDepositedValidators new value + * @param _newDepositedValidators new value for deposited validators counter */ function unsafeChangeDepositedValidators(uint256 _newDepositedValidators) external { _auth(UNSAFE_CHANGE_DEPOSITED_VALIDATORS_ROLE); @@ -626,7 +625,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @notice Get the amount of Ether temporary buffered on this contract balance + * @notice Get the amount of ether temporary buffered on this contract balance * @dev Buffered balance is kept on the contract from the moment the funds are received from user * until the moment they are actually sent to the official Deposit contract. * @return amount of buffered funds in wei @@ -637,8 +636,8 @@ contract Lido is Versioned, StETHPermit, AragonApp { /** * @notice Get total amount of execution layer rewards collected to Lido contract - * @dev Ether got through LidoExecutionLayerRewardsVault is kept on this contract's balance the same way - * as other buffered Ether is kept (until it gets deposited) + * @dev ether got through LidoExecutionLayerRewardsVault is kept on this contract's balance the same way + * as other buffered ether is kept (until it gets deposited) * @return amount of funds received as execution layer rewards in wei */ function getTotalELRewardsCollected() public view returns (uint256) { @@ -667,16 +666,16 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @dev Check that Lido allows depositing buffered ether to the consensus layer - * Depends on the bunker state and protocol's pause state + * @return true if depositing buffered ether to the consensus layer is allowed + * @dev Depends on the bunker state and protocol's pause state */ function canDeposit() public view returns (bool) { return !_withdrawalQueue().isBunkerModeActive() && !isStopped(); } /** - * @dev Returns depositable ether amount. - * Takes into account unfinalized stETH required by WithdrawalQueue + * @return the amount of ether available to deposit + * @dev Takes into account unfinalized stETH on WithdrawalQueue */ function getDepositableEther() public view returns (uint256) { uint256 bufferedEther = _getBufferedEther(); @@ -685,7 +684,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @dev Invokes a deposit call to the Staking Router contract and updates buffered counters + * @notice Deposit buffered ether to StakingRouter's module with id of `_stakingModuleId` * @param _maxDepositsCount max deposits count * @param _stakingModuleId id of the staking module to be deposited * @param _depositCalldata module calldata From 21b05c67eaa7e8a23dbd3b29e50d626b104d56d4 Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 27 Jun 2023 12:57:53 +0300 Subject: [PATCH 06/13] =?UTF-8?q?=F0=9F=93=9A(Vaults):=20more=20consistenc?= =?UTF-8?q?y=20on=20recover=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0.8.9/LidoExecutionLayerRewardsVault.sol | 24 +++++++++---------- contracts/0.8.9/WithdrawalVault.sol | 12 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/contracts/0.8.9/LidoExecutionLayerRewardsVault.sol b/contracts/0.8.9/LidoExecutionLayerRewardsVault.sol index 7826f57de..e31425c6a 100644 --- a/contracts/0.8.9/LidoExecutionLayerRewardsVault.sol +++ b/contracts/0.8.9/LidoExecutionLayerRewardsVault.sol @@ -94,12 +94,12 @@ contract LidoExecutionLayerRewardsVault { } /** - * Transfers a given `_amount` of an ERC20-token (defined by the `_token` contract address) - * currently belonging to the burner contract address to the Lido treasury address. - * - * @param _token an ERC20-compatible token - * @param _amount token amount - */ + * @notice Transfers a given `_amount` of an ERC20-token (defined by the `_token` contract address) + * currently belonging to the vault contract address to the Lido treasury address. + * + * @param _token an ERC20-compatible token + * @param _amount token amount + */ function recoverERC20(address _token, uint256 _amount) external { require(_amount > 0, "ZERO_RECOVERY_AMOUNT"); @@ -109,12 +109,12 @@ contract LidoExecutionLayerRewardsVault { } /** - * Transfers a given token_id of an ERC721-compatible NFT (defined by the token contract address) - * currently belonging to the burner contract address to the Lido treasury address. - * - * @param _token an ERC721-compatible token - * @param _tokenId minted token id - */ + * @notice Transfers the given tokenId of the ERC721-compatible NFT (defined by the provided token contract address) + * currently belonging to the vault contract address to the Lido treasury address. + * + * @param _token an ERC721-compatible token + * @param _tokenId minted token id + */ function recoverERC721(address _token, uint256 _tokenId) external { emit ERC721Recovered(msg.sender, _token, _tokenId); diff --git a/contracts/0.8.9/WithdrawalVault.sol b/contracts/0.8.9/WithdrawalVault.sol index c5485b785..c4357dbe6 100644 --- a/contracts/0.8.9/WithdrawalVault.sol +++ b/contracts/0.8.9/WithdrawalVault.sol @@ -30,13 +30,13 @@ contract WithdrawalVault is Versioned { // Events /** - * Emitted when the ERC20 `token` recovered (i.e. transferred) + * @notice Emitted when the ERC20 `token` recovered (i.e. transferred) * to the Lido treasury address by `requestedBy` sender. */ event ERC20Recovered(address indexed requestedBy, address indexed token, uint256 amount); /** - * Emitted when the ERC721-compatible `token` (NFT) recovered (i.e. transferred) + * @notice Emitted when the ERC721-compatible `token` (NFT) recovered (i.e. transferred) * to the Lido treasury address by `requestedBy` sender. */ event ERC721Recovered(address indexed requestedBy, address indexed token, uint256 tokenId); @@ -94,8 +94,8 @@ contract WithdrawalVault is Versioned { } /** - * Transfers a given `_amount` of an ERC20-token (defined by the `_token` contract address) - * currently belonging to the burner contract address to the Lido treasury address. + * @notice Transfers a given `_amount` of an ERC20-token (defined by the `_token` contract address) + * currently belonging to the vault contract address to the Lido treasury address. * * @param _token an ERC20-compatible token * @param _amount token amount @@ -111,8 +111,8 @@ contract WithdrawalVault is Versioned { } /** - * Transfers a given token_id of an ERC721-compatible NFT (defined by the token contract address) - * currently belonging to the burner contract address to the Lido treasury address. + * @notice Transfers the given tokenId of the ERC721-compatible NFT (defined by the provided token contract address) + * currently belonging to the vault contract address to the Lido treasury address. * * @param _token an ERC721-compatible token * @param _tokenId minted token id From 584f20ed2e62f9d4ba69912ba1948378c62fc308 Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 27 Jun 2023 13:01:03 +0300 Subject: [PATCH 07/13] =?UTF-8?q?=F0=9F=93=9A=F0=9F=92=85:=20formatting=20?= =?UTF-8?q?for=20burner=20and=20el=20reward=20vault?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/0.8.9/Burner.sol | 284 +++++++++--------- .../0.8.9/LidoExecutionLayerRewardsVault.sol | 65 ++-- 2 files changed, 161 insertions(+), 188 deletions(-) diff --git a/contracts/0.8.9/Burner.sol b/contracts/0.8.9/Burner.sol index 696a2eb2d..ce9120add 100644 --- a/contracts/0.8.9/Burner.sol +++ b/contracts/0.8.9/Burner.sol @@ -13,42 +13,42 @@ import {AccessControlEnumerable} from "./utils/access/AccessControlEnumerable.so import {IBurner} from "../common/interfaces/IBurner.sol"; /** - * @title Interface defining ERC20-compatible StETH token - */ + * @title Interface defining ERC20-compatible StETH token + */ interface IStETH is IERC20 { /** - * @notice Get stETH amount by the provided shares amount - * @param _sharesAmount shares amount - * @dev dual to `getSharesByPooledEth`. - */ + * @notice Get stETH amount by the provided shares amount + * @param _sharesAmount shares amount + * @dev dual to `getSharesByPooledEth`. + */ function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); /** - * @notice Get shares amount by the provided stETH amount - * @param _pooledEthAmount stETH amount - * @dev dual to `getPooledEthByShares`. - */ + * @notice Get shares amount by the provided stETH amount + * @param _pooledEthAmount stETH amount + * @dev dual to `getPooledEthByShares`. + */ function getSharesByPooledEth(uint256 _pooledEthAmount) external view returns (uint256); /** - * @notice Get shares amount of the provided account - * @param _account provided account address. - */ + * @notice Get shares amount of the provided account + * @param _account provided account address. + */ function sharesOf(address _account) external view returns (uint256); /** - * @notice Transfer `_sharesAmount` stETH shares from `_sender` to `_receiver` using allowance. - */ - function transferSharesFrom( - address _sender, address _recipient, uint256 _sharesAmount - ) external returns (uint256); + * @notice Transfer `_sharesAmount` stETH shares from `_sender` to `_receiver` using allowance. + */ + function transferSharesFrom(address _sender, address _recipient, uint256 _sharesAmount) + external + returns (uint256); } /** - * @notice A dedicated contract for stETH burning requests scheduling - * - * @dev Burning stETH means 'decrease total underlying shares amount to perform stETH positive token rebase' - */ + * @notice A dedicated contract for stETH burning requests scheduling + * + * @dev Burning stETH means 'decrease total underlying shares amount to perform stETH positive token rebase' + */ contract Burner is IBurner, AccessControlEnumerable { using SafeERC20 for IERC20; @@ -73,63 +73,42 @@ contract Burner is IBurner, AccessControlEnumerable { address public immutable TREASURY; /** - * Emitted when a new stETH burning request is added by the `requestedBy` address. - */ + * @notice Emitted when a new stETH burning request is added by the `requestedBy` address. + */ event StETHBurnRequested( - bool indexed isCover, - address indexed requestedBy, - uint256 amountOfStETH, - uint256 amountOfShares + bool indexed isCover, address indexed requestedBy, uint256 amountOfStETH, uint256 amountOfShares ); /** - * Emitted when the stETH `amount` (corresponding to `amountOfShares` shares) burnt for the `isCover` reason. - */ - event StETHBurnt( - bool indexed isCover, - uint256 amountOfStETH, - uint256 amountOfShares - ); + * @notice Emitted when the stETH `amount` (corresponding to `amountOfShares` shares) burnt for the `isCover` reason. + */ + event StETHBurnt(bool indexed isCover, uint256 amountOfStETH, uint256 amountOfShares); /** - * Emitted when the excessive stETH `amount` (corresponding to `amountOfShares` shares) recovered (i.e. transferred) - * to the Lido treasure address by `requestedBy` sender. - */ - event ExcessStETHRecovered( - address indexed requestedBy, - uint256 amountOfStETH, - uint256 amountOfShares - ); + * @notice Emitted when the excessive stETH `amount` (corresponding to `amountOfShares` shares) recovered (i.e. transferred) + * to the Lido treasure address by `requestedBy` sender. + */ + event ExcessStETHRecovered(address indexed requestedBy, uint256 amountOfStETH, uint256 amountOfShares); /** - * Emitted when the ERC20 `token` recovered (i.e. transferred) - * to the Lido treasure address by `requestedBy` sender. - */ - event ERC20Recovered( - address indexed requestedBy, - address indexed token, - uint256 amount - ); + * @notice Emitted when the ERC20 `token` recovered (i.e. transferred) + * to the Lido treasure address by `requestedBy` sender. + */ + event ERC20Recovered(address indexed requestedBy, address indexed token, uint256 amount); /** - * Emitted when the ERC721-compatible `token` (NFT) recovered (i.e. transferred) - * to the Lido treasure address by `requestedBy` sender. - */ - event ERC721Recovered( - address indexed requestedBy, - address indexed token, - uint256 tokenId - ); + * @notice Emitted when the ERC721-compatible `token` (NFT) recovered (i.e. transferred) + * to the Lido treasure address by `requestedBy` sender. + */ + event ERC721Recovered(address indexed requestedBy, address indexed token, uint256 tokenId); /** - * Ctor - * - * @param _admin the Lido DAO Aragon agent contract address - * @param _treasury the Lido treasury address (see StETH/ERC20/ERC721-recovery interfaces) - * @param _stETH stETH token address - * @param _totalCoverSharesBurnt Shares burnt counter init value (cover case) - * @param _totalNonCoverSharesBurnt Shares burnt counter init value (non-cover case) - */ + * @param _admin the Lido DAO Aragon agent contract address + * @param _treasury the Lido treasury address (see StETH/ERC20/ERC721-recovery interfaces) + * @param _stETH stETH token address + * @param _totalCoverSharesBurnt Shares burnt counter init value (cover case) + * @param _totalNonCoverSharesBurnt Shares burnt counter init value (non-cover case) + */ constructor( address _admin, address _treasury, @@ -152,76 +131,81 @@ contract Burner is IBurner, AccessControlEnumerable { } /** - * @notice BE CAREFUL, the provided stETH will be burnt permanently. - * - * Transfers `_stETHAmountToBurn` stETH tokens from the message sender and irreversibly locks these - * on the burner contract address. Internally converts `_stETHAmountToBurn` amount into underlying - * shares amount (`_stETHAmountToBurnAsShares`) and marks the converted amount for burning - * by increasing the `coverSharesBurnRequested` counter. - * - * @param _stETHAmountToBurn stETH tokens to burn - * - */ + * @notice BE CAREFUL, the provided stETH will be burnt permanently. + * + * Transfers `_stETHAmountToBurn` stETH tokens from the message sender and irreversibly locks these + * on the burner contract address. Internally converts `_stETHAmountToBurn` amount into underlying + * shares amount (`_stETHAmountToBurnAsShares`) and marks the converted amount for burning + * by increasing the `coverSharesBurnRequested` counter. + * + * @param _stETHAmountToBurn stETH tokens to burn + */ function requestBurnMyStETHForCover(uint256 _stETHAmountToBurn) external onlyRole(REQUEST_BURN_MY_STETH_ROLE) { IStETH(STETH).transferFrom(msg.sender, address(this), _stETHAmountToBurn); uint256 sharesAmount = IStETH(STETH).getSharesByPooledEth(_stETHAmountToBurn); - _requestBurn(sharesAmount, _stETHAmountToBurn, true /* _isCover */); + _requestBurn(sharesAmount, _stETHAmountToBurn, true /* _isCover */ ); } /** - * @notice BE CAREFUL, the provided stETH will be burnt permanently. - * - * Transfers `_sharesAmountToBurn` stETH shares from `_from` and irreversibly locks these - * on the burner contract address. Marks the shares amount for burning - * by increasing the `coverSharesBurnRequested` counter. - * - * @param _from address to transfer shares from - * @param _sharesAmountToBurn stETH shares to burn - * - */ - function requestBurnSharesForCover(address _from, uint256 _sharesAmountToBurn) external onlyRole(REQUEST_BURN_SHARES_ROLE) { + * @notice BE CAREFUL, the provided stETH will be burnt permanently. + * + * Transfers `_sharesAmountToBurn` stETH shares from `_from` and irreversibly locks these + * on the burner contract address. Marks the shares amount for burning + * by increasing the `coverSharesBurnRequested` counter. + * + * @param _from address to transfer shares from + * @param _sharesAmountToBurn stETH shares to burn + * + */ + function requestBurnSharesForCover(address _from, uint256 _sharesAmountToBurn) + external + onlyRole(REQUEST_BURN_SHARES_ROLE) + { uint256 stETHAmount = IStETH(STETH).transferSharesFrom(_from, address(this), _sharesAmountToBurn); _requestBurn(_sharesAmountToBurn, stETHAmount, true /* _isCover */); } /** - * @notice BE CAREFUL, the provided stETH will be burnt permanently. - * - * Transfers `_stETHAmountToBurn` stETH tokens from the message sender and irreversibly locks these - * on the burner contract address. Internally converts `_stETHAmountToBurn` amount into underlying - * shares amount (`_stETHAmountToBurnAsShares`) and marks the converted amount for burning - * by increasing the `nonCoverSharesBurnRequested` counter. - * - * @param _stETHAmountToBurn stETH tokens to burn - * - */ + * @notice BE CAREFUL, the provided stETH will be burnt permanently. + * + * Transfers `_stETHAmountToBurn` stETH tokens from the message sender and irreversibly locks these + * on the burner contract address. Internally converts `_stETHAmountToBurn` amount into underlying + * shares amount (`_stETHAmountToBurnAsShares`) and marks the converted amount for burning + * by increasing the `nonCoverSharesBurnRequested` counter. + * + * @param _stETHAmountToBurn stETH tokens to burn + * + */ function requestBurnMyStETH(uint256 _stETHAmountToBurn) external onlyRole(REQUEST_BURN_MY_STETH_ROLE) { IStETH(STETH).transferFrom(msg.sender, address(this), _stETHAmountToBurn); uint256 sharesAmount = IStETH(STETH).getSharesByPooledEth(_stETHAmountToBurn); - _requestBurn(sharesAmount, _stETHAmountToBurn, false /* _isCover */); + _requestBurn(sharesAmount, _stETHAmountToBurn, false /* _isCover */ ); } /** - * @notice BE CAREFUL, the provided stETH will be burnt permanently. - * - * Transfers `_sharesAmountToBurn` stETH shares from `_from` and irreversibly locks these - * on the burner contract address. Marks the shares amount for burning - * by increasing the `nonCoverSharesBurnRequested` counter. - * - * @param _from address to transfer shares from - * @param _sharesAmountToBurn stETH shares to burn - * - */ - function requestBurnShares(address _from, uint256 _sharesAmountToBurn) external onlyRole(REQUEST_BURN_SHARES_ROLE) { + * @notice BE CAREFUL, the provided stETH will be burnt permanently. + * + * Transfers `_sharesAmountToBurn` stETH shares from `_from` and irreversibly locks these + * on the burner contract address. Marks the shares amount for burning + * by increasing the `nonCoverSharesBurnRequested` counter. + * + * @param _from address to transfer shares from + * @param _sharesAmountToBurn stETH shares to burn + * + */ + function requestBurnShares(address _from, uint256 _sharesAmountToBurn) + external + onlyRole(REQUEST_BURN_SHARES_ROLE) + { uint256 stETHAmount = IStETH(STETH).transferSharesFrom(_from, address(this), _sharesAmountToBurn); - _requestBurn(_sharesAmountToBurn, stETHAmount, false /* _isCover */); + _requestBurn(_sharesAmountToBurn, stETHAmount, false /* _isCover */ ); } /** - * Transfers the excess stETH amount (e.g. belonging to the burner contract address - * but not marked for burning) to the Lido treasury address set upon the - * contract construction. - */ + * @notice Transfers the excess stETH amount (e.g. belonging to the burner contract address + * but not marked for burning) to the Lido treasury address set upon the + * contract construction. + */ function recoverExcessStETH() external { uint256 excessStETH = getExcessStETH(); @@ -235,19 +219,19 @@ contract Burner is IBurner, AccessControlEnumerable { } /** - * Intentionally deny incoming ether - */ + * @dev Intentionally deny incoming ether + */ receive() external payable { revert DirectETHTransfer(); } /** - * Transfers a given `_amount` of an ERC20-token (defined by the `_token` contract address) - * currently belonging to the burner contract address to the Lido treasury address. - * - * @param _token an ERC20-compatible token - * @param _amount token amount - */ + * @notice Transfers a given `_amount` of an ERC20-token (defined by the `_token` contract address) + * currently belonging to the burner contract address to the Lido treasury address. + * + * @param _token an ERC20-compatible token + * @param _amount token amount + */ function recoverERC20(address _token, uint256 _amount) external { if (_amount == 0) revert ZeroRecoveryAmount(); if (_token == STETH) revert StETHRecoveryWrongFunc(); @@ -258,12 +242,12 @@ contract Burner is IBurner, AccessControlEnumerable { } /** - * Transfers a given token_id of an ERC721-compatible NFT (defined by the token contract address) - * currently belonging to the burner contract address to the Lido treasury address. - * - * @param _token an ERC721-compatible token - * @param _tokenId minted token id - */ + * @notice Transfers a given `_tokenId` of an ERC721-compatible NFT (defined by the `_token` contract address) + * currently belonging to the burner contract address to the Lido treasury address. + * + * @param _token an ERC721-compatible token + * @param _tokenId minted token id + */ function recoverERC721(address _token, uint256 _tokenId) external { if (_token == STETH) revert StETHRecoveryWrongFunc(); @@ -273,7 +257,7 @@ contract Burner is IBurner, AccessControlEnumerable { } /** - * Commit cover/non-cover burning requests and logs cover/non-cover shares amount just burnt. + * @notice Commit cover/non-cover burning requests and logs cover/non-cover shares amount just burnt. * * NB: The real burn enactment to be invoked after the call (via internal Lido._burnShares()) * @@ -305,20 +289,18 @@ contract Burner is IBurner, AccessControlEnumerable { totalCoverSharesBurnt += sharesToBurnNowForCover; uint256 stETHToBurnNowForCover = IStETH(STETH).getPooledEthByShares(sharesToBurnNowForCover); - emit StETHBurnt(true /* isCover */, stETHToBurnNowForCover, sharesToBurnNowForCover); + emit StETHBurnt(true, /* isCover */ stETHToBurnNowForCover, sharesToBurnNowForCover); coverSharesBurnRequested -= sharesToBurnNowForCover; sharesToBurnNow += sharesToBurnNowForCover; } if (memNonCoverSharesBurnRequested > 0 && sharesToBurnNow < _sharesToBurn) { - uint256 sharesToBurnNowForNonCover = Math.min( - _sharesToBurn - sharesToBurnNow, - memNonCoverSharesBurnRequested - ); + uint256 sharesToBurnNowForNonCover = + Math.min(_sharesToBurn - sharesToBurnNow, memNonCoverSharesBurnRequested); totalNonCoverSharesBurnt += sharesToBurnNowForNonCover; uint256 stETHToBurnNowForNonCover = IStETH(STETH).getPooledEthByShares(sharesToBurnNowForNonCover); - emit StETHBurnt(false /* isCover */, stETHToBurnNowForNonCover, sharesToBurnNowForNonCover); + emit StETHBurnt(false, /* isCover */ stETHToBurnNowForNonCover, sharesToBurnNowForNonCover); nonCoverSharesBurnRequested -= sharesToBurnNowForNonCover; sharesToBurnNow += sharesToBurnNowForNonCover; @@ -327,33 +309,37 @@ contract Burner is IBurner, AccessControlEnumerable { } /** - * Returns the current amount of shares locked on the contract to be burnt. - */ - function getSharesRequestedToBurn() external view virtual override returns ( - uint256 coverShares, uint256 nonCoverShares - ) { + * @notice Returns the current amount of shares locked on the contract to be burnt. + */ + function getSharesRequestedToBurn() + external + view + virtual + override + returns (uint256 coverShares, uint256 nonCoverShares) + { coverShares = coverSharesBurnRequested; nonCoverShares = nonCoverSharesBurnRequested; } /** - * Returns the total cover shares ever burnt. - */ + * @notice Returns the total cover shares ever burnt. + */ function getCoverSharesBurnt() external view virtual override returns (uint256) { return totalCoverSharesBurnt; } /** - * Returns the total non-cover shares ever burnt. - */ + * @notice Returns the total non-cover shares ever burnt. + */ function getNonCoverSharesBurnt() external view virtual override returns (uint256) { return totalNonCoverSharesBurnt; } /** - * Returns the stETH amount belonging to the burner contract address but not marked for burning. - */ - function getExcessStETH() public view returns (uint256) { + * @notice Returns the stETH amount belonging to the burner contract address but not marked for burning. + */ + function getExcessStETH() public view returns (uint256) { return IStETH(STETH).getPooledEthByShares(_getExcessStETHShares()); } diff --git a/contracts/0.8.9/LidoExecutionLayerRewardsVault.sol b/contracts/0.8.9/LidoExecutionLayerRewardsVault.sol index e31425c6a..52eef0226 100644 --- a/contracts/0.8.9/LidoExecutionLayerRewardsVault.sol +++ b/contracts/0.8.9/LidoExecutionLayerRewardsVault.sol @@ -10,14 +10,13 @@ import "@openzeppelin/contracts-v4.4/token/ERC20/utils/SafeERC20.sol"; interface ILido { /** - * @notice A payable function supposed to be called only by LidoExecLayerRewardsVault contract - * @dev We need a dedicated function because funds received by the default payable function - * are treated as a user deposit - */ + * @notice A payable function supposed to be called only by LidoExecLayerRewardsVault contract + * @dev We need a dedicated function because funds received by the default payable function + * are treated as a user deposit + */ function receiveELRewards() external payable; } - /** * @title A vault for temporary storage of execution layer rewards (MEV and tx priority fee) */ @@ -28,38 +27,26 @@ contract LidoExecutionLayerRewardsVault { address public immutable TREASURY; /** - * Emitted when the ERC20 `token` recovered (i.e. transferred) - * to the Lido treasury address by `requestedBy` sender. - */ - event ERC20Recovered( - address indexed requestedBy, - address indexed token, - uint256 amount - ); + * @notice Emitted when the ERC20 `token` recovered (i.e. transferred) + * to the Lido treasury address by `requestedBy` sender. + */ + event ERC20Recovered(address indexed requestedBy, address indexed token, uint256 amount); /** - * Emitted when the ERC721-compatible `token` (NFT) recovered (i.e. transferred) - * to the Lido treasury address by `requestedBy` sender. - */ - event ERC721Recovered( - address indexed requestedBy, - address indexed token, - uint256 tokenId - ); + * @notice Emitted when the ERC721-compatible `token` (NFT) recovered (i.e. transferred) + * to the Lido treasury address by `requestedBy` sender. + */ + event ERC721Recovered(address indexed requestedBy, address indexed token, uint256 tokenId); /** - * Emitted when the vault received ETH - */ - event ETHReceived( - uint256 amount - ); + * @notice Emitted when the vault received ETH + */ + event ETHReceived(uint256 amount); /** - * Ctor - * - * @param _lido the Lido token (stETH) address - * @param _treasury the Lido treasury address (see ERC20/ERC721-recovery interfaces) - */ + * @param _lido the Lido token (stETH) address + * @param _treasury the Lido treasury address (see ERC20/ERC721-recovery interfaces) + */ constructor(address _lido, address _treasury) { require(_lido != address(0), "LIDO_ZERO_ADDRESS"); require(_treasury != address(0), "TREASURY_ZERO_ADDRESS"); @@ -69,19 +56,19 @@ contract LidoExecutionLayerRewardsVault { } /** - * @notice Allows the contract to receive ETH - * @dev execution layer rewards may be sent as plain ETH transfers - */ + * @notice Allows the contract to receive ETH + * @dev execution layer rewards may be sent as plain ETH transfers + */ receive() external payable { emit ETHReceived(msg.value); } /** - * @notice Withdraw all accumulated rewards to Lido contract - * @dev Can be called only by the Lido contract - * @param _maxAmount Max amount of ETH to withdraw - * @return amount of funds received as execution layer rewards (in wei) - */ + * @notice Withdraw all accumulated rewards to Lido contract + * @dev Can be called only by the Lido contract + * @param _maxAmount Max amount of ETH to withdraw + * @return amount of funds received as execution layer rewards (in wei) + */ function withdrawRewards(uint256 _maxAmount) external returns (uint256 amount) { require(msg.sender == LIDO, "ONLY_LIDO_CAN_WITHDRAW"); From 74d63ffe74ab799e1067e243de0696a3742761e0 Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Thu, 20 Jul 2023 17:05:49 +0300 Subject: [PATCH 08/13] =?UTF-8?q?=F0=9F=93=9A(WQ):=20typos=20and=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/0.8.9/WithdrawalQueue.sol | 22 +++++++++-------- contracts/0.8.9/WithdrawalQueueBase.sol | 30 +++++++++++------------ contracts/0.8.9/WithdrawalQueueERC721.sol | 6 +++-- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/contracts/0.8.9/WithdrawalQueue.sol b/contracts/0.8.9/WithdrawalQueue.sol index 733c4a830..a1474d0eb 100644 --- a/contracts/0.8.9/WithdrawalQueue.sol +++ b/contracts/0.8.9/WithdrawalQueue.sol @@ -92,7 +92,9 @@ abstract contract WithdrawalQueue is AccessControlEnumerable, PausableUntil, Wit } /// @notice Resume withdrawal requests placement and finalization - /// Contract is deployed in paused state and should be resumed explicitly + /// @dev The contract is deployed in paused state and should be resumed explicitly + /// @dev Reverts if sender has no `RESUME_ROLE` + /// @dev Reverts if contract is already resumed function resume() external { _checkRole(RESUME_ROLE, msg.sender); _resume(); @@ -101,7 +103,7 @@ abstract contract WithdrawalQueue is AccessControlEnumerable, PausableUntil, Wit /// @notice Pause withdrawal requests placement and finalization. Claiming finalized requests will still be available /// @param _duration pause duration in seconds (use `PAUSE_INFINITELY` for unlimited) /// @dev Reverts if contract is already paused - /// @dev Reverts reason if sender has no `PAUSE_ROLE` + /// @dev Reverts if sender has no `PAUSE_ROLE` /// @dev Reverts if zero duration is passed function pauseFor(uint256 _duration) external onlyRole(PAUSE_ROLE) { _pauseFor(_duration); @@ -192,7 +194,7 @@ abstract contract WithdrawalQueue is AccessControlEnumerable, PausableUntil, Wit return requestWithdrawalsWstETH(_amounts, _owner); } - /// @notice Returns all withdrawal requests that belongs to the `_owner` address + /// @notice Returns all withdrawal requests that belong to the `_owner` address /// /// WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed /// to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that @@ -202,7 +204,7 @@ abstract contract WithdrawalQueue is AccessControlEnumerable, PausableUntil, Wit return _getRequestsByOwner()[_owner].values(); } - /// @notice Returns status for requests with provided ids + /// @notice Returns status of requests with provided ids /// @param _requestIds array of withdrawal request ids function getWithdrawalStatus(uint256[] calldata _requestIds) external @@ -215,7 +217,7 @@ abstract contract WithdrawalQueue is AccessControlEnumerable, PausableUntil, Wit } } - /// @notice Returns amount of ether available for claim for each provided request id + /// @notice Returns the amount of ether available for claiming for each provided request id /// @param _requestIds array of request ids /// @param _hints checkpoint hints. can be found with `findCheckpointHints(_requestIds, 1, getLastCheckpointIndex())` /// @return claimableEthValues amount of claimable ether for each request, amount is equal to 0 if request @@ -311,10 +313,10 @@ abstract contract WithdrawalQueue is AccessControlEnumerable, PausableUntil, Wit } /// @notice Update bunker mode state and last report timestamp on oracle report - /// @dev should be called by oracle + /// @dev Reverts if sender has no `RESUME_ROLE` /// - /// @param _isBunkerModeNow is bunker mode reported by oracle - /// @param _bunkerStartTimestamp timestamp of start of the bunker mode + /// @param _isBunkerModeNow is bunker mode reported by the oracle + /// @param _bunkerStartTimestamp timestamp of the bunker mode activation /// @param _currentReportTimestamp timestamp of the current report ref slot function onOracleReport(bool _isBunkerModeNow, uint256 _bunkerStartTimestamp, uint256 _currentReportTimestamp) external @@ -342,12 +344,12 @@ abstract contract WithdrawalQueue is AccessControlEnumerable, PausableUntil, Wit } } - /// @notice Check if bunker mode is active + /// @notice Returns `true` if bunker mode is active function isBunkerModeActive() public view returns (bool) { return bunkerModeSinceTimestamp() < BUNKER_MODE_DISABLED_TIMESTAMP; } - /// @notice Get bunker mode activation timestamp + /// @notice Returns bunker mode activation timestamp /// @dev returns `BUNKER_MODE_DISABLED_TIMESTAMP` if bunker mode is disable (i.e., protocol in turbo mode) function bunkerModeSinceTimestamp() public view returns (uint256) { return BUNKER_MODE_SINCE_TIMESTAMP_POSITION.getStorageUint256(); diff --git a/contracts/0.8.9/WithdrawalQueueBase.sol b/contracts/0.8.9/WithdrawalQueueBase.sol index bd443abc4..3ec3222b3 100644 --- a/contracts/0.8.9/WithdrawalQueueBase.sol +++ b/contracts/0.8.9/WithdrawalQueueBase.sol @@ -111,30 +111,30 @@ abstract contract WithdrawalQueueBase { error InvalidHint(uint256 _hint); error CantSendValueRecipientMayHaveReverted(); - /// @notice id of the last request - /// NB! requests are indexed from 1, so it returns 0 if there is no requests in the queue + /// @notice Returns the id of the last request in the queue + /// NB! requests are indexed from 1, so it returns 0 if there are no requests in the queue function getLastRequestId() public view returns (uint256) { return LAST_REQUEST_ID_POSITION.getStorageUint256(); } - /// @notice id of the last finalized request - /// NB! requests are indexed from 1, so it returns 0 if there is no finalized requests in the queue + /// @notice Returns the id of the last finalized request in the queue + /// NB! requests are indexed from 1, so it returns 0 if there are no finalized requests in the queue function getLastFinalizedRequestId() public view returns (uint256) { return LAST_FINALIZED_REQUEST_ID_POSITION.getStorageUint256(); } - /// @notice amount of ETH on this contract balance that is locked for withdrawal and available to claim + /// @notice Returns the amount of ether on the balance locked for withdrawal and available to claim function getLockedEtherAmount() public view returns (uint256) { return LOCKED_ETHER_AMOUNT_POSITION.getStorageUint256(); } - /// @notice length of the checkpoint array. Last possible value for the hint. - /// NB! checkpoints are indexed from 1, so it returns 0 if there is no checkpoints + /// @notice Returns the length of the checkpoint array. Last possible value for the hint. + /// NB! checkpoints are indexed from 1, so it returns 0 if there are no checkpoints yet function getLastCheckpointIndex() public view returns (uint256) { return LAST_CHECKPOINT_INDEX_POSITION.getStorageUint256(); } - /// @notice return the number of unfinalized requests in the queue + /// @notice Returns the number of unfinalized requests in the queue function unfinalizedRequestNumber() external view returns (uint256) { return getLastRequestId() - getLastFinalizedRequestId(); } @@ -183,15 +183,15 @@ abstract contract WithdrawalQueueBase { uint256 remainingEthBudget; /// @notice flag that is set to `true` if returned state is final and `false` if more calls are required bool finished; - /// @notice static array to store last request id in each batch + /// @notice the resulting array of batches, represented by the id of the last request in the batch uint256[MAX_BATCHES_LENGTH] batches; /// @notice length of the filled part of `batches` array uint256 batchesLength; } /// @notice Offchain view for the oracle daemon that calculates how many requests can be finalized within - /// the given budget, time period and share rate limits. Returned requests are split into batches. - /// Each batch consist of the requests that all have the share rate below the `_maxShareRate` or above it. + /// the given budget, time period, and share rate limits. Returned requests are split into batches. + /// All requests belonging to one batch must have their share rate above or below (or equal) to the `_maxShareRate`. /// Below you can see an example how 14 requests with different share rates will be split into 5 batches by /// this method /// @@ -285,11 +285,11 @@ abstract contract WithdrawalQueueBase { return _state; } - /// @notice Checks finalization batches, calculates required ether and the amount of shares to burn + /// @notice Checks finalization batches, calculates required amount of ether to lock and the number of shares to burn /// @param _batches finalization batches calculated offchain using `calculateFinalizationBatches()` - /// @param _maxShareRate max share rate that will be used for request finalization (1e27 precision) - /// @return ethToLock amount of ether that should be sent with `finalize()` method - /// @return sharesToBurn amount of shares that belongs to requests that will be finalized + /// @param _maxShareRate the max share rate (ETH per share) for the request finalization (1e27 precision) + /// @return ethToLock the amount of ether to be sent with `finalize()` method + /// @return sharesToBurn the number of shares to be burnt to match this finalization call function prefinalize(uint256[] calldata _batches, uint256 _maxShareRate) external view diff --git a/contracts/0.8.9/WithdrawalQueueERC721.sol b/contracts/0.8.9/WithdrawalQueueERC721.sol index ecaeef17d..ebe41c1e1 100644 --- a/contracts/0.8.9/WithdrawalQueueERC721.sol +++ b/contracts/0.8.9/WithdrawalQueueERC721.sol @@ -124,7 +124,7 @@ contract WithdrawalQueueERC721 is IERC721Metadata, IERC4906, WithdrawalQueue { } /// @notice Sets the Base URI for computing {tokenURI}. It does not expect the ending slash in provided string. - /// @dev If NFTDescriptor address isn't set the `baseURI` would be used for generating erc721 tokenURI. In case + /// @dev If NFTDescriptor address isn't set the `baseURI` would be used for generating the ERC-721 token URI. In case /// NFTDescriptor address is set it would be used as a first-priority method. function setBaseURI(string calldata _baseURI) external onlyRole(MANAGE_TOKEN_URI_ROLE) { _getBaseURI().value = _baseURI; @@ -144,8 +144,10 @@ contract WithdrawalQueueERC721 is IERC721Metadata, IERC4906, WithdrawalQueue { emit NftDescriptorAddressSet(_nftDescriptorAddress); } - /// @notice Finalize requests from last finalized one up to `_lastRequestIdToBeFinalized` + /// @notice Finalize requests from the last finalized one up to `_lastRequestIdToBeFinalized` /// @dev ether to finalize all the requests should be calculated using `prefinalize()` and sent along + /// @param _lastRequestIdToBeFinalized the last request id to finalize + /// @param _maxShareRate the max share rate (ETH per share) for the request finalization (1e27 precision) function finalize(uint256 _lastRequestIdToBeFinalized, uint256 _maxShareRate) external payable { _checkResumed(); _checkRole(FINALIZE_ROLE, msg.sender); From 4b5cebbc41fac992a133fc8bc23f7043eb6199bb Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 15 Aug 2023 13:24:50 +0300 Subject: [PATCH 09/13] =?UTF-8?q?=F0=9F=93=9A:=20comments=20for=20submit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/0.4.24/Lido.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/0.4.24/Lido.sol b/contracts/0.4.24/Lido.sol index dd7861888..f846574d9 100644 --- a/contracts/0.4.24/Lido.sol +++ b/contracts/0.4.24/Lido.sol @@ -444,10 +444,10 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @notice Send funds to the pool - * @dev Users are able to submit their funds by transacting to the fallback function. + * @notice Send funds to the pool and mints `StETH` tokens to `msg.sender` address + * @dev Users are able to submit their funds by sending ether to the contract address. * Unlike vanilla Ethereum Deposit contract, accepting only 32-Ether transactions, Lido - * accepts payments of any size. Submitted Ethers are stored in Buffer until someone calls + * accepts payments of any size. Submitted ether are stored in the buffer until someone calls * deposit() and pushes them to the Ethereum Deposit contract. */ // solhint-disable-next-line no-complex-fallback @@ -458,7 +458,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @notice Send funds to the pool with optional _referral parameter + * @notice Send funds to the pool with the optional `_referral` parameter and mints `StETH` tokens to `msg.sender` address * @dev This function is alternative way to submit funds. Supports optional referral address. * @return Amount of StETH shares generated */ From 448d5e3702cae07fbf655adf3643e3d458915d2e Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 15 Aug 2023 18:16:25 +0300 Subject: [PATCH 10/13] =?UTF-8?q?=F0=9F=93=9A:=20chores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/0.4.24/Lido.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/0.4.24/Lido.sol b/contracts/0.4.24/Lido.sol index f846574d9..ca292f881 100644 --- a/contracts/0.4.24/Lido.sol +++ b/contracts/0.4.24/Lido.sol @@ -444,7 +444,7 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @notice Send funds to the pool and mints `StETH` tokens to `msg.sender` address + * @notice Sends funds to the pool and mints `StETH` tokens to the `msg.sender` address * @dev Users are able to submit their funds by sending ether to the contract address. * Unlike vanilla Ethereum Deposit contract, accepting only 32-Ether transactions, Lido * accepts payments of any size. Submitted ether are stored in the buffer until someone calls @@ -458,8 +458,8 @@ contract Lido is Versioned, StETHPermit, AragonApp { } /** - * @notice Send funds to the pool with the optional `_referral` parameter and mints `StETH` tokens to `msg.sender` address - * @dev This function is alternative way to submit funds. Supports optional referral address. + * @notice Sends funds to the pool with the optional `_referral` parameter and mints `StETH` tokens to the `msg.sender` address + * @param _referral optonal referral address. See https://lido.fi/referral for details. * @return Amount of StETH shares generated */ function submit(address _referral) external payable returns (uint256) { From 5eda88d68799c30d43012f50770c7b92c7e93857 Mon Sep 17 00:00:00 2001 From: Alexey Potapkin Date: Tue, 15 Aug 2023 18:45:32 +0300 Subject: [PATCH 11/13] =?UTF-8?q?=F0=9F=93=9A(StETH):=20after-review=20fix?= =?UTF-8?q?es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- contracts/0.4.24/StETH.sol | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3ace63eb2..471fb8512 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Tests](https://github.com/lidofinance/lido-dao/workflows/Tests/badge.svg)](https://github.com/lidofinance/lido-dao/actions) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) -The Lido Ethereum Liquid Staking Protocol allows their users to earn staking rewards on the Beacon chain without locking ether or maintaining staking infrastru ether +The Lido Ethereum Liquid Staking Protocol allows their users to earn staking rewards on the Beacon Chain without locking ether or maintaining staking infrastructure. Users can deposit ether to the Lido smart contract and receive stETH tokens in return. The smart contract then stakes tokens with the DAO-picked node operators. Users' deposited funds are pooled by the DAO, node operators never have direct access to the users' assets. diff --git a/contracts/0.4.24/StETH.sol b/contracts/0.4.24/StETH.sol index 29fdf4c14..1e5fdb1f7 100644 --- a/contracts/0.4.24/StETH.sol +++ b/contracts/0.4.24/StETH.sol @@ -176,7 +176,7 @@ contract StETH is IERC20, Pausable { * * Requirements: * - * - `_recipient` cannot be the zero address or stETH contract itself. + * - `_recipient` cannot be the zero address or the stETH contract itself. * - the caller must have a balance of at least `_amount`. * - the contract must not be paused. * @@ -200,6 +200,9 @@ contract StETH is IERC20, Pausable { /** * @notice Sets `_amount` as the allowance of `_spender` over the caller's tokens. * + * @dev allowance can be set to "infinity" (INFINITE_ALLOWANCE). + * In this case allowance is not to be spent on transfer, that can save some gas. + * * @return a boolean value indicating whether the operation succeeded. * Emits an `Approval` event. * @@ -217,13 +220,13 @@ contract StETH is IERC20, Pausable { /** * @notice Moves `_amount` tokens from `_sender` to `_recipient` using the * allowance mechanism. `_amount` is then deducted from the caller's - * allowance. + * allowance if the allowance is not infinite. * * @return a boolean value indicating whether the operation succeeded. * * Emits a `Transfer` event. * Emits a `TransferShares` event. - * Emits an `Approval` event indicating the updated allowance. + * Emits an `Approval` event if allowance is updated. * * Requirements: * @@ -322,7 +325,7 @@ contract StETH is IERC20, Pausable { * * Requirements: * - * - `_recipient` cannot be the zero address or stETH contract itself. + * - `_recipient` cannot be the zero address or the stETH contract itself. * - the caller must have at least `_sharesAmount` shares. * - the contract must not be paused. * @@ -338,12 +341,12 @@ contract StETH is IERC20, Pausable { /** * @notice Moves `_sharesAmount` token shares from the `_sender` account to the `_recipient` using * the allowance mechanism. The amount of tokens equivalent to `_sharesAmount` is then deducted - * from the caller's allowance. + * from the caller's allowance if the allowance is not infinite. * * @return amount of transferred tokens. * Emits a `TransferShares` event. * Emits a `Transfer` event. - * Emits an `Approval` event indicating the updated allowance. + * Emits an `Approval` event if allowance is updated. * * Requirements: * From 219676eb9b8ffba0d6b924de56cdaf2b50d0413d Mon Sep 17 00:00:00 2001 From: George Avsetsin Date: Wed, 27 Sep 2023 18:48:18 +0300 Subject: [PATCH 12/13] fix: exited validators count typo in IStakingModule interface --- contracts/0.8.9/interfaces/IStakingModule.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/0.8.9/interfaces/IStakingModule.sol b/contracts/0.8.9/interfaces/IStakingModule.sol index 416f89da4..332fb047e 100644 --- a/contracts/0.8.9/interfaces/IStakingModule.sol +++ b/contracts/0.8.9/interfaces/IStakingModule.sol @@ -97,10 +97,10 @@ interface IStakingModule { /// @notice Updates the number of the validators in the EXITED state for node operator with given id /// @param _nodeOperatorIds bytes packed array of the node operators id - /// @param _stuckValidatorsCounts bytes packed array of the new number of EXITED validators for the node operators + /// @param _exitedValidatorsCounts bytes packed array of the new number of EXITED validators for the node operators function updateExitedValidatorsCount( bytes calldata _nodeOperatorIds, - bytes calldata _stuckValidatorsCounts + bytes calldata _exitedValidatorsCounts ) external; /// @notice Updates the number of the refunded validators for node operator with the given id From c5cbba729fcdf7d8c218696e2d9588d0181c7492 Mon Sep 17 00:00:00 2001 From: Yuri Tkachenko Date: Tue, 16 Apr 2024 11:10:25 +0000 Subject: [PATCH 13/13] docs: remove Packed64x4 origin comment, looks like it is a copy-paste from Math256.sol --- contracts/0.4.24/lib/Packed64x4.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/0.4.24/lib/Packed64x4.sol b/contracts/0.4.24/lib/Packed64x4.sol index 109323f43..34a1c4df9 100644 --- a/contracts/0.4.24/lib/Packed64x4.sol +++ b/contracts/0.4.24/lib/Packed64x4.sol @@ -1,8 +1,6 @@ // SPDX-FileCopyrightText: 2023 Lido // SPDX-License-Identifier: MIT -// Copied from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/0457042d93d9dfd760dbaa06a4d2f1216fdbe297/contracts/utils/math/Math.sol - // See contracts/COMPILERS.md // solhint-disable-next-line pragma solidity ^0.4.24;