reNFT - kaveyjoe's results

Collateral-free, permissionless, and highly customizable EVM NFT rentals.

General Information

Platform: Code4rena

Start Date: 08/01/2024

Pot Size: $83,600 USDC

Total HM: 23

Participants: 116

Period: 10 days

Judge: 0xean

Total Solo HM: 1

Id: 317

League: ETH

reNFT

Findings Distribution

Researcher Performance

Rank: 34/116

Findings: 1

Award: $269.86

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Awards

269.8643 USDC - $269.86

Labels

analysis-advanced
grade-a
sufficient quality report
A-11

External Links

reNFT Advanced Analysis Report

Overview

reNFT is a pioneering protocol and platform enabling peer-to-peer renting of non-fungible tokens (NFTs). This report delves into a detailed analysis of reNFT, encompassing its core features, technical framework, potential use cases, and associated risks.

1. Core Features and Mechanism

  • Collateral-Free Renting: Utilizing a novel escrow system, reNFT eliminates the need for renters to deposit collateral, significantly reducing barriers to entry.
  • Multi-Chain Support: Currently deployed on Ethereum and Polygon, with integrations planned for other popular blockchains, enhancing accessibility and reach.
  • Flexible Pricing and Duration: Renters and lenders can freely determine rental fees and durations, fostering a customized and dynamic marketplace.
  • Scholarship Automation: Streamlined workflow for Axie Infinity scholarships, automating rental agreements and reward distribution for scholars.
  • Smart Contract Security: Open-source and auditing ongoing by reputable platform Code4rena, promoting transparency and building trust.

2. Technical Framework

  • Smart Contracts: Securely manage escrow deposits, rental agreements, and fee distributions through audited smart contracts.
  • Tokenomics: RENFT token fuels the platform's ecosystem, rewarding token holders for participation and governance.
  • API and SDKs: Facilitate seamless integration with various Web3 projects and marketplaces, expanding reNFT's reach and utility.
  • Decentralized Governance: A DAO structure empowers community decision-making on protocol upgrades and future development.

3. Potential Use Cases

  • NFT Gaming: Rent gaming NFTs to gain access to play-to-earn opportunities without incurring high upfront costs.
  • Digital Art Sharing: Rent valuable artworks for temporary display or personal enjoyment, expanding access to exclusive pieces.
  • Metaverse Land Use: Lease virtual land parcels for events, experiences, or resource generation within metaverse platforms.
  • Fractional Ownership and Liquidity: Facilitate fractional ownership of expensive NFTs through renting out smaller portions.
  • Decentralized Finance (DeFi) Integration: Utilize NFTs as collateral in DeFi lending protocols by enabling renting for income generation.

4 . Market Potential

The NFT market is experiencing explosive growth, and reNFT addresses a crucial need within this space: unlocking the utility of NFTs beyond mere ownership. By enabling rentals, reNFT opens up new avenues for revenue generation for NFT holders and expands access to NFT experiences for a wider audience. This creates a win-win situation for all stakeholders involved.

Contracts Overview

1 . PaymentEscrow.sol

i .Purpose

  • The contract serves as a payment escrow module within a larger system for handling rental payments. ii. Architecture
  • Implements the Proxiable and Module interfaces.
  • Uses a base contract (PaymentEscrowBase) to store token balances separately.
  • Handles different types of rental orders, including pro-rata and in-full settlements.

iii. Storage

  • Keeps track of token balances in the escrow (balanceOf mapping).
  • Manages a fee percentage (fee) to be deducted from payments.

iv. Functions

  • Handles settling payments for rental orders (settlePayment and settlePaymentBatch).
  • Supports increasing token deposits (increaseDeposit).
  • Allows setting the fee percentage (setFee).
  • Provides a mechanism for collecting protocol fees (skim).
  • Supports contract upgrades (upgrade).

2 . Storage.sol

