xanoutas/solidity-security-findings huggingface dataset:
Insuffecient Signature Validation
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L107


# Vulnerability details

```
function _recoverSignerFromPayload(
    bytes32 payloadHash,
    bytes memory signature
) internal view returns (address) {
    // Derive original EIP-712 digest using domain separator and order hash.
    bytes32 digest = _DOMAIN_SEPARATOR.toTypedDataHash(payloadHash);

    // Recover the signer address of the signature.
    return digest.recover(signature);
}
```

The _recoverSignerFromPayload function is responsible for recovering the signer from a given payload hash and signature. If the payload hash is not correctly constructed or if the signature is not properly validated, it could lead to the wrong address being recovered, allowing unauthorized parties to execute transactions.

### Mitigation

Ensure that the payload hash is constructed correctly according to EIP-712 standards and that the signature is checked for validity (e.g not from a zero address).

```
function _recoverSignerFromPayload(
    bytes32 payloadHash,
    bytes memory signature
) internal view returns (address) {
    // Ensure the signature is not empty.
    require(signature.length == 65, "Invalid signature length");

    // Derive original EIP-712 digest using domain separator and order hash.
    bytes32 digest = _DOMAIN_SEPARATOR.toTypedDataHash(payloadHash);

    // Recover the signer address of the signature.
    address signer = digest.recover(signature);

    // Ensure the recovered address is not the zero address.
    require(signer != address(0), "Invalid signer recovered");

    return signer;
}
```

### Impact

Incorrect signature validation can lead to unauthorized access and execution of transactions. By ensuring that the signature is of the correct length and that the recovered signer is not the zero address, the contract can prevent invalid or malicious signatures from being accepted.



## Assessed type

Invalid Validation
Delegate Call Whitelisted addresses can be bypassed
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Reclaimer.sol#L71


# Vulnerability details

The reclaimRentalOrder function is designed to be called only through a delegate call from a whitelisted address. However, the contract relies solely on the original address check to enforce this, which may not be sufficient if the contract's logic is replicated at a different address.

### Mitigation

To strengthen the enforcement, the contract could maintain a list of whitelisted addresses or use a dedicated modifier that checks against a dynamic list managed by the contract owner or another governance mechanism.

```
modifier onlyWhitelisted() {
    require(isWhitelisted(msg.sender), "ReclaimerPackage: Caller not whitelisted");
    _;
}

function isWhitelisted(address _address) public view returns (bool) {
    // Implement logic to check if the address is whitelisted
}
```

### Impact

Enforcement mechanism could potentially be bypassed leading to unauthorized use of the reclaimRentalOrder function. Implementing a dynamic whitelist check ensures that only authorized addresses can invoke the function through delegate calls, enhancing security and control over the reclaim process.


## Assessed type

Access Control
Item Transfer Logic can lead to loss of assets
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Reclaimer.sol#L90


# Vulnerability details

The reclaimRentalOrder function iterates over each item in the rentalOrder.items array and checks the itemType to determine whether to call _transferERC721 or _transferERC1155. However, if an item is neither ERC721 nor ERC1155, the function does nothing, potentially leaving the item untransferred.

### Mitigation

To mitigate this, the contract should handle all expected ItemType values and include a default case that reverts the transaction if an unknown ItemType is encountered. This ensures that all items are accounted for and that the contract behaves predictably.

```

for (uint256 i = 0; i < itemCount; ++i) {
    Item memory item = rentalOrder.items[i];

    if (item.itemType == ItemType.ERC721) {
        _transferERC721(item, rentalOrder.lender);
    } else if (item.itemType == ItemType.ERC1155) {
        _transferERC1155(item, rentalOrder.lender);
    } else {
        revert Errors.ReclaimerPackage_UnknownItemType();
    }
}
```

### Impact

The impact of not handling all ItemType values is that some assets may not be reclaimed, leading to potential loss of assets or disputes between parties. By ensuring all cases are handled, the contract becomes more robust and reliable, preventing any assets from being stuck or unaccounted for.


## Assessed type

Token-Transfer
Missing Fields for Hash Construction in `_deriveRentalOrderHash` and `_deriveOrderMetadataHash`
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L181-L194
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L231-L238


# Vulnerability details

## Impact:

The identified issue in the `_deriveRentalOrderHash` and `_deriveOrderMetadataHash` functions could potentially lead to incorrect hash generation due to missing fields. Specifically, the absence of the `order.rentalWallet` field in the `_deriveRentalOrderHash` function and the missing fields `metadata.orderType` and `metadata.emittedExtraData` in the `_deriveOrderMetadataHash` function may result in inaccurate hash calculations. This discrepancy could lead to unexpected behavior when interacting with the protocol, potentially affecting the correctness of the rental order and order metadata.

## Proof of Concept:

The issue is evident in the `_deriveRentalOrderHash` function, where the `order.rentalWallet` field is not included in the hash construction:

```solidity
return
    keccak256(
        abi.encode(
            _RENTAL_ORDER_TYPEHASH,
            order.seaportOrderHash,
            keccak256(abi.encodePacked(itemHashes)),
            keccak256(abi.encodePacked(hookHashes)),
            order.orderType,
            order.lender,
            order.renter,
            //@audit missing order.rentalWallet
            order.startTimestamp,
            order.endTimestamp
        )
    );
```

The expected parameters for hash construction are mentioned in `_deriveRentalTypehashes()` function and should be:

```solidity
// Construct the RentalOrder type string.
bytes memory rentalOrderTypeString = abi.encodePacked(
    "RentalOrder(bytes32 seaportOrderHash,Item[] items,Hook[] hooks,uint8 orderType,address lender,address renter,address rentalWallet,uint256 startTimestamp,uint256 endTimestamp)"
);
```

Similarly, in the `_deriveOrderMetadataHash` function, the `metadata.orderType` and `metadata.emittedExtraData` fields are missing from the hash construction:

```solidity
//@audit missing metadata.orderType && metadata.emittedExtraData when constructing hash
return
    keccak256(
        abi.encode(
            _ORDER_METADATA_TYPEHASH,
            metadata.rentDuration,
            keccak256(abi.encodePacked(hookHashes))
        )
    );
```

The expected parameters for hash construction are mentioned in `_deriveRentalTypehashes()` function and should be:

```solidity
// Construct the OrderMetadata type string.
bytes memory orderMetadataTypeString = abi.encodePacked(
    "OrderMetadata(uint8 orderType,uint256 rentDuration,Hook[] hooks,bytes emittedExtraData)"
);
```

Those issues will lead to incorrect hashs construction which can impact the protocol working for the creation or settlement of rentals

## Tools Used:

Manual review

## Recommended Mitigation Steps:

Update the `_deriveRentalOrderHash` and `_deriveOrderMetadataHash` functions to include the m
"Signer.sol" doesn't strictly follow the EIP-712, which can result in some validation issues when integration
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L162-L195
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L218-L239
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L273-L288


# Vulnerability details

## Impact
Some functions in "Signer.sol" which are used to derive hash don't strictly follow EIP-712, those generated hash are used when validating a Seaport order, as a result, a Seaport order with correct EIP-712 hash may not be executed and cause integration issues.

