ParaSpace contest - Rolezn'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: 23/106

Findings: 5

Award: $1,155.32

QA:
grade-a
Gas:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: carlitox477

Also found by: 0xDave, Jeiwan, Rolezn, __141345__, imare, nicobevi

Labels

2 (Med Risk)
partial-50
duplicate-267

Awards

102.8853 USDC - $102.89

External Links

Judge has assessed an item in Issue #80 as M risk. The relevant finding follows:

[LOW‑10] getPrice and combine will not work if expirationPeriod == 0 The following conditions will fail if expirationPeriod is set to 0. There is currently no limit that it cannot be set to 0.

Proof Of Concept 243: require( 244: (block.number - updatedAt) <= config.expirationPeriod, 245: "NFTOracle: asset price expired" 246: ); https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/NFTFloorOracle.sol#L243-L246

419: if (diffBlock <= config.expirationPeriod) { 420: validPriceList[validNum] = priceInfo.twap; 421: validNum++; 422: } https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/NFTFloorOracle.sol#L419-L422

#0 - c4-judge

2023-01-25T11:10:02Z

dmvt marked the issue as duplicate of #28

#1 - c4-judge

2023-01-25T11:10:08Z

dmvt marked the issue as partial-50

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/tree/main/paraspace-core/contracts/misc/ParaSpaceOracle.sol#L128

Vulnerability details

Description

According to Chainlink’s documentation, the latestAnswer function is deprecated. This function might suddenly stop working if Chainlink stop supporting deprecated APIs and the old API can return stale data.

Impact

The old API can return stale data.

<ins>Proof Of Concept</ins>

It is indicated in the docs that the contract: "Use of Chainlink Aggregators as first source of price"

126: IEACAggregatorProxy source = IEACAggregatorProxy(assetsSources[asset]);
127: if (address(source) != address(0)) {
128:    price = uint256(source.latestAnswer());
129: }

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

<ins>Recommended Mitigation Steps</ins>

Use the latestRoundData function to get the price instead. Add checks on the return data with proper revert messages if the price is stale or the round is uncomplet. See docs for reference: https://docs.chain.link/docs/price-feeds-api-reference/

#1 - c4-judge

2022-12-20T17:44:29Z

dmvt marked the issue as duplicate of #5

#2 - c4-judge

2023-01-09T16:32:08Z

dmvt marked the issue as partial-50

#3 - c4-judge

2023-01-23T15:57:30Z

dmvt marked the issue as satisfactory

Summary<a name="Summary">

Low Risk Issues

IssueContexts
LOW‑1Missing Checks for Address(0x0)7
LOW‑2Unused receive() Function Will Lock Ether In Contract1
LOW‑3Missing Contract-existence Checks Before Low-level Calls1
LOW‑4Contracts are not using their OZ Upgradeable counterparts87
LOW‑5Low Level Calls With Solidity Version 0.8.14 Can Result In Optimiser Bug1
LOW‑6Missing parameter validation in constructor12
LOW‑7Prevent division by 02
LOW‑8Upgrade OpenZeppelin Contract Dependency2
LOW‑9The nonReentrant modifier should occur before all other modifiers25
LOW‑10getPrice and combine will not work if expirationPeriod == 02

Total: 140 contexts over 10 issues

Non-critical Issues

IssueContexts
NC‑1Critical Changes Should Use Two-step Procedure30
NC‑2Use a more recent version of Solidity32
NC‑3Event Is Missing Indexed Fields2
NC‑4Constants Should Be Defined Rather Than Using Magic Numbers1
NC‑5Missing event for critical parameter change8
NC‑6Implementation contract may not be initialized16
NC‑7Use of Block.Timestamp2
NC‑8Non-usage of specific imports20
NC‑9Expressions for constant values such as a call to keccak256(), should use immutable rather than constant3
NC‑10Use bytes.concat()12
NC‑11Open TODOs3
NC‑12No need to initialize uints to zero10
NC‑13Use delete to Clear Variables4
NC‑14Duplicate imports4
NC‑15Missing NATSPEC documentation4
NC‑16Insufficient NATSPEC documentation4

Total: 144 contexts over 14 issues

Low Risk Issues

<a href="#Summary">[LOW‑1]</a><a name="LOW&#x2011;1"> Missing Checks for Address(0x0)

Lack of zero-address validation on address parameters may lead to transaction reverts, waste gas, require resubmission of transactions and may even force contract redeployments in certain cases within the protocol.

<ins>Proof Of Concept</ins>
70: function setAddress: address newAddress

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L70

142: function setPriceOracle: address newPriceOracle

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L142

158: function setACLManager: address newAclManager

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L158

170: function setACLAdmin: address newAclAdmin

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L170

182: function setPriceOracleSentinel: address newPriceOracleSentinel

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L182

224: function setProtocolDataProvider: address newDataProvider

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L224

235: function setWETH: address newWETH

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L235

<ins>Recommended Mitigation Steps</ins>

Consider adding explicit zero-address validation on input parameters of address type.

<a href="#Summary">[LOW‑2]</a><a name="LOW&#x2011;2"> Unused receive() Function Will Lock Ether In Contract

If the intention is for the Ether to be used, the function should call another function, otherwise it should revert

<ins>Proof Of Concept</ins>
149: receive() external payable {}

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L149

<ins>Recommended Mitigation Steps</ins>

The function should call another function, otherwise it should revert

<a href="#Summary">[LOW‑3]</a><a name="LOW&#x2011;3"> Missing Contract-existence Checks Before Low-level Calls

Low-level calls return success if there is no code present at the specified address.

<ins>Proof Of Concept</ins>
145: (bool success, ) = to.call{value: value}(new bytes(0));

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L145

<ins>Recommended Mitigation Steps</ins>

In addition to the zero-address checks, add a check to verify that <address>.code.length > 0

<a href="#Summary">[LOW‑4]</a><a name="LOW&#x2011;4"> Contracts are not using their OZ Upgradeable counterparts

The non-upgradeable standard version of OpenZeppelin’s library are inherited / used by the contracts. It would be safer to use the upgradeable versions of the library contracts to avoid unexpected behaviour.

<ins>Proof of Concept</ins>
4: import "../dependencies/openzeppelin/contracts/AccessControl.sol";
5: import "../dependencies/openzeppelin/upgradeability/Initializable.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/NFTFloorOracle.sol#L4-L5

14: import {IERC20Detailed} from "../dependencies/openzeppelin/contracts/IERC20Detailed.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L14

12: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";
13: import {IERC1271} from "../../dependencies/openzeppelin/contracts/IERC1271.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/LooksRareAdapter.sol#L12-L13

12: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";
13: import {IERC1271} from "../../dependencies/openzeppelin/contracts/IERC1271.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L12-L13

13: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";
14: import {IERC1271} from "../../dependencies/openzeppelin/contracts/IERC1271.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/X2Y2Adapter.sol#L13-L14

4: import {Ownable} from "../../dependencies/openzeppelin/contracts/Ownable.sol";
10: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L4-L10

5: import {SafeCast} from "../../../dependencies/openzeppelin/contracts/SafeCast.sol";
6: import {IERC20} from "../../../dependencies/openzeppelin/contracts/IERC20.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/BorrowLogic.sol#L5-L6

4: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/FlashClaimLogic.sol#L4

4: import {IERC20} from "../../../dependencies/openzeppelin/contracts/IERC20.sol";
5: import {IERC721Enumerable} from "../../../dependencies/openzeppelin/contracts/IERC721Enumerable.sol";
6: import {Math} from "../../../dependencies/openzeppelin/contracts/Math.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L4-L6

4: import {IERC20} from "../../../dependencies/openzeppelin/contracts//IERC20.sol";
8: import {Math} from "../../../dependencies/openzeppelin/contracts/Math.sol";
17: import {Address} from "../../../dependencies/openzeppelin/contracts/Address.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol#L4-L17

4: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";
16: import {SafeERC20} from "../../../dependencies/openzeppelin/contracts/SafeERC20.sol";
17: import {IERC20} from "../../../dependencies/openzeppelin/contracts/IERC20.sol";
18: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";
26: import {Address} from "../../../dependencies/openzeppelin/contracts/Address.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L4-L26

5: import {Address} from "../../../dependencies/openzeppelin/contracts/Address.sol";
6: import {IERC20} from "../../../dependencies/openzeppelin/contracts/IERC20.sol";
7: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/PoolLogic.sol#L5-L7

4: import {IERC20} from "../../../dependencies/openzeppelin/contracts/IERC20.sol";
5: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/SupplyLogic.sol#L4-L5

4: import {IERC20} from "../../../dependencies/openzeppelin/contracts/IERC20.sol";
5: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";
6: import {Address} from "../../../dependencies/openzeppelin/contracts/Address.sol";
25: import {SafeCast} from "../../../dependencies/openzeppelin/contracts/SafeCast.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L4-L25

4: import {IERC20} from "../../dependencies/openzeppelin/contracts/IERC20.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/DefaultReserveAuctionStrategy.sol#L4

22: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";
23: import {IERC721Receiver} from "../../dependencies/openzeppelin/contracts/IERC721Receiver.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L22-L23

15: import {IERC20} from "../../dependencies/openzeppelin/contracts/IERC20.sol";
16: import {SafeERC20} from "../../dependencies/openzeppelin/contracts/SafeERC20.sol";
25: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";
26: import {IERC721Receiver} from "../../dependencies/openzeppelin/contracts/IERC721Receiver.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolMarketplace.sol#L15-L26

21: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";
22: import {IERC721Receiver} from "../../dependencies/openzeppelin/contracts/IERC721Receiver.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L21-L22

