xanoutas/solidity-security-findings huggingface dataset:
Checkpointing global reward cam allow front-running of user reward checkpointing in same block. 
Audit: 2024-02-uniswap-foundation-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-02-uniswap-foundation/blob/5a2761c8277541a24bc551fbd624413b384bea94/src/UniStaker.sol#L753-L756
https://github.com/code-423n4/2024-02-uniswap-foundation/blob/5a2761c8277541a24bc551fbd624413b384bea94/src/UniStaker.sol#L764-L767


# Vulnerability details

## Impact
A malicious actor could front-run a transaction that calls `_claimReward` or any other function that updates a user's reward checkpoint (e.g., _stake, _stakeMore, _alterBeneficiary, etc.). By doing so, the attacker can calculate the user's unclaimed rewards before the user's checkpoint is updated, and steal a portion of the user's earned rewards.
Here's how the attack would work:
1. Alice calls `_claimReward` or any other function that updates her reward checkpoint.
2. The attacker front-runs Alice's transaction with a transaction that calls `_checkpointGlobalReward`.
3. The attacker can now calculate Alice's unclaimed rewards before her checkpoint is updated.
4. The attacker can then call `_claimReward` for Alice's address, effectively stealing a portion of Alice's earned rewards.
The severity of this issue is considered high. It allows a malicious actor to steal earned rewards from users, which defeats the purpose of the staking contract and erodes trust in the system. Users' rewards, which they have rightfully earned by staking their tokens, are at risk of being stolen.


## Proof of Concept
there is a potential front-running vulnerability when checkpointing global rewards and user rewards in the same block.
The relevant code sections are:

       function _checkpointGlobalReward() internal {
           rewardPerTokenAccumulatedCheckpoint = rewardPerTokenAccumulated();
           lastCheckpointTime = lastTimeRewardDistributed();
       }

       function _checkpointReward(address _beneficiary) internal {
           unclaimedRewardCheckpoint[_beneficiary] = 
       unclaimedReward(_beneficiary);
           beneficiaryRewardPerTokenCheckpoint[_beneficiary] = 
       rewardPerTokenAccumulatedCheckpoint; 
       }
The issue is that _checkpointGlobalReward updates the global rewardPerTokenAccumulatedCheckpoint variable, which is then read in _checkpointReward.
A malicious miner could exploit this by:
1. Call `_checkpointGlobalReward`
2. Call `_checkpointReward` for one or more addresses they control
3. Front-run and include a transaction that updates state to reduce actual accrued rewards
4. The updated rewardPerTokenAccumulatedCheckpoint no longer reflects actual accrued rewards at time of user checkpoint
This means the user reward checkpoints could be manipulated to a lower value than they should be, reducing claimed rewards.


## Tools Used
Manual
## Recommended Mitigation Steps
Instead of checkpointing the global reward first, the contract should checkpoint the user's rewards before updating the global reward. This way, even if a front-running transaction occurs, the user's rewards will have already been checkpointed, and the attacker
The sufficient reward token balance check at the end of `notifyRewardAmount()` performs less accurately due to a precision loss
Audit: 2024-02-uniswap-foundation-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L594-L596


# Vulnerability details

## Impact
Contract's reward token check can be hiddenly bypassed due to a rounding error in the final check

## Proof of Concept
Solidity rounds down the result of an integer division, and because of that, it is always recommended to multiply before dividing to avoid that precision loss. In the case of a prior division over multiplication, the final result may face serious precision loss as the first answer would face truncated precision and then multiplied to another integer.
If we check the function `notifyRewardAmount()`, we see that a check exists at the end of the function which ensures the contract has sufficient tokens.

```Solidity
    // This check cannot _guarantee_ sufficient rewards have been transferred to the contract,
    // because it cannot isolate the unclaimed rewards owed to stakers left in the balance. While
    // this check is useful for preventing degenerate cases, it is not sufficient. Therefore, it is
    // critical that only safe reward notifier contracts are approved to call this method by the
    // admin.
    if (
      (scaledRewardRate * REWARD_DURATION) > (REWARD_TOKEN.balanceOf(address(this)) * SCALE_FACTOR)
    ) revert UniStaker__InsufficientRewardBalance();
```

And also, the calculation of the `scaledRewardRate` parameter:

```Solidity
if (block.timestamp >= rewardEndTime) {
      scaledRewardRate = (_amount * SCALE_FACTOR) / REWARD_DURATION;
    } else {
      uint256 _remainingReward = scaledRewardRate * (rewardEndTime - block.timestamp);
      scaledRewardRate = (_remainingReward + _amount * SCALE_FACTOR) / REWARD_DURATION;
    }
```

