xanoutas/solidity-security-findings huggingface dataset:
burn function which had no restraints and could be called by anyone can cause too many token  because  _burn have  bug  at OLAS contract 
Audit: 2023-12-autonolas-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/governance/contracts/OLAS.sol#L118
https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/governance/lib/solmate/src/tokens/ERC20.sol#L196


# Vulnerability details

## Impact
Anyone can call burn function to cause too many token.

## Proof of Concept

https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/governance/contracts/OLAS.sol#L118

    function burn(uint256 amount) external {
        _burn(msg.sender, amount);
    }    

_burn which refer to erc20 at solmate don't  to check overflow 

https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/governance/lib/solmate/src/tokens/ERC20.sol#L195
   
    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount; // bug 

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }

## Tools Used
vscode

## Recommended Mitigation Steps
use openzeppelin erc20 safemath functionn or limit access control such as：        
if (msg.sender != minter) {
            revert ManagerOnly(msg.sender, minter);
        




















## Assessed type

Under/Overflow
Polygon reorgs can lead to tokens being lost
Audit: 2023-12-autonolas-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/main/governance/contracts/bridges/FxERC20RootTunnel.sol#L54-L56


# Vulnerability details

## Background
Polygon blockchain reorgs occurs [multiple times a day](https://polygonscan.com/blocks_forked). These reorgs can have a big block depth. At the time of writing, 35 reorgs happened(!) in the last 24 hours. I want to emphasize that these reorgs happen a lot. In fact, this is one of the main reasons that bridging from Polygon to Ethereum using `FxPortal` takes around 30 minutes. The `FxPortal` waits until the transaction proof becomes valid.
### Proof of Concept
Consider the following:
- Alice wants to bridge 1000 OLAS from Ethereum to Polygon.
- Alice calls `FxERC20RootTunnel.withdraw` to initiate the bridging.
```javascript
    /// @dev Withdraws bridged tokens on L1 in order to obtain their original version on L2.
    /// @notice Destination address is the same as the sender address.
    /// @param amount Token amount to be withdrawn.
    function withdraw(uint256 amount) external {
        _withdraw(msg.sender, amount);
    }
```
- `stateSync()` gets called, which initiates the flight from Ethereum to Polygon.
	- [stateSync Polygon docs](https://docs.polygon.technology/pos/architecture/bor/state-sync/?h=statesync)
- The call arrives on Polygon. The `rootToken` gets minted to Alice in `_processMessageFromChild` on Polygon. This `rootToken` is a 1-1 reflection of the OLAS token on the Ethereum network.
```javascript
    function _processMessageFromChild(bytes memory message) internal override {
        (address from, address to, uint256 amount) = abi.decode(message, (address, address, uint256));
        IERC20(rootToken).mint(to, amount);
        emit FxDepositERC20(childToken, rootToken, from, to, amount);
```
- A reorg happens.
- Previous states of X amount of blocks are reverted.
- Alice won't have the minted `rootToken` anymore on Polygon and the 1000 OLAS she deposited on Ethereum can not be retrieved by her. 

This means that Alice has lost her funds.
## Tools Used
Manual Review
## Recommended Mitigation Steps
Introduce a mechanism that allows users to retrieve their funds on Ethereum if the deposit fails on the Polygon chain. You could introduce a callback from Polygon back to Ethereum to guarantee that the bridging process of a user has been successful. 



## Assessed type

Other
[H-04] Reentrancy in the wveOLAS contract
Audit: 2023-12-autonolas-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/governance/contracts/wveOLAS.sol#L263-L273


# Vulnerability details

## Impact
Any interaction from a contract (A) with another contract (B) and any transfer of Ether hands over control to that contract (B). This makes it possible for B to call back into A before this interaction is completed.

Check-effects-interaction:
Potential violation of Checks-Effects-Interaction pattern in wveOLAS.totalSupplyLockedAtT(uint256): Could potentially lead to re-entrancy vulnerability. 

## Proof of Concept
The vulnerable function called totalSupplyLockedAtT is depicted below.

```sol
    function totalSupplyLockedAtT(uint256 ts) external view returns (uint256 vPower) {
        // Get the total number of supply points
        uint256 numPoints = IVEOLAS(ve).totalNumPoints();
        PointVoting memory sPoint = IVEOLAS(ve).mapSupplyPoints(numPoints);
        // Check the last supply point timestamp is not smaller than the specified ts
        if (ts >= sPoint.ts) {
            vPower = IVEOLAS(ve).totalSupplyLockedAtT(ts);
        } else {
            revert WrongTimestamp(sPoint.ts, ts);
        }
    }
```

The exploit contract that re-enters the wveOLAS contract is depicted below and written in remix IDE.
```sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "./wveOLAS.sol";

contract wveOLASX {

    wveOLAS public x1;
    // veOLAS address
    address public immutable ve;
    // OLAS address
    address public immutable token;
    // veOLAS token name
    string public constant name = "Voting Escrow OLAS";
    // veOLAS token symbol
    string public constant symbol = "veOLAS";
    // veOLAS token decimals
    uint8 public constant decimals = 18;

    constructor(wveOLAS _x1) {
        x1 = wveOLAS(_x1);
    }

    function testReen(address _x1) external payable {
        uint256 ts = msg.value;
        while (x1.balanceOf(address(_x1)) > 1e18)
        {
            x1.totalSupplyLockedAtT(ts + 1 ether); 
        }
    }

    /// @dev Reverts other calls such that the original veOLAS is used.
    fallback() external {
        revert ImplementedIn(ve);
    }
}

```

The log result of loss of funds from the wveOLAS contract in remix IDE is displayed below.
```log
# Call to totalSupplyLockedAtT function
transact to wveOLASX.testReen pending ... 
[vm]from: 0x5B3...eddC4to: ERC20.(fallback) 0x000...00003value: 1000000000000000000 weidata: 0xc79...eddc4logs: 0hash: 0x214...e8293
status	0x1 Transaction mined and execution succeed
transaction hash	0x21452e44d358f7ba92b88f989c23ef8d538a634a442e4db68a21fc2053be8293
block hash	0x9c0c19bad209202eecd1239d9e2fa41df760aa1a5e8f972800b9569e914b19aa
block number	3
from	0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
to	ERC20.(fallback) 0x0000000000000000000000000000000000000003
gas	 gas
transaction cost	22272 gas 
execution cost	840 gas 
input	0xc79...eddc4
decoded input	-
decoded output	 - 
logs	[]
val
Parameter parsing bug in HomeMediator.sol processMessageFromForeign() function
Audit: 2023-12-autonolas-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/governance/contracts/bridges/HomeMediator.sol#L131


# Vulnerability details

## Impact
The processMessageFromForeign() function may incorrectly parse the messages. Initially, it increments the value of i by 20 (line 132) and then loads a word as the target address using mload. However, in my understading, the target address should be loaded from a memory offset of data+0, not data+20.
It will cause unexpencted behaviors when forwarding messages from the foreign contract.

## Proof of Concept
https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/governance/contracts/bridges/HomeMediator.sol#L131

## Tools Used
Manual Analysis

## Recommended Mitigation Steps
Use the following logic to parse the parameters.

```
assembly {
    // Read the address (20 bytes)
    target := mload(add(data, i))
    // Move the index after the address
    i := add(i, 20)

    // Read the uint96 value (12 bytes)
    value := mload(add(data, i))
    // Move the index after the uint96 value
    i := add(i, 12)

    // Read the payload length (4 bytes)
    payloadLength := mload(add(data, i))
    // Move the index after the payload length
    i := add(i, 4)
}






## Assessed type

call/delegatecall
ETHOwned will calculate the error
Audit: 2023-12-autonolas-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/tokenomics/contracts/Treasury.sol#L120-L133
https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/tokenomics/contracts/Treasury.sol#L257-L301


# Vulnerability details

## Impact

ETHOwned calculation errors will cause the `depositServiceDonationsETH` function to be unable to be called normally, and ETH may not be received normally.

## Proof of Concept

When the user calls `depositServiceDonationsETH`, ETH will be sent to the Treasury contract. `depositServiceDonationsETH` will only increase the value of `ETHFromServices`, but in fact when receive receives eth, `ETHOwned` will also increase.

receive and depositServiceDonationsETH implement the variables ETHFromServices and ETHOwned as follows

```solidity
      receive() external payable {
        if (msg.value < minAcceptedETH) {
            revert LowerThan(msg.value, minAcceptedETH);
        }

        uint256 amount = ETHOwned;
        amount += msg.value;
        // Check for the overflow values, specifically when fuzzing, since practically these amounts are not realistic
        if (amount + ETHFromServices > type(uint96).max) {
            revert Overflow(amount, type(uint96).max);
        }
        ETHOwned = uint96(amount);
        emit ReceiveETH(msg.sender, msg.value);
    }
  ...
  function depositServiceDonationsETH(uint256[] memory serviceIds, uint256[] memory amounts) external payable {
        ...

        // Check if the total transferred amount corresponds to the sum of amounts from services
        if (msg.value != totalAmount) {
            revert WrongAmount(msg.value, totalAmount);
        }

        // Accumulate received donation from services
        uint256 donationETH = ETHFromServices + msg.value;
        // Check for the overflow values, specifically when fuzzing, since realistically these amounts are assumed to be not possible
        if (donationETH + ETHOwned > type(uint96).max) {
            revert Overflow(donationETH, type(uint96).max);
        }
        ETHFromServices = uint96(donationETH);
        emit DonateToServicesETH(msg.sender, serviceIds, amounts, msg.value);
				...
    }
```

When a user makes a donation, it will cause `donationETH + ETHOwned` to expand twice. In addition, it will also cause the condition `amount + ETHFromServices > type(uint96).max` in the receive function to be more easily satisfied, resulting in the inability to receive ETH.

## Tools Used

Manual Review

## Recommended Mitigation Steps

Add `ETHOwned -= uint96(msg.value)` in `depositServiceDonationsETH`




## Assessed type

ETH-Transfer
Withdraw amount returned by `getLiquidityAmountsAndPositions` may be incorrect
Audit: 2023-12-autonolas-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/main/lockbox-solana/solidity/liquidity_lockbox.sol#L377


# Vulnerability details

## Impact
The `getLiquidityAmountsAndPositions()` function in the `liquidity_lockbox` contract is used to calculate the liquidity amounts and positions to be withdrawn for a given total withdrawal amount. It iterates through each deposited position following a FIFO order as shown below:

```solidity
        uint64 liquiditySum = 0;
        uint32 numPositions = 0;
        uint64 amountLeft = 0;

        // Get the number of allocated positions
        for (uint32 i = firstAvailablePositionAccountIndex; i < numPositionAccounts; ++i) {
            address positionAddress = positionAccounts[i];
            uint64 positionLiquidity = mapPositionAccountLiquidity[positionAddress];

            // Increase a total calculated liquidity and a number of positions to return
            liquiditySum += positionLiquidity;
            numPositions++;

            // Check if the accumulated liquidity is enough to cover the requested amount
            if (liquiditySum >= amount) {
                amountLeft = liquiditySum - amount;
                break;
            }
        }
```

However, there is an error in the calculation of the last position amount when it entails a partial withdrawal. The `amountLeft` variable represents the leftover liquidity in the last position after the user's withdrawals, but it is assigned to the returned amounts as if it represented the amount the user should withdraw:

```solidity
        // Adjust the last position, if it was not fully allocated
        if (numPositions > 0 && amountLeft > 0) {
            positionAmounts[numPositions - 1] = amountLeft;
        }
```

This discrepancy could lead to users withdrawing an incorrect amount if they use `getLiquidityAmountsAndPositions()`, as intended, to obtain positions and amounts to use when calling `withdraw()`. This can result in significant unintended transfer of funds for the user, especially in cases where the last position in `positionAmounts` is of significant size. Given the fact that this issue can occur under normal usage of the contract, this issue is assessed as medium severity.
## Proof of Concept
Consider the following step-by-step scenario:

1. Alice has a large amount of bridged tokens.
2. Alice decides to withdraw a small portion of her liquidity. She has written a script that calls `getLiquidityAmountsAndPositions()` to calculate the positions and amounts for the withdrawal and iterates through the returned arrays in a series of calls to `withdraw()`.
3. The `firstAvailablePositionAccountIndex` points to a very large position, which causes `getLiquidityAmountsAndPositions()` to return an amount much larger than Alice intended.
4. Alice unknowingly passes the returned amount to `withdraw` and as a result ends up withdrawing far more tokens than she intended, potentially depleting her liquidity in the contract.
MALICIOUS USER CAN `DoS` A NORMAL USER FROM LOCKING THE `OLAS` TOKENS FOR A SHORTER PERIOD OF TIME, TO GET VOTING POWER
Audit: 2023-12-autonolas-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/main/governance/contracts/veOLAS.sol#L411-L418
https://github.com/code-423n4/2023-12-autonolas/blob/main/governance/contracts/veOLAS.sol#L437-L439
https://github.com/code-423n4/2023-12-autonolas/blob/main/governance/contracts/veOLAS.sol#L498-L500


# Vulnerability details

## Impact

The `veOLAS.createLockFor` function is used to deposit `amount` of `OLAS` tokens for `account` and locks for `unlockTime`. The `createLockFor` is an external function which can be called by any user since there is no access control. Hence any user can create a lock for any `account` by locking an `OLAS` token amount > 0. 

The `createLockFor` function calls the `veOLAS._createLockFor` function which performs input validation checks on the passed in `amount` and `unlockTime` values to ensure they are in the acceptable ranges. Then the `veOLAS._depositFor` function is called for `DepositType.CREATE_LOCK_TYPE` transaction to create the lock by transferring the `OLAS` token amount from the `msg.sender` to the `veOLAS` contract. 

Let's assume the following scenario now:

1. User A needs to deposit 1000 OLAS tokens for a Locked period of 1 Year. 
2. The normal user calls on the `veOLAS.createLock` function with the `amount = 1000e18` and `unlockTime = 1 YEAR`.
3. A malicious user sees this transaction and needs to `DoS` the User A on the Locked period of the `OLAS` token deposit.
4. The malicious user front-runs the `veOLAS.createLock` transaction with the `veOLAS.createLockFor` transaction with the `amount = 1 OLAS`, `unlockTime = 3 YEARS 364 DAYS`, `account = User A address`. 
5. Since the `input parameters` provided to the `veOLAS.createLock` function are valid and are within the acceptable ranges the `createLock` transaction will execute.
6. The `createLock` transaction will now revert since now the `lockedBalance.amount > 0`. 
7. Now the `User A` can `increase` his locked token amount by calling the `veOLAS.increaseAmount` but is not able to reduce the `locked end time` to `1 YEAR` since it is already set to `3 YEARS 364 DAYS` by the malicious user. 
8. There is no functionality to decrease the lock endtime of the locked OLAS tokens in the `veOLAS` contract. `veOLAS.increaseUnlockTime` function can not be used to reduce the lock end time since the transaction will revert if the lock end time is attempted to be reduced than the existing lock end time.     
9. Hence since the `User A` needs to `OLAS` token after one year and there is no way for him to withdraw the tokens only after one year (since the lockedBalance.endTime has already being set to 3 YEARS and 364 DAYS) he will not be able to locke his `OLAS` tokens to obtain the voting power.
10. Thus a malicious user can `DoS` any valid user who intends to lock the tokens for a shorter period of time than the `MAXTIME of 4 YEARS`.
11. Thus the normal user will not be able to lock his excessive `OLAS` tokens in the `veOLAS` contract to obtain the vot
Reliance on unknown `governorCheckProposalId` is a potential backdoor and risks loss of critical function control
Audit: 2023-12-autonolas-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/main/governance/contracts/multisigs/GuardCM.sol#L108
https://github.com/code-423n4/2023-12-autonolas/blob/main/governance/contracts/multisigs/GuardCM.sol#L544-L550


# Vulnerability details

## Impact
The `GuardCM` contract is designed to restrict the actions of the Community Multisig (CM). However, a potential backdoor could allow the CM to bypass these restrictions and gain unrestricted access. 

The issue arises from the reliance on a specific proposal ID with unknown fields to check if governance is still alive. The contract stores the hash of an unknown proposal and checks if it has been defeated before allowing the CM to pause the guard.

If the secret proposal that hashes to `governorCheckProposalId` is e.g. a call to `pause()`, the CM will be able to pause the guard regardless of the actions of the voters. This is because if the proposal is passed, the guard would be paused, and if it is defeated, it would give the permission to the CM to pause it. This issue could lead to a scenario where the CM gains full control, bypassing the intended restrictions and potentially leading to misuse or exploitation of the contract.

It is also worth noting that this situation exemplifies a case of [security through obscurity](https://en.wikipedia.org/wiki/Security_through_obscurity), a design approach that is often criticized for its inherent vulnerabilities. In this case, the design of the `GuardCM` contract relies heavily on gated knowledge for a critical function, which introduces additional risks. If this privileged information is lost or becomes inaccessible, the CM would be rendered incapable of pausing the guard when necessary, potentially leading to severe consequences.
## Proof of Concept
Consider the following scenario:
1. The `governorCheckProposalId` is the hash of a call to `GuardCM.pause()`.
2. The proposal hash is stored as `governorCheckProposalId` in the `GuardCM` contract.
3. The voters do not approve the proposal, leading to a `Defeated` state.
4. Despite the `Defeated` state, the CM can call `pause()` on the `GuardCM` contract.
5. The guard is paused, giving the CM unrestricted access.

Alternatively:
1. Governance becomes inactive.
2. The CM needs to launch a proposal with hash `governorCheckProposalId` in order to be able to unpause the guard.
3. However, the information about the specific proposal fields required has been lost.
4. As a result, the CM is unable to execute the critical function when needed.

## Tools Used
Manual review

## Recommended Mitigation Steps
The reliance on an unknown  `governorCheckProposalId` introduces significant risks, including a potential backdoor and loss of control over critical functions. Given these risks, it may be prudent to reconsider this mechanism.

If it's necessary to keep this mechanism, consider implementing additional checks or transparency into the process of setting and using the `governorCheckProposalId`. Alternat
Potential inaccurate calculation of `maxBond` and `effectiveBond` in case of delayed call to `checkpoint()`
Audit: 2023-12-autonolas-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/tokenomics/contracts/Tokenomics.sol#L1010-L1029
https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/tokenomics/contracts/Tokenomics.sol#L925-L942


# Vulnerability details

## Impact
The [`checkpoint()`](https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/tokenomics/contracts/Tokenomics.sol#L880) function in the `Tokenomics` contract is responsible for recording global data when a new epoch starts. 

This function contains a potential issue when the `checkpoint()` function is not called exactly at the end of an epoch that finishes very close to the end of a tokenomics year. If the new epoch rolls over a new year but the `numYears` variable, as calculated in the previous call to `checkpoint()` on line [1010](https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/tokenomics/contracts/Tokenomics.sol#L1010), does not account for this, the `maxBond` and `effectiveBond` values will be calculated without taking into account the new year. As pointed out in the[ inline comments](https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/tokenomics/contracts/Tokenomics.sol#L1007-L1009), this calculation needs to happen when the epoch that rolls over a new year is started. This could lead to inaccurate calculations and potential imbalances in the tokenomics of the system.

```solidity
       // Adjust max bond value if the next epoch is going to be the year change epoch
        // Note that this computation happens before the epoch that is triggered in the next epoch (the code above) when
        // the actual year changes
        numYears = (block.timestamp + curEpochLen - timeLaunch) / ONE_YEAR;
        // Account for the year change to adjust the max bond
        if (numYears > currentYear) {
            // Calculate the inflation remainder for the passing year
            // End of the year timestamp
            uint256 yearEndTime = timeLaunch + numYears * ONE_YEAR;
            // Calculate the inflation per epoch value until the end of the year
            inflationPerEpoch = (yearEndTime - block.timestamp) * curInflationPerSecond;
            // Recalculate the inflation per second based on the new inflation for the current year
            curInflationPerSecond = getInflationForYear(numYears) / ONE_YEAR;
            // Add the remainder of the inflation for the next epoch based on a new inflation per second ratio
            inflationPerEpoch += (block.timestamp + curEpochLen - yearEndTime) * curInflationPerSecond;
            // Calculate the max bond value
            curMaxBond = (inflationPerEpoch * nextEpochPoint.epochPoint.maxBondFraction) / 100;
            // Update state maxBond value
            maxBond = uint96(curMaxBond);
            // Reset the tokenomics parameters upda