xanoutas/solidity-security-findings huggingface dataset:
maxSumOfPrices check is broken
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

0xRajeev


# Vulnerability details

## Impact

rentAllCards() requires the sender to specify a _maxSumOfPrices parameter which specifies “limit to the sum of the bids to place” as specified in the Natspec @param comment. This is apparently for front-run protection.

However, this function parameter constraint for _maxSumOfPrices is broken in the function implementation which leads to the total of bids places greater than the _maxSumOfPrices specified.

Impact: The user may not have sufficient deposit, be foreclosed and/or impacted on other bids/markets.

## Proof of Concept

Scenario: Assume two cards for a market with current winning rentals of 50 each. _maxSumofPrices = 101 passes check on L643 but then the forced 10% increase on L650 (assuming sender is not the owner of either card) causes newRentals to be called with 55 for each card thus totalling to 110 which is > 101 as requested by the user.

https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCMarket.sol#L636-L637

https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCMarket.sol#L639-L657


## Tools Used

Manual Analysis

## Recommended Mitigation Steps

Modify the max sum of prices check logic to consider the 10% increase scenarios. Document and suggest the max sum of prices for the user in the UI based on the card prices and 10% requirement depending on card ownership.
Prediction question string is not emitted in any event
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

0xRajeev


# Vulnerability details

## Impact

The entire prediction market is premised around the question posted to the oracle but this question string is never emitted as an event parameter for off-chain observation. This is critical for transparency and should be included in the event emitted here along with the question ID.

## Proof of Concept

https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCMarket.sol#L406

## Tools Used

Manual Analysis

## Recommended Mitigation Steps

Add question string to event.
Incorrect/Insufficient validation of market locking timestamp
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

0xRajeev


# Vulnerability details

## Impact

Three timestamps are used during market creation to indicate market opening, locking and oracle resolution times. The validation of these timestamps is performed in RCFactory during market creation.

The validation for market locking _timestamp[1]  is performed only if maximumDuration is != 0 where the default value is 0 and is set only if setMaximumDuration() is called. Even in that validation, the use of block.timestamp should really be _timestamps[0] (market opening timestamp) because the market opening-locking duration should be counted from _timestamp[0] and not block.timestamp at createMarket() time. _timestamp[0] could be in the past. This check also doesn't account for advancedWarning aspect of market opening.

Impact: Incorrect/Insufficient validations of all possible market opening/locking configurations could affect user interactions with the market by breaking assumed invariants in the code.

## Proof of Concept

https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCFactory.sol#L530-L535

https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCFactory.sol#L519-L528


## Tools Used

Manual Analysis

## Recommended Mitigation Steps

Specify all possible market opening/locking invariants and validate correctly against all variations of them.
RCFactory uberOwner cannot be burned
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

0xRajeev


# Vulnerability details

## Impact

The notice for changeUberOwner() and the documentation indicates there may be a requirement to renounce the uberOwner address at some point possibly to prevent further changes to reference market contract address. This is typically done by setting it to 0 burn address. However, because of the zero-address check in changeUberOwner(), this is not possible in the current implementation.

Impact: uberOwner can never be renounced by burning to 0 address.

## Proof of Concept

https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCFactory.sol#L444-L449

https://github.com/code-423n4/2021-06-realitycards#mortar_board-governance-mortar_board

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/00128bd26061986d10172573ceec914a4f3b4d3c/contracts/access/Ownable.sol#L48-L58

## Tools Used

Manual Analysis

## Recommended Mitigation Steps

Create a special renounceUberOwner() function (similar to OpenZeppelin’s renounceOwnership) for specifically setting it to burn address 0 and renouncing. This will allow changing it (to a non-owner address or a multisig) using the current changeUberOwner() function but also renouncing it by burning if/when necessary.
Use two steps in order to change the uberOwner 
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

a_delamo


# Vulnerability details

## Impact

In all three contracts (`RCFactory`, `RCOrderbook` and `RCTreasury`) in order to apply or execute important changes/functionalities, you need to be the `uberOwner`. 

