xanoutas/solidity-security-findings huggingface dataset:
Incorrect Usage of block.timestamp in newConfig Function
Audit: 2023-08-shell-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-08-shell/blob/main/src/proteus/EvolvingProteus.sol#L72


# Vulnerability details

## Description

In the newConfig function, the usage of block.timestamp to calculate the endTimestamp is problematic. The block.timestamp represents the current timestamp in seconds since the Unix epoch. The code intends to add _duration to block.timestamp to calculate the endTimestamp, but there is an implicit assumption about the unit of _duration.

If _duration is provided in seconds, the calculation will be correct. However, if _duration is in units other than seconds (e.g., minutes or hours), the resulting endTimestamp will be incorrect and may lead to undesired behavior.

## Impact

 Calculated endTimestamp will be incorrect when _duration is provided in units other than seconds. This can lead to incorrect timing for time-sensitive operations. For example, if a contract relies on endTimestamp to determine when a certain action is allowed or forbidden, the action might be enabled or disabled at the wrong times.
## Proof of Concept
 Let's assume _duration is provided in minutes, but the code assumes it's in seconds. I'll illustrate this by showing the difference between the expected and actual endTimestamp values.


// Assume the contract  is deployed and accessible here

// Call the newConfig function with _duration in minutes
uint256 _durationInMinutes = 5; // 5 minutes
Config memory config = newConfig(0, 0, 0, 0, _durationInMinutes);

// Expected endTimestamp calculation (with _duration in seconds)
uint256 expectedEndTimestamp = block.timestamp + _durationInMinutes * 60; // Convert minutes to seconds

// Print the expected and actual endTimestamp values
console.log("Expected endTimestamp:", expectedEndTimestamp);
console.log("Actual endTimestamp:", config.endTimestamp);


we will notice that the expected and actual endTimestamp values will differ. This is because the _durationInMinutes value was assumed to be in seconds in the contract, leading to incorrect calculations for the endTimestamp.

This demonstrates that when _duration is provided in a different time unit, the resulting endTimestamp will not match the 

## Tools Used
Manual Review
## Recommended Mitigation Steps


Bug Report: Incorrect Usage of block.timestamp in newConfig Function

Summary:
The newConfig function in the provided Solidity code is intended to create a new configuration with specific initial and final values, along with a duration. However, there is an issue with the usage of block.timestamp which may lead to unexpected behavior.

Description:
In the newConfig function, the usage of block.timestamp to calculate the endTimestamp is problematic. The block.timestamp represents the current timestamp in seconds since the Unix epoch. The code intends to add _duration to block.timestamp to calculate the endTimestamp, but there is an implicit assumption about the unit of _duration.

If _duration is provided in seconds, the calculation will
Upgraded Q -> 3 from #23 [1722887783819]
Audit: 2024-07-munchables-findings
Severity: HIGH

Judge has assessed an item in Issue #23 as 3 risk. The relevant finding follows:

 # [L-04] LandManager::transferToUnoccupiedPlot() function doesn't update the **toilerState.dirty** mapping variable
The [transferToUnoccupiedPlot()](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L199-L226) function allows users to transfer their NFTs to an unoccupied slot, however only the latestTaxRate is updated, which is not necessary as the latestTaxRate is updated in the [_farmPlots()](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L232-L310) function before the logic in the [transferToUnoccupiedPlot()](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L199-L226) function which is called beforehand. However the dirty variable in the **mapping(uint256 => ToilerState) public toilerState;** mapping is not updated
```solidity
    struct ToilerState {
        uint256 lastToilDate;
        uint256 plotId;
        address landlord;
        uint256 latestTaxRate;
        bool dirty;
    }
```
This will be a problem and result in a user loosing rewards in the following scenario. Consider that a user stakes his NFT in the last available plot for a certain landlord, however the landlord decreases his lock in the LockManager contract, and now has less available plots. When the user that staked in the last plot tries to farm his accrued rewards and the [farmPlots()](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L228-L230) function is called which in turn calls the [_farmPlots()](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L232-L310) internal function, the dirty variable will be set to true. If a user sees that the available plots of a landlord have decreased and directly calls the [transferToUnoccupiedPlot()](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L199-L226) function, the [_farmPlots()](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L232-L310) internal function logic will be executed before the logic in [transferToUnoccupiedPlot()](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L199-L226) and the dirty variable will be set to true again. If a user transfers his NFT to a previous plot, that should be receiving rewards the dirty variable will still be equal to true, and the user won't be able to accrue and later farm any rewards.

