Papr contest - Ruhum's results

NFT Lending Powered by Uniswap v3.

General Information

Platform: Code4rena

Start Date: 16/12/2022

Pot Size: $60,500 USDC

Total HM: 12

Participants: 58

Period: 5 days

Judge: Trust

Total Solo HM: 4

Id: 196

League: ETH

Backed Protocol

Findings Distribution

Researcher Performance

Rank: 11/58

Findings: 1

Award: $1,330.41

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Jeiwan

Also found by: Koolex, Ruhum, rotcivegaf

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
duplicate-183

Awards

1330.4109 USDC - $1,330.41

External Links

Lines of code

https://github.com/with-backed/papr/blob/9528f2711ff0c1522076b9f93fba13f88d5bd5e6/src/PaprController.sol#L159

Vulnerability details

Impact

The collateral is assigned to the operator's vault because of a parameter mismatch. This impacts the ability of third parties to integrate the PaprController contract. You're not able to create an intermediary contract that adds collateral to a user's vault. It has to be the user themselves sending the NFT directly else the collateral is assigned to the calling contract (operator). If the collateral is assigned to the NFT owner's vault you can have two types of integrations:

  • the intermediary contract has its own vault and handles all the user logic itself (user approved NFT to intermediary contract -> contract transfers NFT to itself -> contract sends NFT to PaprController to add the collateral to their vault)
  • intermediary contract works with the user's own vault (user approves NFT to intermediary contract -> contract transfers NFT to PaprController to add to user's vault)

Only the first integration type is possible in the current form because the collateral is always assigned to the operator (intermediary contract).

Generally, I believe that the collateral being assigned to the operator is unexpected behavior that might cause headaches if the caller doesn't read the contracts properly. To undo that, the operator has to pay back the debt, remove the collateral and send it back to the user. Depending on the contract used to transfer the collateral in the first place, that might not be possible. In that rare scenario that might cause a loss of funds.

Proof of Concept

The onERC721Received() function has the following interface

function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4);

The PaprController contract expects the first parameter to be the NFT owner, although that's the operator's address (see NATSPEC comment):

    /// @notice Handler for safeTransferFrom of an NFT
    /// @dev Should be preferred to `addCollateral` if only one NFT is being added
    /// to avoid approval call and save gas
    /// @param from the current owner of the nft
    /// @param _id the id of the NFT
    /// @param data encoded IPaprController.OnERC721ReceivedArgs
    /// @return selector indicating succesful receiving of the NFT
    function onERC721Received(address from, address, uint256 _id, bytes calldata data)
        external
        override
        returns (bytes4)
    {
        IPaprController.OnERC721ReceivedArgs memory request = abi.decode(data, (IPaprController.OnERC721ReceivedArgs));

        IPaprController.Collateral memory collateral = IPaprController.Collateral(ERC721(msg.sender), _id);

        _addCollateralToVault(from, collateral);

        if (request.swapParams.minOut > 0) {
            _increaseDebtAndSell(from, request.proceedsTo, ERC721(msg.sender), request.swapParams, request.oracleInfo);
        } else if (request.debt > 0) {
            _increaseDebt(from, collateral.addr, request.proceedsTo, request.debt, request.oracleInfo);
        }

        return ERC721TokenReceiver.onERC721Received.selector;
    }

Tools Used

none

Use the owner's address instead of the operator's.

#0 - c4-judge

2022-12-25T14:34:37Z

trust1995 marked the issue as duplicate of #121

#1 - c4-judge

2022-12-25T14:34:45Z

trust1995 marked the issue as satisfactory

#2 - c4-judge

2022-12-25T16:58:11Z

trust1995 changed the severity to 3 (High Risk)

#3 - c4-judge

2022-12-25T17:45:58Z

trust1995 marked the issue as duplicate of #183

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