xanoutas/solidity-security-findings huggingface dataset:
`bringUnusedETHBackIntoGiantPool` in `GiantSavETHVaultPool` can be used to steal `LPTokens`
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantSavETHVaultPool.sol#L137


# Vulnerability details

## Impact
real `LPTokens` can be transferred out of `GiantSavETHVaultPool` through fake `_savETHVaults` provided by an attacker.
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantSavETHVaultPool.sol#L137

## Proof of Concept
`bringUnusedETHBackIntoGiantPool` takes in `_savETHVaults`, `_lpTokens`, and burns certain amount o`_lpTokens`. The tokens are thoroughly verified by `burnLPToken` in `SavETHVault`. 
However, theres is no checking for the validity of `_savETHVaults`, nor the relationship between `LPTokens` and `_savETHVaults`. Therefore, an attacker can create fake contracts for `_savETHVaults`, with `burnLPTokens`, that takes `LPTokens` as parameters. The `msg.sender` in `burnLPTokens` is `GiantSavETHVaultPool`, thus the attacker can transfer `LPTokens` that belongs to `GiantSavETHVaultPool` to any addresses it controls.

## Tools Used
manual

## Recommended Mitigation Steps
Always passing liquid staking manager address, checking its real and then requesting either the savETH vault or staking funds vault is a good idea to prove the validity of vaults.
`batchRotateLPTokens` in `GiantMevAndFeesPool` can be used to steal `LPTokens`
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L106


# Vulnerability details


## Impact
real `LPTokens` can be transferred out of `GiantMevAndFeesPool` through fake `_stakingFundsVaults` provided by an attacker.
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L106

## Proof of Concept
`batchRotateLPTokens` takes in `_stakingFundsVaults`, `_oldLPTokens`, `_newLPTokens` and rotate `_amounts` from old to new tokens. The tokens are thoroughly verified by `rotateLPTokens` in `ETHPoolLPFactory`. 
However, theres is no checking for the validity of `_stakingFundsVaults`, nor the relationship between `LPTokens` and `_stakingFundsVaults`. Therefore, an attacker can create fake contracts for `_stakingFundsVaults`, with `batchRotateLPTokens`, that takes `LPTokens` as parameters. The `msg.sender` in `batchRotateLPTokens` is `GiantMevAndFeesPool`, thus the attacker can transfer `LPTokens` that belongs to `GiantMevAndFeesPool` to any addresses it controls.

## Tools Used
manual

## Recommended Mitigation Steps
Always passing liquid staking manager address, checking its real and then requesting either the savETH vault or staking funds vault is a good idea to prove the validity of vaults.
`batchRotateLPTokens` in `GiantSavETHVaultPool` can be used to steal `LPTokens`
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantSavETHVaultPool.sol#L105


# Vulnerability details


## Impact
real `LPTokens` can be transferred out of `GiantSavETHVaultPool` through fake `_stakingFundsVaults` provided by an attacker.
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantSavETHVaultPool.sol#L105

## Proof of Concept
`batchRotateLPTokens` takes in `_stakingFundsVaults`, `_oldLPTokens`, `_newLPTokens` and rotate `_amounts` from old to new tokens. The tokens are thoroughly verified by `rotateLPTokens` in `ETHPoolLPFactory`. 
However, theres is no checking for the validity of `_stakingFundsVaults`, nor the relationship between `LPTokens` and `_stakingFundsVaults`. Therefore, an attacker can create fake contracts for `_stakingFundsVaults`, with `batchDepositETHForStaking`, that takes `LPTokens` as parameters. The `msg.sender` in `batchDepositETHForStaking` is `GiantSavETHVaultPool`, thus the attacker can transfer `LPTokens` that belongs to `GiantSavETHVaultPool` to any addresses it controls.

## Tools Used
manual

## Recommended Mitigation Steps
Always passing liquid staking manager address, checking its real and then requesting either the savETH vault or staking funds vault is a good idea to prove the validity of vaults.
`batchDepositETHForStaking` in `GiantSavETHVaultPool.sol` can be ticked to steal all ETH in the pool
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantSavETHVaultPool.sol#L29


# Vulnerability details

## Impact
All Eth can be drained by fake vault addresses.
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantSavETHVaultPool.sol#L29