## Proof of Concept
When deriving the Domain Separator, according to EIP-712 (https://eips.ethereum.org/EIPS/eip-712), ```name```, ```version```, ```chainId```, ```verifyingContract``` and ```salt``` are required. However, the ```_deriveDomainSeparator()``` lacks a salt:

```
function _deriveDomainSeparator(
        bytes32 _eip712DomainTypeHash,
        bytes32 _nameHash,
        bytes32 _versionHash
    ) internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    _eip712DomainTypeHash,
                    _nameHash,
                    _versionHash,
                    block.chainid,
                    address(this)
                )
            );
    }
```

When deriving rentalOrderHash, it doesn't consider the ```RentalOrder.rentalWallet```:

```
struct RentalOrder {
    bytes32 seaportOrderHash;
    Item[] items;
    Hook[] hooks;
    OrderType orderType;
    address lender;
    address renter;
    address rentalWallet;
    uint256 startTimestamp;
    uint256 endTimestamp;
}
```

```
keccak256(
                abi.encode(
                    _RENTAL_ORDER_TYPEHASH,
                    order.seaportOrderHash,
                    keccak256(abi.encodePacked(itemHashes)),
                    keccak256(abi.encodePacked(hookHashes)),
                    order.orderType,
                    order.lender,
                    order.renter,
                    order.startTimestamp,
                    order.endTimestamp
                )
            );
```

When deriving orderMetadataHash, it doesn't consider OrderMetadata.OrderType and OrderMetadata.emittedExtraData:

```
struct OrderMetadata {
    // Type of order being created.
    OrderType orderType;
    // Duration of the rental in seconds.
    uint256 rentDuration;
    // Hooks that will act as middleware for the items in the order.
    Hook[] hooks;
    // Any extra data to be emitted upon order fulfillment.
    bytes emittedExtraData;
}
```

```
keccak256(
                abi.encode(
                    _ORDER_METADATA_TYPEHASH,
                    metadata.rentDuration,
                    keccak256(abi.encodePacked(hookHashes))
                )
            );
```

Those generated hash can be used to validate if an order should be executed. For example,
Potential Memory Leak
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Accumulator.sol#L32


# Vulnerability details

The _insert function updates the free memory pointer, but if this update is not done correctly, it could lead to a memory leak.

```
function _insert(
    bytes memory rentalAssets,
    RentalId rentalId,
    uint256 rentalAssetAmount
) internal pure {
    // ... existing code ...

    // Problematic: Potential incorrect update of the free memory pointer
    mstore(0x40, add(newItemPosition, 0x40))
}
```

### Mitigations

To mitigate potential memory leaks, you should ensure that the free memory pointer is updated to the correct location after each insertion. This is particularly important if the contract performs other memory operations after calling _insert.

```
function _insert(
    bytes memory rentalAssets,
    RentalId rentalId,
    uint256 rentalAssetAmount
) internal pure {
    // ... existing code ...

    // Mitigation: Correctly update the free memory pointer
    let newFreePtr := add(newItemPosition, 0x40)
    mstore(0x40, newFreePtr)
}
```

### Impact

The impact of not correctly updating the free memory pointer is that subsequent memory allocations could overwrite existing data or allocate memory that overlaps with the rentalAssets array, leading to data corruption or other unexpected behavior. Setting the free memory pointer to the correct location after each insertion ensures that future memory allocations do not interfere with the rentalAssets array, thus preventing memory leaks and preserving data integrity.



## Assessed type

Other
Missing struct elements in the hash calculation can lead to EIP-712 compliance issues
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L183-L193
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L233-L237


# Vulnerability details

## Impact

The ` _deriveRentalOrderHash` and `_deriveOrderMetadataHash` functions in the ` Signer.sol`  contract lack the utilization of all parameters from the structs intended for hash derivation according to the [EIP-712 specifications](https://eips.ethereum.org/EIPS/eip-712). This omission could lead to identical hashes if it becomes possible to input the same values for all parameters except the currently excluded ones. This practice of excluding some parameters not only diminishes uniqueness and expands the potential attack surface it also introduces incompatibility with the EIP-712 specification. 

Also note that unlike `_deriveRentalOrderHash` and `_deriveOrderMetadataHash`, the typeHashes of [OrderMetada](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L384-L385) and [RentalOrder](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L362-L363) are derived correctly, with all parameters included.

## Proof of Concept

Parameters used in `_deriveRentalOrderHash`, `rentalWallet` is missing.

```solidity
// Signer.sol::_deriveRentalOrderHash
keccak256(
    abi.encode(
        _RENTAL_ORDER_TYPEHASH,
        order.seaportOrderHash,
        keccak256(abi.encodePacked(itemHashes)),
        keccak256(abi.encodePacked(hookHashes)),
        order.orderType,
        order.lender,
        order.renter,
        order.startTimestamp,
        order.endTimestamp
    )
);

// RentalStructs.sol
struct RentalOrder {
    bytes32 seaportOrderHash;
    Item[] items;
    Hook[] hooks;
    OrderType orderType;
    address lender;
    address renter;
    address rentalWallet;
    uint256 startTimestamp;
    uint256 endTimestamp;
}
```
Parameters used in `_deriveOrderMetadataHash`, `orderType` and `emittedExtraData` is missing.

```solidity
// Signer.sol::_deriveOrderMetadataHash
keccak256(
    abi.encode(
        _ORDER_METADATA_TYPEHASH,
        metadata.rentDuration,
        keccak256(abi.encodePacked(hookHashes))
    )
);

// RentalStructs.sol
struct OrderMetadata {
    // Type of order being created.
    OrderType orderType;
    // Duration of the rental in seconds.
    uint256 rentDuration;
    // Hooks that will act as middleware for the items in the order.
    Hook[] hooks;
    // Any extra data to be emitted upon order fulfillment.
    bytes emittedExtraData;
}
```

## Tools Used

Manual Review

## Recommended Mitigation Steps

In the hash derivation functions in question, add all the parameters mentioned in the structs, taking into account the EIP-712 specification.











## Assessed type

Other
Partial order's can lead to loss of rented asset 
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L189-L194


# Vulnerability details

## Impact
Lost rental assets for the lender and forever possession of the rented asset for the attacker on partial orders

## Proof of Concept
The addRentals functions adds a rental order without checking if the same orderHash is currently active

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L189-L194
```solidity
    function addRentals(
        bytes32 orderHash,
        RentalAssetUpdate[] memory rentalAssetUpdates
    ) external onlyByProxy permissioned {
       
        orders[orderHash] = true;
```

An attacker can make use of this to fill a partial order in half twice in the same block to produce the same orderhash. This will result in only half of the rented asset being take outable by the lender since the first call to `stopRent` will clear the `orderHash` from the order's mapping 

### POC Test
https://gist.github.com/10xhash/4cef50612dfcb290bf232567769dfbae

## Tools Used
Manual Review

## Recommended Mitigation Steps
If the `orderHash` already exist, revert


## Assessed type

Invalid Validation
Incorrect Rental Asset Tracking
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L197


# Vulnerability details

```
// Add the rented items to storage.
for (uint256 i = 0; i < rentalAssetUpdates.length; ++i) {
    RentalAssetUpdate memory asset = rentalAssetUpdates[i];

    // Update the order hash for that item.
    rentedAssets[asset.rentalId] += asset.amount;
}
```

### Mitigation

```
// Add the rented items to storage.
for (uint256 i = 0; i < rentalAssetUpdates.length; ++i) {
    RentalAssetUpdate memory asset = rentalAssetUpdates[i];

    // For ERC721, ensure that the amount is always set to 1 when actively rented.
    if (asset.tokenType == TokenType.ERC721) {
        require(asset.amount == 1, "Invalid amount for ERC721");
        rentedAssets[asset.rentalId] = 1;
    } else {
        rentedAssets[asset.rentalId] += asset.amount;
    }
}
```

### Impact

The code does not account for the unique nature of ERC721 tokens, which should have a quantity of 1 when rented. Without this check, the contract could incorrectly track the number of ERC721 tokens rented, potentially allowing multiple rentals of a unique asset. The mitigation ensures that for ERC721 tokens, the amount is always set to 1, reflecting the non-fungible nature of these assets.



## Assessed type

ERC721
setFallbackHandler is not access controlled in Guard allowing renter's to steal rented assets
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Guard.sol#L195-L293


# Vulnerability details

## Impact
Renter's can steal rented assets

## Proof of Concept
The implemented guard doesn't block the `setFallbackHandler` function call on the safe. 

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Guard.sol#L195-L293

This allows the owner to set the rented asset as the `fallbackHandler`. Following this, a call to the safe with calldata corresponding to the rented asset's transfer function will allow the attacker to transfer the asset to any address.

### POC Test
https://gist.github.com/10xhash/56ef3505b5ccb98d49283ae96ec92805

## Tools Used
Manual Review

## Recommended Mitigation Steps
Block `setFallbackHandler` in the guard


## Assessed type

Access Control
Direct Transfers are not handled correctly
Audit: 2024-01-renft-findings
Severity: HIGH

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L37


# Vulnerability details

The PaymentEscrow contract lacks a mechanism to prevent or handle tokens sent directly to the contract without using the increaseDeposit function.

### Mitigation

The contract could implement a receive or fallback function that reverts unless the transfer is part of a valid process

```
receive() external payable {
    revert("Direct ETH deposits are not allowed");
}

fallback() external payable {
    revert("Fallback call not allowed");
}
```

For ERC20 tokens, a similar mechanism is not as straightforward because ERC20 tokens do not notify the contract when they are transferred. However, a pattern involving a tokenReceived function could be used in conjunction with ERC223 or ERC777 tokens, which do provide such notifications.

### Impact

Without a mechanism to handle direct transfers, tokens sent to the contract outside of the increaseDeposit function will not be accounted for in the balanceOf mapping. This could lead to discrepancies between the actual token balance of the contract and the recorded balance, potentially affecting the settlement process. By implementing a receive or fallback function that reverts, the contract can prevent accidental direct transfers of Ether. For ERC20 tokens, educating users and providing clear instructions on how to interact with the contract is essential, as Solidity does not provide a native way to prevent or revert direct ERC20 transfers.



## Assessed type

Token-Transfer