Farseen0/scar-pairs huggingface dataset:
HIGH severity: All CCIP messages reverts when decoded. **Description:** YieldFi has integrated Chainlink CCIP alongside its existing LayerZero support to enable cross-chain token transfers using multiple messaging protocols. To support this, a custom message payload is used to indicate the token transfer. This payload is decoded in...

Vulnerable code:
(uint32 dstId, address to, address token, uint256 amount, bytes32 trxnType) = abi.decode(_data, (uint32, address, address, uint256, bytes32));
HIGH severity: Incorrect `owner` passed to `Manager::redeem` in YToken withdrawal flow. **Description:** YieldFi’s yield tokens (`YTokens`) implement a more complex withdrawal mechanism than a standard ERC-4626 vault. Instead of executing withdrawals immediately, they defer them to a central `Manager` contract, which queues the request for off-chain processing and later execution...

Vulnerable code:
// Override _withdraw to request funds from manager
function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares) internal override nonReentrant notPaused {
    require(receiver != address(0) && owner != address(0) && assets > 0 && shares > 0, "!valid");
    require(!IBlackList(administrator).isBlackListed(caller) && !IBlackList(administrator).isBlackListed(receiver), "blacklisted");
    if (caller != owner) {
        _spendAllowance(owner, caller, shares);
    }
    // Instead of burning shares here, just redirect to Manager
    // The share burning will happen during order execution
    // Don't update totAssets here either, as the assets haven't left the system yet
    // @audit-issue `msg.sender` passed as owner
    IManager(manager).redeem(msg.sender, address(this), asset(), shares, receiver, address(0), "");
}