we can see there is a hidden division before a multiplication that makes round down the whole expression. 
This is bad as the precision loss can be significant, which leads to checking the sufficient tokens less accurately. To be precise, the abovementioned invariant can be written in this way:

`(scaledRewardRate * REWARD_DURATION) <= (REWARD_TOKEN.balanceOf(address(this)) * SCALE_FACTOR)`

However, due to the priority of division over multiplication in the calculation of `scaledRewardRate`, in the **current implementation**, the `(scaledRewardRate * REWARD_DURATION)` is always equal or less than the **actual** `(scaledRewardRate * REWARD_DURATION)`.
Thus, it may incorrectly check the invariant in some cases.

## Tools Used
Manual Review
## Recommended Mitigation Steps
Consider rewriting the sufficient token condition in a way that the `REWARD_DURATION` is multiplied first.


## Assessed type

Math
Rewards in the `UniStaker.sol` contract for the initial period can be lost
Audit: 2024-02-uniswap-foundation-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L570-L599


# Vulnerability details

## Impact

The `UniStaker.sol` contract within the `UniStaker Infrastructure Protocol` is designed to manage the staking of UNI tokens and the distribution of rewards generated from protocol fees on `Uniswap V3`. This contract allows UNI holders to stake their tokens, delegate their governance voting rights, and earn rewards based on the fees collected from Uniswap V3 pools. The rewards are distributed in a designated token, which is determined at the deployment of the contracts.

The staking mechanism is inspired by the Synthetix `StakingRewards.sol` implementation, which distributes rewards over a fixed period. This period restarts whenever new rewards are added to the system. Stakers can deposit their UNI tokens into the contract, delegate their voting rights, and specify a beneficiary for their rewards. The contract tracks each staker's deposit on a per-position basis, allowing for independent management of each staking position.

Rewards management and distribution are handled through a system where the accrued fees from Uniswap V3 pools are auctioned for the designated reward token. The `UniStaker.sol` contract collects these tokens and distributes them to stakers based on their share of the total staked UNI. The distribution rate is determined by the amount of reward tokens available and the duration over which they are to be distributed.

The reward calculation and distribution mechanism is designed to ensure fair and proportional allocation of rewards to all stakers based on their contribution to the pool. However, this system relies on the accurate tracking of staking durations and the timely update of reward rates.

The primary impact of the bug in the `UniStaker.sol` contract is the potential loss of rewards for the initial period of staking. This can occur when the reward distribution mechanism does not account for the time elapsed between the initiation of the reward period and the participation of the first staker.
The vulnerability in the `UniStaker.sol` contract mirrors the issue found in Synthetix's staking rewards mechanism, where rewards for the initial period can be lost if there are no participants to claim them. In the context of the UniStaker Infrastructure Protocol, this means that rewards generated from protocol fees could go unclaimed during periods of low or no participation in staking. This not only leads to inefficiencies in reward distribution but also disincentivizes early participation in the staking process.

## Proof of Concept

- [`UniStaker.sol#notifyRewardAmount()`](https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L555-L599) function

