NFT Smart Contract Final Audit 27-09-2024
NFT Smart Contract Final Audit 27-09-2024
Summary
Overview
Project Summary
Audit Summary
Vulnerability Summary
Findings
1. NFT Staking Reward Wallet
2. NFT Creation Contract
3. NFT Staking Contract
Functional Testing
Appendix
Disclaimer
Summary
The security assessment revealed issues ranging from minor to critical in severity.
Critical issues require immediate attention to prevent potential security breaches,
while minor issues are mostly recommendations for improving code efficiency and
maintainability.
Addressing the identified issues and recommendations will significantly enhance the
security posture and operational efficiency of the NFTCreationContract,
NFTStakingRewardWallet, and NFTStakingContract contracts. Adhering to these
suggestions will ensure the contracts meet high-security standards and align with
industry best practices.
Overview
Project Summary:
Project Name PTEK Smart Contract
Description The Audit report of smart contracts with Static and Manual analysis.
NFTCreationContract
Contract Address NFTStakingContract
NFTStakingRewardWallet
Audit Summary
Vulnerability Summary
Low 14 Fixed
High 7 Fixed
* Follow recommendations for improved code security
Findings
1) Reentrancy (moderate)
Issue- The current use of the onlyOwner modifier in functions send and
safeMint helps mitigate reentrancy attack risks by restricting access to
the contract's owner.Even with access control, it's essential to architect
smart contracts with inherent protections against reentrancy attacks.
Status- PropTech requires the send function to include both value and
data in the transaction, which is implemented using a low-level call
mechanism.
2. NFTCreationContract
ID File Name Category Severity Status
NFTStakingContract NFTStakingContract.sol Gas Optimization, Low, High, Low -
Coding style, moderate, high Fixed
Arithmetic Moderate -
operations,missing Partially Fixed*
logic
* Follow recommendations for improved code security
3) State-variables (Low)
Issue- These stage limits are not updated following deployment, yet it is
not declared as immutable.
Recommendation- Declare these stage limit variables as immutable.By
declaring the variables as immutable, accessing these stage limits will
be cheaper compared to regular state variables, which would involve
more expensive storage reads. This results in gas savings across any
function calls that interact with these limits.
4) Declaration of weiDecimal(Low)
Issue- The weiDecimal variables are used to define no. of wei in a PTEK
but are not declared as constants. These values stay the same after the
contract is deployed, and their current declaration may lead to
unnecessary gas costs when they are accessed.
Issue- The weiDecimal Literals with many digits are difficult to read and
review.
Recommendation- Use Ether Suffix to make the code more readable.
Status- Proptech agreed that the use of literals with excessive digits is a
concern; however, they are not making alterations at this time to avoid
extending the testing cycle related to decimal precision.
9) Reentrancy (moderate)
2) NFTStakingRewardWallet :-
A. It verifies that the NFTStakingRewardWallet smart contract can
receive PTEK transactions and emit a BalanceReceived event as
confirmation.
B.The test verifies that the contract owner can successfully transfer
PTEK from the contract's balance to a specified address
(NFTStakingContract in this case), ensuring the recipient's balance
increases by the correct amount.
C. The test asserts that attempts by non-owners to invoke the send
function are properly rejected.
D. The test asserts that sending rewards to zero addresses are properly
rejected.
E.Missing Function: getTotalBalance(high)
The NFTStakingRewardWallet contract lacks a function to retrieve the total
PTEK balance of the NFT Staking Reward Wallet.
3) NFTStakingContract:-
A. This test case checks the contract's functionality to lock PTEK and
simultaneously create a user profile upon receiving PTEK
B. This test case checks that the NFTStakingContract allows its owner to
retrieve user information, including current day, PTEK Locked and
staking details.
C.The test asserts that attempts by non-owners to retrieve user
information are properly rejected.
D. This test case checks the contract's ability to receive the reward
amount in PTEK from the NFT Staking Reward Wallet, based on the
locked PTEK and the applicable reward percentage that is determined by
the pack price and current stage.
Discrepancy:
As per the business rules, the reward should be triggered when the user
sends PTEK to the NFT Staking Wallet from their wallet. However, the
current implementation triggers the reward distribution when the owner
mints the NFT for the user, which is not aligned with the specified
requirements.
F.To ensure that the staking smart contract correctly transitions between
stages based on the total amount of PTEK locked and restricts the
contract from accepting new members once the total locked amount
reaches the defined stageMaxLimit. This test verifies both the correct
progression through stages and the enforcement of limits on new
member additions.
Note:The stage limits have been lowered for testing by setting values
like uint private stage2Limit = 20000 * weiDecimal; instead of the
original 2000000 * weiDecimal. This modification enables faster and
more efficient testing in the Hardhat environment, making it easier to
simulate stage transitions without requiring large token amounts.
Steps:
1)Simulate the initial funding by sending Ether to the nftRewardWallet
from the owner and additional addresses to prepare the contract to be
able to transfer the reward amount to NFTStakingContract.
2)Perform transactions(transfer PTEK from user wallet to
NFTStakingContract) and mint NFTs for different addresses.
Verify that the contract transitions through stages 1, 2, 3, and 4 correctly
based on the total PTEK locked.
3)Attempt to add new members after reaching the maximum limit and
ensure the contract rejects further additions with the appropriate error
message.
Another Scenario:
If dailyLockTime is set up to 1 day (i.e., not greater than
86400 seconds)
When dailyLockTime is configured for up to 1 day (not exceeding
86400 seconds) in the constructor during deployment, the
dailyReward executes successfully, but a critical issue arises. The
dailyReward function can be invoked multiple times within a
single day without updating dailyLockTime, which contradicts the
intended contract behavior. Even though only the owner can call
this function, it should still restrict the owner to one call per day.
Suggested Fixes
● Introduce logic to deactivate users once their total locked amount
has been unlocked within the 3-year period.
L. This test case verifies that the owner can call payPendingReward for
the interval between the contract's creation time and the current
deployment time. Initially, the owner funds the nftRewardWallet and
stakes an amount using the staking contract. The owner then mints an
NFT for addr1 with a timestamp that is 5 days in the past.
The test checks the balance of addr1 before making multiple calls to
payPendingReward, ensuring rewards are accumulated correctly. After
six successful calls, it attempts an additional call, which should revert
with an error message indicating that pending rewards have already been
paid.
Next, the test verifies that the balance of addr1 reflects the correct
amount earned. The owner then invokes dailyLocking, and the test
expects an event indicating that daily rewards have been unlocked. An
attempt to call dailyReward again on the same day should revert with an
appropriate error message.
Finding’s Categories:
Reentrancy Risk
Reentrancy Risk findings identify vulnerabilities where external calls could lead to
unwanted re-entry into contract functions, potentially compromising contract
integrity and leading to unintended behavior or asset loss.
Gas Optimization
Gas Optimization findings highlight areas where the contract's operations could be
made more gas-efficient, either through optimizing storage access patterns or
restructuring code to minimize computational overhead, thereby reducing transaction
costs.
Arithmetic Operations
Arithmetic Precision Loss findings pinpoint instances where the order of
mathematical operations could lead to significant precision loss, affecting the
contract's financial calculations and potentially leading to incorrect outcomes.
Compiler Versioning
Compiler Versioning findings emphasize the importance of specifying a fixed
compiler version to avoid unpredictable behavior or vulnerabilities introduced by
compiler updates, ensuring consistent and secure contract compilation.
This report is subject to the terms and conditions (including without limitation,
description of services, confidentiality, disclaimer, and limitation of liability)
outlined in the Services Agreement, or the scope of services, and terms and
conditions provided to the Company in connection with the Agreement. This
report provided in connection with the Services outlined in the Agreement shall
be used by the Company only to the extent permitted under the terms and
conditions outlined in the Agreement. This report may not be transmitted,
disclosed, referred to, or relied upon by any person for any purposes without
SoluLab’s prior written consent.
This report should not be used in any way to make decisions around investment
or involvement with any particular project. This report in no way provides
investment advice, nor should be leveraged as investment advice of any sort.
This report represents an extensive assessment process intended to help our
customers increase the quality of their code while reducing the high level of
risk presented by cryptographic tokens and blockchain technology.
SoluLab’s goal is to help reduce the attack vectors and the high level of
variance associated with utilizing new and consistently changing technologies,
and in no way claims any guarantee of security or functionality