i . Purpose

  • The contract, "Storage," is responsible for managing various storage functionalities within the protocol.
  • It handles storage related to active rentals, deployed rental safes, hooks, and whitelists. ii. Architecture
  • Implements the Proxiable and Module interfaces.
  • Uses a base contract (StorageBase) for storing different types of data separately. iii. Storage
  • Manages the status of rental orders (orders mapping) and the number of actively rented tokens (rentedAssets mapping).
  • Tracks deployed rental safes and their nonces (deployedSafes mapping and totalSafes counter).
  • Handles hooks and their status, allowing for different functionalities (_contractToHook mapping and hookStatus mapping).
  • Maintains whitelists for delegates and extensions (whitelistedDelegates and whitelistedExtensions mappings). iv. Functions
  • Allows adding and removing rental orders and associated rental assets (addRentals, removeRentals, removeRentalsBatch). Manages deployed rental safes (addRentalSafe).
  • Connects hooks to destination addresses and updates their status (updateHookPath, updateHookStatus).
  • Toggles the whitelist status for delegates and extensions (toggleWhitelistDelegate, toggleWhitelistExtension).
  • Provides view functions for checking the status of rented assets and hooks (isRentedOut, contractToHook, hookOnTransaction, hookOnStart, hookOnStop).

3 . Accumulator.sol

i . Purpose

  • The contract, "Accumulator," provides functionality for managing dynamically allocated data struct arrays directly in memory.
  • Specifically designed for accumulating an array of RentalAssetUpdate structs where the total size is not known at instantiation.

ii . Key Components Insert Function (_insert)

  • Adds a new RentalAssetUpdate to the dynamic array stored in memory.
  • Utilizes assembly to efficiently manage memory and array updates.
  • The intermediary representation of the dynamic array is maintained in a byte data structure.

Convert to Static Function (_convertToStatic)

  • Converts the intermediary dynamic byte data of RentalAssetUpdate into a conventional Solidity array.
  • Extracts RentalId and amount information from the byte data and creates an array of RentalAssetUpdate structs.

4 . Reclaimer.sol

i . Purpose

  • The contract, "Reclaimer," is designed to retrieve rented assets from a wallet contract once a rental has been stopped and transfer them to the proper recipient.
  • It is part of a system where the reclaiming process is intended to be delegate called by the rental safe and operates within specific constraints to prevent unauthorized access.

ii. Key Components Original Deployment Address

  • The contract stores the original deployment address during construction (original), and its methods include checks to ensure proper delegate calls from the rental safe.

Transfer Functions (_transferERC721 and _transferERC1155)

  • Helper functions facilitating the safe transfer of ERC721 and ERC1155 tokens to a specified recipient. Utilizes OpenZeppelin's IERC721 and IERC1155 interfaces for safe transfers.

Reclaim Rental Order Function (reclaimRentalOrder)

  • Initiates the process of reclaiming rented assets specified in a RentalOrder.
  • The reclaiming process is intended to be triggered via delegate call from the rental safe.
  • Checks are implemented to ensure that the calling address is the rental wallet specified in the order and that the function is only callable in the context of a delegate call.

5 . Signer.sol

i . Purpose The contract, "Signer," manages logic related to signed payloads and signature verification when creating rentals. It is designed to ensure the integrity of the rental creation process through signature validation. ii . Key Components EIP-712 Structs and Typehashes

  • The contract leverages EIP-712 structured data and typehashes to create a standardized and secure way of signing and verifying signatures.
  • Typehashes are derived for various structs representing different components of the rental system, such as items, hooks, rental orders, order fulfillments, order metadata, and rent payloads.

Signature Verification

  • The contract implements functions for validating the signer of a payload hash using ECDSA signatures.
  • It includes checks to ensure that the intended fulfiller and the actual fulfiller match, preventing order sniping by unauthorized parties.
  • The expiration time of protocol signatures is validated to ensure they have not expired.

Hash Derivation Functions

  • Several internal functions are provided to derive the hash of different components, including items, hooks, rental orders, order fulfillments, order metadata, and rent payloads.
  • These hash derivation functions contribute to the construction of the payload hash that is later signed.

EIP-712 Domain Separator

  • The contract constructs the EIP-712 domain separator using the contract's name, version, chain ID, and address.
  • The domain separator is used in signature recovery to prevent replay attacks.

6 . Admin.sol

