reNFT - albertwh1te'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: 106/116

Findings: 1

Award: $2.72

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

2.7205 USDC - $2.72

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
duplicate-64

External Links

Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L190-L202 https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/policies/Stop.sol#L265-L306

Vulnerability details

Impact

When a borrower is blacklisted by USDC and the lender sets ERC20 as USDC, transferring USDC to the borrower becomes impossible, leading to a chain of reverts:

PaymentEscrow._settlePaymentInFull reverts PaymentEscrow._settlePayment reverts PaymentEscrow.settlePayment reverts Stop.stopRent reverts

As a result, the borrower's PAY rentals can't be stopped, allowing them to keep the NFT indefinitely.

Proof of Concept

The implementation of USDC's transfer and transferFrom functions differs from other ERC20 contracts. It first checks if the account is on the blacklist.

    modifier notBlacklisted(address _account) {
        require(
            !blacklisted[_account],
            "Blacklistable: account is blacklisted"
        );
        _;
    }
    /**
     * @notice Transfer tokens from the caller
     * @param to    Payee's address
     * @param value Transfer amount
     * @return True if successful
     */
    function transfer(address to, uint256 value)
        external
        override
        whenNotPaused
        notBlacklisted(msg.sender)
        notBlacklisted(to)
        returns (bool)
    {
        _transfer(msg.sender, to, value);
        return true;
    }

    /**
     * @notice Transfer tokens by spending allowance
     * @param from  Payer's address
     * @param to    Payee's address
     * @param value Transfer amount
     * @return True if successful
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    )
        external
        override
        whenNotPaused
        notBlacklisted(msg.sender)
        notBlacklisted(from)
        notBlacklisted(to)
        returns (bool)
    {
        require(
            value <= allowed[from][msg.sender],
            "ERC20: transfer amount exceeds allowance"
        );
        _transfer(from, to, value);
        allowed[from][msg.sender] = allowed[from][msg.sender].sub(value);
        return true;
    }
  1. The blacklisted borrower borrows an NFT
  2. The rental process can't be halted due to fail of usdc transcations.

Tools Used

Foundry

Allow users to claim their fees instead of sending them directly to the user's address.

Assessed type

ERC20

#0 - c4-pre-sort

2024-01-21T17:35:52Z

141345 marked the issue as duplicate of #64

#1 - c4-judge

2024-01-28T20:49:26Z

0xean changed the severity to 2 (Med Risk)

#2 - c4-judge

2024-01-28T21:00:34Z

0xean marked the issue as satisfactory

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