it("Should handle redeem request through third party", async function () {
  // Grant manager role to deployer for manager operations
  await administrator.grantRoles(MINTER_AND_REDEEMER, [deployer.address]);

  const sharesToRedeem = toN(50, 18); // 18 decimals for shares

  await ytoken.connect(user).approve(u1.address, sharesToRedeem);

  // Spy on manager.redeem call
  const redeemTx = await ytoken.connect(u1).redeem(sharesToRedeem, user.address, user.address);

  // Wait for transaction
  await redeemTx.wait();

  // to check if manager.redeem was called we can check the event of manager contract
  const events = await manager.queryFilter("OrderRequest");
  expect(events.length).to.be.greaterThan(0);
  expect(events[0].args[0]).to.equal(user.address); // owner, who's tokens should be burnt
  expect(events[0].args[1]).to.equal(ytoken.target); // yToken
  expect(events[0].args[2]).to.equal(usdc.target); // Asset
  expect(events[0].args[4]).to.equal(sharesToRedeem); // Amount
  expect(events[0].args[3]).to.equal(user.address); // Receiver
  expect(events[0].args[5]).to.equal(false); // isDeposit (false for redeem)
});
HIGH severity: Commented-out blacklist check allows restricted transfers. **Description:** In [`PerpetualBond::_update`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/PerpetualBond.sol#L508-L510), the line intended to restrict transfers between non-blacklisted users is currently commented out:

This effectively...

Vulnerable code:
function _update(address from, address to, uint256 amount) internal virtual override {
    // Placeholder for Blacklist check
    // require(!IBlackList(administrator).isBlackListed(from) && !IBlackList(administrator).isBlackListed(to), "blacklisted");
HIGH severity: `Manager::_transferFee` returns invalid `feeShares` when `fee` is zero. **Description:** When a user deposits directly into `Manager::deposit`, the protocol fee is calculated via the [`Manager::_transferFee`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/Manager.sol#L226-L242) function:

The issue is that when...

Vulnerable code:
function _transferFee(address _yToken, uint256 _shares, uint256 _fee) internal returns (uint256) {
    if (_fee == 0) {
        return _shares;
    }
    uint256 feeShares = (_shares * _fee) / Constants.HUNDRED_PERCENT;

    IERC20(_yToken).safeTransfer(treasury, feeShares);

    return feeShares;
}

// transfer fee to treasury, already applied on adjustedShares
uint256 adjustedFeeShares = _transferFee(order.yToken, adjustedShares, _fee);

// Calculate adjusted gas fee shares
uint256 adjustedGasFeeShares = (_gasFeeShares * order.exchangeRateInUnderlying) / currentExchangeRate;

// transfer gas to caller
IERC20(order.yToken).safeTransfer(_caller, adjustedGasFeeShares);

// remaining shares after gas fee
uint256 sharesAfterAllFee = adjustedShares - adjustedFeeShares - adjustedGasFeeShares;

if (_fee == 0) {
-     return _shares;
+     return 0;
  }
LOW severity: `Ytoken:previewMint` and `YToken:previewWithdraw` round in favor of user. **Description:** For the L2 `YToken` contracts, assets are not managed directly. Instead, the vault’s exchange rate is provided by an oracle, using the exchange rate from L1 as the source of truth.

This architectural choice requires custom implementations of functions like `previewMint`,...

Vulnerable code:
// Calculate assets based on exchange rate
  return (grossShares * exchangeRate()) / Constants.PINT;

// Calculate shares needed for requested assets based on exchange rate
  uint256 sharesWithoutFee = (assets * Constants.PINT) / exchangeRate();
LOW severity: Missing sequencer uptime check in `OracleAdapter`. **Description:** On L2, the `YToken` exchange rate is provided by custom Chainlink oracles. The exchange rate is queried in [`OracleAdapter::fetchExchangeRate`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/OracleAdapter.sol#L52-L77):

However,...

Vulnerable code:
function fetchExchangeRate(address token) external view override returns (uint256) {
    address oracle = oracles[token];
    require(oracle != address(0), "Oracle not set");

    (, /* uint80 roundId */ int256 answer, , /* uint256 startedAt */ uint256 updatedAt /* uint80 answeredInRound */, ) = IOracle(oracle).latestRoundData();

    require(answer > 0, "Invalid price");
    require(updatedAt > 0, "Round not complete");
    require(block.timestamp - updatedAt < staleThreshold, "Stale price");

    // Get decimals and normalize to 1e18 (PINT)
    uint8 decimals = IOracle(oracle).decimals();

    if (decimals < 18) {
        return uint256(answer) * (10 ** (18 - decimals));
    } else if (decimals > 18) {
        return uint256(answer) / (10 ** (decimals - 18));
    } else {
        return uint256(answer);
    }
}
HIGH severity: Direct YToken deposits can lock funds below minimum withdrawal threshold. **Description:** In [`Manager::deposit`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/Manager.sol#L134-L155), there is a check enforcing a minimum deposit amount inside...

Vulnerable code:
uint256 normalizedAmount = _normalizeAmount(_yToken, _asset, _amount);
require(IERC4626(_yToken).convertToShares(normalizedAmount) >= minSharesInYToken[_yToken], "!minShares");

require(_amount >= minSharesInYToken[_yToken], "!minShares");

require(receiver != address(0) && assets > 0 && shares > 0, "!valid");
HIGH severity: Hardcoded `extraArgs` violates CCIP best practices. **Description:** When sending cross-chain messages via CCIP, Chainlink recommends keeping the `extraArgs` parameter mutable to allow for future upgrades or configuration changes, as outlined in their [best practices](https://docs.chain.link/ccip/best-practices#using-extraargs).

However, this...

Vulnerable code:
// Sends the message to the destination endpoint
Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({
    receiver: abi.encode(_receiver), // ABI-encoded receiver address
    data: abi.encode(_encodedMessage), // ABI-encoded string
    tokenAmounts: new Client.EVMTokenAmount[](0), // Empty array indicating no tokens are being sent
    // @audit-issue `extraArgs` hardcoded
    extraArgs: Client._argsToBytes(Client.EVMExtraArgsV2({ gasLimit: 200_000, allowOutOfOrderExecution: true })),
    feeToken: address(0) // For msg.value
});
HIGH severity: Static `gasLimit` will result in overpayment. **Description:** Since [unspent gas is not refunded](https://docs.chain.link/ccip/best-practices#setting-gaslimit), Chainlink recommends carefully setting the `gasLimit` within the `extraArgs` parameter to avoid overpaying for execution.

In...

Vulnerable code:
extraArgs: Client._argsToBytes(Client.EVMExtraArgsV2({ gasLimit: 200_000, allowOutOfOrderExecution: true })),
HIGH severity: Unverified `_receiver` can cause irrecoverable token loss. **Description:** When a user bridges their YTokens using CCIP, they call [`BridgeCCIP::send`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/bridge/ccip/BridgeCCIP.sol#L117-L158). One of the parameters passed to this function is `_receiver`, which...

Vulnerable code:
function send(address _yToken, uint64 _dstChain, address _to, uint256 _amount, address _receiver) external payable notBlacklisted(msg.sender) notBlacklisted(_to) notPaused {
    require(_amount > 0, "!amount");
    require(lockboxes[_yToken] != address(0), "!token !lockbox");
    require(IERC20(_yToken).balanceOf(msg.sender) >= _amount, "!balance");
    require(_to != address(0), "!receiver");
    require(tokens[_yToken][_dstChain] != address(0), "!destination");

    bytes memory _encodedMessage = abi.encode(_dstChain, _to, tokens[_yToken][_dstChain], _amount, Constants.BRIDGE_SEND_HASH);

    // Sends the message to the destination endpoint
    Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({
        // @audit-issue `_receiver` not verified
        receiver: abi.encode(_receiver), // ABI-encoded receiver address
        data: abi.encode(_encodedMessage), // ABI-encoded string
        tokenAmounts: new Client.EVMTokenAmount[](0), // Empty array indicating no tokens are being sent
        extraArgs: Client._argsToBytes(Client.EVMExtraArgsV2({ gasLimit: 200_000, allowOutOfOrderExecution: true })),
        feeToken: address(0) // For msg.value
    });
HIGH severity: Chainlink router configured twice. **Description:** In `BridgeCCIP`, there is a dedicated storage slot for the CCIP router address, [`router`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/bridge/ccip/BridgeCCIP.sol#L32-L33):

This value can be updated by the admin through...

Vulnerable code:
contract BridgeCCIP is CCIPReceiver, Ownable {
    address public router;

function setRouter(address _router) external onlyAdmin {
    require(_router != address(0), "!router");
    router = _router;
    emit SetRouter(msg.sender, _router);
}

IRouterClient(router).ccipSend{ value: msg.value }(_dstChain, evm2AnyMessage);
HIGH severity: Missing vesting check in `PerpetualBond::setVestingPeriod`. **Description:** Both `YToken` and `PerpetualBond` support reward vesting through a configurable vesting period. The admin can update this period via the `setVestingPeriod` function. However, there is an inconsistency in how the two contracts validate changes to the vesting period:

-...

Vulnerable code:
function setVestingPeriod(uint256 _vestingPeriod) external onlyAdmin {
      require(getUnvestedAmount() == 0, "!vesting");
      require(_vestingPeriod > 0, "!vestingPeriod");
      vestingPeriod = _vestingPeriod;
  }

function setVestingPeriod(uint256 _vestingPeriod) external onlyAdmin {
      // @audit-issue no check for `getUnvestedAmount() == 0`
      require(_vestingPeriod > 0, "!vestingPeriod");
      vestingPeriod = _vestingPeriod;
      emit VestingPeriodUpdated(_vestingPeriod);
  }
HIGH severity: Balance check for yield claims in `PerpetualBond::_validate` can be easily bypassed. **Description:** In [`PerpetualBond::_validate`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/PerpetualBond.sol#L312-L314), there's a check to ensure that users have a non-zero balance before claiming yield:

However, this check can be...

Vulnerable code:
// Yield claim
require(balanceOf(_caller) > 0, "!bond balance"); // Caller must hold bonds to claim yield
require(accruedRewardAtCheckpoint[_caller] > 0, "!claimable yield"); // Must have claimable yield

- require(balanceOf(_caller) > 0, "!bond balance");
+ require(_convertToBond(balanceOf(_caller)) > minimumTxnThreshold, "!bond balance");

// Convert yield amount to bond tokens for threshold comparison
uint256 yieldInBondTokens = _convertToBond(claimableYieldAmount);

// Check if the yield claim is worth executing
require(yieldInBondTokens >= minimumTxnThreshold, "!min txn threshold");
HIGH severity: `PerpetualBond.epoch` not updated after yield distribution. **Description:** In [`PerpetualBond::distributeBondYield`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/PerpetualBond.sol#L215-L241) the caller is supposed to provide a `nonce` that matches [`epoch +...

Vulnerable code:
function distributeBondYield(uint256 _yieldAmount, uint256 nonce) external notPaused onlyRewarder {
    require(nonce == epoch + 1, "!epoch");
HIGH severity: Order not eligible at `eligibleAt`. **Description:** Both in [`PerpetualBond::executeOrder`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/PerpetualBond.sol#L411) and [`Manager::executeOrder`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/...

Vulnerable code:
require(block.timestamp > order.eligibleAt, "!waitingPeriod");

- require(block.timestamp > order.eligibleAt, "!waitingPeriod");
+ require(block.timestamp >= order.eligibleAt, "!waitingPeriod");
HIGH severity: `_receiverGas` check excludes minimum acceptable value. **Description:** In the LayerZero bridge contracts [`BridgeLR::send`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/bridge/BridgeLR.sol#L76) and [`BridgeMB::send`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2f...

Vulnerable code:
require(_receiverGas > MIN_RECEIVER_GAS, "!gas");

- require(_receiverGas > MIN_RECEIVER_GAS, "!gas");
+ require(_receiverGas >= MIN_RECEIVER_GAS, "!gas");
HIGH severity: Unused errors. **Description:** In the library [`Common`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/libs/Common.sol#L5-L6) there are two unused errors:

Consider removing these.

**YieldFi:** Fixed in commit...

Vulnerable code:
error SignatureVerificationFailed();
error BadSignature();
HIGH severity: Potential risk if callback logic is enabled in the future. **Description:** Both the `Manager` and `PerpetualBond` contracts implement a two-step process for user interactions. As part of these calls, users can provide a `_callback` address and accompanying `_callbackData`. For example, here are the parameters for...

Vulnerable code:
function deposit(..., address _callback, bytes calldata _callbackData) external notPaused nonReentrant {

uint256 receiptId = IReceipt(receipt).mint(msg.sender, Order(..., address(0), ""));

// Execute the callback
if (order.callback != address(0)) {
    (bool success, ) = order.callback.call(order.callbackData);
    require(success, "callback failed");
}
HIGH severity: `bondFaceValue` read in `PerpetualBond::_convertToBond` can be cached. **Description:** The storage value `bondFaceValue` is read twice in [`PerpetualBond::__convertToBond`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/PerpetualBond.sol#L291-L294):

The value can be cached and only read once:

**YieldFi:**...

Vulnerable code:
function _convertToBond(uint256 assetAmount) internal view returns (uint256) {
    if (bondFaceValue == 0) return 0; // Prevent division by zero
    return (assetAmount * 1e18) / bondFaceValue;
}

function _convertToBond(uint256 assetAmount) internal view returns (uint256) {
    // cache read
    uint256 _bondFaceValue = bondFaceValue;
    if (_bondFaceValue == 0) return 0; // Prevent division by zero
    return (assetAmount * 1e18) / _bondFaceValue;
}
LOW severity: Unnecessary external call in `YToken::_decimalsOffset` and `YToken:_decimalsOffset`. **Description:** In [`YToken::_decimalsOffset`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/tokens/YToken.sol#L314-L316) and [`YTokenL2::_decimalsOffset`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/...

Vulnerable code:
function _decimalsOffset() internal view virtual override returns (uint8) {
    return 18 - IERC20Metadata(asset()).decimals();
}
HIGH severity: Order read twice in `Manager::executeOrder`. **Description:** In [`Manager::executeOrder`](https://github.com/YieldFiLabs/contracts/blob/40caad6c60625d750cc5c3a5a7df92b96a93a2fb/contracts/core/Manager.sol#L207-L214) the order data is fetched from the Receipt:

Then order is read again in both...

Vulnerable code:
Order memory order = IReceipt(receipt).readOrder(_receiptId);
require(block.timestamp > order.eligibleAt, "!waitingPeriod");
require(_fee <= Constants.ONE_PERCENT, "!fee");
if (order.orderType) {
    _deposit(msg.sender, _receiptId, _amount, _fee, _gas);
} else {
    _withdraw(msg.sender, _receiptId, _amount, _fee, _gas);
}

function _deposit(address _caller, uint256 _receiptId, uint256 _shares, uint256 _fee, uint256 _gasFeeShares) internal {
    Order memory order = IReceipt(receipt).readOrder(_receiptId);

function _withdraw(address _caller, uint256 _receiptId, uint256 _assetAmountOut, uint256 _fee, uint256 _gasFeeShares) internal {
    Order memory order = IReceipt(receipt).readOrder(_receiptId);
LOW severity: Re-entrancy protection can be evaded via `TimelockController::executeBatch`. **Description:** `EthenaTimelockController::execute` overrides `TimelockController::execute` and adds a `nonReentrant` modifier to prevent re-entrant calls back into it.

However `TimelockController::executeBatch` is not overridden so re-entrancy can still occur that way. Beyond the re-entrancy...

Vulnerable code:
function maliciousExecute() external {
    if (!reentered) {
        reentered = true;
        // re-enter the timelock through executeBatch
        bytes memory data = abi.encodeWithSignature("maliciousFunction()");
        address[] memory targets = new address[](1);
        targets[0] = address(this);
        uint256[] memory values = new uint256[](1);
        values[0] = 0;
        bytes[] memory payloads = new bytes[](1);
        payloads[0] = data;
        timelock.executeBatch(targets, values, payloads, bytes32(0), bytes32(0));
    }
}
LOW severity: `TimelockController` won't revert when executing on non-existent contracts. **Description:** `TimelockController::_execute` does this:

If `target` is a non-existent contract but `data` contains a valid expected function call with parameters, the `call` will return `true`; `Address.verifyCallResult` fails to catch this case.

**Proof Of Concept:**
Add PoC function to...

Vulnerable code:
function _execute(address target, uint256 value, bytes calldata data) internal virtual {
    (bool success, bytes memory returndata) = target.call{value: value}(data);
    Address.verifyCallResult(success, returndata);
}

function testExecuteNonExistentContract() public {
    bytes memory data = abi.encodeWithSignature("DONTEXIST()");
        _scheduleWaitExecute(address(0x1234), data);
}
LOW severity: `EthenaTimelockController::addToWhitelist` and `removeFromWhitelist` don't revert for non-existent `target` address. **Description:** `EthenaTimelockController::addToWhitelist` and `removeFromWhitelist` should revert if the `target` address doesn't exist (has no code).

**Proof of Concept:** Add PoC function to `test/EthenaTimelockController.t.sol`:

Run with: `forge test --match-test...

Vulnerable code:
function testAddNonExistentContractToWhitelist() public {
    bytes memory addToWhitelistData = abi.encodeWithSignature(
        "addToWhitelist(address,bytes4)", address(0x1234), bytes4(keccak256("DONTEXIST()"))
    );
    _scheduleWaitExecute(address(timelock), addToWhitelistData);
}
HIGH severity: Use named imports. **Description:** Use named imports:

**Ethena:** Fixed in commit [89d4190](https://github.com/ethena-labs/timelock-contract/commit/89d41901be3387c11c2150c19eb99883ed807d79#diff-8ca72e61ebf9a693737b5c9052aa3814e8b291e3d6dd0341fe88b5b5e781427bL4-R5).

**Cyfrin:** Verified.

Vulnerable code:
- import "@openzeppelin/contracts/governance/TimelockController.sol";
- import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
+ import {TimelockController, Address} from "@openzeppelin/contracts/governance/TimelockController.sol";
+ import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
HIGH severity: Use named mappings. **Description:** Use named mappings to explicitly indicate the purpose of keys and values:

**Ethena:** Fixed in commit [89d4190](https://github.com/ethena-labs/timelock-contract/commit/89d41901be3387c11c2150c19eb99883ed807d79#diff-8ca72e61ebf9a693737b5c9052aa3814e8b291e3d6dd0341fe88b5b5e781427bL28-...

Vulnerable code:
-    mapping(address => mapping(bytes4 => bool)) private _functionWhitelist;
+    mapping(address target => mapping(bytes4 selector => bool allowed)) private _functionWhitelist;
MEDIUM severity: Unfair distribution of unbonding due to improper validator withdrawal index advancement. **Description:** `PolygonStrategy::unbond` tracks the `validatorWithdrawalIndex` to evenly distribute unbonding requests across vaults. The index is advanced based on the loop progression rather than actual unbonding actions, which can lead to uneven distribution of unbonding across...

Vulnerable code:
while (toUnbondRemaining != 0) {
    // Process vault[i]...
    ++i;
    if (i >= vaults.length) i = 0;
}
validatorWithdrawalIndex = i; // @audit This happens regardless of whether unbonding occurred on the last processed vault or not
MEDIUM severity: Validator and protocol fees can exceed 100 percent of rewards in `PolygonStrategy.sol`. **Description:** The `setValidatorMEVRewardsPercentage` function in `PolygonStrategy.sol` allows setting the validator MEV rewards percentage up to 100% (10,000 basis points), but does not account for the total protocol fees (`_totalFeesBasisPoints`). This means the combined sum of all fees can...

Vulnerable code:
function setValidatorMEVRewardsPercentage(
    uint256 _validatorMEVRewardsPercentage
) external onlyOwner {
    // @audit should consider the totalFeesBasisPoints.
    // updateDeposits will report more than it can pay in fees.
    if (_validatorMEVRewardsPercentage > 10000) revert FeesTooLarge();

    validatorMEVRewardsPercentage = _validatorMEVRewardsPercentage;
    emit SetValidatorMEVRewardsPercentage(_validatorMEVRewardsPercentage);
}

// updateFee
if (_totalFeesBasisPoints() > 3000) revert FeesTooLarge();

function updateDeposits(
        bytes calldata
    )
        external
        onlyStakingPool
        returns (int256 depositChange, address[] memory receivers, uint256[] memory amounts)
    {
    ...
@>            uint256 validatorMEVRewards = ((balance - totalQueued) *
                validatorMEVRewardsPercentage) / 10000;

            receivers = new address[](fees.length + (validatorMEVRewards != 0 ? 1 : 0));
            amounts = new uint256[](receivers.length);

            for (uint256 i = 0; i < fees.length; ++i) {
                receivers[i] = fees[i].receiver;
@>                amounts[i] = (uint256(depositChange) * fees[i].basisPoints) / 10000;
            }

            if (validatorMEVRewards != 0) {
@>                receivers[receivers.length - 1] = address(validatorMEVRewardsPool);
@>                amounts[amounts.length - 1] = validatorMEVRewards;
            }
           ...
}

// StakingPool._updateStrategyRewards
uint256 sharesToMint = (totalFeeAmounts * totalShares) /
    (totalStaked - totalFeeAmounts);
_mintShares(address(this), sharesToMint);