i . Purpose

  • The contract, "Admin," acts as an interface for administering various protocol-related functionalities, including fee management, proxy management, and whitelist management.
  • It implements the Policy interface, ensuring proper integration with the protocol's governance structure.

ii . Key Components Dependencies on Modules

  • The contract depends on two modules: Storage and PaymentEscrow. These modules are crucial for the functioning of the contract, and their addresses are dynamically configured during activation.

Permissions and Keycodes

  • The contract requests and is granted specific permissions from the kernel for interacting with the Storage and PaymentEscrow modules. Permissions include toggling whitelist settings,upgrading modules, and freezing modules.

External Functions

  • The contract provides external functions to manage the protocol's administration`, allowing authorized administrators to perform actions related to whitelist management, module upgrades, freezing, and fee adjustments.

7 . Create.sol

i . Purpose

The contract"Create," is to serve as an interface for creating rental orders within a decentralized application (DApp) or smart contract system. The contract involves the rental of assets and interacts with other modules and interfaces.

ii . Key Components

Policy Inheritance

  • The contract inherits from Policy, Signer, Zone, and Accumulator. This suggests that it incorporates certain policies, signature handling, zone functionality, and accumulation logic.

Configuration and Initialization

  • The contract has a configureDependencies function that sets up dependencies on other modules. It also has a requestPermissions function for obtaining permissions from the kernel.

View Functions

  • Several view functions are provided for retrieving information, such as domainSeparator, getRentalOrderHash, getRentPayloadHash, and getOrderMetadataHash.

Internal Functions

  • Internal functions such as _emitRentalOrderStarted, _processBaseOrderOffer, _processPayOrderOffer, etc., are used for internal processing and emitting events.
  • These functions handle the logic for processing offer items, consideration items, and hooks.

Rental Order Initialization

  • The _rentFromZone function initializes a rental order based on the provided payload and seaport payload.
  • It performs various checks, processes offer and consideration items, and updates storage accordingly.

Order Validation

  • The validateOrder function is the entry point for creating a rental. It validates the order, recovers the signer, and initiates the rental process.

8 . Factory.sol

i . Purpose

  • The contract "Factory", is to serve as a factory for deploying rental safes. Rental safes are smart contracts that allow a group of owners to collectively manage and control assets by requiring multiple signatures for transaction execution. The contract acts as an interface for the deployment and configuration of these safes. Some key components and features include:

ii . Key Components Kernel Policy Configuration

  • Storage Module Dependency: The contract depends on a Storage module, and its configureDependencies function sets the address of this module. The Storage module appears to be critical for maintaining state related to rental safes. Policies:

  • Stop Policy and Guard Policy: The contract references and uses a Stop policy and a Guard policy. The initializeRentalSafe function enables the stop policy as a module and sets the guard policy for a rental safe. External Contracts:

  • Gnosis Safe Contracts: The contract interacts with external Gnosis Safe contracts, such as SafeL2, SafeProxyFactory, and TokenCallbackHandler. These contracts likely provide core functionalities for safe deployment, proxy creation, and handling callbacks.

Constructor

  • The constructor initializes the contract with addresses of the kernel, stop policy, guard policy, fallback handler, safe proxy factory, and safe singleton`.

Configuration Functions

  • configureDependencies: Called upon policy activation to configure dependencies, ensuring the contract has the correct address for the Storage module.
  • requestPermissions: Called upon policy activation to request permissions from the kernel, specifically permission to execute addRentalSafe in the Storage module.

External Functions

  • initializeRentalSafe: Initializes a rental safe by enabling the stop policy module and setting the guard policy. It is expected to be called after the deployment of a rental safe.
  • deployRentalSafe: Deploys and initializes a rental safe with specified owners and a signature threshold. It utilizes the Gnosis Safe proxy factory to create a new safe instance.

Events

  • RentalSafeDeployment: An event emitted after successfully deploying a rental safe. It includes details such as the safe address, owners, and threshold.

9 . Guard.sol

i . Purpose The contract, "Guard" serves as an interface responsible for guarding transactions originating from a rental wallet. It imposes restrictions on certain types of transactions and allows for customization through the use of external hook contracts.

ii . Key Components

Kernel Policy Configuration

  • The contract depends on the Storage module for maintaining state related to rental safes. The configureDependencies function ensures that the contract has the correct address for the Storage module.

Internal Functions

  • _loadValueFromCalldata: Private function to load a `bytes32 value from calldata at a specified offset.
  • _revertSelectorOnActiveRental: Reverts if a specified selector is called on an actively rented token.
  • _revertNonWhitelistedExtension: Reverts if an extension is not whitelisted.
  • _forwardToHook: Forwards a Gnosis Safe call to a hook contract for additional processing.
  • _checkTransaction: Prevents certain transactions involving ERC721/ERC1155 tokens or changing modules/guard contract.

