xanoutas/solidity-security-findings huggingface dataset:
Reclaimer contract may block asset recovery due to failed transfers
Audit: 2024-01-renft-findings
Severity: MEDIUM

# Lines of code

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


# Vulnerability details

## Impact
The `Reclaimer` contract provides functionality for retrieving rented assets from a wallet contract once a rental has been stopped, and transferring them to the proper recipient. This is achieved by means of the [`reclaimRentalOrder()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Reclaimer.sol#L71) function being invoked as a `DelegateCall` from the renter's safe.

This function requires all transfers to succeed or the transaction reverts. However, if something goes wrong and an item is blocked or removed from the Safe during the rental, the lender will not be able to retrieve any of his other assets lent in the same order. This is because the `reclaimRentalOrder()` function iterates over all items in the rental order and attempts to transfer them. If any of these transfers fail, the entire transaction is reverted, leaving the lender unable to recover any of their assets.

This could lead to a situation where a lender's assets are locked indefinitely if a single item in a rental order becomes untransferable for any reason.

## Proof of Concept
Consider the following scenario:

1. Alice rents multiple items to Bob.
2. During the rental period, one of the items becomes blocked or is removed from the Safe.
3. Alice attempts to stop the rental and recover her assets by calling the `reclaimRentalOrder()` function.
4. The `reclaimRentalOrder()` function attempts to transfer all items in the rental order back to Alice.
5. The transfer of the blocked item fails, causing the entire transaction to revert.
6. As a result, Alice is unable to recover any of her assets, even those that are not blocked.

## Tools Used
Manual review

## Recommended Mitigation Steps
A potential solution to this issue could be to allow the lender to pass a list of items to ignore as a parameter to the [`Stop.stopRent()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L265) function if he's the one calling. This would allow the lender to recover their other assets even if one item in the rental order is untransferable.


## Assessed type

ERC721
Any renter can prevent the lender from getting back their rented tokens
Audit: 2024-01-renft-findings
Severity: MEDIUM

# Lines of code

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


# Vulnerability details

## Impact
The `Guard.sol` contract is used in order to prevent malicious actions ,endangering the lender's assets, from being performed by a rental safe. The issue is that it allows making calls to disable the whitelisted modules of a gnosis safe:
```
} else if (selector == gnosis_safe_disable_module_selector) {
            // Load the extension address from calldata.
            address extension = address(
                uint160(
                    uint256(
                        _loadValueFromCalldata(data, gnosis_safe_disable_module_offset)
                    )
                )
            );

            // Check if the extension is whitelisted.
            _revertNonWhitelistedExtension(extension);
}
```
Therefore, after a rental is created, a malicious renter can disable the `Stop` module from their rental safe, which was enabled initially. Consequently, any call to `stopRent` will always fail as `_reclaimRentedItems` will no longer be able to call `execTransactionFromModule`. This would render all of the lender's assets stuck in the rental safe.

## Proof of Concept
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Guard.sol#L255-L266
As we can see any module that is whitelisted, including `Stop.sol` can easily be disabled.

## Tools Used
Manual review

## Recommended Mitigation Steps
In `_checkTransaction` in the `if (selector == gnosis_safe_disable_module_selector)` prevent the disabling of the `Stop` policy.


## Assessed type

DoS
generateSaltWithSender does not work correctly
Audit: 2024-01-renft-findings
Severity: MEDIUM

# Lines of code

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


# Vulnerability details

## Impact
Wrong salt returned from generateSaltWithSender() in [Create2Deployer.sol](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/Create2Deployer.sol#L107-L119).

## Proof of Concept
As we can see, the first 20 bytes of the salt has to be the address of the sender.
```solidity
  if (address(bytes20(salt)) != msg.sender) {
            revert Errors.Create2Deployer_UnauthorizedSender(msg.sender, salt);
        }
```

However, the function that calculates the salt does not do that. It returns the last 8 bytes of the sender, concatenated with bytes from `data`

```solidity
function generateSaltWithSender(
        address sender,
        bytes12 data
    ) public pure returns (bytes32 salt) {
        assembly {
            // Use `or` to combine the bytes20 address and bytes12 data together.
            salt := or(
                // Shift the address 12 bytes to the left.
                shl(0x60, sender),
                // Shift the extra data 20 bytes to the right.
                shr(0xA0, data)
            )
        }
    }
```

## Tools Used
Manual Review

## Recommended Mitigation Steps
Make the function return the correct salt.


## Assessed type

Error
Hooks required to succeed on both `onStart` and `onStop` may prevent rental termination
Audit: 2024-01-renft-findings
Severity: MEDIUM

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Create.sol#L480-L482
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L209-L212


# Vulnerability details

## Impact
The reNFT protocol uses hooks, which can act as middleware to a target contract or execute during rental start or stop. The [`updateHookStatus()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L313) function in the `Storage` module allows the admin to set the permissions of a hook using a bitmap consisting of 3 bits, which represent whether the `onTransaction()`, `onStart()` and `onStop()` functions are whitelisted for a given module, respectively:
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L313-L326

```solidity
function updateHookStatus(
	address hook,
	uint8 bitmap
) external onlyByProxy permissioned {
	// Require that the `hook` address is a contract.
	if (hook.code.length == 0) revert Errors.StorageModule_NotContract(hook);

	// 7 is 0x00000111. This ensures that only a valid bitmap can be set.
	if (bitmap > uint8(7))
		revert Errors.StorageModule_InvalidHookStatusBitmap(bitmap);

	// Update the status of the hook.
	hookStatus[hook] = bitmap;
}
```
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L144-L172
```solidity
/**
 * @notice Determines whether the `onTransaction()` function is enabled for the hook.
 *
 * @param hook Address of the hook contract.
 */
function hookOnTransaction(address hook) external view returns (bool) {
	// 1 is 0x00000001. Determines if the masked bit is enabled.
	return (uint8(1) & hookStatus[hook]) != 0;
}

/**
 * @notice Determines whether the `onStart()` function is enabled for the hook.
 *
 * @param hook Address of the hook contract.
 */
function hookOnStart(address hook) external view returns (bool) {
	// 2 is 0x00000010. Determines if the masked bit is enabled.
	return uint8(2) & hookStatus[hook] != 0;
}

/**
 * @notice Determines whether the `onStop()` function is enabled for the hook.
 *
 * @param hook Address of the hook contract.
 */
function hookOnStop(address hook) external view returns (bool) {
	// 4 is 0x00000100. Determines if the masked bit is enabled.
	return uint8(4) & hookStatus[hook] != 0;
}
```

However, the current implementation requires hook to always succeed on both `onStart()` and `onStop()` calls if they are provided in an order. This means if a hook is only whitelisted for `onStop()`, it will not be possible to create rentals using it as the [`addHooks()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Create.sol#L464) function, called during the creation of a rental, will revert:
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3a
EIP-712 typehash is incorrect for `RentalOrder` and `RentPayload` structs
Audit: 2024-01-renft-findings
Severity: MEDIUM

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L373-L375
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L394-L400


# Vulnerability details

## Impact
According to the EIP-712 standard, if a struct type references other struct types, the set of referenced struct types should be appended directly to the encoding of the type containing them, and this set should be sorted by name ([1](https://eips.ethereum.org/EIPS/eip-712#definition-of-encodetype)). However, in the current implementation in the `Signer` contract, the [`_RENTAL_ORDER_TYPEHASH`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L373-L375) and [`_RENT_PAYLOAD_TYPEHASH`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L394-L400) are not derived correctly, leading to non-compliance with the EIP-712 standard.

## Proof of Concept
The `rentalOrderTypeHash` returned by the [`_deriveRentalTypehashes()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L339) function, which is stored as `_RENTAL_ORDER_TYPEHASH` in the constructor, is meant to represent the EIP-712 typehash for the RentalOrderStruct. However, it is computed as:
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L373-L375
```solidity
rentalOrderTypeHash = keccak256(
	abi.encode(rentalOrderTypeString, hookTypeString, itemTypeString)
);
```
This is incorrect, as EIP-712 specifies that the set of referenced struct types is appended directly to the encoding of the type containing them, which can be achieved by using `abi.encodePacked()`:
```solidity
rentalOrderTypeHash = keccak256(
	abi.encodePacked(rentalOrderTypeString, hookTypeString, itemTypeString)
);
```
This is equivalent to `keccak256(string.concat(rentalOrderTypeString, hookTypeString, itemTypeString))` and EIP-712 compliant.

Furthermore, the typehash for the `RentPayload` struct is derived correctly using `abi.encodePacked()`, but the correct sorting order is not observed as the `OrderMetadata` type string is appended before the `OrderFulfillment` type string:
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L394-L400
```solidity
rentPayloadTypeHash = keccak256(
	abi.encodePacked(
		rentPayloadTypeString,
		orderMetadataTypeString,
		orderFulfillmentTypeString
	)
);
```

This breaks EIP-712 compliance, so can be [seen](https://github.com/code-423n4/2023-07-lens-findings/issues/141#issuecomment-1695727736) as an instance of “function of the protocol or its availability could be impacted” and is hence classified as medium severity.

## Tools Used
Manual review

## Recommended Mitigation Steps
To fix these issues, the `_d
Disabling a hook during rent prevents rental from being stopped
Audit: 2024-01-renft-findings
Severity: MEDIUM

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L209-L212


# Vulnerability details

## Impact
The reNFT protocol uses hooks, which can act as middleware to a target contract or execute during rental start or stop. The [`updateHookStatus()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L313) function in the `Storage` module allows the admin to set the permissions of a hook using a bitmap consisting of 3 bits, which represent whether the `onTransaction()`, `onStart()` and `onStop()` functions are whitelisted for a given module, respectively:
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L313-L326

```solidity
function updateHookStatus(
	address hook,
	uint8 bitmap
) external onlyByProxy permissioned {
	// Require that the `hook` address is a contract.
	if (hook.code.length == 0) revert Errors.StorageModule_NotContract(hook);

	// 7 is 0x00000111. This ensures that only a valid bitmap can be set.
	if (bitmap > uint8(7))
		revert Errors.StorageModule_InvalidHookStatusBitmap(bitmap);

	// Update the status of the hook.
	hookStatus[hook] = bitmap;
}
```
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/Storage.sol#L144-L172
```solidity
/**
 * @notice Determines whether the `onTransaction()` function is enabled for the hook.
 *
 * @param hook Address of the hook contract.
 */
function hookOnTransaction(address hook) external view returns (bool) {
	// 1 is 0x00000001. Determines if the masked bit is enabled.
	return (uint8(1) & hookStatus[hook]) != 0;
}

/**
 * @notice Determines whether the `onStart()` function is enabled for the hook.
 *
 * @param hook Address of the hook contract.
 */
function hookOnStart(address hook) external view returns (bool) {
	// 2 is 0x00000010. Determines if the masked bit is enabled.
	return uint8(2) & hookStatus[hook] != 0;
}

/**
 * @notice Determines whether the `onStop()` function is enabled for the hook.
 *
 * @param hook Address of the hook contract.
 */
function hookOnStop(address hook) external view returns (bool) {
	// 4 is 0x00000100. Determines if the masked bit is enabled.
	return uint8(4) & hookStatus[hook] != 0;
}
```

However, disabling a hook for `onStop()` will prevent any ongoing rentals in which the hook is enabled from being closed. This is because the [`_removeHooks()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L194) function, which is called form [`stopRent()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L265) and [`stopRentBatch()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L313) on rental termination, will revert if any of the hooks in the order
Lender can DOS stopRent and prevent renter from getting reward
Audit: 2024-01-renft-findings
Severity: MEDIUM

# Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L293
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Reclaimer.sol#L33


# Vulnerability details

## Impact
Lenders who might not need token back can DOS stopRent and prevent renter from being rewarded for renting token.

As stated by docs, users have motivation to rent out token and even pay because there is a greater for that;

>>This may sound counter-intuitive but the rationale is that some lenders may get benefit (tokens, rewards, etc) from allowing others to interact with contracts (on-chain games, etc) with their assets to extract some type of value from the lended asset.

## Proof of Concept
1. Alice creates a Pay Order that last one week, to rent out an ERC721 that is not so valuable for more benefits, and offers to pay 100USDC to the renter.

2. The order was fulfilled by Bob and the RentOrder was created.

3. Bob who expects to get paid after a week for renting Alice's token then calls ```stopRent``` to close the rent, transfer Alice's token back, and get paid.

4. The function could fail for various reasons;
-- If Alice adds an extended time check in a contract that receives the token, the hook IERC721Receiver function will revert if Alice's time is yet to elapse
``` solidity
function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
require(block.timestamp > AliceTime); //This could be a year later instead of a week
 return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
}
``` 
-- Alice could include a logic that consumes all gas to DOS the transaction forever, the token remains in the renterWaller and the Renter never gets paid.


## Tools Used
Manual review.

## Recommended Mitigation Steps
Only EOA should be accepted as the Lender's address to prevent such an attack scenario.





## Assessed type

ERC721
`OrderMetadata` encoding breaks EIP-712 compliance
Audit: 2024-01-renft-findings
Severity: MEDIUM

# Lines of code

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


# Vulnerability details

## Impact
According to the EIP-712 specification, structs are [encoded](https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct) by taking the hash of the concatenation of their type hash and the encoding of each of their fields. However, the [`_deriveOrderMetadataHash()`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L218) function in the `Signer` contract is incorrect in that it omits one of the struct's fields, `emittedExtraData`, when computing the hash of the `OrderMetadata` struct.

## Proof of Concept
The [`OrderMetadata`](https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/libraries/RentalStructs.sol#L50) struct is defined as follows:
```solidity
struct OrderMetadata {
    OrderType orderType;
    uint256 rentDuration;
    Hook[] hooks;
    bytes emittedExtraData;
}
```

But the `_deriveOrderMetadataHash()` returns:
https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/packages/Signer.sol#L232-L238
```solidity
	keccak256(
		abi.encode(
			_ORDER_METADATA_TYPEHASH,
			metadata.rentDuration,
			keccak256(abi.encodePacked(hookHashes))
		)
	);
```

The `emittedExtraData` field is left out when computing the hash of the `OrderMetadata`. This breaks EIP-712 compliance, so can be [seen](https://github.com/code-423n4/2023-07-lens-findings/issues/141#issuecomment-1695727736) as an instance of “function of the protocol or its availability could be impacted” and is hence classified as medium severity.

## Tools Used
Manual review

## Recommended Mitigation Steps
To mitigate this issue, the `_deriveOrderMetadataHash()` function should be updated to include the `emittedExtraData` field when computing the hash of the `OrderMetadata` struct. This will ensure that the function is in compliance with the EIP-712 specification and that the hash accurately represents the `OrderMetadata` struct.



## Assessed type

Other
Long period self rents will block hook disabling
Audit: 2024-01-renft-findings
Severity: MEDIUM

# Lines of code

https://github.com/re-nft/smart-contracts/blob/main/src/policies/Stop.sol#L194-L212


# Vulnerability details

## Impact

The protocol has admin-owned hooks, which can be used instead of `_checkTransaction` from GnosisSafe to disable transferring and approving the rented assets. There can be cases where hooks can contain vulnerable code in their `onTransaction` function and admins should disable them. Still, a malicious user can effectively block them from disabling by creating a rent to himself with a long rent period. As there will most likely be other rents using these hooks, admins will be forced to call `updateHookStatus` for `onStop` and all funds will be locked inside the `PaymentEscrow` contract, with no way to be recovered.

## Proof of Concept

[Stop.sol#L211](https://github.com/re-nft/smart-contracts/blob/main/src/policies/Stop.sol#L194-L212)

```solidity
function _removeHooks(
    Hook[] calldata hooks,
    Item[] calldata rentalItems,
    address rentalWallet
) internal {
    // Define hook target, item index, and item.
    address target;
    uint256 itemIndex;
    Item memory item;

    // Loop through each hook in the payload.
    for (uint256 i = 0; i < hooks.length; ++i) {
        // Get the hook address.
        target = hooks[i].target;

        // Check that the hook is reNFT-approved to execute on rental stop.
        if (!STORE.hookOnStop(target)) { 
-->         revert Errors.Shared_DisabledHook(target); //@audit will revert if hook onStop function is disabled
        }
```

## Tools Used

Manual Review

## Recommended Mitigation Steps

Consider adding a blacklist to disable hooks only for certain renters, this will ensure that other users who are using the **same hook will be able to stop their rents**, without losing their funds.


## Assessed type

Context