## Proof of Concept
In `batchDepositETHForStaking`, `_savETHVault` is checked for its validity through
```
SavETHVault savETHPool = SavETHVault(_savETHVaults[i]); 
require(
    liquidStakingDerivativeFactory.isLiquidStakingManager(address(savETHPool.liquidStakingManager())),
    "Invalid liquid staking manager"
);
```
However, an attacker can create a fake contract that retuns a correct `liquidStakingNetworkManager`, thus passing the check easily.
After the check, any ETH in the pool will be sent to an address this fake contract provide:
```
savETHPool.batchDepositETHForStaking{ value: transactionAmount }(
    _blsPublicKeys[i],
    _stakeAmounts[i]
);
```

## Tools Used
manual

## Recommended Mitigation Steps
Always passing liquid staking manager address, checking its real and then requesting either the savETH vault or staking funds vault is a good idea rather than other way around from a giant pool perspective.
`batchDepositETHForStaking` in `GiantMevAndFeesPool.sol` can be ticked to steal all ETH in the pool
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L28


# Vulnerability details

## Impact
All Eth can be drained by fake vault addresses.
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L28

## Proof of Concept
In `batchDepositETHForStaking`, `_stakingFundsVault` is checked for its validity through
```
StakingFundsVault sfv = StakingFundsVault(payable(_stakingFundsVault[i]));
require(
    liquidStakingDerivativeFactory.isLiquidStakingManager(address(sfv.liquidStakingNetworkManager())),
    "Invalid liquid staking manager"
);
```
However, an attacker can create a fake contract that retuns a correct `liquidStakingNetworkManager`, thus passing the check easily.
After the check, any ETH in the pool will be sent to an address this fake contract provide:
```
sfv.batchDepositETHForStaking{ value: _ETHTransactionAmounts[i] }(
    _blsPublicKeyOfKnots[i],
    _amounts[i]
);
```

## Tools Used
manual

## Recommended Mitigation Steps
Always passing liquid staking manager address, checking its real and then requesting either the savETH vault or staking funds vault is a good idea rather than other way around from a giant pool perspective.
`GiantMevAndFeesPool::afterTokenTransfer` doesn't update claimed amount of sender
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L170-L173


# Vulnerability details

## Impact
After a token transfer of `GiantMevAndFeesPool`'s GiantLP, the receiver gets their claimed amount updated to the correct value, but the sender does not. If more than zero tokens were transferred, that amount in the sender's future rewards will be lost, and any transactions that try to distribute ETH rewards to the sender - which is necessary before a balance change - will revert from an underflow until `accumulatedETHPerLPShare` has increased enough for the sender to have a nonnegative amount due.

## Proof of Concept
`GiantMevAndFeesPool` provides itsself as the `transferHookProcessor` to its GiantLP so it can distribute rewards first and update amounts claimed on transfers. In `afterTokenTransfer` it only updates the claimed amount for the receiving account.