4: import {IERC20} from "../../dependencies/openzeppelin/contracts/IERC20.sol";
5: import {IERC721} from "../../dependencies/openzeppelin/contracts/IERC721.sol";
6: import {IERC1155} from "../../dependencies/openzeppelin/contracts/IERC1155.sol";
7: import {IERC721Metadata} from "../../dependencies/openzeppelin/contracts/IERC721Metadata.sol";
8: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";
10: import {SafeCast} from "../../dependencies/openzeppelin/contracts/SafeCast.sol";
20: import {SafeERC20} from "../../dependencies/openzeppelin/contracts/SafeERC20.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L4-L20

7: import {IERC20} from "../../dependencies/openzeppelin/contracts/IERC20.sol";
8: import {IERC721} from "../../dependencies/openzeppelin/contracts/IERC721.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L7-L8

4: import {IERC20} from "../../dependencies/openzeppelin/contracts/IERC20.sol";
5: import {IERC721} from "../../dependencies/openzeppelin/contracts/IERC721.sol";
6: import {IERC1155} from "../../dependencies/openzeppelin/contracts/IERC1155.sol";
7: import {IERC721Metadata} from "../../dependencies/openzeppelin/contracts/IERC721Metadata.sol";
8: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";
10: import {SafeCast} from "../../dependencies/openzeppelin/contracts/SafeCast.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMoonBirds.sol#L4-L10

4: import {IERC20} from "../../dependencies/openzeppelin/contracts/IERC20.sol";
5: import {IERC721} from "../../dependencies/openzeppelin/contracts/IERC721.sol";
6: import {IERC1155} from "../../dependencies/openzeppelin/contracts/IERC1155.sol";
7: import {IERC721Metadata} from "../../dependencies/openzeppelin/contracts/IERC721Metadata.sol";
8: import {Address} from "../../dependencies/openzeppelin/contracts/Address.sol";
9: import {SafeERC20} from "../../dependencies/openzeppelin/contracts/SafeERC20.sol";
10: import {SafeCast} from "../../dependencies/openzeppelin/contracts/SafeCast.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L4-L10

4: import {Context} from "../../../dependencies/openzeppelin/contracts/Context.sol";
5: import {Strings} from "../../../dependencies/openzeppelin/contracts/Strings.sol";
6: import {Address} from "../../../dependencies/openzeppelin/contracts/Address.sol";
7: import {IERC165} from "../../../dependencies/openzeppelin/contracts/IERC165.sol";
8: import {IERC721Metadata} from "../../../dependencies/openzeppelin/contracts/IERC721Metadata.sol";
9: import {IERC721Receiver} from "../../../dependencies/openzeppelin/contracts/IERC721Receiver.sol";
10: import {IERC721Enumerable} from "../../../dependencies/openzeppelin/contracts/IERC721Enumerable.sol";
13: import {SafeCast} from "../../../dependencies/openzeppelin/contracts/SafeCast.sol";
21: import {ReentrancyGuard} from "../../../dependencies/openzeppelin/contracts/ReentrancyGuard.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L4-L21

4: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";
5: import {SafeERC20} from "../../../dependencies/openzeppelin/contracts/SafeERC20.sol";
6: import {IERC20} from "../../../dependencies/openzeppelin/contracts/IERC20.sol";
10: import {Math} from "../../../dependencies/openzeppelin/contracts/Math.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/ApeStakingLogic.sol#L4-L10

4: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";
5: import {SafeERC20} from "../../../dependencies/openzeppelin/contracts/SafeERC20.sol";
6: import {IERC20} from "../../../dependencies/openzeppelin/contracts/IERC20.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L4-L6

4: import {OwnableUpgradeable} from "../dependencies/openzeppelin/upgradeability/OwnableUpgradeable.sol";
11: import {IERC721} from "../dependencies/openzeppelin/contracts/IERC721.sol";
12: import {IERC721Receiver} from "../dependencies/openzeppelin/contracts/IERC721Receiver.sol";
17: import {ReentrancyGuard} from "../dependencies/openzeppelin/contracts/ReentrancyGuard.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L4-L17

<ins>Recommended Mitigation Steps</ins>

Where applicable, use the contracts from @openzeppelin/contracts-upgradeable instead of @openzeppelin/contracts.

<a href="#Summary">[LOW‑5]</a><a name="LOW&#x2011;5"> Low Level Calls With Solidity Version Before 0.8.14 Can Result In Optimiser Bug

The project contracts in scope are using low level calls with solidity version before 0.8.14 which can result in optimizer bug. https://medium.com/certora/overly-optimistic-optimizer-certora-bug-disclosure-2101e3f7994d

Simliar findings in Code4rena contests for reference: https://code4rena.com/reports/2022-06-illuminate/#5-low-level-calls-with-solidity-version-0814-can-result-in-optimiser-bug

<ins>Proof Of Concept</ins>

POC can be found in the above medium reference url.

Functions that execute low level calls in contracts with solidity version under 0.8.14

643: assembly {
         mstore(reservesList, sub(reservesListCount, droppedReservesCount))
     }

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L643

<ins>Recommended Mitigation Steps</ins>

Consider upgrading to at least solidity v0.8.15.

<a href="#Summary">[LOW‑6]</a><a name="LOW&#x2011;6"> Missing parameter validation in constructor

Some parameters of constructors are not checked for invalid values.

<ins>Proof Of Concept</ins>
53: address fallbackOracle
54: address baseCurrency

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/ParaSpaceOracle.sol#L53-L54

24: address _factory
25: address _manager
26: address _addressProvider

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L24-L26

45: string memory marketId
45: address owner

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L45

32: address apeCoinStaking

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L32

16: address apeCoinStaking

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L16

16: address apeCoinStaking

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L16

44: address _punk
45: address _wpunk
46: address _pool

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L44-L46

<ins>Recommended Mitigation Steps</ins>

Validate the parameters.

<a href="#Summary">[LOW‑7]</a><a name="LOW&#x2011;7"> Prevent division by 0

On several locations in the code precautions are not being taken for not dividing by 0, this will revert the code.

These functions can be called with 0 value in the input, this value is not checked for being bigger than 0, that means in some scenarios this can potentially trigger a division by zero.

<ins>Proof Of Concept</ins>
349: return userTotalDebt / assetUnit

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L349

531: return (balance / assetUnit

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L531

<ins>Recommended Mitigation Steps</ins>

Recommend making sure division by 0 won’t occur by checking the variables beforehand and handling this edge case.

<a href="#Summary">[LOW‑8]</a><a name="LOW&#x2011;8"> Upgrade OpenZeppelin Contract Dependency

An outdated OZ version is used (which has known vulnerabilities, see: https://github.com/OpenZeppelin/openzeppelin-contracts/security/advisories).

<ins>Proof Of Concept</ins>
    "@openzeppelin/contracts": "4.2.0"

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/package.json#L31

    "@openzeppelin/contracts-upgradeable": "4.2.0"

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/package.json#L32

<ins>Recommended Mitigation Steps</ins>

Update OpenZeppelin Contracts Usage in package.json

<a href="#Summary">[LOW‑9]</a><a name="LOW&#x2011;9"> The nonReentrant modifier should occur before all other modifiers

Currently the nonReentrant modifier is not the first to occur, it should occur before all other modifiers.

<ins>Proof Of Concept</ins>

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L263

79: function mint(
        address onBehalfOf,
        DataTypes.ERC721SupplyParams[] calldata tokenData
    ) external virtual override onlyPool nonReentrant returns (uint64, uint64) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L79

87: function burn(
        address from,
        address receiverOfUnderlying,
        uint256[] calldata tokenIds
    ) external virtual override onlyPool nonReentrant returns (uint64, uint64) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L87

119: function transferOnLiquidation(
        address from,
        address to,
        uint256 value
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L119

199: function transferUnderlyingTo(address target, uint256 tokenId)
        external
        virtual
        override
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L199

214: function handleRepayment(address user, uint256 amount)
        external
        virtual
        override
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L214

102: function burn(
        address from,
        address receiverOfUnderlying,
        uint256[] calldata tokenIds
    ) external virtual override onlyPool nonReentrant returns (uint64, uint64) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L102

159: function unstakePositionAndRepay(uint256 tokenId, address incentiveReceiver)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L159

26: function depositApeCoin(ApeCoinStaking.SingleNft[] calldata _nfts)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L26

39: function claimApeCoin(uint256[] calldata _nfts, address _recipient)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L39

52: function withdrawApeCoin(
        ApeCoinStaking.SingleNft[] calldata _nfts,
        address _recipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L52

66: function depositBAKC(ApeCoinStaking.PairNftWithAmount[] calldata _nftPairs)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L66

82: function claimBAKC(
        ApeCoinStaking.PairNft[] calldata _nftPairs,
        address _recipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L82

97: function withdrawBAKC(
        ApeCoinStaking.PairNftWithAmount[] memory _nftPairs,
        address _apeRecipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L97

26: function depositApeCoin(ApeCoinStaking.SingleNft[] calldata _nfts)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L26

39: function claimApeCoin(uint256[] calldata _nfts, address _recipient)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L39

52: function withdrawApeCoin(
        ApeCoinStaking.SingleNft[] calldata _nfts,
        address _recipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L52

66: function depositBAKC(ApeCoinStaking.PairNftWithAmount[] calldata _nftPairs)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L66

82: function claimBAKC(
        ApeCoinStaking.PairNft[] calldata _nftPairs,
        address _recipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L82

97: function withdrawBAKC(
        ApeCoinStaking.PairNftWithAmount[] memory _nftPairs,
        address _apeRecipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L97

40: function burn(
        address from,
        address receiverOfUnderlying,
        uint256[] calldata tokenIds
    ) external virtual override onlyPool nonReentrant returns (uint64, uint64) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMoonBirds.sol#L40

123: function decreaseUniswapV3Liquidity(
        address user,
        uint256 tokenId,
        uint128 liquidityDecrease,
        uint256 amount0Min,
        uint256 amount1Min,
        bool receiveEthAsWeth
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L123

458: function setIsUsedAsCollateral(
        uint256 tokenId,
        bool useAsCollateral,
        address sender
    ) external virtual override onlyPool nonReentrant returns (bool) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L458

474: function batchSetIsUsedAsCollateral(
        uint256[] calldata tokenIds,
        bool useAsCollateral,
        address sender
    )
        external
        virtual
        override
        onlyPool
        nonReentrant
        returns (
            uint256 oldCollateralizedBalance,
            uint256 newCollateralizedBalance
        )
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L474

529: function startAuction(uint256 tokenId)
        external
        virtual
        override
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L529

540: function endAuction(uint256 tokenId)
        external
        virtual
        override
        onlyPool
        nonReentrant
    {
<ins>Recommended Mitigation Steps</ins>

Re-sort modifiers so that the nonReentrant modifier occurs first.

<a href="#Summary">[LOW‑10]</a><a name="LOW&#x2011;10"> getPrice and combine will not work if expirationPeriod == 0

The following conditions will fail if expirationPeriod is set to 0. There is currently no limit that it cannot be set to 0.

<ins>Proof Of Concept</ins>
243: require(
244:    (block.number - updatedAt) <= config.expirationPeriod,
245:    "NFTOracle: asset price expired"
246: );

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/NFTFloorOracle.sol#L243-L246

419: if (diffBlock <= config.expirationPeriod) {
420:    validPriceList[validNum] = priceInfo.twap;
421:    validNum++;
422: }

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/NFTFloorOracle.sol#L419-L422

Non Critical Issues

<a href="#Summary">[NC‑1]</a><a name="NC&#x2011;1"> Critical Changes Should Use Two-step Procedure

The critical procedures should be two step process.

See similar findings in previous Code4rena contests for reference: https://code4rena.com/reports/2022-06-illuminate/#2-critical-changes-should-use-two-step-procedure

<ins>Proof Of Concept</ins>
175: function setConfig(uint128 expirationPeriod, uint128 maxPriceDeviation)

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

183: function setPause(address _asset, bool _flag)

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

195: function setPrice(address _asset, uint256 _twap)

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

221: function setMultiplePrices(

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

66: function setAssetSources(

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

74: function setFallbackOracle(address fallbackOracle)

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

56: function setMarketId(string memory newMarketId)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L56

70: function setAddress(bytes32 id, address newAddress)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L70

81: function setAddressAsProxy(bytes32 id, address newImplementationAddress)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L81

121: function setPoolConfiguratorImpl(address newPoolConfiguratorImpl)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L121

142: function setPriceOracle(address newPriceOracle)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L142

158: function setACLManager(address newAclManager) external override onlyOwner {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L158

170: function setACLAdmin(address newAclAdmin) external override onlyOwner {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L170

182: function setPriceOracleSentinel(address newPriceOracleSentinel)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L182

224: function setProtocolDataProvider(address newDataProvider)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L224

235: function setWETH(address newWETH) external override onlyOwner {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L235

242: function setMarketplace(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L242

413: function setSApeUseAsCollateral(address user) internal {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L413

378: function setUserUseERC20AsCollateral(address asset, bool useAsCollateral)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L378

397: function setUserUseERC721AsCollateral(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L397

151: function setReserveInterestRateStrategyAddress(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L151

166: function setReserveAuctionStrategyAddress(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L166

181: function setConfiguration(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L181

206: function setAuctionRecoveryHealthFactor(uint64 value)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L206

263: function setAuctionValidityTime(address user)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L263

136: function setUnstakeApeIncentive(uint256 incentive) external onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L136

131: function setIncentivesController(IRewardController controller)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L131

142: function setBalanceLimit(uint64 limit) external onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L142

224: function setApprovalForAll(address operator, bool approved)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L224

458: function setIsUsedAsCollateral(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L458

<ins>Recommended Mitigation Steps</ins>

Lack of two-step procedure for critical operations leaves them error-prone. Consider adding two step procedure on the critical functions.

<a href="#Summary">[NC‑2]</a><a name="NC&#x2011;2"> Use a more recent version of Solidity

<a href="https://blog.soliditylang.org/2022/02/16/solidity-0.8.12-release-announcement/">0.8.12</a>: string.concat() instead of abi.encodePacked(<str>,<str>)

<a href="https://blog.soliditylang.org/2022/03/16/solidity-0.8.13-release-announcement/">0.8.13</a>: Ability to use using for with a list of free functions

<a href="https://blog.soliditylang.org/2022/05/18/solidity-0.8.14-release-announcement/">0.8.14</a>:

ABI Encoder: When ABI-encoding values from calldata that contain nested arrays, correctly validate the nested array length against calldatasize() in all cases. Override Checker: Allow changing data location for parameters only when overriding external functions.

<a href="https://blog.soliditylang.org/2022/06/15/solidity-0.8.15-release-announcement/">0.8.15</a>:

Code Generation: Avoid writing dirty bytes to storage when copying bytes arrays. Yul Optimizer: Keep all memory side-effects of inline assembly blocks.

<a href="https://blog.soliditylang.org/2022/08/08/solidity-0.8.16-release-announcement/">0.8.16</a>:

Code Generation: Fix data corruption that affected ABI-encoding of calldata values represented by tuples: structs at any nesting level; argument lists of external functions, events and errors; return value lists of external functions. The 32 leading bytes of the first dynamically-encoded value in the tuple would get zeroed when the last component contained a statically-encoded array.

<a href="https://blog.soliditylang.org/2022/09/08/solidity-0.8.17-release-announcement/">0.8.17</a>:

Yul Optimizer: Prevent the incorrect removal of storage writes before calls to Yul functions that conditionally terminate the external EVM call.

<ins>Proof Of Concept</ins>
pragma solidity 0.8.10;

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

pragma solidity 0.8.10;

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

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/LooksRareAdapter.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/X2Y2Adapter.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/AuctionLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/BorrowLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/FlashClaimLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/PoolLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/SupplyLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/DefaultReserveAuctionStrategy.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolMarketplace.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolStorage.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMoonBirds.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/ApeStakingLogic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L2

pragma solidity 0.8.10;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L2

<ins>Recommended Mitigation Steps</ins>

Consider updating to a more recent solidity version.

<a href="#Summary">[NC‑3]</a><a name="NC&#x2011;3"> Event Is Missing Indexed Fields

Index event fields make the field more quickly accessible to off-chain tools that parse events. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields).

Each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three fields, all of the fields should be indexed.

<ins>Proof Of Concept</ins>
event OracleConfigSet(uint128 expirationPeriod, uint128 maxPriceDeviation);

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

event UnstakeApeIncentiveUpdated(uint256 oldValue, uint256 newValue);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/ApeStakingLogic.sol#L29

<a href="#Summary">[NC‑4]</a><a name="NC&#x2011;4"> Constants Should Be Defined Rather Than Using Magic Numbers

It is not clear what the value 30 stands for and what's the rational behind its value.

<ins>Proof Of Concept</ins>
133: ApeStakingLogic.executeSetUnstakeApeIncentive(dataStorage, 30);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L133

<a href="#Summary">[NC‑5]</a><a name="NC&#x2011;5"> Missing event for critical parameter change

When changing state variables events are not emitted. Emitting events allows monitoring activities with off-chain monitoring tools.

<ins>Proof Of Concept</ins>
151: function setReserveInterestRateStrategyAddress(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L151

166: function setReserveAuctionStrategyAddress(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L166

181: function setConfiguration(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L181

206: function setAuctionRecoveryHealthFactor(uint64 value)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L206

263: function setAuctionValidityTime(address user)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L263

131: function setIncentivesController(IRewardController controller)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L131

142: function setBalanceLimit(uint64 limit) external onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L142

458: function setIsUsedAsCollateral(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L458

<a href="#Summary">[NC‑6]</a><a name="NC&#x2011;6"> Implementation contract may not be initialized

OpenZeppelin recommends that the initializer modifier be applied to constructors. Per OZs Post implementation contract should be initialized to avoid potential griefs or exploits. https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680/5

<ins>Proof Of Concept</ins>
49: constructor(
        IPoolAddressesProvider provider,
        address[] memory assets,
        address[] memory sources,
        address fallbackOracle,
        address baseCurrency,
        uint256 baseCurrencyUnit
    )

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

23: constructor(
        address _factory,
        address _manager,
        address _addressProvider
    )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L23

45: constructor(string memory marketId, address owner)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L45

50: constructor(
        uint256 maxPriceMultiplier,
        uint256 minExpPriceMultiplier,
        uint256 minPriceMultiplier,
        uint256 stepLinear,
        uint256 stepExp,
        uint256 tickLength
    )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/DefaultReserveAuctionStrategy.sol#L50

51: constructor(IPoolAddressesProvider provider)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L51

64: constructor(IPoolAddressesProvider provider)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L64

62: constructor(IPoolAddressesProvider provider)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolMarketplace.sol#L62

89: constructor(IPoolAddressesProvider provider)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L89

43: constructor(IPool pool, bool atomic_pricing)
        MintableIncentivizedERC721(
            pool,
            "NTOKEN_IMPL",
            "NTOKEN_IMPL",
            atomic_pricing
        )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L43

32: constructor(IPool pool, address apeCoinStaking) NToken(pool, false)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L32

16: constructor(IPool pool, address apeCoinStaking)
        NTokenApeStaking(pool, apeCoinStaking)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L16

16: constructor(IPool pool, address apeCoinStaking)
        NTokenApeStaking(pool, apeCoinStaking)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L16

32: constructor(IPool pool) NToken(pool, false)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMoonBirds.sol#L32

33: constructor(IPool pool) NToken(pool, true)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L33

83: constructor(
        IPool pool,
        string memory name_,
        string memory symbol_,
        bool atomic_pricing
    )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L83

43: constructor(
        address _punk,
        address _wpunk,
        address _pool
    )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L43

<a href="#Summary">[NC‑7]</a><a name="NC&#x2011;7"> Use of Block.Timestamp

Block timestamps have historically been used for a variety of applications, such as entropy for random numbers (see the Entropy Illusion for further details), locking funds for periods of time, and various state-changing conditional statements that are time-dependent. Miners have the ability to adjust timestamps slightly, which can prove to be dangerous if block timestamps are used incorrectly in smart contracts. References: SWC ID: 116

<ins>Proof Of Concept</ins>
778: .calculateAuctionPriceMultiplier(startTime, block.timestamp);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L778

285: userConfig.auctionValidityTime = block.timestamp;
<ins>Recommended Mitigation Steps</ins>

Block timestamps should not be used for entropy or generating random numbers—i.e., they should not be the deciding factor (either directly or through some derivation) for winning a game or changing an important state.

Time-sensitive logic is sometimes required; e.g., for unlocking contracts (time-locking), completing an ICO after a few weeks, or enforcing expiry dates. It is sometimes recommended to use block.number and an average block time to estimate times; with a 10 second block time, 1 week equates to approximately, 60480 blocks. Thus, specifying a block number at which to change a contract state can be more secure, as miners are unable to easily manipulate the block number.

<a href="#Summary">[NC‑8]</a><a name="NC&#x2011;8"> Non-usage of specific imports

The current form of relative path import is not recommended for use because it can unpredictably pollute the namespace. Instead, the Solidity docs recommend specifying imported symbols explicitly. https://docs.soliditylang.org/en/v0.8.15/layout-of-source-files.html#importing-other-source-files

A good example:

import {OwnableUpgradeable} from "openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol";
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";
import {SafeCastLib} from "solmate/utils/SafeCastLib.sol";
import {ERC20} from "solmate/tokens/ERC20.sol";
import {IProducer} from "src/interfaces/IProducer.sol";
import {GlobalState, UserState} from "src/Common.sol";
<ins>Proof Of Concept</ins>
4: import "../dependencies/openzeppelin/contracts/AccessControl.sol";
5: import "../dependencies/openzeppelin/upgradeability/Initializable.sol";
6: import "./interfaces/INFTFloorOracle.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/NFTFloorOracle.sol#L4-L6

10: import "../../../interfaces/INTokenApeStaking.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/FlashClaimLogic.sol#L10

30: import "../../../interfaces/INTokenApeStaking.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L30

4: import "../libraries/paraspace-upgradeability/ParaReentrancyGuard.sol";
5: import "../libraries/paraspace-upgradeability/ParaVersionedInitializable.sol";
7: import "../../interfaces/IPoolApeStaking.sol";
8: import "../../interfaces/IPToken.sol";
9: import "../../dependencies/yoga-labs/ApeCoinStaking.sol";
10: import "../../interfaces/IXTokenType.sol";
11: import "../../interfaces/INTokenApeStaking.sol";
20: import "../libraries/logic/BorrowLogic.sol";
21: import "../libraries/logic/SupplyLogic.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L4-L21

12: import "../../interfaces/INTokenApeStaking.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L12

7: import "../../../interfaces/IPool.sol";
11: import "./MintableERC721Logic.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/ApeStakingLogic.sol#L7

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/ApeStakingLogic.sol#L11

7: import "../../../interfaces/IRewardController.sol";
8: import "../../libraries/types/DataTypes.sol";
9: import "../../../interfaces/IPool.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L7-L9

<ins>Recommended Mitigation Steps</ins>

Use specific imports syntax per solidity docs recommendation.

<a href="#Summary">[NC‑9]</a><a name="NC&#x2011;9"> Expressions for constant values such as a call to keccak256(), should use immutable rather than constant

While it doesn't save any gas because the compiler knows that developers often make this mistake, it's still best to use the right tool for the task at hand. There is a difference between constant variables and immutable variables, and they should each be used in their appropriate contexts. constants should be used for literal values written into the code, and immutable variables should be used for expressions, or values calculated in, or passed into the constructor.

<ins>Proof Of Concept</ins>
70: bytes32 public constant UPDATER_ROLE = keccak256("UPDATER_ROLE");

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

16: bytes32 constant POOL_STORAGE_POSITION =
        bytes32(uint256(keccak256("paraspace.proxy.pool.storage")) - 1);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolStorage.sol#L16

23: bytes32 constant APE_STAKING_DATA_STORAGE_POSITION =
        bytes32(
            uint256(keccak256("paraspace.proxy.ntoken.apestaking.storage")) - 1

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L23

<a href="#Summary">[NC‑10]</a><a name="NC&#x2011;10"> Use bytes.concat()

Solidity version 0.8.4 introduces bytes.concat() (vs abi.encodePacked(<bytes>,<bytes>))

<ins>Proof Of Concept</ins>
63: orderInfo.id = abi.encodePacked(makerAsk.r, makerAsk.s, makerAsk.v)
86: bytes memory data = abi.encodePacked(selector, params)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/LooksRareAdapter.sol#L63

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/LooksRareAdapter.sol#L86

99: bytes memory data = abi.encodePacked(selector, params)
115: bytes memory data = abi.encodePacked(selector, params)
99: bytes memory data = abi.encodePacked(selector, params)
115: bytes memory data = abi.encodePacked(selector, params)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L99

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L115

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L99

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L115

75: orderInfo.id = abi.encodePacked(order.r, order.s, order.v)
94: bytes memory data = abi.encodePacked(selector, params)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/X2Y2Adapter.sol#L75

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/X2Y2Adapter.sol#L94

1076: keccak256(abi.encodePacked(params.orderInfo.id)
1077: keccak256(abi.encodePacked(params.credit.orderId)
1116: abi.encodePacked(
                "Credit(address token,uint256 amount,bytes orderId)
1128: keccak256(abi.encodePacked(credit.orderId)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1076

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1077

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1116

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1128

<ins>Recommended Mitigation Steps</ins>

Use bytes.concat() and upgrade to at least Solidity version 0.8.4 if required.

<a href="#Summary">[NC‑11]</a><a name="NC&#x2011;1"> Open TODOs

An open TODO is present. It is recommended to avoid open TODOs as they may indicate programming errors that still need to be fixed.

<ins>Proof Of Concept</ins>
238: // TODO using bit shifting for the 2^96

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L238

59: makerAsk.price, // TODO: take minPercentageToAsk into account

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/LooksRareAdapter.sol#L59

442: // TODO: support PToken

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L442

<a href="#Summary">[NC‑12]</a><a name="NC&#x2011;12"> No need to initialize uints to zero

There is no need to initialize uint variables to zero as their default value is 0

<ins>Proof Of Concept</ins>
411: uint256 validNum = 0;

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

125: uint256 price = 0;

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

208: uint256 sum = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L208

380: uint256 price = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L380

71: uint256 amountToWithdraw = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L71

135: uint256 amountToWithdraw = 0;
137: uint256 actualTransferAmount = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L135

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L137

631: uint256 droppedReservesCount = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L631

205: uint64 collateralizedTokens = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L205

272: uint64 burntCollateralizedTokens = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L272

<a href="#Summary">[NC‑13]</a><a name="NC&#x2011;13"> Use delete to Clear Variables

delete a assigns the initial value for the type to a. i.e. for integers it is equivalent to a = 0, but it can also be used on arrays, where it assigns a dynamic array of length zero or a static array of the same length with all elements reset. For structs, it assigns a struct with all members reset. Similarly, it can also be used to set an address to zero address. It has no effect on whole mappings though (as the keys of mappings may be arbitrary and are generally unknown). However, individual keys and what they map to can be deleted: If a is a mapping, then delete a[x] will delete the value stored at x.

The delete key better conveys the intention and is also more idiomatic. Consider replacing assignments of zero with delete statements.

<ins>Proof Of Concept</ins>
380: price = 0;
410: downpayment = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L380

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L410

589: vars.ethLeft = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L589

123: reserve.accruedToTreasury = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/PoolLogic.sol#L123

<a href="#Summary">[NC‑14]</a><a name="NC&#x2011;14"> Duplicate imports

There are several occasions where there several imports of the same file

<ins>Proof Of Concept</ins>
4: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";
18: import {IERC721} from "../../../dependencies/openzeppelin/contracts/IERC721.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L4

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L18

5: import {Errors} from "../libraries/helpers/Errors.sol";
25: import {Errors} from "../libraries/helpers/Errors.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L5

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L25

5: import {Errors} from "../libraries/helpers/Errors.sol";
28: import {Errors} from "../libraries/helpers/Errors.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolMarketplace.sol#L5

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolMarketplace.sol#L28

5: import {Errors} from "../libraries/helpers/Errors.sol";
24: import {Errors} from "../libraries/helpers/Errors.sol";

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L5

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L24

<a href="#Summary">[NC‑15]</a><a name="NC&#x2011;15"> Missing NATSPEC documentation

<ins>Proof Of Concept</ins>
25: function getAskOrderInfo(bytes memory params, address weth)
67: function getBidOrderInfo(
73: function matchAskWithTakerBid(
96: function matchBidWithTakerAsk(address, bytes calldata)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/LooksRareAdapter.sol

25: function getAskOrderInfo(bytes memory params, address weth)
60: function getBidOrderInfo(
93: function matchAskWithTakerBid(
109: function matchBidWithTakerAsk(address, bytes calldata)
124: function isBasicOrder(AdvancedOrder memory advancedOrder)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol

31: function getAskOrderInfo(bytes memory params, address weth)
79: function getBidOrderInfo(
88: function matchAskWithTakerBid(
104: function matchBidWithTakerAsk(address, bytes calldata)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/X2Y2Adapter.sol

261: function getFeederSize() public view returns (uint256) {
265: function _whenNotPaused(address _asset) internal view {
270: function _isAssetExisted(address _asset) internal view returns (bool) {
274: function _isFeederExisted(address _feeder) internal view returns (bool) {
278: function _addAsset(address _asset)
296: function _removeAsset(address _asset)
307: function _addFeeder(address _feeder)
326: function _removeFeeder(address _feeder)
351: function _checkValidity(address _asset, uint256 _twap)
376: function _finalizePrice(address _asset, uint256 _twap) internal {
388: function _addRawValue(address _asset, uint256 _twap) internal {
397: function _combine(address _asset, uint256 _twap)
432: function _quickSort(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/NFTFloorOracle.sol

138: function getTokenPrice(address asset, uint256 tokenId)
155: function getTokensPrices(address asset, uint256[] calldata tokenIds)
172: function getTokensPricesSum(address asset, uint256[] calldata tokenIds)
218: function _onlyAssetListingOrPoolAdmins() internal view {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/ParaSpaceOracle.sol

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol

399: function getLtvAndLTForUniswapV3(
450: function _getUserBalanceForUniswapV3(
535: function _getAssetPrice(address oracle, address currentReserveAddress)
543: function _getTokenPrice(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol

63: function executeBuyWithCredit(
160: function executeBatchBuyWithCredit(
229: function executeAcceptBidWithCre
267: function executeBatchAcceptBidWithCredit(
552: function _checkAllowance(address token, address operator) internal {
559: function _cache(DataTypes.ExecuteMarketplaceParams memory params)
569: function _refundETH(uint256 ethLeft) internal {
575: function _depositETH(
593: function _transferAndCollateralize(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol

214: function executeGetAssetLtvAndLT(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/PoolLogic.sol

134: function executeSupplyERC721Base(
335: function executeWithdrawERC721(
396: function executeDecreaseUniswapV3Liquidity(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/SupplyLogic.sol

189: function validateWithdrawERC721(
442: function validateSetUseERC721AsCollateral(
801: function validateEndAuction(
1065: function validateBuyWithCredit(
1071: function validateAcceptBidWithCredit(
1092: function verifyCreditSignature(
1110: function hashCredit(DataTypes.Credit memory credit)
1133: function getDomainSeparator() internal view returns (bytes32) {
1155: function validateForUniswapV3(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol

90: function calculateAuctionPriceMultiplier(
101: function _calculateAuctionPriceMultiplierByTicks(uint256 ticks)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/DefaultReserveAuctionStrategy.sol

413: function setSApeUseAsCollateral(address user) internal {
428: function getUserHf(address user) internal view returns (uint256) {
443: function checkSApeIsNotPaused(DataTypes.PoolStorage storage ps)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol

237: function decreaseUniswapV3Liquidity(
397: function setUserUseERC721AsCollateral(
793: function onERC721Received(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol

251: function getAssetLtvAndLT(address asset, uint256 tokenId)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol

290: function _safeTransferFrom(
364: function _mintMultiple(
384: function _burnMultiple(address user, uint256[] calldata tokenIds)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol

95: function _burn(
127: function rescueERC20(
136: function rescueERC721(
151: function rescueERC1155(
168: function executeAirdrop(
271: function onERC721Received(
280: function onERC1155Received(
295: function onERC1155BatchReceived(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol

130: function initializeStakingData() internal {
136: function setUnstakeApeIncentive(uint256 incentive) external onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol

144: function _safeTransferETH(address to, uint256 value) internal {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol

80: function executeTransfer(
135: function executeTransferCollateralizable(
153: function executeSetIsUsedAsCollateral(
187: function executeMintMultiple(
260: function executeBurnMultiple(
340: function executeApprove(
348: function _approve(
357: function executeApprovalForAll(
368: function executeStartAuction(
386: function executeEndAuction(
402: function _checkBalanceLimit(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol

<a href="#Summary">[NC‑15]</a><a name="NC&#x2011;15"> Insufficient NATSPEC documentation

<ins>Proof Of Concept</ins>

Missing @param for expirationPeriod and maxPriceDeviation

175: function setConfig(uint128 expirationPeriod, uint128 maxPriceDeviation)

Missing @param for _asset and _flag

183: setPause(address _asset, bool _flag)

Missing @param for _twaps

183: function setMultiplePrices(

Missing @notice

236: getPrice(address _asset)
252: getLastUpdateTime(address _asset)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/NFTFloorOracle.sol

Missing @param for params and vars

362: function _getUserBalanceForERC721(

Missing @param for reserve, xTokenAddress and assetPrice

362: function _getUserBalanceForERC721(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol

Missing @param for reservesData

564: function _supplyNewCollateral(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol

Missing @return for uint256

114: function _buyWithCredit(

Missing @return for uint256 and uin256

376: function _delegateToPool(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol

Missing @param for user, ps and oracle

166: function executeGetUserAccountData(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/PoolLogic.sol

Missing @param for assetType

63: function validateSupply(

Missing @param for reservesData

590: function validateLiquidateERC721(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol

Missing @return for uint256

182: function getUserApeStakingAmount(address user)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol

#0 - c4-judge

2023-01-25T11:04:40Z

dmvt marked the issue as grade-a

Findings Information

🌟 Selected for report: IllIllI

Also found by: B2, Deivitto, Dravee, PaludoX0, RaymondFam, Rolezn, Sathish9098, _Adam, ahmedov, c3phas, chrisdior4, cyberinn, rjs, saneryee

Labels

bug
G (Gas Optimization)
grade-b
G-05

Awards

145.9382 USDC - $145.94

External Links

Summary<a name="Summary">

Gas Optimizations

IssueContextsEstimated Gas Saved
GAS‑1Multiple Address Mappings Can Be Combined Into A Single Mapping Of An Address To A Struct, Where Appropriate1-
GAS‑2Duplicated require()/revert() Checks Should Be Refactored To A Modifier Or Function401120
GAS‑3Empty Blocks Should Be Removed Or Emit Something2-
GAS‑4<x> += <y> Costs More Gas Than <x> = <x> + <y> For State Variables26-
GAS‑5++i/i++ Should Be unchecked{++i}/unchecked{i++} When It Is Not Possible For Them To Overflow, As Is The Case When Used In For- And While-loops491715
GAS‑6require()/revert() Strings Longer Than 32 Bytes Cost Extra Gas18-
GAS‑7abi.encode() is less efficient than abi.encodepacked()2200
GAS‑8Using 10**X for constants isn't gas efficient1-
GAS‑9Public Functions To External16-
GAS‑10Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead26-
GAS‑11Optimize names to save gas15330
GAS‑12Use immutable weth variable value1-
GAS‑13State variables only set in the constructor should be declared immutable1-
GAS‑14internal functions only called once can be inlined to save gas23-
GAS‑15Setting the constructor to payable19247
GAS‑16Functions guaranteed to revert when called by normal users can be marked payable651365
GAS‑17Using unchecked blocks to save gas2272
GAS‑18Structs can be packed into fewer storage slots1-

Total: 307 contexts over 17 issues

Gas Optimizations

<a href="#Summary">[GAS‑1]</a><a name="GAS&#x2011;1"> Multiple Address Mappings Can Be Combined Into A Single Mapping Of An Address To A Struct, Where Appropriate

Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot.

<ins>Proof Of Concept</ins>
74: mapping(address => PriceInformation) public assetPriceMap;
81: mapping(address => FeederPosition) private feederPositionMap;
88: mapping(address => FeederRegistrar) public assetFeederMap;

Can be changed to:

    struct priceFeederStruct {
        PriceInformation assetPriceMap;
        FeederPosition feederPositionMap;
        FeederRegistrar assetFeederMap;
    }
    
    mapping(address => priceFeederStruct) public priceFeederInfo;

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

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

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

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

<a href="#Summary">[GAS‑2]</a><a name="GAS&#x2011;2"> Duplicated require()/revert() Checks Should Be Refactored To A Modifier Or Function

Saves deployment costs

<ins>Proof Of Concept</ins>
51: (orderInfo.offer.length > 0, Errors.INVALID_MARKETPLACE_ORDER);
84: (orderInfo.offer.length > 0, Errors.INVALID_MARKETPLACE_ORDER);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L51

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L84

68: (amount != 0, Errors.INVALID_AMOUNT);
160: (amount != 0, Errors.INVALID_AMOUNT);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L68

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L160

85: (isActive, Errors.RESERVE_INACTIVE);
185: (isActive, Errors.RESERVE_INACTIVE);
207: (isActive, Errors.RESERVE_INACTIVE);
390: (isActive, Errors.RESERVE_INACTIVE);
438: (isActive, Errors.RESERVE_INACTIVE);
460: (isActive, Errors.RESERVE_INACTIVE);
1029: (isActive, Errors.RESERVE_INACTIVE);
1057: (isActive, Errors.RESERVE_INACTIVE);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L85

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L185

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L207

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L390

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L438

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L460

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1029

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1057

86: (!isPaused, Errors.RESERVE_PAUSED);
186: (!isPaused, Errors.RESERVE_PAUSED);
208: (!isPaused, Errors.RESERVE_PAUSED);
391: (!isPaused, Errors.RESERVE_PAUSED);
439: (!isPaused, Errors.RESERVE_PAUSED);
461: (!isPaused, Errors.RESERVE_PAUSED);
1030: (!isPaused, Errors.RESERVE_PAUSED);
1058: (!isPaused, Errors.RESERVE_PAUSED);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L86

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L186

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L208

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L391

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L439

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L461

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1030

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1058

768: (vars.collateralReserveActive, Errors.RESERVE_INACTIVE);
824: (vars.collateralReserveActive, Errors.RESERVE_INACTIVE);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L768

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L824

769: (!vars.collateralReservePaused, Errors.RESERVE_PAUSED);
825: (!vars.collateralReservePaused, Errors.RESERVE_PAUSED);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L769

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L825

937: (!reserve.configuration.getPaused(), Errors.RESERVE_PAUSED);
950: (!reserve.configuration.getPaused(), Errors.RESERVE_PAUSED);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L937

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L950

1068: (!params.marketplace.paused, Errors.MARKETPLACE_PAUSED);
1074: (!params.marketplace.paused, Errors.MARKETPLACE_PAUSED);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1068

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1074

157: (asset != address(0), Errors.ZERO_ADDRESS_NOT_VALID);
172: (asset != address(0), Errors.ZERO_ADDRESS_NOT_VALID);
187: (asset != address(0), Errors.ZERO_ADDRESS_NOT_VALID);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L157

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L172

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L187

<a href="#Summary">[GAS‑3]</a><a name="GAS&#x2011;3"> Empty Blocks Should Be Removed Or Emit Something

The code should be refactored such that they no longer exist, or the block should do something useful, such as emitting an event or reverting. If the contract is meant to be extended, the contract should be abstract and the function signatures be added without any default implementation. If the block is an empty if-statement block to avoid doing subsequent checks in the else-if/else conditions, the else-if/else conditions should be nested under the negation of the if-statement, because they involve different classes of checks, which may lead to the introduction of errors when the code is later modified (if(x){}else if(y){...}else{...} => if(!x){if(y){...}else{...}})

<ins>Proof Of Concept</ins>
50: {}

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L50

149: receive() external payable {}

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L149

<a href="#Summary">[GAS‑4]</a><a name="GAS&#x2011;4"> <x> += <y> Costs More Gas Than <x> = <x> + <y> For State Variables

<ins>Proof Of Concept</ins>
149: token0Amount += positionData.tokensOwed0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L149

150: token1Amount += positionData.tokensOwed1;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L150

211: sum += getTokenPrice(tokenIds[index]);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L211

169: vars.payableDebtByERC20Assets += vars

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L169

176: vars.avgLtv += vars.userBalanceInBaseCurrency * vars.ltv;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L176

178: vars.totalCollateralInBaseCurrency += vars

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L178

185: vars.avgLiquidationThreshold += vars.liquidationThreshold;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L185

189: vars.totalDebtInBaseCurrency += _getUserDebtInBaseCurrency(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L189

231: vars.avgERC721LiquidationThreshold += vars

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L231

233: vars.totalERC721CollateralInBaseCurrency += vars

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L233

237: vars.avgLtv += vars.ltv;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L237

380: totalValue += _getTokenPrice(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L380

479: totalValue += tokenPrice;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L479

496: totalLTV += tmpLTV * tokenPrice;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L496

497: totalLiquidationThreshold +=

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L497

83: vars.ethLeft -= _buyWithCredit(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L83

205: vars.ethLeft -= _buyWithCredit(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L205

397: price += item.startAmount;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L397

77: amountToWithdraw += _nfts[index].amount;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L77

166: amountToWithdraw += _nftPairs[index].amount;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L166

215: totalAmount += getTokenIdStakingAmount(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/ApeStakingLogic.sol#L215

257: apeStakedAmount += bakcStakedAmount;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/ApeStakingLogic.sol#L257

146: erc721Data.userState[from].collateralizedBalance -= 1;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L146

318: erc721Data.userState[user].balance -= balanceToBurn;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L318

<a href="#Summary">[GAS‑5]</a><a name="GAS&#x2011;5"> ++i/i++ Should Be unchecked{++i}/unchecked{i++} When It Is Not Possible For Them To Overflow, As Is The Case When Used In For- And While-loops

The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas PER LOOP

<ins>Proof Of Concept</ins>
229: for (uint256 i = 0; i < _assets.length; i++) {

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

291: for (uint256 i = 0; i < _assets.length; i++) {

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

321: for (uint256 i = 0; i < _feeders.length; i++) {

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

413: for (uint256 i = 0; i < feederSize; i++) {

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

95: for (uint256 i = 0; i < assets.length; i++) {

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

197: for (uint256 i = 0; i < assets.length; i++) {

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

193: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L193

210: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L210

38: for (i = 0; i < params.nftTokenIds.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/FlashClaimLogic.sol#L38

371: for (uint256 index = 0; index < totalBalance; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L371

466: for (uint256 index = 0; index < totalBalance; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/GenericLogic.sol#L466

177: for (uint256 i = 0; i < marketplaceIds.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L177

284: for (uint256 i = 0; i < marketplaceIds.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L284

382: for (uint256 i = 0; i < params.orderInfo.consideration.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L382

470: for (uint256 i = 0; i < params.orderInfo.offer.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L470

58: for (uint16 i = 0; i < params.reservesCount; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/PoolLogic.sol#L58

104: for (uint256 i = 0; i < assets.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/PoolLogic.sol#L104

184: for (uint256 index = 0; index < params.tokenData.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/SupplyLogic.sol#L184

131: for (uint256 index = 0; index < amount; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L131

212: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L212

465: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L465

910: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L910

1034: for (uint256 i = 0; i < params.nftTokenIds.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1034

72: for (uint256 index = 0; index < _nfts.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L72

103: for (uint256 index = 0; index < _nfts.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L103

138: for (uint256 index = 0; index < _nftPairs.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L138

172: for (uint256 index = 0; index < actualTransferAmount; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L172

199: for (uint256 index = 0; index < _nftPairs.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L199

279: for (uint256 index = 0; index < _nfts.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L279

289: for (uint256 index = 0; index < _nftPairs.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L289

634: for (uint256 i = 0; i < reservesListCount; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L634

106: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L106

145: for (uint256 i = 0; i < ids.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L145

107: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L107

51: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMoonBirds.sol#L51

97: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMoonBirds.sol#L97

493: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L493

213: for (uint256 index = 0; index < totalBalance; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/ApeStakingLogic.sol#L213

207: for (uint256 index = 0; index < tokenData.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L207

280: for (uint256 index = 0; index < tokenIds.length; index++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L280

82: for (uint256 i = 0; i < punkIndexes.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L82

109: for (uint256 i = 0; i < punkIndexes.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L109

136: for (uint256 i = 0; i < punkIndexes.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L136

174: for (uint256 i = 0; i < punkIndexes.length; i++) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L174

<a href="#Summary">[GAS‑6]</a><a name="GAS&#x2011;6"> require()/revert() Strings Longer Than 32 Bytes Cost Extra Gas

<ins>Proof Of Concept</ins>
118: require(_isAssetExisted(_asset), "NFTOracle: asset not existed");

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

128: require(_isFeederExisted(_feeder), "NFTOracle: feeder not existed");

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

207: require(dataValidity, "NFTOracle: invalid price data");

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

267: require(!_paused, "NFTOracle: nft price feed paused");

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

356: require(_twap > 0, "NFTOracle: price should be more than 0");

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

51: require(orderInfo.offer.length > 0, Errors.INVALID_MARKETPLACE_ORDER);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L51

84: require(orderInfo.offer.length > 0, Errors.INVALID_MARKETPLACE_ORDER);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/SeaportAdapter.sol#L84

38: require(runInput.details.length == 1, Errors.INVALID_MARKETPLACE_ORDER);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/X2Y2Adapter.sol#L38

51: require(nfts.length == 1, Errors.INVALID_MARKETPLACE_ORDER);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/marketplaces/X2Y2Adapter.sol#L51

86: require(id != POOL, Errors.INVALID_ADDRESSES_PROVIDER_ID);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L86

406: require((variableDebt != 0), Errors.NO_DEBT_OF_SELECTED_TYPE);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L406

418: require(userBalance != 0, Errors.UNDERLYING_BALANCE_ZERO);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L418

60: require(initializingPool == POOL, Errors.POOL_ADDRESSES_DO_NOT_MATCH);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L60

176: require(airdropParams.length >= 4, Errors.INVALID_AIRDROP_PARAMETERS);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L176

70: require(msg.sender == _underlyingAsset, Errors.OPERATION_NOT_SUPPORTED);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMoonBirds.sol#L70

193: require(to != owner, "ERC721: approval to old owner");

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L193

92: require(to != address(0), "ERC721: transfer to the zero address");

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L92

199: require(to != address(0), "ERC721: mint to the zero address");

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L199

<a href="#Summary">[GAS‑7]</a><a name="GAS&#x2011;7"> abi.encode() is less efficient than abi.encodepacked()

See for more information: https://github.com/ConnorBlockchain/Solidity-Encode-Gas-Comparison

<ins>Proof Of Concept</ins>
1124: abi.encode(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1124

1136: abi.encode(

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1136

<a href="#Summary">[GAS‑8]</a><a name="GAS&#x2011;8"> Using 10**X for constants isn't gas efficient

In Solidity, a constant expression in a variable will compute the expression everytime the variable is called. It's not the result of the expression that is stored, but the expression itself.

As Solidity supports the scientific notation, constants of form 10**X can be rewritten as 1eX to save the gas cost from the calculation with the exponentiation operator **.

<ins>Proof Of Concept</ins>
245: ((oracleData.token0Price * (10**18)) /

Should be change to:

245: ((oracleData.token0Price * (1e18)) /

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L245

<ins>Recommended Mitigation Steps</ins>

Replace 10**X with 1eX

<a href="#Summary">[GAS‑9]</a><a name="GAS&#x2011;9"> Public Functions To External

The following functions could be set external to save gas and improve code quality. External call cost is less expensive than of public functions.

<ins>Proof Of Concept</ins>
function initialize(
        address _admin,
        address[] memory _feeders,
        address[] memory _assets
    ) public initializer {

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

function getFeederSize() public view returns (uint256) {

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

function getLiquidityAmountFromPositionData(
        UinswapV3PositionData memory positionData
    ) public pure returns (uint256 token0Amount, uint256 token1Amount) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L113

function getLpFeeAmountFromPositionData(
        UinswapV3PositionData memory positionData
    ) public view returns (uint256 token0Amount, uint256 token1Amount) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L144

function getTokenPrice(uint256 tokenId) public view returns (uint256) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L156

function getAddress(bytes32 id) public view override returns (address) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L65

function executeBorrow(
        mapping(address => DataTypes.ReserveData) storage reservesData,
        mapping(uint256 => address) storage reservesList,
        DataTypes.UserConfigurationMap storage userConfig,
        DataTypes.ExecuteBorrowParams memory params
    ) public {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/BorrowLogic.sol#L52

function initialize(
        IPool initializingPool,
        address underlyingAsset,
        IRewardController incentivesController,
        string calldata nTokenName,
        string calldata nTokenSymbol,
        bytes calldata params
    ) public virtual override initializer {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L52

function initialize(
        IPool initializingPool,
        address underlyingAsset,
        IRewardController incentivesController,
        string calldata nTokenName,
        string calldata nTokenSymbol,
        bytes calldata params
    ) public virtual override initializer {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L36

function getBAKC() public view returns (IERC721) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L64

function name() public view override returns (string memory) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L96

function totalSupply() public view virtual override returns (uint256) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L604

function getTokenIdStakingAmount(
        uint256 poolId,
        ApeCoinStaking _apeCoinStaking,
        uint256 tokenId
    ) public view returns (uint256) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/ApeStakingLogic.sol#L231

function executeTransfer(
        MintableERC721Data storage erc721Data,
        IPool POOL,
        bool ATOMIC_PRICING,
        address from,
        address to,
        uint256 tokenId
    ) public {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L80

function isAuctioned(
        MintableERC721Data storage erc721Data,
        IPool POOL,
        uint256 tokenId
    ) public view returns (bool) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L424

function onERC721Received(
        address,
        address,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L232

<a href="#Summary">[GAS‑10]</a><a name="GAS&#x2011;10"> Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead

When using elements that are smaller than 32 bytes, your contract's gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.

https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Each operation involving a uint8 costs an extra 22-28 gas (depending on whether the other operand is also a variable of type uint8) as compared to ones involving uint256, due to the compiler having to clear the higher bits of the memory word before operating on the uint8, as well as the associated stack operations of doing so. Use a larger size then downcast where needed

<ins>Proof Of Concept</ins>
18: uint128 expirationPeriod;

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

20: uint128 maxPriceDeviation;

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

47: uint8 index;

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

300: uint8 assetIndex = assetFeederMap[_asset].index;

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

330: uint8 feederIndex = feederPositionMap[_feeder].index;

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

43: uint8 token0Decimal;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L43

44: uint8 token1Decimal;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L44

45: uint160 sqrtPriceX96;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L45

125: uint16 liquidationAssetReserveId;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol#L125

581: interfaceId == type(IERC721Metadata).interfaceId;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L581

13: uint64 balance;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L13

14: uint64 collateralizedBalance;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L14

15: uint128 additionalData;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L15

42: uint64 balanceLimit;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L42

103: uint64 oldSenderBalance = erc721Data.userState[from].balance;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L103

105: uint64 oldRecipientBalance = erc721Data.userState[to].balance;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L105

106: uint64 newRecipientBalance = oldRecipientBalance + 1;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L106

200: uint64 oldBalance = erc721Data.userState[to].balance;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L200

205: uint64 collateralizedTokens = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L205

247: uint64 newBalance = oldBalance + uint64(tokenData.length);

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L247

272: uint64 burntCollateralizedTokens = 0;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L272

273: uint64 balanceToBurn;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L273

408: uint64 balanceLimit = erc721Data.balanceLimit;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/libraries/MintableERC721Logic.sol#L408

<a href="#Summary">[GAS‑11]</a><a name="GAS&#x2011;11"> Optimize names to save gas

Contracts most called functions could simply save gas by function ordering via Method ID. Calling a function at runtime will be cheaper if the function is positioned earlier in the order (has a relatively lower Method ID) because 22 gas are added to the cost of a function for every position that came before it. The caller can save on gas if you prioritize most called functions.

See more <a href="https://medium.com/joyso/solidity-how-does-function-name-affect-gas-consumption-in-smart-contract-47d270d8ac92">here</a>

<ins>Proof Of Concept</ins>

Relevant to all in-scope contracts, read more about it <a href="https://medium.com/joyso/solidity-how-does-function-name-affect-gas-consumption-in-smart-contract-47d270d8ac92">here</a>

<ins>Recommended Mitigation Steps</ins>

Find a lower method ID name for the most called functions for example Call() vs. Call1() is cheaper by 22 gas For example, the function IDs in the Gauge.sol contract will be the most used; A lower method ID may be given.

<a href="#Summary">[GAS‑12]</a><a name="GAS&#x2011;12"> Use immutable weth variable value

It is cheaper to use weth variable as immutable and store the value of WETH address. It saves one storage read and make the code clearer.

<ins>Proof Of Concept</ins>
92: address weth = _addressesProvider.getWETH();

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L92

<a href="#Summary">[GAS‑13]</a><a name="GAS&#x2011;13"> State variables only set in the constructor should be declared immutable

Avoids a Gsset (20000 gas) in the constructor, and replaces each Gwarmacces (100 gas) with a PUSH32 (3 gas).

<ins>Proof Of Concept</ins>
65: _underlyingAsset = underlyingAsset

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L65

<a href="#Summary">[GAS‑14]</a><a name="GAS&#x2011;14"> internal functions only called once can be inlined to save gas

<ins>Proof Of Concept</ins>
265: function _whenNotPaused

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

388: function _addRawValue

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

218: function _onlyAssetListingOrPoolAdmins

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

302: function _updateParaProxyImpl

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L302

435: function _burnCollateralPTokens

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol#L435

465: function _burnCollateralNTokens

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol#L465

488: function _liquidatePTokens

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol#L488

523: function _burnDebtTokens

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol#L523

564: function _supplyNewCollateral

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol#L564

605: function _calculateDebt

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/LiquidationLogic.sol#L605

376: function _delegateToPool

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L376

552: function _checkAllowance

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L552

593: function _transferAndCollateralize

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L593

118: function validateSupplyFromNToken

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L118

740: function validateStartAuction

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L740

801: function validateEndAuction

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L801

944: function validateTransferERC721

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L944

1133: function getDomainSeparator

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/ValidationLogic.sol#L1133

413: function setSApeUseAsCollateral

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L413

69: function _onlyPoolConfigurator

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L69

76: function _onlyPoolAdmin

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L76

130: function initializeStakingData

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L130

51: function _decreaseLiquidity

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L51

<a href="#Summary">[GAS‑15]</a><a name="GAS&#x2011;15"> Setting the constructor to payable

Saves ~13 gas per instance

<ins>Proof Of Concept</ins>
49: constructor(
        IPoolAddressesProvider provider,
        address[] memory assets,
        address[] memory sources,
        address fallbackOracle,
        address baseCurrency,
        uint256 baseCurrencyUnit
    )

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

23: constructor(
        address _factory,
        address _manager,
        address _addressProvider
    )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/UniswapV3OracleWrapper.sol#L23

45: constructor(string memory marketId, address owner)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L45

50: constructor(
        uint256 maxPriceMultiplier,
        uint256 minExpPriceMultiplier,
        uint256 minPriceMultiplier,
        uint256 stepLinear,
        uint256 stepExp,
        uint256 tickLength
    )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/DefaultReserveAuctionStrategy.sol#L50

51: constructor(IPoolAddressesProvider provider)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolApeStaking.sol#L51

64: constructor(IPoolAddressesProvider provider)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolCore.sol#L64

62: constructor(IPoolAddressesProvider provider)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolMarketplace.sol#L62

89: constructor(IPoolAddressesProvider provider)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L89

43: constructor(IPool pool, bool atomic_pricing)
        MintableIncentivizedERC721(
            pool,
            "NTOKEN_IMPL",
            "NTOKEN_IMPL",
            atomic_pricing
        )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L43

32: constructor(IPool pool, address apeCoinStaking) NToken(pool, false)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L32

16: constructor(IPool pool, address apeCoinStaking)
        NTokenApeStaking(pool, apeCoinStaking)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L16

16: constructor(IPool pool, address apeCoinStaking)
        NTokenApeStaking(pool, apeCoinStaking)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L16

32: constructor(IPool pool) NToken(pool, false)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMoonBirds.sol#L32

33: constructor(IPool pool) NToken(pool, true)

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L33

83: constructor(
        IPool pool,
        string memory name_,
        string memory symbol_,
        bool atomic_pricing
    )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L83

43: constructor(
        address _punk,
        address _wpunk,
        address _pool
    )

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L43

<a href="#Summary">[GAS‑16]</a><a name="GAS&#x2011;16"> Functions guaranteed to revert when called by normal users can be marked payable

If a function modifier or require such as onlyOwner/onlyX is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are CALLVALUE(2), DUP1(3), ISZERO(3), PUSH2(3), JUMPI(10), PUSH1(3), DUP1(3), REVERT(0), JUMPDEST(1), POP(2) which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost.

<ins>Proof Of Concept</ins>
139: function addAssets(address[] calldata _assets)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {

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

148: function removeAsset(address _asset)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
        onlyWhenAssetExisted(_asset)
    {

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

158: function addFeeders(address[] calldata _feeders)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {

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

167: function removeFeeder(address _feeder)
        external
        onlyWhenFeederExisted(_feeder)
    {

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

175: function setConfig(uint128 expirationPeriod, uint128 maxPriceDeviation)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {

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

183: function setPause(address _asset, bool _flag)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {

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

195: function setPrice(address _asset, uint256 _twap)
        public
        onlyRole(UPDATER_ROLE)
        onlyWhenAssetExisted(_asset)
        whenNotPaused(_asset)
    {

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

221: function setMultiplePrices(
        address[] calldata _assets,
        uint256[] calldata _twaps
    ) external onlyRole(UPDATER_ROLE) {

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

66: function setAssetSources(
        address[] calldata assets,
        address[] calldata sources
    ) external override onlyAssetListingOrPoolAdmins {

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

74: function setFallbackOracle(address fallbackOracle)
        external
        override
        onlyAssetListingOrPoolAdmins
    {

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

56: function setMarketId(string memory newMarketId)
        external
        override
        onlyOwner
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L56

70: function setAddress(bytes32 id, address newAddress)
        external
        override
        onlyOwner
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L70

81: function setAddressAsProxy(bytes32 id, address newImplementationAddress)
        external
        override
        onlyOwner
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L81

105: function updatePoolImpl(
        IParaProxy.ProxyImplementation[] calldata implementationParams,
        address _init,
        bytes calldata _calldata
    ) external override onlyOwner {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L105

121: function setPoolConfiguratorImpl(address newPoolConfiguratorImpl)
        external
        override
        onlyOwner
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L121

142: function setPriceOracle(address newPriceOracle)
        external
        override
        onlyOwner
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L142

158: function setACLManager(address newAclManager) external override onlyOwner {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L158

170: function setACLAdmin(address newAclAdmin) external override onlyOwner {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L170

182: function setPriceOracleSentinel(address newPriceOracleSentinel)
        external
        override
        onlyOwner
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L182

224: function setProtocolDataProvider(address newDataProvider)
        external
        override
        onlyOwner
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L224

235: function setWETH(address newWETH) external override onlyOwner {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L235

242: function setMarketplace(
        bytes32 id,
        address marketplace,
        address adapter,
        address operator,
        bool paused
    ) external override onlyOwner {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/configuration/PoolAddressesProvider.sol#L242

110: function initReserve(
        address asset,
        address xTokenAddress,
        address variableDebtAddress,
        address interestRateStrategyAddress,
        address auctionStrategyAddress
    ) external virtual override onlyPoolConfigurator {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L110

139: function dropReserve(address asset)
        external
        virtual
        override
        onlyPoolConfigurator
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L139

151: function setReserveInterestRateStrategyAddress(
        address asset,
        address rateStrategyAddress
    ) external virtual override onlyPoolConfigurator {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L151

166: function setReserveAuctionStrategyAddress(
        address asset,
        address auctionStrategyAddress
    ) external virtual override onlyPoolConfigurator {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L166

181: function setConfiguration(
        address asset,
        DataTypes.ReserveConfigurationMap calldata configuration
    ) external virtual override onlyPoolConfigurator {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L181

196: function rescueTokens(
        DataTypes.AssetType assetType,
        address token,
        address to,
        uint256 amountOrTokenId
    ) external virtual override onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L196

206: function setAuctionRecoveryHealthFactor(uint64 value)
        external
        virtual
        override
        onlyPoolConfigurator
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/pool/PoolParameters.sol#L206

79: function mint(
        address onBehalfOf,
        DataTypes.ERC721SupplyParams[] calldata tokenData
    ) external virtual override onlyPool nonReentrant returns (uint64, uint64) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L79

87: function burn(
        address from,
        address receiverOfUnderlying,
        uint256[] calldata tokenIds
    ) external virtual override onlyPool nonReentrant returns (uint64, uint64) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L87

119: function transferOnLiquidation(
        address from,
        address to,
        uint256 value
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L119

127: function rescueERC20(
        address token,
        address to,
        uint256 amount
    ) external override onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L127

136: function rescueERC721(
        address token,
        address to,
        uint256[] calldata ids
    ) external override onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L136

151: function rescueERC1155(
        address token,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external override onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L151

168: function executeAirdrop(
        address airdropContract,
        bytes calldata airdropParams
    ) external override onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L168

199: function transferUnderlyingTo(address target, uint256 tokenId)
        external
        virtual
        override
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L199

214: function handleRepayment(address user, uint256 amount)
        external
        virtual
        override
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NToken.sol#L214

102: function burn(
        address from,
        address receiverOfUnderlying,
        uint256[] calldata tokenIds
    ) external virtual override onlyPool nonReentrant returns (uint64, uint64) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L102

136: function setUnstakeApeIncentive(uint256 incentive) external onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L136

159: function unstakePositionAndRepay(uint256 tokenId, address incentiveReceiver)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenApeStaking.sol#L159

26: function depositApeCoin(ApeCoinStaking.SingleNft[] calldata _nfts)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L26

39: function claimApeCoin(uint256[] calldata _nfts, address _recipient)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L39

52: function withdrawApeCoin(
        ApeCoinStaking.SingleNft[] calldata _nfts,
        address _recipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L52

66: function depositBAKC(ApeCoinStaking.PairNftWithAmount[] calldata _nftPairs)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L66

82: function claimBAKC(
        ApeCoinStaking.PairNft[] calldata _nftPairs,
        address _recipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L82

97: function withdrawBAKC(
        ApeCoinStaking.PairNftWithAmount[] memory _nftPairs,
        address _apeRecipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenBAYC.sol#L97

26: function depositApeCoin(ApeCoinStaking.SingleNft[] calldata _nfts)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L26

39: function claimApeCoin(uint256[] calldata _nfts, address _recipient)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L39

52: function withdrawApeCoin(
        ApeCoinStaking.SingleNft[] calldata _nfts,
        address _recipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L52

66: function depositBAKC(ApeCoinStaking.PairNftWithAmount[] calldata _nftPairs)
        external
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L66

82: function claimBAKC(
        ApeCoinStaking.PairNft[] calldata _nftPairs,
        address _recipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L82

97: function withdrawBAKC(
        ApeCoinStaking.PairNftWithAmount[] memory _nftPairs,
        address _apeRecipient
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMAYC.sol#L97

40: function burn(
        address from,
        address receiverOfUnderlying,
        uint256[] calldata tokenIds
    ) external virtual override onlyPool nonReentrant returns (uint64, uint64) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenMoonBirds.sol#L40

123: function decreaseUniswapV3Liquidity(
        address user,
        uint256 tokenId,
        uint128 liquidityDecrease,
        uint256 amount0Min,
        uint256 amount1Min,
        bool receiveEthAsWeth
    ) external onlyPool nonReentrant {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/NTokenUniswapV3.sol#L123

131: function setIncentivesController(IRewardController controller)
        external
        onlyPoolAdmin
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L131

142: function setBalanceLimit(uint64 limit) external onlyPoolAdmin {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L142

458: function setIsUsedAsCollateral(
        uint256 tokenId,
        bool useAsCollateral,
        address sender
    ) external virtual override onlyPool nonReentrant returns (bool) {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L458

474: function batchSetIsUsedAsCollateral(
        uint256[] calldata tokenIds,
        bool useAsCollateral,
        address sender
    )
        external
        virtual
        override
        onlyPool
        nonReentrant
        returns (
            uint256 oldCollateralizedBalance,
            uint256 newCollateralizedBalance
        )
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L474

529: function startAuction(uint256 tokenId)
        external
        virtual
        override
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L529

540: function endAuction(uint256 tokenId)
        external
        virtual
        override
        onlyPool
        nonReentrant
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/tokenization/base/MintableIncentivizedERC721.sol#L540

202: function emergencyERC721TokenTransfer(
        address token,
        uint256 tokenId,
        address to
    ) external onlyOwner {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L202

217: function emergencyPunkTransfer(address to, uint256 punkIndex)
        external
        onlyOwner
    {

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/ui/WPunkGateway.sol#L217

<ins>Recommended Mitigation Steps</ins>

Functions guaranteed to revert when called by normal users can be marked payable.

<a href="#Summary">[GAS‑17]</a><a name="GAS&#x2011;17"> Using unchecked blocks to save gas

Solidity version 0.8+ comes with implicit overflow and underflow checks on unsigned integers. When an overflow or an underflow isn’t possible (as an example, when a comparison is made before the arithmetic operation), some gas can be saved by using an unchecked block

<ins>Proof Of Concept</ins>
243: require(
244:     (block.number - updatedAt) <= config.expirationPeriod,
245:     "NFTOracle: asset price expired"
246: );

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/misc/NFTFloorOracle.sol#L243-L246

400: uint256 downpayment = price - vars.creditAmount;

https://github.com/code-423n4/2022-11-paraspace/tree/main/paraspace-core/contracts/protocol/libraries/logic/MarketplaceLogic.sol#L400

<a href="#Summary">[GAS‑18]</a><a name="GAS&#x2011;18"> Structs can be packed into fewer storage slots

Each slot saved can avoid an extra Gsset (20000 gas) for the first setting of the struct. Subsequent reads as well as writes have smaller gas savings

<ins>Proof Of Concept</ins>

There is no need to use uint256 for timestamp as it is unlikely to ever reach the max uint256 value. uint64 is enough for timestamps

struct PriceInformation {
    // last reported floor price(offchain twap)
    uint256 twap;
    // last updated blocknumber
    uint256 updatedAt;
    // last updated timestamp
    uint256 updatedTimestamp;
}

Saving 2 slots by changing to:

struct PriceInformation {
    // last reported floor price(offchain twap)
    uint64 twap;
    // last updated blocknumber
    uint64 updatedAt;
    // last updated timestamp
    uint64 updatedTimestamp;
}

#0 - c4-judge

2023-01-25T11:10:33Z

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