0% found this document useful (0 votes)
55 views38 pages

NFT Smart Contract Final Audit 27-09-2024

This document is an audit report for the NFTCreationContract, NFTStakingRewardWallet, and NFTStakingContract smart contracts, focusing on identifying vulnerabilities and ensuring compliance with best practices. The audit revealed a total of 23 issues, with varying severity levels, and provided recommendations for improvements, including implementing reentrancy guards and optimizing gas usage. Addressing the identified issues is crucial for enhancing the security and efficiency of the contracts.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
55 views38 pages

NFT Smart Contract Final Audit 27-09-2024

This document is an audit report for the NFTCreationContract, NFTStakingRewardWallet, and NFTStakingContract smart contracts, focusing on identifying vulnerabilities and ensuring compliance with best practices. The audit revealed a total of 23 issues, with varying severity levels, and provided recommendations for improvements, including implementing reentrancy guards and optimizing gas usage. Addressing the identified issues is crucial for enhancing the security and efficiency of the contracts.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

Table of Contents

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

This report presents a comprehensive audit of the NFTCreationContract,


NFTStakingRewardWallet, and NFTStakingContract smart contracts. These
contracts are designed to work together in managing NFT minting, staking rewards,
and PTEK token locking within the platform. The audit's primary goal was to
identify potential vulnerabilities, verify the integrity of the contract logic, and ensure
compliance with best practices and project requirements.

The auditing process involved:


- Analyzing the smart contracts for vulnerability to common and advanced attack
vectors.
- Reviewing the codebase for adherence to current best practices and industry
standards.
- Verifying that the contract logic fulfills the project's specifications and goals.

The primary areas of focus during the audit included:


- Reentrancy prevention, especially in functions handling fund transfers.
- Correct implementation of reward distribution based on global locking stages.
- Gas optimization to improve overall contract efficiency.
- Correct handling of access control through the onlyOwner modifier and other
mechanisms.
- Proper validation and state changes during NFT minting, PTEK locking, and
reward distribution.

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.

Recommendations from this audit include:


- Implementing reentrancy guards to protect against potential attacks.
- Optimizing storage patterns to reduce gas consumption.
- Enhancing event emission practices for improved transparency and monitoring.
-Ensure reward distribution logic accurately calculate rewards based on user stake,
PTEK rate, and stage-specific allowance unlocking percentage, ensuring fairness and
consistency across all stages
-If there is no specific requirement for using Solidity version 0.8.19, it is advisable
to upgrade to version 0.8.24. This version offers the same stability with added
improvements and optimizations.
-Follow the Solidity naming convention.

Some of the above recommendations have not yet been implemented.


Please ensure that all recommendations are followed as closely as possible to
improve code security, performance, and readability.

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.

Platform EVM Compatible Chains

Smart Contract Language Solidity

Codebase PTEK Smart Contract

NFTCreationContract
Contract Address NFTStakingContract
NFTStakingRewardWallet

Audit Summary

Delivery Date TBD

Audit Methodology Static analysis, Manual Review, Functional Testing

Vulnerability Summary

Initial Audit Final Audit Status

Total Issues 23 No new issues

Low 14 Fixed

Moderate 2 Partially Fixed*

High 7 Fixed
* Follow recommendations for improved code security
Findings

ID File Name Category Severity Status


NFTCreationContrac NFTCreationContract.sol Gas Optimization, Low, Low -Fixed
t Coding style moderate Moderate -
Partially Fixed*
NFTStakingReward NFTStakingRewardWallet.s Gas Optimization, Low, moderate Low -Fixed
Wallet ol Coding style Moderate -
Partially Fixed*
* Follow recommendations for improved code security

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.

Recommendation- Consider using a reentrancy guard modifier for


functions making external calls or transferring Ether. This practice
ensures that the contract remains secure against reentrancy attacks.Also
apply the checks-effects-interactions pattern by ensuring that internal
state changes occur before making any external calls.

Status- Partially fixed by the developer. In the


NFTCreationContract.safeMint(address,string), the state-changing
operation (_setTokenURI) is executed after the external call (_safeMint).
Similarly, in the NFTStakingRewardWallet.send(address,uint256)
function, the external call is made before emitting the NFTRewardSent
event.

2) Low level call(Low)


