Q2 2026 Security & Compliance Report67 incidents, $764M in losses, 88% from operational failures.
Get the report →

Audit name:

[SCA] Seedworld | Land Management | Feb2025

Date:

Mar 6, 2025

Table of Content

→Introduction
→Audit Summary
→System Overview
→Potential Risks
→Findings
→Appendix 1. Definitions
→Appendix 2. Scope
→Appendix 3. Additional Valuables
→Disclaimer

Want a comprehensive audit report like this?

Introduction

We express our gratitude to the Seedworld team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.

Seedworld is a free-to-play UGC gaming platform where players create games, build worlds, and trade in a blockchain-powered fantasy metaverse with a resource-driven economy and sustainable creator ecosystem.

Document

NameSmart Contract Code Review and Security Analysis Report for Seedworld
Audited BySeher Saylik
Approved ByIvan Bondar
Websitehttps://seedworld.io/→
Changelog27/02/2025 - Preliminary Report
06/03/2025 - Final Report
PlatformEthereum
LanguageSolidity
TagsNon-fungible Token (NFT); NFT Staking
Methodologyhttps://hackenio.cc/sc_methodology→
  • Document

    Name
    Smart Contract Code Review and Security Analysis Report for Seedworld
    Audited By
    Seher Saylik
    Approved By
    Ivan Bondar
    Changelog
    27/02/2025 - Preliminary Report
    06/03/2025 - Final Report
    Platform
    Ethereum
    Language
    Solidity
    Tags
    Non-fungible Token (NFT); NFT Staking

Review Scope

Repositoryhttps://github.com/SeedworldStudios/product-evm-contracts/tree/main/contracts/land-management→
Commitbbd5bad973122c9b8cddb8e42b83d4a8ee348995
Retest3d3d9813663563b635318cd8dee3176a65b15673

Audit Summary

11Total Findings
9Resolved
1Accepted
1Mitigated

The system users should acknowledge all the risks summed up in the risks section of the report

Documentation quality

  • Functional requirements are partially provided.

  • Technical description is not provided.

Code quality

  • The development environment is configured.

Test coverage

Code coverage of the project is 69.49% (branch coverage).

  • Deployment and basic user interactions are covered with tests.

  • Different stake extending scenarios are not tested entirely.

  • Interactions by several users are not tested thoroughly.

System Overview

Seedworld is an NFT-based staking protocol designed for managing virtual land assets. It comprises the following primary contracts:

LandNFT — an upgradeable ERC721A-based NFT contract for managing Land NFTs. It includes advanced features such as EIP-712 signature verification for authorized minting, role-based access control, royalty management via ERC2981, and configurable metadata through base URI settings. This contract enables the creation and management of multiple NFT types representing virtual land parcels, while ensuring that minting requests are validated through secure off-chain signatures.

NFTStaking — a contract that allows users to stake their LandNFT tokens for a predefined or dynamic duration. It supports two staking modes:

  • Fixed Duration Staking: Users can stake NFTs using preset duration values. The contract validates the duration against a list of allowed fixed durations.

  • Dynamic Duration Staking: Users can stake NFTs with a flexible duration, provided the chosen duration falls within an allowed range.

PaymentGateway — contract that enables users to make payments using either whitelisted ERC20 tokens or native ETH, transferring the funds securely to a designated safe wallet after validating payment details like token balance and expiry time.

Privileged roles

  • The DEFAULTADMINROLE in the LandNFT:

    • add new NFT types and update existing ones.

    • configure the base URI

    • sets the user NFT type hash

    • set validator address

    • set max supply

    • configure the royalty settings

  • The DEFAULTADMINROLE in the NFTStaking can:

    • add/remove fixed staking durations

    • set the dynamic stake range

    • enable/disable dynamic or fixed stakings

    • set NFT address

    • set max tokens

  • The DEFAULTADMINROLE in the PaymentGate can:

    • set safe wallet

    • whitelist/blacklist a token

    • withdraw native/ERC20 tokens to safeWallet address

Potential Risks

The NFTStaking contract is designed solely for NFT staking functionality and intentionally does not include any built-in reward mechanism. As a result, any reward distribution, incentive structure, or related reward mechanism is explicitly out of scope for this contract’s design and implementation.

Inconsistent and evolving requirements during the audit have introduced uncertainties regarding the intended functionality and security posture of the solution. This variability may result in potential gaps or misalignments that could affect the system's reliability and security, underscoring the need for clearer specifications and formal change management procedures.

