ParaSpace contest - jayphbee's results

The First Ever Cross-Margin NFT Financialization Protocol.

General Information

Platform: Code4rena

Start Date: 28/11/2022

Pot Size: $192,500 USDC

Total HM: 33

Participants: 106

Period: 11 days

Judge: LSDan

Total Solo HM: 15

Id: 186

League: ETH

ParaSpace

Findings Distribution

Researcher Performance

Rank: 74/106

Findings: 1

Award: $103.92

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

[L-1] Lack zero address check.

There need some address zero check to protect user from accidently losing funds in the WETHGateway contract.

function repayETH(uint256 amount, address onBehalfOf)

The onBehalfOf address should be checked if it is zero.

function repayETH(uint256 amount, address onBehalfOf)

The onBehalfOf address should be checked if it is zero.

function withdrawETHWithPermit(
        uint256 amount,
        address to,
        uint256 deadline,
        uint8 permitV,
        bytes32 permitR,
        bytes32 permitS
    ) external override nonReentrant {

The to address should be checked if it is zero.

There are three locations:

[N-01] meaningless revert string

Revert string should clearly describe the revert reason.

    receive() external payable {
        //only contracts can send ETH to the core
        require(msg.sender.isContract(), "22");
    }

[L-02] ParaReentrancyGuard storage variable isn't initialized in PoolApeStaking and PoolMarketplace.

The construtor in ParaReentrancyGuard was commentted out.

    // constructor() {
    //     _status = _NOT_ENTERED;
    // }

This indicates that contract inherited from ParaReentrancyGuard must initialize the _status variable itself. The PoolCore.sol contract initialize it in the initialize function

function initialize(IPoolAddressesProvider provider)
        external
        virtual
        initializer
    {
        require(
            provider == ADDRESSES_PROVIDER,
            Errors.INVALID_ADDRESSES_PROVIDER
        );

        RGStorage storage rgs = rgStorage();

        rgs._status = _NOT_ENTERED;
    }

But we didn't find it is initialized like PoolCore do in the PoolApeStaking and PoolMarketplace contract.

The impact is that ParaReentrancyGuard's usage doesn't follow design spec, which could result in unexpected behavior in the future.

recommendation:

Either

  1. initialize the _status variable in the construtor of ParaReentrancyGuard or
  2. initilize the _status variable like PoolCore do in the PoolApeStaking and PoolMarketplace contract.

[L-03] WETHGateway.repayETH will revert if msg.value > paybackAmount

In the repayETH function, paybackAmount eth will be deposit to WETH contract to get paybackAmount weth back.

WETH.deposit{value: paybackAmount}();

And then repay msg.value to pool

IPool(pool).repay(address(WETH), msg.value, onBehalfOf);

Here if msg.value > paybackAmount, IPool(pool).repay will revert due to insufficient weth.

Recommendation

change

IPool(pool).repay(address(WETH), msg.value, onBehalfOf);

to

IPool(pool).repay(address(WETH), paybackAmount, onBehalfOf);

#0 - c4-judge

2023-01-25T16:26:18Z

dmvt marked the issue as grade-b

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