Issue- Low-level calls are error-prone as they do not check for the
existence of the called contract's code or whether the call succeeded,
leading to potential errors or silent failures.

Recommendation- Avoid using low-level calls unless absolutely


necessary. Prefer using higher-level functions like transfer, send etc, as
they offer better safety, automatic error handling, and clarity.

Status- PropTech requires the send function to include both value and
data in the transaction, which is implemented using a low-level call
mechanism.

3) Enhanced Documentation (Low)

Issue- The current smart contract lacks NatSpec comments, missing an


opportunity to provide valuable documentation directly within the code.

Recommendation- Implement NatSpec comments throughout the


contract. This includes descriptive summaries for contract functionality,
parameters, return values, and any notable side effects or requirements.

Status - Fixed by the developer.

4) Contract Flexibility with Upgradeable Functions (Low)

Issue- The current implementation of the NFTStakingContract and


NFTStakingRewardWallet contracts does not utilize upgradeable
patterns. This limitation restricts the ability to address bugs, improve
functionality, or adapt to new requirements post-deployment.

Recommendation- Implement upgradeable contracts using a proxy


pattern, such as those provided by established frameworks like
OpenZeppelin's Upgrades. This approach allows for the modification
and enhancement of contract logic without losing the existing state or
redeploying the contract.
Status - PropTech chose not to implement a flexible and upgradeable
strategy because they aimed to create an immutable smart contract. This
approach ensures that the contract cannot be changed, offering greater
confidence and protection to users.

Slither Tool Result:-


1. NFTStakingRewardWallet

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

1) Missing Semicolon [Compilation Error ] (high)

Issue-The safeMint function and dailyReward in the


NFTStakingContract is missing a semicolon at the end of a statement,
which is causing a compilation error.
Recommendation- Include the semicolon to fix this compilation error.

Status - Fixed by the developer.

2)Undeclared Identifier [Compilation Error ] (high)

Issue-The identifier rewardPercentage is used in the contract code but


has not been declared. This undeclared identifier results in a compilation
error and prevents the contract from functioning as intended.

Recommendation- Declare the rewardPercentage variable before using


it in the contract. Ensure it has the correct data type and scope to be used
within the function or contract where needed.

Status - Fixed by the developer.

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.

Status - Fixed by the developer.

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.

Recommendation- Declare weiDecimal as constant. This can be done


by adding the constant keyword to their declarations.

Status - Fixed by the developer.

5) Uses literals with too many digit(Low)

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.

6) Boolean comparison with constant values(Low)

Issue- In the current implementation of NFTStakingContract, several


functions compare boolean variables to constant values (true or false) in
require statements.
Recommendation- By removing the redundant comparison to boolean
constants, you reduce the complexity of your code, making it cleaner and
more gas-efficient.

Status - Fixed by the developer.

7) Event Emission for State Changes (Low)

Issue- The functions (initUser, mintNFT, updateStage, dailyLocking,


dailyReward) of NFTStakingContract that alter the contract's state but do
not emit events following these changes. Emitting events after state
changes is a best practice in smart contract development.

Recommendation- Introduce new events that correspond to the actions


performed within the above mentioned functions. Emit these events
immediately after the state changes occur within these functions.

Status - Fixed by the developer.

8) Public Visibility for Functions (Low)

Issue- The userDetail function is currently marked as public, implying


they can be called both internally and externally.
Recommendation- Change the visibility of the functions from public to
external. The external visibility specifier is more gas-efficient for
functions that are intended to be called only from outside the contract.
This change not only optimizes gas usage but also clarifies the intended
use of these functions.

Status - Fixed by the developer.

9) Reentrancy (moderate)

Issue-The current use of the onlyOwner modifier in functions mintNFT


and dailyReward 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.

Recommendation- Consider using a reentrancy guard modifier for


functions making external calls or transferring Ether. This practice
ensures that the contract remains secure against reentrancy attacks.Also
apply the checks-effects-interactions pattern by ensuring that internal
state changes occur before making any external calls.

Status- Partially fixed by the developer. In the NFTStakingContract,


several functions involve external calls being made before
state-changing operations.

In lockReward(address,uint256), the external call


(nftRewardWallet.send) is executed before updating the stage
(updateStage(currentStage + 1)), aligning with business logic to
distribute rewards first and then update the stage.