External Functions

  • checkTransaction: Checks a transaction initiated by a rental safe, allowing external hooks to intervene in the control flow.
  • checkAfterExecution: Placeholder for post-execution checks (currently unimplemented).
  • updateHookPath: Connects a target contract to a hook for transaction processing.
  • updateHookStatus: Toggles the status of a hook contract, defining the functionality it supports.

10 . Stop.sol

i . Purpose The contract "Stop", functions as an interface to manage the stopping of rental orders. It ensures that rental orders are stopped under appropriate conditions, facilitates the execution of hooks associated with stopping, and manages the settlement of payments.

ii . Key Components

Kernel Policy Configuration

  • The contract depends on the Storage and PaymentEscrow modules for maintaining state related to rental orders and handling payments, respectively. The configureDependencies function ensures that the contract has the correct addresses for these modules.

Internal Functions

  • _emitRentalOrderStopped: Helper function to emit an event signaling that a rental order has been stopped.
  • _validateRentalCanBeStopped: Validates whether a rental order can be stopped based on its type, end timestamp, and the address of the expected lender.
  • _reclaimRentedItems: Initiates the reclaiming of rented items, bypassing the guard, and transferring them back to the lender using the Safe module.
  • _removeHooks: Processes hooks associated with stopping the rental order, executing only those with the appropriate status.

External Functions

  • stopRent: Stops a single rental order by validating conditions, processing hooks, reclaiming rented items, settling payments, and removing relevant data from storage.
  • stopRentBatch: Stops multiple rental orders in a batch, applying similar logic as stopRent for each order in the batch.

11 . Create2Deployer.sol

i . Purpose

  • The contract "Create2Deployer" facilitates the deployment of contracts using the CREATE2 opcode with additional security measures. It aims to prevent frontrunning and unauthorized deployments across different chains by tying the deployment address to the sender's address and a unique salt.

ii . Key Components

Deployed Contract Tracking

  • The deployed mapping keeps track of whether a contract has already been deployed to a specific address to prevent redeploys.