Consider the following example:
 - **LandLordA** has 10 available plots, userA stakes his NFT at plotId 9.
 - **LandLordA** decreases his lock and now only have 5 available plots.
 - **UserA** sees that and decides to move his NFT to plotId 4, which is not occupied, in order to continue receiving rewards. However when he calls the [transferToUnoccupiedPlot()](https://github.com/code-423n4/2024-07-munc
Upgraded Q -> 3 from #314 [1722887703631]
Audit: 2024-07-munchables-findings
Severity: HIGH

Judge has assessed an item in Issue #314 as 3 risk. The relevant finding follows:

 ## [QA-02] `transferToUnoccupiedPlot` fails to update `toilerState.plotId`, leading to incorrect plot tracking and could also unnecessarily mark plots as "dirty"

#### Impact

The `transferToUnoccupiedPlot` function in the LandManager contract fails to update the `plotId` in the `toilerState` mapping when a Munchable NFT is moved to a new plot resulting in a discrepancy between the actual plot a token is associated with and the plot recorded in the `toilerState`. 

#### Proof of Concept

Look at the `transferToUnoccupiedPlot` function: https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L199-L227

```solidity
function transferToUnoccupiedPlot(
    uint256 tokenId,
    uint256 plotId
) external override forceFarmPlots(msg.sender) notPaused {
    (address mainAccount, ) = _getMainAccountRequireRegistered(msg.sender);
    ToilerState memory _toiler = toilerState[tokenId];
    uint256 oldPlotId = _toiler.plotId;
    uint256 totalPlotsAvail = _getNumPlots(_toiler.landlord);
    // ... (validity checks)

    toilerState[tokenId].latestTaxRate = plotMetadata[_toiler.landlord]
        .currentTaxRate;
    plotOccupied[_toiler.landlord][oldPlotId] = Plot({
        occupied: false,
        tokenId: 0
    });
    plotOccupied[_toiler.landlord][plotId] = Plot({
        occupied: true,
        tokenId: tokenId
    });

    emit FarmPlotLeave(_toiler.landlord, tokenId, oldPlotId);
    emit FarmPlotTaken(toilerState[tokenId], tokenId);
}
```

The function updates the `plotOccupied` mapping for both the old and new plots, correctly marking the old plot as unoccupied and the new plot as occupied. But, it fails to update the `plotId` in the `toilerState` mapping for the token.

This means that while `plotOccupied` correctly reflects the new state, `toilerState[tokenId].plotId` still contains the old plot ID. This could lead to issues in other parts of the protocol that rely on the `toilerState` mapping, such as the [`_farmPlots` function](https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L250):

```solidity
function _farmPlots(address _sender) internal {
    // ...
    for (uint8 i = 0; i < staked.length; i++) {
        // ...
        _toiler = toilerState[tokenId];
  @>      // ...
        if (_getNumPlots(landlord) < _toiler.plotId) {
            timestamp = plotMetadata[landlord].lastUpdated;
            toilerState[tokenId].dirty = true;
        }
        // ... (farming calculations using _toiler.plotId)
    }
    // ...
}
```

In this function, the outdated `plotId` in `toilerState` could lead to incorrect farming calculations or unnecessary marking of plots as "dirty".

#### Recommended Mitigation Steps

Update the `transferToUnoccupiedPlot` function to include an update
Incomplete Update of ToilerState in LandManager::transferToUnoccupiedPlot()
Audit: 2024-07-munchables-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L199-L226


# Vulnerability details

## Description
The [`LandManager::transferToUnoccupiedPlot()`](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L199-L226) function does not properly update the `ToilerState` for the given `tokenId`.

```solidity 
File: src/managers/LandManager.sol

199:     function transferToUnoccupiedPlot(
200:         uint256 tokenId,
201:         uint256 plotId
202:     ) external override forceFarmPlots(msg.sender) notPaused {
203:         (address mainAccount, ) = _getMainAccountRequireRegistered(msg.sender);
204:         ToilerState memory _toiler = toilerState[tokenId];
205:         uint256 oldPlotId = _toiler.plotId;
206:         uint256 totalPlotsAvail = _getNumPlots(_toiler.landlord);
207:         if (_toiler.landlord == address(0)) revert NotStakedError();
208:         if (munchableOwner[tokenId] != mainAccount) revert InvalidOwnerError();
209:         if (plotOccupied[_toiler.landlord][plotId].occupied)
210:             revert OccupiedPlotError(_toiler.landlord, plotId);
211:         if (plotId >= totalPlotsAvail) revert PlotTooHighError();
212: 
213:@>       toilerState[tokenId].latestTaxRate = plotMetadata[_toiler.landlord]    //@audit only update the latestTaxRate state
214:             .currentTaxRate;
215:         plotOccupied[_toiler.landlord][oldPlotId] = Plot({
216:             occupied: false,
217:             tokenId: 0
218:         });
219:         plotOccupied[_toiler.landlord][plotId] = Plot({
220:             occupied: true,
221:             tokenId: tokenId
222:         });
223: 
224:         emit FarmPlotLeave(_toiler.landlord, tokenId, oldPlotId);
225:         emit FarmPlotTaken(toilerState[tokenId], tokenId);
226:     }
```

The `ToilerState` struct:
``` soldiity
    struct ToilerState {    
        uint256 lastToilDate;   
        uint256 plotId;
        address landlord;    
        uint256 latestTaxRate;
        bool dirty;
    }
```

The [LandManager::transferToUnoccupiedPlot()](https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L199-L226) is intended to allow renters to change their plot to an unoccupied plot for various reasons, such as:

1. Changing to a lesser `plotId` to avoid invalid plotId values when the landlord updates their plots.
2. Moving to a valid plot when the current `ToilerState` is dirty, preventing farming.

However, the incomplete update of the `ToilerState` when transferring to an unoccupied plot results in incorrect behavior of the `ToilerState` for the `tokenId`.


## Impact
The impact of this issue can manifest in multiple ways due to the incorrect update of the `ToilerState`. 

The core functions that are affected by this issue are:
#### 1. **[LandManager::unstakeMunchable()](https://github.com/code-423n4/2024-07-munchables
Deflation of Total Schnibbles Value Due to Error in Bonus Math Calculation
Audit: 2024-07-munchables-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-07-munchables/blob/main/src/managers/LandManager.sol#L283-L286


# Vulnerability details

## Impact
Loss of Player Fund value due to deflation of Total Schnibbles as a result of Schnibbles bonus addition math operation which should have increase Total Schnibbles but reverse is the case as total Schnibbles would be deflated by approximately 100 times over when _farmPlots(...) function is called in the LandManager contract
## Proof of Concept
https://github.com/code-423n4/2024-05-munchables/blob/main/guides/ARCHITECTURE.md

[Schnibbles Addition Operation as shown in Doc](https://github.com/user-attachments/assets/b5a12d53-6a82-431b-aeed-4e7775201f4c)
The links above from the munchables documentation shows that protocol gives migration bonus that gives players additional daily Schnibbles.
```solidity
    function _farmPlots(address _sender) internal {
        ...
        int256 finalBonus;
        uint256 schnibblesTotal;
        uint256 schnibblesLandlord;
        for (uint8 i = 0; i < staked.length; i++) {
            ...
            finalBonus =
                int16(
                    REALM_BONUSES[
                        (uint256(immutableAttributes.realm) * 5) +
                            uint256(landlordMetadata.snuggeryRealm)
                    ]
                ) +
                int16(
                    int8(RARITY_BONUSES[uint256(immutableAttributes.rarity)])
                );
            schnibblesTotal =
                (timestamp - _toiler.lastToilDate) *
                BASE_SCHNIBBLE_RATE;
            schnibblesTotal = uint256(
                (int256(schnibblesTotal) +
>>>                    (int256(schnibblesTotal) * finalBonus)) / 100  ❌
            );
...
}
```
The code above shows how this bonus is implemented and added to the total schnibbles for players in the _farmPlots(...) function in the LandManager contract. It can be noted that final bonus is calculated by adding RealmBonuses & RarityBonuses after which it is used to calculate a bonus addition to the total Schnibbles in other to increase or decrease it depending on the bonus value as bonus can also be negative. 
Item 35 and 36 of this munchables documentation at https://github.com/code-423n4/2024-05-munchables/blob/main/guides/CONSTANTS.md shows that bonus are represented with a direct value that represents the percentage of bonus in relation to 100%, as can be noted in the doc 1 is equivalent to 1%, 2 to 2% and so on
[RealmBonuses & RarityBonuses Doc ScreenShot](https://github.com/user-attachments/assets/32c3af69-5019-404d-b791-48f50d30ddd2)
This can also be verified in the pointer in the code quoted by this report which shows a division by 100 i.e 100%.
In summary the problem this report is trying to point out is that the 100 is wrongly placed, it is understandable that multiplication of the bonus should first be carried out before division by 100 to avoid precision loss which is why the 100 is outside the br
Incorrect bonus calculation in `_farmPlots` function leading to undervaluation of `schnibblesTotal`
Audit: 2024-07-munchables-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L280-L286


# Vulnerability details

## Impact
The incorrect calculation of `schnibblesTotal` in the `_farmPlots` function results in significantly lower rewards being calculated and distributed. `schnibblesTotal` value represents the total rewards (`schnibbles`) generated by the staked munchables over a period of time. Therefore an incorrect calculation of `schnibblesTotal` means that the rewards distributed to both the `renter` and the `landlord` will be significantly lower than intended.

Also, the `renterMetadata.unfedSchnibbles` and `landlordMetadata.unfedSchnibbles` are updated based on the `schnibblesTotal` value. An incorrect `schnibblesTotal` results in incorrect updates to these state variables, causing inaccurate tracking of rewards.

>I reached out to the sponsor to confirm  if the protocol's intention was to apply `finalBonus` as a percentage modifier to `schnibblesTotal` and his response was "Yes" and he also confirmed the bug described in this report.


## Proof of Concept
Take a look at this part of the code: https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L280-L286

```solidity
schnibblesTotal =
    (timestamp - _toiler.lastToilDate) *
    BASE_SCHNIBBLE_RATE;
schnibblesTotal = uint256(
    (int256(schnibblesTotal) +
        (int256(schnibblesTotal) * finalBonus)) / 100
);
```

As seen above, the code attempts to apply a bonus by adding the product of `schnibblesTotal` and `finalBonus` to `schnibblesTotal` itself, and then dividing by 100. This is not correct because it effectively reduces the `schnibblesTotal` by a factor of 100.

For example let's say:

- `timestamp = 2000`
- `_toiler.lastToilDate = 1000`
- `BASE_SCHNIBBLE_RATE = 10`
- `finalBonus = 20` (representing a 20% bonus)

The implemented code will calculate it as:

1. **Calculate `schnibblesTotal` without bonus:**
   ```solidity
   schnibblesTotal = (timestamp - _toiler.lastToilDate) * BASE_SCHNIBBLE_RATE;

   schnibblesTotal = (2000 - 1000) * 10;
   schnibblesTotal = 10000;
   ```

2. **Apply the bonus:**
   ```solidity
   schnibblesTotal = uint256(
       (int256(schnibblesTotal) + (int256(schnibblesTotal) * finalBonus)) / 100
   );

   schnibblesTotal = uint256(
       (10000 + (10000 * 20)) / 100
   );
   schnibblesTotal = uint256(
       (10000 + 200000) / 100
   );
   schnibblesTotal = uint256(
       210000 / 100
   );
   schnibblesTotal = 2100;
   ```

BUT, It should actually be calculated this way:

1. **Calculate `schnibblesTotal` without bonus:**
   ```solidity
   schnibblesTotal = (timestamp - _toiler.lastToilDate) * BASE_SCHNIBBLE_RATE;
   schnibblesTotal = (2000 - 1000) * 10;
   schnibblesTotal = 10000;
   ```

2. **Apply the bonus:**
   ```solidity
   schnibblesTotal = uint256(
       (int256(schnibblesTotal) * (100 + finalBonus)) / 100
   )
Missing `ToilerState[tokenId].plot` updatation in `transferToUnoccupiedPlot` leads to incorrect rewards calculation
Audit: 2024-07-munchables-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L199
https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L29
https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/interfaces/ILandManager.sol#L7


# Vulnerability details

## Vulnerability Description 

Main purpose of [transferToUnoccupiedPlot](https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L199) function is to transfer Munchable (TokenId) from one Plot to another plot and it then update the [plotOcuppied](https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L215-L222) mapping correctly and update the tax to [latestTaxRate](https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L213). But, The issues lies in the [transferToUnoccupiedPlot](https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L199) function where it neglects to update the plotId of Munchable TokenId in it's [Toiler'sState Mapping](https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L29) leading to an incorrectness between the actual location of the Munchable and its recorded state.

## Code Snippet

[transferToUnoccupiedPlot](https://github.com/code-423n4/2024-07-munchables/blob/94cf468aaabf526b7a8319f7eba34014ccebe7b9/src/managers/LandManager.sol#L199)

```solidity
function transferToUnoccupiedPlot(
        uint256 tokenId,
        uint256 plotId
    ) external override forceFarmPlots(msg.sender) notPaused {
        (address mainAccount, ) = _getMainAccountRequireRegistered(msg.sender);
        ToilerState memory _toiler = toilerState[tokenId];
        uint256 oldPlotId = _toiler.plotId;
        uint256 totalPlotsAvail = _getNumPlots(_toiler.landlord);
        if (_toiler.landlord == address(0)) revert NotStakedError();
        if (munchableOwner[tokenId] != mainAccount) revert InvalidOwnerError();
        if (plotOccupied[_toiler.landlord][plotId].occupied)
            revert OccupiedPlotError(_toiler.landlord, plotId);
        if (plotId >= totalPlotsAvail) revert PlotTooHighError();

        toilerState[tokenId].latestTaxRate = plotMetadata[_toiler.landlord]
            .currentTaxRate;
        plotOccupied[_toiler.landlord][oldPlotId] = Plot({
            occupied: false,
            tokenId: 0
        });
        plotOccupied[_toiler.landlord][plotId] = Plot({
            occupied: true,
            tokenId: tokenId
        });
        //@audit  Missing: Update toilerState[tokenId].plotId
        emit FarmPlotLeave(_toiler.landlord, tokenId, oldPlotId);
        emit F