In mintNFT(address,uint,string,bool,bool), the external call to mint the


NFT (soulBoundNFT.safeMint) happens before updating the user's
information (users[user] = _user).

Similarly, in dailyReward(address), the reward is sent to the user


(user.send(dailyRewardPTEK)) before updating the user's reward status
(users[user] = _user).

In the payPendingReward(address,uint) function of the


NFTStakingContract, the external call to transfer dailyRewardPTEK to
the user occurs before updating the user's information and emitting the
PendingRewardUnlocked event.

10) Storage Access in Contract Functions (Low)

Issue- The functions dailyReward currently perform multiple reads from


storage for the same variables, leading to increased gas costs and less
efficient execution.

Recommendation- Optimize this function by minimizing redundant


storage reads. Read the necessary data from storage once at the
beginning of the function, store it in local variables, and use these local
variables throughout the function. This approach reduces gas
consumption and enhances the function's efficiency.

Status - Fixed by the developer.

11) Enhanced Documentation (Low)


Issue- The current smart contract lacks NatSpec comments, missing an
opportunity to provide valuable documentation directly within the code.

Recommendation- Implement NatSpec comments throughout the


contract. This includes descriptive summaries for contract functionality,
parameters, return values, and any notable side effects or requirements.
Status - Fixed by the developer.

12) Block Timestamp for Control Decisions (Low)

Issue- The dailyLocking function relies on block.timestamp to determine


whether the PTEK rate and global PTEK locked values can be updated.
Using block.timestamp introduces potential risk, as miners can slightly
manipulate it to alter the behavior of the contract.

Recommendation- Include a time buffer to mitigate the risk of miner


manipulation. (For example 1 hour)

Status-PropTech has determined that adding any buffer time to


block.timestamp compromises the integrity of the check and disrupts the
functionality, making the time-sensitive logic ineffective.As The
block.timestamp must strictly be 12:01 AM for the intended
functionality to work as designed.

13) Contract Interactions with Interfaces (Low)

Issue- The direct deployment of NFTCreationContract and


NFTStakingRewardWallet from the NFTStakingContract constructor,
without the use of interfaces, limits the system's modularity and
flexibility.

Recommendation-Leverage Solidity interfaces to define how


NFTStakingContract interacts with NFTStakingRewardWallet and
NFTCreationContract. Deploy these contracts independently and set
their addresses in NFTStakingContract post-deployment. This decouples
the contracts, allowing each to be updated or replaced without impacting
the others. Using interfaces enhances contract modularity and can lead to
more efficient gas usage during interactions.

Status - PropTech chooses not to use separate deployments for


NFTStakingRewardWallet and NFTCreationContract for their specific
use cases.

14) Contract Flexibility with Upgradeable Functions (Low)

Issue- The current implementation of the NFTStakingContract contracts


does not utilize upgradeable patterns. This limitation restricts the ability
to address bugs, improve functionality, or adapt to new requirements
post-deployment.

Recommendation- Implement upgradeable contracts using a proxy


pattern, such as those provided by established frameworks like
OpenZeppelin's Upgrades. This approach allows for the modification
and enhancement of contract logic without losing the existing state or
redeploying the contract.

Status - PropTech chose not to implement a flexible and upgradeable


strategy because they aimed to create an immutable smart contract. This
approach ensures that the contract cannot be changed, offering greater
confidence and protection to users.
Slither Tool Result:-
Functional Testing:
1) NFTCreationContract:-
A. Ensure that the contract allows the owner to successfully mint a
unique NFT.

B.Ensure that non-owners are prevented from minting a unique NFT.


Note:The current implementation of the minting process uses boolean
inputs to determine if an NFT is classified as Legendary or Rare,
instead of using an on-chain randomization mechanism.

PropTech comment- To support the PTEK business model and ensure


metadata is added to NFTs before minting, the randomization process for
rare and legendary attributes is performed on the backend. This approach
ensures that the NFTs are properly assigned their attributes prior to being
uploaded.

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.

Status - Fixed by the developer.

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.

PropTech Comment-The NFT reward calculation for a user depends on


the exchange rate of PTEK at the time of NFT purchase. As the user
sends PTEK from his/her wallet to NFT Staking Contract (indicating
purchase of NFT), it is not possible to receive exchange rate in that
transaction. The next step, after receiving NFT PTEK from a user, is to
mint NFT for that user, so the above mentioned problem has been solved
in that step as the NFTmint function has all the necessary information for
reward calculations along with minting NFT.
E. This test case ensures that the mintNFT function enforces proper
access control by reverting the transaction if a non-owner address
attempts to mint an NFT. The test simulates a scenario where a
non-owner (represented by addr1) tries to invoke the mintNFT function
with specific parameters, and verifies that the transaction is reverted with
the appropriate error message indicating that only the contract owner is
authorized to perform this action.

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.

it("Validate Stage Transition Based on Total PTEK Locked and


restrict contract to accepting new members once the total PTEK
locked reaches stageMaxLimit", async () => {
await owner.sendTransaction({
to: await staking.nftRewardWallet(),
value: ethers.parseEther("9500.0"),
});
await addrs[11].sendTransaction({
to: await staking.nftRewardWallet(),
value: ethers.parseEther("9500.0"),
});
await addrs[12].sendTransaction({
to: await staking.nftRewardWallet(),
value: ethers.parseEther("9500.0"),
});
await addrs[13].sendTransaction({
to: await staking.nftRewardWallet(),
value: ethers.parseEther("9500.0"),
});
expect(await staking.currentStage()).to.equal(1);
await addr1.sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await staking
.connect(owner)
.mintNFT(addr1.address, 10000, "uri", true, true);
expect(await staking.currentStage()).to.equal(1);
await addr2.sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await staking
.connect(owner)
.mintNFT(addr2.address, 10000, "uri", true, true);
expect(await staking.currentStage()).to.equal(2);
await addrs[0].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await addrs[1].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await staking
.connect(owner)
.mintNFT(addrs[0].address, 10000, "uri", true, true);
await staking
.connect(owner)
.mintNFT(addrs[1].address, 10000, "uri", true, true);
await addrs[2].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
expect(await staking.currentStage()).to.equal(2);
await staking
.connect(owner)
.mintNFT(addrs[2].address, 10000, "uri", true, true);
expect(await staking.currentStage()).to.equal(3);
await addrs[3].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await addrs[4].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await staking
.connect(owner)
.mintNFT(addrs[3].address, 10000, "uri", true, true);
await staking
.connect(owner)
.mintNFT(addrs[4].address, 10000, "uri", true, true);
await addrs[5].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await staking
.connect(owner)
.mintNFT(addrs[5].address, 10000, "uri", true, true);
expect(await staking.currentStage()).to.equal(3);
await addrs[6].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await staking
.connect(owner)
.mintNFT(addrs[6].address, 10000, "uri", true, true);
expect(await staking.currentStage()).to.equal(4);
await addrs[7].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await addrs[8].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await staking
.connect(owner)
.mintNFT(addrs[7].address, 10000, "uri", true, true);
await staking
.connect(owner)
.mintNFT(addrs[8].address, 10000, "uri", true, true);
expect(await staking.currentStage()).to.equal(4);
await addrs[9].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
});
await staking
.connect(owner)
.mintNFT(addrs[9].address, 10000, "uri", true, true);
await expect(
addrs[10].sendTransaction({
to: staking.target,
value: ethers.parseEther("8000.0"),
})
).to.be.revertedWith("error: new members limit reached");
});

G.This test case evaluates the NFTStakingContract functionality to


prevent the owner from updating the PTEK rate and total global PTEK
locked within 24 hours of the previous update. It ensures that updates to
these parameters can only be performed after a 24-hour waiting period.
Initially, the simulation has the owner update the PTEK rate and global
locked PTEK via the dailyLocking function, recording the
dailyLockTime for the next update. The test then attempts another
update within 24 hours, which should revert with an error message. After
simulating 24 hours passing with moveBlocks, the owner successfully
updates the PTEK rate, validating the 24-hour restriction mechanism.

H.[FAILED]This test simulates the reward distribution mechanism,


where a user should receive PTEK daily reward based on their locked
PTEK and Daily Unlocking Allowance percentage from the NFT
Staking Reward Wallet. However, the contract fails due to the below
condition in dailyReward function:(high)
The current timestamp is used in the dailyLockTime constructor variable
during deployment, but this approach is not functioning as expected.
Also tried with a timestamp of 12:01 AM for the same day while
deploying the contract,but it too failed.

The above condition always evaluates to false, preventing the


dailyReward function from executing as expected, even though the
dailyLocking function successfully completes.

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.

Moreover, the owner can continuously update dailyLockTime


without waiting for 24 hours between updates. This bypasses the
intended 24-hour restriction, allowing the owner to make multiple
updates within the same day. Both of these behaviors are
unexpected and need to be addressed to ensure proper time-bound
reward distributions and updates.

Status - Recommendation is to have the suggested flow for


improvisation.

I.Incorrect Daily Unlocking Allowance Logic(high)

The contract logic for calculating the Daily Unlocking Allowance


Percentage is flawed.
According to business rules,Daily Unlocking Allowance % should be
calculated as:

However, the contract instead uses the following logic


Status - PropTech has reviewed and verified the formula for calculating
the Daily Unlocking Allowance Percentage, confirming its accuracy.
Testing of the daily distribution process has been successfully conducted,
with the process functioning as intended and no issues encountered.
PropTech affirms that the implemented logic aligns with the business
requirements and performs effectively in practice.

J.Missing Logic in dailyReward function:(high)

The contract lacks a mechanism to deactivate users who have unlocked


their total locked amount (staked + reward) within the specified 3-year
period. As a result, users can continue unlocking rewards until the full
3-year period, even if they have already surpassed their total staked
amount, as long as the contract maintains a sufficient balance. This
oversight allows for potential over-unlocking and must be addressed to
ensure users cannot withdraw more than their entitled amount within the
defined time frame.

Suggested Fixes
● Introduce logic to deactivate users once their total locked amount
has been unlocked within the 3-year period.

Status - Fixed by the developer.


K. Missing Function: getTotalBalance(high)

The NFTStakingContract contract lacks a function to retrieve the total


PTEK balance of the NFTStakingContract.

Status - Fixed by the developer.

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.

Finally, after simulating the passage of 24 hours using moveBlocks, the


owner calls dailyLocking again and successfully unlocks daily rewards,
confirming that the time restriction is enforced properly.
Proposed Improvements to the payPendingReward Function
Logic-
The payPendingReward function requires enhancements to effectively
manage the final day of a user's reward period (day 1095). Specifically,
the function should implement logic to unlock the remaining rewards by
setting dailyRewardPTEK to _user.totalStaked - _user.unlocked and
deactivate the user after they have claimed their rewards. Additionally, to
prevent unnecessary reverts during the last iteration, the function should
check if dailyRewardPTEK exceeds _user.totalLocked. If it does, the
function should adjust dailyRewardPTEK to match _user.totalLocked
and deactivate the user.
While this scenario is unlikely to occur unless there is a significant delay
(e.g., more than 444 days) in deploying the contracts, including this logic
is important for ensuring robustness and preventing potential issues in
reward distribution.

NOTE-As discussed in the meeting, user onboarding may commence


prior to the contract going live. In this scenario, the pending reward
function will be utilized to distribute rewards for the interval between the
contract's creation time (during onboarding) and the contract deployment
time. However, users will be required to make a deposit once the
contract is live.
Appendix

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.

Event Logging Practices


Event Logging Practices findings review the contract's use of events for
transparency and tracking, identifying opportunities to enhance visibility into
contract operations and critical actions for off-chain monitoring and interfacing.

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.

Solidity Best Practices


Solidity Best Practices findings include recommendations for adhering to established
coding conventions and practices unique to Solidity development, aiming to improve
code security, readability, and maintainability.
Disclaimer

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 is not, nor should be considered, an “endorsement” or


“disapproval” of any particular project or team. This report is not, nor should
be considered, an indication of the economics or value of any “product” or
“asset” created by any team or project that contracts SoluLab to perform a
security assessment. This report does not provide any warranty or guarantee
regarding the absolute bug-free nature of the technology analyzed, nor do they
provide any indication of the technologies proprietors, business, business
model, or legal compliance.

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.

Blockchain technology and cryptographic assets present a high level of


ongoing risk. SoluLab’s position is that each company and individual is
responsible for their due diligence and continuous security.

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

You might also like