Deployment Function - deploy

  • Validates the sender by checking that the first 20 bytes of the salt match the `sender's address.
  • Calculates the target deployment address using CREATE2 and ensures it has not been deployed before.
  • Prevents redeploys by updating the deployed mapping.
  • Executes the contract deployment and checks if the actual deployment address matches the target.

Address Calculation Function - getCreate2Address

  • Calculates the target address for contract deployment using CREATE2 based on the salt and init code.

Salt Generation Function - generateSaltWithSender

  • Generates a unique salt using the sender's address and additional data to make the salt unique.
  • Ties the deployment sender to the salt of the CREATE2 address, preventing frontrunning on different chains.

12 . Kernel.sol

i . Purpose The Contrat "kernel" acts as a registry managing policy and module contracts. The kernel allows the installation, upgrade, activation, and deactivation of modules and policies, while maintaining dependencies and permissions. The contracts have a modular structure, including abstract contracts for adapters, modules, and policies.

ii . Key Components

KernelAdapter

  • Base contract for both policies and modules, providing common access to logic related to the kernel contract.
  • Contains functions for changing the active kernel and modifiers for enforcing kernel-related access.

Module

  • Abstract contract inherited by all module implementations.
  • Includes functions for managing permissions and initialization.

Policy

  • Abstract contract inherited by all policy implementations.
  • Manages activation, dependencies, and permissions.
  • Allows the kernel to grant or revoke the active status of the policy.

Kernel

  • Manages policies, modules, roles, and permissions.
  • Allows execution of various actions, such as installing/upgrading modules, activating/deactivating policies, and migrating the kernel.
  • Grants and revokes roles for specific addresses.
  • Handles dependencies between policies and modules.

Contracts Architectural Diagram

1 . PaymentEscrow.sol

PayentEsrow

2 . Storage.sol

Storage

3 . Accumulator.sol

Accumulator

4 . Reclaimer.sol

Reclaimer

5 . Signer.sol

Signer

6 . Admin.sol

Admin

7 . Create.sol

Create

8 . Factory.sol

Factory

9 . Guard.sol

Guard

10 . Stop.sol

Stop

11 . Create2Deployer.sol

Creare2Deployer

12 . Kernel.sol

Kernel

Codebase Quality Analysis

Modularity: The codebase appears to be structured in a modular way, utilizing various contracts to manage specific functionalities. This can contribute to easier maintenance and upgrades.

Interfaces: The use of interfaces, such as Proxiable and Module, suggests a well-thought-out design, promoting code reusability and flexibility.

**Standardization: **Leveraging EIP-712 for signature verification and adhering to common interfaces like ERC721 and ERC1155 indicates a commitment to standardization and interoperability.

Comments and Documentation: The inclusion of comments for functions and sections provides A level of documentation, aiding developers in understanding the code.

Centralization Risks

  • The ability to upgrade both the Storage and PaymentEscrow modules introduces centralization risks. The contract owner, having the "ADMIN_ADMIN" role, can potentially wield significant control over protocol upgrades.

  • The security of the rental creation process heavily relies on the correctness of the signature verification mechanism.

  • The use of external hook contracts introduces complexity and dependencies. The correctness and security of the system heavily rely on the proper implementation and security of these hooks.

  • Migrating the kernel to a new contract is a critical operation and must be performed with caution. Failure to re-add modules and policies to the new kernel can lead to a loss of functionality.

Systematic Risks

  • Delegate Call Constraints are in place to limit the calling addresses to whitelisted entities (addresses explicitly whitelisted by the Admin policy).

  • The initializeRentalSafe function assumes that delegate call restrictions are in place due to the guard policy. If delegate calls were allowed without restriction, an attacker could potentially change the module/guard contacts after deployment, leading to unauthorized transfers of rented assets.

  • The deployRentalSafe function requires a valid threshold, and improper validation may result in unexpected behavior. Ensuring that the threshold is within the correct range is crucial for the security of the deployed safes.

  • The deployment process involves multiple steps, including delegate calls and interactions with external contracts. Any issues during this process, such as reentrancy vulnerabilities or unexpected state changes, could pose risks to the correct deployment and initialization of rental safes.

  • Granting and revoking roles should be carefully managed to avoid unintended consequences. The grantRole and revokeRole functions require proper validation.

  • The uniqueness of the safe addresses is based on the nonce generation using keccak256(abi.encode(STORE.totalSafes() + 1, block.chainid)). If there are issues with nonce generation or if the chain ID is manipulated, it could result in non-unique safe addresses, leading to potential security issues.

  • The warning about delegate call assumption indicates a potential security concern. It's crucial to ensure that delegate call restrictions are effectively implemented by the `guard policy.

Learning and Insights

The codebase review of reNFT has significantly contributed to my growth in codebase skills by providing a comprehensive understanding of various aspects of smart contract development. Here's how this review has been instrumental in enhancing my skills:

Architecture Understanding

  • The review helped me grasp the architecture of a complex decentralized application. I learned about the modular structure, interfaces, and how different contracts interact within the reNFT protocol.

Smart Contract Patterns

  • I gained insights into common patterns used in smart contract development, such as Proxiable and Module interfaces. Understanding these patterns is crucial for building modular and upgradeable contracts.

Storage Management

  • The review delved into the storage management strategies employed in the reNFT protocol. I learned how to organize and store data efficiently, considering different types of information like balances, rental orders, and safes.