The owner's ability to modify royalty settings even after NFTs are minted creates a risk that users may face unexpected changes to their revenue streams from secondary sales, potentially undermining trust and expected returns.

Administrative Key Control Risks: The digital contract architecture relies on administrative keys for critical operations. Centralized control over these keys presents a significant security risk, as compromise or misuse can lead to unauthorized actions or loss of funds.

Flexibility and Risk in Contract Upgrades: The project's contracts are upgradable, allowing the administrator to update the contract logic at any time. While this provides flexibility in addressing issues and evolving the project, it also introduces risks if upgrade processes are not properly managed or secured, potentially allowing for unauthorized changes that could compromise the project's integrity and security.

Findings

F-2025-1085Incorrect Duration Calculation for Active Stakes
Status
fixed
Severity

High
F-2025-1085Unpreserved Accrued Staking Duration on Stake Extension
Status
fixed
Severity

High
F-2025-1085NFT Address Update Vulnerability Enabling Malicious Contract Replacement
Status
fixed
Severity

Medium
F-2025-1084Unrestricted Admin Control over Royalty Settings
Status
accepted
Severity

Medium
F-2025-1085Unsafe ERC20 Transfer in sweepERC20Tokens Function
Status
fixed
Severity

Low
F-2025-1085Initializer Is Not Disabled In constructor
Status
fixed
Severity

Low
F-2025-1085Potential Denial-of-Service (DoS) via Unbounded Loop Iterations
Status
mitigated
Severity

Low
F-2025-1085Gas Inefficiencient Error Handling and Mixing Custom Errors with Require Statements
Status
fixed
Severity

Observation
F-2025-1085Missing Empty NFT Type Validation
Status
fixed
Severity

Observation
F-2025-1084Lack of Check in setMaxSupply
Status
fixed
Severity

Observation
Code
―
Title
Status
Severity
F-2025-1085Incorrect Duration Calculation for Active Stakes
fixed

High
F-2025-1085Unpreserved Accrued Staking Duration on Stake Extension
fixed

High
F-2025-1085NFT Address Update Vulnerability Enabling Malicious Contract Replacement
fixed

Medium
F-2025-1084Unrestricted Admin Control over Royalty Settings
accepted

Medium
F-2025-1085Unsafe ERC20 Transfer in sweepERC20Tokens Function
fixed

Low
F-2025-1085Initializer Is Not Disabled In constructor
fixed

Low
F-2025-1085Potential Denial-of-Service (DoS) via Unbounded Loop Iterations
mitigated

Low
F-2025-1085Gas Inefficiencient Error Handling and Mixing Custom Errors with Require Statements
fixed

Observation
F-2025-1085Missing Empty NFT Type Validation
fixed

Observation
F-2025-1084Lack of Check in setMaxSupply
fixed

Observation
1-10 of 11 findings

Identify vulnerabilities in your smart contracts.

Appendix 1. Definitions

Severities

When auditing smart contracts, Hacken is using a risk-based approach that considers Likelihood, Impact, Exploitability and Complexity metrics to evaluate findings and score severities.

Reference on how risk scoring is done is available through the repository in our Github organization:

Severity

Description

Critical
Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

High
High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

Medium
Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

Low
Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.
  • Severity

    Critical

    Description

    Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

    Severity

    High

    Description

    High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

    Severity

    Medium

    Description

    Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

    Severity

    Low

    Description

    Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.

Potential Risks

The "Potential Risks" section identifies issues that are not direct security vulnerabilities but could still affect the project’s performance, reliability, or user trust. These risks arise from design choices, architectural decisions, or operational practices that, while not immediately exploitable, may lead to problems under certain conditions. Additionally, potential risks can impact the quality of the audit itself, as they may involve external factors or components beyond the scope of the audit, leading to incomplete assessments or oversight of key areas. This section aims to provide a broader perspective on factors that could affect the project's long-term security, functionality, and the comprehensiveness of the audit findings.

Appendix 2. Scope

The scope of the project includes the following smart contracts from the provided repository:

Scope Details

Repositoryhttps://github.com/SeedworldStudios/product-evm-contracts/tree/main/contracts/land-management→
Commitbbd5bad973122c9b8cddb8e42b83d4a8ee348995
Retest3d3d9813663563b635318cd8dee3176a65b15673
WhitepaperN/A
RequirementsSubmitted as a zip file.
Technical RequirementsN/A

Appendix 3. Additional Valuables

Verification of System Invariants