In order to change the `uberOwner`, you would execute the following method:
```
    function changeUberOwner(address _newUberOwner) external {
        require(msgSender() == uberOwner, "Extremely Verboten");
        require(_newUberOwner != address(0));
        uberOwner = _newUberOwner;
    }
```
If the wrong address would be introduced, it would make the contract unusable. 

## Recommended Mitigation Steps

I would recommend using a two steps process. This way we would protect for human errors.

```
    address public uberOwner;
   address public proposedUberOwner;

    function proposeNewUberOwner(address _newUberOwner) external {
        require(msgSender() == uberOwner, "Extremely Verboten");
        require(_newUberOwner != address(0));
        proposedUberOwner= _newUberOwner;
    }

   function becomeUberOwner() external {
        require(msgSender() == proposedUberOwner, "Extremely Verboten");
        uberOwner = proposedUberOwner;
        proposedUberOwner = address(0);
   }
```
RCFactory.createMarket() does not enforce _timestamps[1] and _timestamps[2] being larger than _timestamps[0], even though proper functioning requires them to be so
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

jvaqa


# Vulnerability details

RCFactory.createMarket() does not enforce _timestamps[1] and _timestamps[2] being larger than _timestamps[0], even though proper functioning requires them to be so.

## Impact

IRCMarket defines a sequence of events that each market should progress through sequentially, CLOSED, OPEN, LOCKED, WITHDRAW. // [1]

The comments explicitly state that _incrementState() should be called "thrice". // [2]

However, it is possible to create a market where these events do not occur sequentially.

You can create a market where the marketOpeningTime is later than the marketLockingTime and oracleResolutionTime.

This is because although RCFactory checks to ensure that _timestamps[2] is greater than _timestamps[1], it does not check to ensure that _timestamps[1] is greater than _timestamps[0]. // [3]

This is also because although RCFactory checks to ensure that _timestamps[0] is equal to or greater than block.timestamp, it makes no check for a minimum value for _timestamps[1] or _timestamps[2], or a relative check between the value of _timestamps[0] and _timestamps[1]. // [4]

Thus, you can create a market where the marketLockingTime and the oracleResolutionTime occur before the marketOpeningTime.

## Proof of Concept

When calling RCFactory.createMarket(), Alice can supply 0 as the argument for _timestamps[1] and _timestamps[2], and any value equal to or greater than block.timestamp for _timestamps[0]. // [5]

## Recommended Mitigation Steps

Add the following check to RCFactory.createMarket():

require(
    _timestamps[0] < _timestamps[1],
    "market must begin before market can lock"
);

[1] https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/interfaces/IRCMarket.sol#L7

[2] https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCMarket.sol#L1093

[3] https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCFactory.sol#L539

[4] https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCFactory.sol#L521

[5] https://github.com/code-423n4/2021-06-realitycards/blob/86a816abb058cc0ed9b6f5c4a8ad146f22b8034c/contracts/RCFactory.sol#L468
Uninitialized Local Variables found in RCNftHubL2.sol
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

maplesyrup


# Vulnerability details

## Impact

2 - Medium Risk
   - Uninitialized local variables can cause possible accidental loss of funds. All variables must be initialized to avoid and negative side effects from variables not initialized.

## Proof of Concept
According to the Slither-analyzer documentation (https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-local-variables), uninitialized local variable run the risk of bad side effects of using them during this state. An uninitialized local variable can cause a loss of funds. Sending funds to an uninitialized address holding variable can lead to funds being lost.

-------------------------------------------

RCNftHubL2.deposit(address,bytes).i <----is a local variable never initialized

(contracts/nfthubs/RCNftHubL2.sol line(s)#150) 

-------------------------------------------

Console output (Slither log):

INFO:Detectors:
RCOrderbook.removeOldBids(address)._loopCounter (contracts/RCOrderbook.sol#677) is a local variable never initialized
RCMarket.lockMarket().i (contracts/RCMarket.sol#453) is a local variable never initialized
RCOrderbook.cleanWastePile().i (contracts/RCOrderbook.sol#717) is a local variable never initialized
RCOrderbook.getBid(address,address,uint256)._newBid (contracts/RCOrderbook.sol#818) is a local variable never initialized
RCOrderbook.addMarket(address,uint256,uint256)._newBid (contracts/RCOrderbook.sol#168) is a local variable never initialized
RCOrderbook.addMarket(address,uint256,uint256).i (contracts/RCOrderbook.sol#166) is a local variable never initialized
RCNftHubL2.deposit(address,bytes).i (contracts/nfthubs/RCNftHubL2.sol#150) is a local variable never initialized
RCOrderbook._newBidInOrderbook(address,address,uint256,uint256,uint256,RCOrderbook.Bid)._newBid (contracts/RCOrderbook.sol#301) is a local variable never initialized
RCOrderbook.removeOldBids(address)._cardCount (contracts/RCOrderbook.sol#676) is a local variable never initialized
RCOrderbook.closeMarket()._newBid (contracts/RCOrderbook.sol#660) is a local variable never initialized
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-local-variables

## Tools Used

Solidity Compiler 0.8.4
Hardhat v2.3.3
Slither v0.8.0

Compiled, Tested, Deployed contracts on a local hardhat network.

Ran Slither-analyzer for further detecting and testing.

## Recommended Mitigation Steps

(Worked best under python venv)
1. Clone Project Repository
2. Run Project against Hardhat network;
   compile and run default test on contracts.
3. Installed slither analyzer:
  https://github.com/crytic/slither
4. Ran [$ slither .] against RCOrderbook.sol and all contracts to verify results
Possible locked-ether (funds) issue found in RCNftHubL2.sol
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

maplesyrup


# Vulnerability details

## Impact
2 - Medium Risk
   - Possible accidental loss of funds or information due to code manipulation or bad side effects of not properly outlining a payable function

## Proof of Concept

When running the analyzer code, the following functions were found in RCNftHubL2.sol to possibly lock funds due to it being a payable function with no withdraw function associated.

----------------------------
Contract locking ether found:

Contract RCNftHubL2 

(contracts/nfthubs/RCNftHubL2.sol line(s)#15-239) has payable functions:

NativeMetaTransaction.executeMetaTransaction(address,bytes,bytes32,bytes32,uint8) 

(contracts/lib/NativeMetaTransaction.sol line(s)#31-67)

But does not have a function to withdraw the ether
----------------------------

According to Slither analyzer detector documentation (https://github.com/crytic/slither/wiki/Detector-Documentation#contracts-that-lock-ether)

Possible functions that receive funds with the payable attribute must have a withdraw function to secure that funds can be sent out from the function or remove payable attribute.

Although the function may not receive funds directly, there should be a withdraw function added to ensure that information needed from the function can be withdrawn safely or do not include payable attribute.

Console Output (Slither log):

INFO:Detectors:
Contract locking ether found:
	Contract RCNftHubL2 (contracts/nfthubs/RCNftHubL2.sol#15-239) has payable functions:
	 - NativeMetaTransaction.executeMetaTransaction(address,bytes,bytes32,bytes32,uint8) (contracts/lib/NativeMetaTransaction.sol#31-67)
	But does not have a function to withdraw the ether
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#contracts-that-lock-ether

## Tools Used

Solidity Compiler 0.8.4
Hardhat v2.3.3
Slither v0.8.0

Compiled, Tested, Deployed contracts on a local hardhat network.

Ran Slither-analyzer for further detecting and testing.

## Recommended Mitigation Steps

(Worked best under python venv)
1. Clone Project Repository
2. Run Project against Hardhat network;
   compile and run default test on contracts.
3. Installed slither analyzer:
  https://github.com/crytic/slither
4. Ran [$ slither .] against RCNftHubL2.sol and all contracts to verify results
Uninitialized Local Variables found in RCOrderbook.sol
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

maplesyrup


# Vulnerability details

## Impact

2 - Medium Risk
   - Possible accidental loss of funds if variables do not contain the right information such as correct addresses in this specific scenario.

## Proof of Concept
According to Slither documentation (https://github.com/crytic/slither/wiki/Detector-Documentation#configuration-32), uninitialized local variables can cause the risk of loss of funds due to inappropriate usage of these variables while using the contract. All variables must be initialized to insure they do not run the risk of incorrect calculations or sending funds to a 0x0 address.

It is recommended that all variables need to be initialized. If the variable needs to be 0, then it is best to explicitly assign 0 to the variable.

The following local variables in RCOrderbook are not initialized:

RCOrderbook.getBid(address,address,uint256)._newBid <--- is a local variable never initialized

(contracts/RCOrderbook.sol line(s)#818)

 -------------------------------------------------------------------

RCOrderbook.removeOldBids(address)._cardCount <--- is a local variable never initialized

(contracts/RCOrderbook.sol line(s)#676)

 -------------------------------------------------------------------

RCOrderbook._newBidInOrderbook(address,address,uint256,uint256,uint256,RCOrderbook.Bid)._newBid <--- is a local variable never initialized

(contracts/RCOrderbook.sol line(s)#301)

 -------------------------------------------------------------------

RCOrderbook.addMarket(address,uint256,uint256).i <--- is a local variable never initialized

(contracts/RCOrderbook.sol line(s)#166)

 -------------------------------------------------------------------

RCOrderbook.removeOldBids(address)._loopCounter <--- is a local variable never initialized

(contracts/RCOrderbook.sol line(s)#677)

 -------------------------------------------------------------------

RCOrderbook.cleanWastePile().i <--- is a local variable never initialized

(contracts/RCOrderbook.sol line(s)#717)

 -------------------------------------------------------------------

RCOrderbook.closeMarket()._newBid <--- is a local variable never initialized

(contracts/RCOrderbook.sol line(s)#660) 

 -------------------------------------------------------------------

RCOrderbook.addMarket(address,uint256,uint256)._newBid <--- is a local variable never initialized

(contracts/RCOrderbook.sol line(s)#168)

 -------------------------------------------------------------------

Console output (Slither log):

INFO:Detectors:
RCOrderbook.removeOldBids(address)._loopCounter (contracts/RCOrderbook.sol#677) is a local variable never initialized
RCMarket.lockMarket().i (contracts/RCMarket.sol#453) is a local variable never initialized
RCOrderbook.cleanWastePile().i (contracts/RCOrderbook.sol#717) is a local variable never initialized
RCOrderbook.getBid(address,address,uint256)._newBid (contracts/RCOrderbook.sol#818) is a local variable never initialized
RCOrderbook.addMarket(address
Possible Reentrency not-involving-eth Issues [RCOrderbook.sol]
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

maplesyrup


# Vulnerability details

## Impact

2 - Medium Risk
   - Possible reentrancy found in the contract, possible loss of funds due to code manipulation

## Proof of Concept

According to the Slither-analyzer documentation (https://github.com/crytic/slither/wiki/Detector-Documentation#configuration-32): Detection of reentrancy was found in the following functions as there are external calls made before state variables are changed. This can lead to a possible attack on the functions and contract.

Reentrancy found in:

contracts/RCOrderbook.sol

line(s) 280-340

RCOrderbook._newBidInOrderbook(address, address, uint256, uint256, uint256, RCOrderbook.Bid) 

External calls:

	treasury.increaseBidRate(_user,_price) 
	(contracts/RCOrderbook.sol line(s)#328)
	
	transferCard(_market,_card,_oldOwner,_user,_price) 
	(contracts/RCOrderbook.sol line(s)#331)
	
	_rcmarket.transferCard(_oldOwner,_newOwner,_card,_price,_timeLimit) 
	(contracts/RCOrderbook.sol line(s)#870)


State variables written after the call(s):

	transferCard(_market,_card,_oldOwner,_user,_price) 
	(contracts/RCOrderbook.sol line(s)#331)
	
	ownerOf[_market][_card] = _newOwner 
	(contracts/RCOrderbook.so line(s)#866)

 -------------------------------------------------------------------

RCOrderbook._removeBidFromOrderbookIgnoreOwner(address,uint256) 
(contracts/RCOrderbook.sol line(s)#492-527):

External calls:

	treasury.decreaseBidRate(_user,_currUser.price) 
	(contracts/RCOrderbook.sol line(s)#499)

State variables written after the call(s):

	index[_user][_market][_card] = 0 
	(contracts/RCOrderbook.sol line(s)#520)
	
	index[_user][user[_user][_index].market][user[_user][_index].token] = _index 
	(contracts/RCOrderbook.sol line(s)#522-524)
	
	user[_tempNext][index[_tempNext][_market][_card]].prev = _tempPrev 
	(contracts/RCOrderbook.sol line(s)#504)
	
	user[_tempPrev][index[_tempPrev][_market][_card]].next = _tempNext 
	(contracts/RCOrderbook.sol line(s)#505)
	
	user[_user][_index] = user[_user][_lastRecord] 
	(contracts/RCOrderbook.sol line(s)#515)
	
	user[_user].pop() 
	(contracts/RCOrderbook.sol line(s)#517)

 -------------------------------------------------------------------

RCOrderbook.closeMarket() 
(contracts/RCOrderbook.sol line(s)#633-669):

External calls:
	treasury.updateRentalRate(_owner,_market,_price,0,block.timestamp) 
	(contracts/RCOrderbook.sol line(s)#641-647)

State variables written after the call(s):
	user[_market][index[_market][_market][i]].prev = _market 
	(contracts/RCOrderbook.sol line(s)#654) 
	
	user[_market][index[_market][_market][i]].next = _market 
	(contracts/RCOrderbook.sol line(s)#655) 
	
	user[_firstBid][index[_market][_firstBid][i]].prev = address(this) 
	(contracts/RCOrderbook.sol line(s)#656)
	
	user[_lastBid][index[_market][_lastBid][i]].next = address(this)
	(contracts/RCOrderbook.sol line(s)#657) 
	
	user[address(this)].push(_newBid) 
	(contracts/RCOrderbook.sol line(s)#667)

 --------------------------------------------------
Possible locked-ether (funds) Issue in RCOrderbook.sol
Audit: 2021-06-realitycards-findings
Severity: MEDIUM

# Handle

maplesyrup


# Vulnerability details

## Impact

2 - Medium Risk 
       - Possible loss or lock of funds found in a function in the contract

## Proof of Concept

When running the analyzer code, the following functions were found in RCOrderbook.sol to possibly lock funds due to it being a payable function with no withdraw function associated.

----------------------------
Contract locking ether found:

// contracts/RCOrderbook.sol 
// line(s) 15-876

Contract RCOrderbook 

has payable functions: 

// contracts/lib/NativeMetaTransaction.sol
// line(s) 31-67	

NativeMetaTransaction.executeMetaTransaction(address,bytes,bytes32,bytes32,uint8)

But does not have a function to withdraw the funds
--------------------------

According to Slither analyzer detector documentation (https://github.com/crytic/slither/wiki/Detector-Documentation#contracts-that-lock-ether)

Possible functions that receive funds with the payable attribute must have a withdraw function to secure that funds can be sent out from the function or remove payable attribute.

Although the function may not receive funds directly, there should be a withdraw function added to ensure that information needed from the function can be withdrawn safely or do not include payable attribute.

Console Output (Slither log):

INFO:Detectors:
Contract locking ether found:
	Contract RCOrderbook (contracts/RCOrderbook.sol#15-876) has payable functions:
	 - NativeMetaTransaction.executeMetaTransaction(address,bytes,bytes32,bytes32,uint8) (contracts/lib/NativeMetaTransaction.sol#31-67)
	But does not have a function to withdraw the ether
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#contracts-that-lock-ether


## Tools Used

Solidity Compiler 0.8.4
Hardhat v2.3.3
Slither v0.8.0

Compiled, Tested, Deployed contracts on a local hardhat network.

Ran Slither-analyzer for further detecting and testing.

## Recommended Mitigation Steps
(Worked best under python venv)
1. Clone Project Repository
2. Run Project against Hardhat network;
     compile and run default test on contracts.
3. Installed slither analyzer:
    https://github.com/crytic/slither
4. Ran [$ slither .] against RCOrderbook.sol and all contracts to verify results