Security Considerations

  • The detailed analysis of each contract highlighted security measures incorporated in the codebase. Learning about secure asset transfers, signature verification using EIP-712, and preventing replay attacks has increased my awareness of potential vulnerabilities.

Memory Management Techniques

  • The review provided exposure to memory management techniques, especially in the context of the Accumulator.sol contract. Understanding how to efficiently handle dynamically allocated data in memory using assembly is a valuable skill.

Delegate Calls and Reentrancy Protection

  • Through the Reclaimer.sol contract, I gained insights into the use of delegate calls for specific functionalities. Additionally, the contract demonstrated measures to prevent unauthorized access and protect against reentrancy attacks during the reclaiming process.

External Contract Interaction

  • The contracts in the review interacted with external contracts, such as Gnosis Safe contracts. Understanding how to interface with external contracts for functionalities like deployment and callback handling is essential in decentralized ecosystems.

Signature Verification and EIP Standards

  • The Signer.sol contract showcased the implementation of signature verification using EIP-712 structured data and typehashes. Learning how to validate signatures securely is crucial for any system involving signed payloads.

Administrative and Governance Aspects

  • The Admin.sol contract shed light on the administrative aspects of a protocol, including permissions, module upgrades, and fee adjustments. Understanding how governance structures are integrated into smart contracts is vital for protocol maintenance.

Factory Contract for Deployment

  • The Factory.sol contract demonstrated how to use a factory pattern for deploying rental safes. Learning about kernel policy configuration and interaction with external contracts for deployment is valuable for designing scalable systems.

Secure Contract Deployment

  • The Create2Deployer.sol contract introduced me to the secure deployment of contracts using CREATE2. Understanding how to prevent frontrunning and tying deployment addresses to unique salts is crucial for deploying contracts in a secure manner.

Policy and Module Management

  • The Kernel.sol contract acted as a registry managing policies and modules. Understanding how policies and modules are activated, upgraded, and deactivated provides insights into governance structures and contract lifecycle management.

Recommendation

  • Assess the risks associated with centralization and consider decentralization mechanisms if appropriate.
  • Ensure a robust mechanism for setting and updating fees, potentially considering external governance.
  • Provide clear documentation outlining the intended usage of the contract and the constraints on delegate ,kernel interactions, role assignments, and permission updates and also explaining the EIP-712 integration and how the contract ensures secure payload creation and signature verification.
  • Verify the interaction with external interfaces (e.g., IERC721 and IERC1155) to ensure safe token transfers.
  • Implement extensive testing, including unit tests and scenario tests, to verify the contract's functionality and security features.
  • A mechanism for community governance or multisig control could enhance decentralization and security
  • A clear process for kernel migration, including updating dependencies and permissions, should be established.
  • Educate the community about the roles and responsibilities of administrators, ensuring understanding and alignment with the protocol's governance principles.

Conclusion

reNFT presents a groundbreaking solution for unlocking the true potential of NFTs by enabling their utilization through renting. Its innovative features, multi-chain support, and flexible use cases position it as a key player in the evolving NFT landscape. However, addressing potential risks and fostering community engagement remain crucial for reNFT's long-term success. This report provides a comprehensive foundation for further analysis and evaluation of this transformative protocol.

Message For reNFT Team

Congratulations on the successful completion of the codebase audit for reNFT within the Code4rena platform. The depth and quality of your codebase reflect a remarkable commitment to security, transparency, and excellence in blockchain development.

As an C4 warden reviewing the reNFT codebase, I was thoroughly impressed by the meticulous design and robust architecture of your smart contracts. Each module, from PaymentEscrow to Create2Deployer, demonstrates a profound understanding of the complexities involved in handling rental payments, managing storage functionalities, and ensuring secure deployment of contracts. the reNFT codebase reflects an exceptional level of diligence and expertise in blockchain development. The team's commitment to security, modular design, and adherence to best practices is evident throughout the codebase.

I want to extend my best wishes to the entire reNFT team for the success of your project. Your dedication to excellence in smart contract development and security is truly commendable.

Time spent:

35 hours

#0 - c4-judge

2024-01-27T20:26:48Z

0xean marked the issue as grade-a

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter