ParaSpace contest - rvierdiiev'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: 60/106

Findings: 2

Award: $122.23

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Awards

18.3064 USDC - $18.31

Labels

bug
2 (Med Risk)
satisfactory
duplicate-420

External Links

Lines of code

https://github.com/code-423n4/2022-11-paraspace/blob/main/paraspace-core/contracts/misc/ParaSpaceOracle.sol#L115-L136

Vulnerability details

Impact

ParaSpaceOracle.getAssetPrice doesn't check if price is fresh. As result stale price can be used which can lead to protocol loses if price has changed.

Proof of Concept

https://github.com/code-423n4/2022-11-paraspace/blob/main/paraspace-core/contracts/misc/ParaSpaceOracle.sol#L115-L136

    function getAssetPrice(address asset)
        public
        view
        override
        returns (uint256)
    {
        if (asset == BASE_CURRENCY) {
            return BASE_CURRENCY_UNIT;
        }


        uint256 price = 0;
        IEACAggregatorProxy source = IEACAggregatorProxy(assetsSources[asset]);
        if (address(source) != address(0)) {
            price = uint256(source.latestAnswer());
        }
        if (price == 0 && address(_fallbackOracle) != address(0)) {
            price = _fallbackOracle.getAssetPrice(asset);
        }


        require(price != 0, Errors.ORACLE_PRICE_NOT_READY);
        return price;
    }

If IEACAggregatorProxy exists for asset then it's price is fetched using source.latestAnswer() function. After the price is fetched there is only check that price is not 0. But there is no check if the price is fresh. It's possible that price will be not 0, but it will be stale. And this can lead to protocol loses if the real price has changed meanwhile the aggregator was not working.

Tools Used

VsCode

IEACAggregatorProxy also has latestTimestamp() function. Result of this function should be checked with some stake period to detect if the price is fresh enough.

#1 - c4-judge

2022-12-20T17:44:38Z

dmvt marked the issue as duplicate of #5

#2 - c4-judge

2023-01-23T15:57:19Z

dmvt marked the issue as satisfactory

Lines of code

https://github.com/code-423n4/2022-11-paraspace/blob/main/paraspace-core/contracts/misc/NFTFloorOracle.sol#L183-L189

Vulnerability details

Impact

It's possible to pause not existing asset in NFTFloorOracle. As a result when asset will be added it will be paused and will be not possible to set and get price for it until it will be unpaused.

Proof of Concept

https://github.com/code-423n4/2022-11-paraspace/blob/main/paraspace-core/contracts/misc/NFTFloorOracle.sol#L183-L189

    function setPause(address _asset, bool _flag)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        assetFeederMap[_asset].paused = _flag;
        emit AssetPaused(_asset, _flag);
    }

NFTFloorOracle.setPause allows to pause asset and restrict setting price for it. Because there is no onlyWhenAssetExisted modifier it's possible to pause asset that doesn't exist. Later, when admin will add asset it will be paused already and it will be not possible to set price for it until it will be noticed and admin unpause asset.

Tools Used

VsCode

Add nlyWhenAssetExisted modifier to setPause function.

#0 - c4-judge

2023-01-09T22:33:57Z

dmvt changed the severity to QA (Quality Assurance)

#1 - c4-judge

2023-01-25T12:33:17Z

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