[/contracts/liquid-staking/GiantMevAndFeesPool.sol#L170-L173](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L170-L173):
```solidity
170    function afterTokenTransfer(address, address _to, uint256) external {
171        require(msg.sender == address(lpTokenETH), "Caller is not giant LP");
172        _setClaimedToMax(_to);
173    }
```

Before a token transfer, `SyndicateRewardsProcessor::_distributeETHRewardsToUserForToken` is called in the pre transfer hook for the sender and receiver, which will revert on line 61 if `claimed[_user][_token]` > `(accumulatedETHPerLPShare * balance) / PRECISION`

[/contracts/liquid-staking/GiantMevAndFeesPool.sol#L146-L167](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L146-L167):
```solidity
146    function beforeTokenTransfer(address _from, address _to, uint256) external {
147        require(msg.sender == address(lpTokenETH), "Caller is not giant LP");
148        updateAccumulatedETHPerLP();
149
150        // Make sure that `_from` gets total accrued before transfer as post transferred anything owed will be wiped
151        if (_from != address(0)) {
152            _distributeETHRewardsToUserForToken(
153                _from,
154                address(lpTokenETH),
155                lpTokenETH.balanceOf(_from),
156                _from
157            );
158        }
159
160        // Make sure that `_to` gets total accrued before transfer as post transferred anything owed will be wiped
161        _distributeETHRewardsToUserForToken(
162            _to,
163            address(lpTokenETH),
164            lpTokenETH.balanceOf(_to),
165            _to
166        );
167    }
```

[/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L51-L73](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking
Variable `claimed` its being resetting instead of adding
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L63


# Vulnerability details

## Impact
The variable [`claimed`](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L63) that keeps tracking of the total amount claimed per user per token its being being resetting with a wrong value.
This impacts on the line `due` calculation on [SyndicateRewardsProcessor.sol#L61](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L61)
```solidity
            uint256 due = ((accumulatedETHPerLPShare * balance) / PRECISION) - claimed[_user][_token];
```

## Proof of Concept
Yo could create a contract that mint LP, then in one transaction loop a  transfer function with no value and use the received ether to redeposit and repeat. 

## Tools Used
manual revision

## Recommended Mitigation Steps
On [SyndicateRewardsProcessor.sol#L63](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L63) instead of
```
                claimed[_user][_token] = due;
```
You could do
```
                claimed[_user][_token] += due;
```
Multi reentrancy issues leveragin on `_distributeETHRewardsToUserForToken` method
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/39a3a84615725b7b2ce296861352117793e4c853/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L67
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L146
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/StakingFundsVault.sol#L315


# Vulnerability details

## Impact
Multiple reentrancy issues mainly trigger by a low call ETH transfer.

## Proof of Concept
Everytime you use the `_distributeETHRewardsToUserForToken` method on [SyndicateRewardsProcessor.sol#L67](https://github.com/code-423n4/2022-11-stakehouse/blob/39a3a84615725b7b2ce296861352117793e4c853/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L67) there are many reentrancy opportunities for an attacker.

For example, a contract can call the function transfer of `GiantLP` several times to transfer an amount from and to self. Because the update of the claimed would not be done until it is executed the function `_afterTokenTransfer`, the due amount calculated in `_distributeETHRewardsToUserForToken` of SyndicateRewardsProcessor contract and the `lastInteractedTimestamp` of `GiantLP `contract will be incorrect.


## Tools Used
Manual revision

## Recommended Mitigation Steps
You could keep adding `nonReentrant` modifiers, but i think the safest call here is to wrap ETH into WETH an transfer it as a normal ERC20 to avoid unwanted callbacks.
Possibly reentrancy attacks in `_distributeETHRewardsToUserForToken` function
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L51-L73
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L146-L167
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantPoolBase.sol#L66-L90
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/StakingFundsVault.sol#L66-L104
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/StakingFundsVault.sol#L110-L143
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/StakingFundsVault.sol#L314-L340


# Vulnerability details

### Author: rotcivegaf

### Impact

The root of the problem are in the `_distributeETHRewardsToUserForToken` who makes a call to distribute the ether rewards. With this call the recipient can execute an reentrancy attack calling several times the different function to steal founds or take advantage of other users/protocol

### Proof of Concept

This functions use the `_distributeETHRewardsToUserForToken`:

#### [`beforeTokenTransfer`, **GiantMevAndFeesPool** contract](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L146-L167):

The contract **GiantLP** use the **GiantMevAndFeesPool** contract as [`transferHookProcessor`](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantLP.sol#L14) and when use the functions [`_mint`, `_burn`, `transferFrom` and `transfer` of the ERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.7/contracts/token/ERC20/ERC20.sol), the function [`beforeTokenTransfer`](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L146-L167) implemented in the **GiantMevAndFeesPool** bring a possibility to make a reentrancy attack because in the function [`_distributeETHRewardsToUserForToken`](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L51-L73) implemented in the [**GiantMevAndFeesPool** make a `call` to the `_recipient`](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/SyndicateRewardsProcessor.sol#L67-L68)

A contract can call the function `transfer` of **GiantLP** contract several time, transfer an `amount` from and to self, as the update of the [`claimed`](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca128
anyone can steal `eth` from `GiantPools`
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/GiantSavETHVaultPool.sol#L50
https://github.com/code-423n4/2022-11-stakehouse/blob/main/contracts/liquid-staking/GiantMevAndFeesPool.sol#L44


# Vulnerability details

## Impact
An attacker can create a contract that behaves like a vault. Using this an attacker can steal all `eth` in both GiantPools.

## Proof of Concept

The attack works because there is no validation that the actual vault belongs to the manager, here's the code from `GiantSavETHVaultPool.sol`, the code looks very similar in `GiantMevAndFeesPool.sol`:

```javascript
29:    function batchDepositETHForStaking(
30:        address[] calldata _savETHVaults,
31:        uint256[] calldata _ETHTransactionAmounts,
32:        bytes[][] calldata _blsPublicKeys,
33:        uint256[][] calldata _stakeAmounts
34:    ) public {
        ...
        
41:        // For every vault specified, supply ETH for at least 1 BLS public key of a LSDN validator
42:        for (uint256 i; i < numOfSavETHVaults; ++i) {
43:            uint256 transactionAmount = _ETHTransactionAmounts[i];
44:
45:            // As ETH is being deployed to a savETH pool vault, it is no longer idle
46:            idleETH -= transactionAmount;
47:
48:            SavETHVault savETHPool = SavETHVault(_savETHVaults[i]);
49:            require(
50:                liquidStakingDerivativeFactory.isLiquidStakingManager(address(savETHPool.liquidStakingManager())),
51:                "Invalid liquid staking manager"
52:            );
53:
54:            // Deposit ETH for staking of BLS key
55:            savETHPool.batchDepositETHForStaking{ value: transactionAmount }(
56:                _blsPublicKeys[i],
57:                _stakeAmounts[i]
58:            );
59:        }
60:    }
```

This piece of code only checks that the return from the vault is the manager contract:

```javascript
49:            require(
50:                liquidStakingDerivativeFactory.isLiquidStakingManager(address(savETHPool.liquidStakingManager())),
51:                "Invalid liquid staking manager"
52:            );
```
If an attacker deploys a fake vault that responds with an address of a staking manager deployed by the `LSDNFactory` it will be accepted as a vault. Then the attacker can transfer any `eth` available in the pool to the fake contract.

PoC using forge:

`FakeVault.sol`
```javascript
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

contract FakeVault {

    address public liquidStakingManager;
    address public liquidStakingNetworkManager;

    constructor(address _lsm) {
        liquidStakingManager = _lsm;
        liquidStakingNetworkManager = _lsm;
    }

    function batchDepositETHForStaking(bytes[] calldata , uint256[] calldata ) public payable {
        // takes your eth
    }
}

```

PoC forge test in `GiantPools.t.sol`:
```javascript
    function testFakeVaultCanStealEthFromGiantPools() public {
        address feesAndMevUserOne =
`GiantMevAndFeesPool` and `GiantSavEthVaultPool` ETH can be deposited to contracts outside of the system
Audit: 2022-11-stakehouse-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L28-L53
https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantSavETHVaultPool.sol#L29-L60


# Vulnerability details

## Impact
`GiantMevAndFeesPool` and `GiantSavEthVaultPool` contain a function for depositing ETH for staking into other contracts. To check if contracts are part of the system, both call `liquidStakingNetworkManager` on a user provided address and check with the systems's `LSDNFactory` that the returned address is a valid liquid staking network manager. A malicious contract could be created that implements the necessary functions to receive deposits and returns a valid liquid staking network manager address and be used to drain ETH from the `GiantMevAndFeesPool` and `GiantSavEthVaultPool`.

## Proof of Concept
[/contracts/liquid-staking/GiantMevAndFeesPool.sol#L28-L53](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantMevAndFeesPool.sol#L28-L53):
```solidity
28    function batchDepositETHForStaking(
29        address[] calldata _stakingFundsVault,
30        uint256[] calldata _ETHTransactionAmounts,
31        bytes[][] calldata _blsPublicKeyOfKnots,
32        uint256[][] calldata _amounts
33    ) external {
34        uint256 numOfVaults = _stakingFundsVault.length;
35        require(numOfVaults > 0, "Zero vaults");
36        require(numOfVaults == _blsPublicKeyOfKnots.length, "Inconsistent lengths");
37        require(numOfVaults == _amounts.length, "Inconsistent lengths");
38        for (uint256 i; i < numOfVaults; ++i) {
39            // As ETH is being deployed to a staking funds vault, it is no longer idle
40            idleETH -= _ETHTransactionAmounts[i];
41
42            StakingFundsVault sfv = StakingFundsVault(payable(_stakingFundsVault[i]));
43            require( // @audit only checks sfv returns a correct value, not if it was actually created by a valid factory/deployer
44                liquidStakingDerivativeFactory.isLiquidStakingManager(address(sfv.liquidStakingNetworkManager())),
45                "Invalid liquid staking manager"
46            );
47            // @audit if contract has matching function signature, all funds can be transferred to it
48            sfv.batchDepositETHForStaking{ value: _ETHTransactionAmounts[i] }(
49                _blsPublicKeyOfKnots[i],
50                _amounts[i]
51            );
52        }
53    }
```

[/contracts/liquid-staking/GiantSavETHVaultPool.sol#L29-L60](https://github.com/code-423n4/2022-11-stakehouse/blob/4b6828e9c807f2f7c569e6d721ca1289f7cf7112/contracts/liquid-staking/GiantSavETHVaultPool.sol#L29-L60):
```solidity
29    function batchDepositETHForStaking(
30        address[] calldata _savETHVaults,
31        uint256[] calldata _ETHTransactionAmounts,
32        byt