During the audit of Seedworld, Hacken followed its methodology by performing fuzz-testing on the project's main functions. Foundry, a tool used for fuzz-testing, was employed to check how the protocol behaves under various inputs. Due to the complex and dynamic interactions within the protocol, unexpected edge cases might arise. Therefore, it was important to use fuzz-testing to ensure that several system invariants hold true in all situations.

Fuzz-testing allows the input of many random data points into the system, helping to identify issues that regular testing might miss. A specific Echidna fuzzing suite was prepared for this task, and throughout the assessment, 10 invariants were tested over 10,000 runs. This thorough testing ensured that the system works correctly even with unexpected or unusual inputs.

Invariant

Test Result

Run Count

LandNFT::getMaxNFTCount() Valid inputs return the expected result and invalid inputs revert.Passed10k
LandNFT::addNFTTypes  Unique, non-empty NFT type strings are successfully added and registered in the contract.Passed10k
LandNFT::toString()  The internal toString function returns the correct decimal string representation for any uint256 value.Passed10k
LandNFT::mintNFT() When processing multiple valid mint requests with proper signatures, the contract correctly updates the total supply.Passed10k
LandNFT::mintNFT Duplicate signatures (attempted replay attacks) are rejected, ensuring each mint request is unique.Passed10k
NFTStaking::stakeNFTsFixedDuration() –  invalid durations revert with InvalidFixedDuration.Passed10k
NFTStaking::extendStakeDuration() – If the remaining time plus the extension exceeds the maximum allowed, it reverts .Passed10k
NFTStaking::stakeNFTDynamicDuration() – Inputs within the allowed dynamic range succeed, while out-of-range inputs revert.Passed10k
NFTStaking::stakeNFTFixedDuration() – Inputs within the allowed fixed range succeed, while out-of-range inputs revert.Passed10k
NFTStaking::unstakeNFTs() – Unstaking before the staking period ends reverts with StakingNotEnded.Passed10k
  • Invariant

    LandNFT::getMaxNFTCount() Valid inputs return the expected result and invalid inputs revert.

    Test Result

    Passed

    Run Count

    10k

    Invariant

    LandNFT::addNFTTypes  Unique, non-empty NFT type strings are successfully added and registered in the contract.

    Test Result

    Passed

    Run Count

    10k

    Invariant

    LandNFT::toString()  The internal toString function returns the correct decimal string representation for any uint256 value.

    Test Result

    Passed

    Run Count

    10k

    Invariant

    LandNFT::mintNFT() When processing multiple valid mint requests with proper signatures, the contract correctly updates the total supply.

    Test Result

    Passed

    Run Count

    10k

    Invariant

    LandNFT::mintNFT Duplicate signatures (attempted replay attacks) are rejected, ensuring each mint request is unique.

    Test Result

    Passed

    Run Count

    10k

    Invariant

    NFTStaking::stakeNFTsFixedDuration() –  invalid durations revert with InvalidFixedDuration.

    Test Result

    Passed

    Run Count

    10k

    Invariant

    NFTStaking::extendStakeDuration() – If the remaining time plus the extension exceeds the maximum allowed, it reverts .

    Test Result

    Passed

    Run Count

    10k

    Invariant

    NFTStaking::stakeNFTDynamicDuration() – Inputs within the allowed dynamic range succeed, while out-of-range inputs revert.

    Test Result

    Passed

    Run Count

    10k

    Invariant

    NFTStaking::stakeNFTFixedDuration() – Inputs within the allowed fixed range succeed, while out-of-range inputs revert.

    Test Result

    Passed

    Run Count

    10k

    Invariant

    NFTStaking::unstakeNFTs() – Unstaking before the staking period ends reverts with StakingNotEnded.

    Test Result

    Passed

    Run Count

    10k

Additional Recommendations

The smart contracts in the scope of this audit could benefit from the introduction of automatic emergency actions for critical activities, such as unauthorized operations like ownership changes or proxy upgrades, as well as unexpected fund manipulations, including large withdrawals or minting events. Adding such mechanisms would enable the protocol to react automatically to unusual activity, ensuring that the contract remains secure and functions as intended.

To improve functionality, these emergency actions could be designed to trigger under specific conditions, such as:

  • Detecting changes to ownership or critical permissions.

  • Monitoring large or unexpected transactions and minting events.

  • Pausing operations when irregularities are identified.

These enhancements would provide an added layer of security, making the contract more robust and better equipped to handle unexpected situations while maintaining smooth operations.

Disclaimer