```solidity
  /// @notice Called by an authorized rewards notifier to alert the staking contract that a new
  /// reward has been transferred to it. It is assumed that the reward has already been
  /// tran
Reward Token Loss When No Stakers at The Current Reward Duration (Partly or Fully)
Audit: 2024-02-uniswap-foundation-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-02-uniswap-foundation/blob/5a2761c8277541a24bc551fbd624413b384bea94/src/UniStaker.sol#L570


# Vulnerability details

## Impact
The vulnerability in the UniStaker contract poses a significant risk of reward token loss for the protocol. This issue arises when there are no stakers present during a reward duration. As a result, the reward tokens allocated for distribution in this duration remain unclaimed, and unrecoverable, leading to a direct loss for the protocol.

## Proof of Concept
Our investigation into the UniStaker contract identified instances where reward tokens were left unclaimed and unrecoverable due to the absence of stakers during reward durations. This underscores the importance of addressing the vulnerability to enhance the protocol's reward distribution mechanism.

Furthermore, the interaction between the `V3FactoryOwner` contract and the `UniStaker` contract, along with the "payout race" mechanism employed by the V3FactoryOwner contract, exacerbates this vulnerability by facilitating reward token distribution through the `notifyRewardAmount` (see [V3FactoryOwner.so#L188](https://github.com/code-423n4/2024-02-uniswap-foundation/blob/5a2761c8277541a24bc551fbd624413b384bea94/src/V3FactoryOwner.sol#L188)) function and inadvertently leading to reward token loss when no stakers are present during reward durations.
```solidity
src/V3FactoryOwner.sol:
181:   function claimFees(
182:     IUniswapV3PoolOwnerActions _pool,
183:     address _recipient,
184:     uint128 _amount0Requested,
185:     uint128 _amount1Requested
186:   ) external returns (uint128, uint128) {
187:     PAYOUT_TOKEN.safeTransferFrom(msg.sender, address(REWARD_RECEIVER), payoutAmount);
188:     REWARD_RECEIVER.notifyRewardAmount(payoutAmount);
```

### Test Cases using Foundry

These test cases will demonstrate scenarios where reward tokens become unrecoverable due to various actions and conditions within the UniStaker contract.

To execute the test suite, copy and paste the provided contract into the `test/UniStaker.t.sol` file. Then, run the following command:

```bash
forge test --match-contract PoC_UnclaimableRewardTest
```


```solidity
contract PoC_UnclaimableRewardTest is UniStakerRewardsTest {

  function testFuzz_UnrecoverableRewardTokenAfterUserStakesThenWithdrawsBeforeAnyRewardsThenClaimAfterRewardDurationWithoutStakers(
    address _depositor,
    uint256 _stakeAmount,
    uint256 _rewardAmount
  ) public {
    vm.assume(_depositor != address(uniStaker));
    (_stakeAmount, _rewardAmount) = _boundToRealisticStakeAndReward(_stakeAmount, _rewardAmount);

    // A user deposits staking tokens
    (, UniStaker.DepositIdentifier _depositId) =
      _boundMintAndStake(_depositor, _stakeAmount, _depositor);

    // Some time passes
    _jumpAheadByPercentOfRewardDuration(101);

    // User withdraws staking tokens before any rewards
    vm.prank(_depositor);
    uniStaker.withdraw(_depositId, _stakeAmount);
Insufficient Fund Check Leads to Potential Protocol Insolvency and Reward Freezing
Audit: 2024-02-uniswap-foundation-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L570-L599


# Vulnerability details

## Impact
Detailed description of the impact of this finding.
description: The `notifyRewardAmount` function in the staking contract contains a vulnerability that could result in protocol insolvency or the freezing of user funds due to an inaccurate calculation of the `scaledRewardRate` relative to the actual `REWARD_TOKEN` balance. This flaw arises because the check for a sufficient balance does not account for unclaimed rewards, potentially allowing the contract to commit to distributing more rewards than the balance can support. If the contract's token balance is insufficient, users may not be able to claim their earned rewards, leading to a loss of trust and functionality in the system. The lack of a robust mechanism to refresh or update the contract's balance after distributing rewards exacerbates the issue, increasing the risk of an insolvent state where the promised rewards exceed the available tokens.
## Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L570-L599
## Tools Used

## Recommended Mitigation Steps
**Finding Recommendation:**

To address the vulnerability identified in the `notifyRewardAmount` function and prevent potential protocol insolvency or freezing of funds/unclaimed yield, it is recommended to implement the following measures:

1. **Regularly Audit and Reconcile Reward Token Balances:** Implement a mechanism to regularly audit and reconcile the contract's balance of `REWARD_TOKEN` to ensure that it accurately reflects the total rewards owed to users, including unclaimed rewards. This will help prevent scenarios where the contract promises more rewards than it can deliver.

2. **Update Reward Rate Calculation:** Modify the reward rate calculation process to account for any unclaimed rewards or outstanding balances from previous reward periods. Consider implementing a mechanism to distribute unclaimed rewards or handle outstanding balances before setting a new reward rate to prevent protocol insolvency.

3. **Enhance Authorization and Access Control:** Strengthen authorization and access control mechanisms to ensure that only trusted and verified reward notifier contracts are approved to call the `notifyRewardAmount` function. This will help mitigate the risk of unauthorized entities manipulating reward rates or causing protocol insolvency.

4. **Implement Emergency Withdrawal Mechanism:** Consider implementing an emergency withdrawal mechanism that allows users to withdraw their funds in case of protocol insolvency or freezing of funds. This mechanism can provide an additional layer of protection for users in case of unforeseen circumstances.

By implementing these recommendations, the protocol can e
Potential Misattribution of Accrued Rewards Due to Missing Claim Logic in Beneficiary Alteration Function
Audit: 2024-02-uniswap-foundation-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L704-L718


# Vulnerability details

## Impact
Detailed description of the impact of this finding.
"description: The `_alterBeneficiary` function in the smart contract fails to claim rewards for the original beneficiary before reassigning the deposit to a new beneficiary. This oversight can result in the original beneficiary not receiving the rewards they have accrued, as the `earningPower` mapping is updated to reflect the new beneficiary's balance without accounting for the unclaimed rewards. Consequently, the new beneficiary could unjustly benefit from rewards earned by the previous holder, leading to potential theft of unclaimed yield or a contract failing to deliver promised returns to the rightful owner."
## Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L704-L718
## Tools Used

## Recommended Mitigation Steps
Finding: High

Recommendation: Add a check in the `_alterBeneficiary` function to ensure that rewards accrued to the original beneficiary are claimed before changing the beneficiary. This can be achieved by including a call to a reward claiming function (e.g., `claimTribute()`) before updating the beneficiary. Additionally, consider implementing a more robust reward distribution mechanism to prevent potential misattribution of rewards in the future. Regularly review and update the contract logic to adhere to best practices for fair reward distribution.


## Assessed type

Invalid Validation
Front-Running Vulnerability in Reward Distribution Allowing Extraction of Miner-Extractable Value (MEV)
Audit: 2024-02-uniswap-foundation-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L753-L756


# Vulnerability details

## Impact
Detailed description of the impact of this finding.
description: The identified vulnerability stems from the potential for an attacker to engage in front-running within the `_checkpointGlobalReward` function of the staking contract. By monitoring the blockchain for transactions calling the `receiveRewards` function and placing a high gas fee transaction to deposit a substantial amount of tokens just before the `receiveRewards` transaction is confirmed, the attacker can manipulate the `rewardPerTokenAccumulatedCheckpoint` and `lastCheckpointTime` to reflect the inflated token amount. Consequently, when the `receiveRewards` transaction is processed, rewards are calculated and distributed based on this inflated stake, allowing the attacker to claim a disproportionate share of the rewards upon withdrawal. This manipulation effectively allows the attacker to extract miner-extractable value (MEV) and constitutes theft of unclaimed yield, severely impacting the fairness of reward distribution and resulting in financial losses for honest stakers.
## Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L753-L756
## Tools Used

## Recommended Mitigation Steps
Finding Recommendation:
To address this vulnerability and prevent front-running attacks on the rewards distribution mechanism, it is recommended to implement safeguards such as:

1. Implementing a delay or lockup period before rewards can be claimed after a deposit is made to prevent attackers from quickly withdrawing their funds and rewards.
2. Implementing a cap on the amount of rewards that can be claimed based on the duration of staking, to prevent disproportionately large rewards for short staking periods.
3. Using secure timestamping techniques or oracle verification to ensure the accuracy of reward calculations and prevent manipulation of timing.
4. Auditing the contract code to identify and address any other potential vulnerabilities that could be exploited in a similar manner.

By implementing these safeguards, the contract can mitigate the risk of MEV extraction through front-running attacks and ensure a fair distribution of rewards to all stakers.


## Assessed type

MEV
Potential Exploitation of Outdated Reward Checkpoint in Staking Reward Calculation
Audit: 2024-02-uniswap-foundation-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L229-L234


# Vulnerability details

## Impact
Detailed description of the impact of this finding.
description: The `rewardPerTokenAccumulated` function in the provided Solidity code is vulnerable to the exploitation of outdated reward checkpoints in exceptional system states. This vulnerability arises because the function computes rewards based on the `rewardPerTokenAccumulatedCheckpoint` without updating it in response to changes in the system state that may prevent accurate reward distribution. If the system enters a state where the total staked amount (`totalStaked`) changes after a shutdown or similar exceptional condition, users could manipulate their rewards by transferring stakes and claiming rewards that are not rightfully theirs, based on the stale `rewardPerTokenAccumulatedCheckpoint`. This can result in unauthorized extraction of unclaimed yield, potentially leading to unjust enrichment at the expense of the protocol and its rightful users. The root cause is the absence of checks and balances to ensure that the checkpoint data reflects the current system state, and the maximum impact could be the theft or freezing of unclaimed yield, undermining the integrity of the reward distribution mechanism.
## Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
https://github.com/code-423n4/2024-02-uniswap-foundation/blob/main/src/UniStaker.sol#L229-L234
## Tools Used

## Recommended Mitigation Steps
Finding Recommendation:
To address the vulnerability identified in the code snippet, it is recommended to implement a mechanism that ensures the `rewardPerTokenAccumulatedCheckpoint` is updated consistently, even in special states where checkpoints are not normally updated. This could involve adding a check within the function to update the checkpoint if certain conditions are met, or implementing a separate function to handle checkpoint updates. Additionally, consider restricting user participation transfers when the system is in the special state to prevent exploitation of outdated data. Regularly auditing and monitoring the code for such vulnerabilities is also recommended to maintain the security and integrity of the protocol.


## Assessed type

Timing