Introduction
We express our gratitude to the MarsCat team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
MarsCat is a privacy-first social platform designed to operate natively on peer-to-peer networks, built upon the RelayX decentralized protocol. The system provides an ERC-20 utility token (MCAT), an ERC-20-based subscription recharge system, a points-based membership system, and a peer-to-peer red packet distribution mechanism. The core user-facing actions include purchasing time-bound membership subscriptions via token or points payments, claiming backend-authorized loyalty points, and sending or receiving token-backed red packets.
Document | |
|---|---|
| Name | Smart Contract Code Review and Security Analysis Report for MarsCat |
| Audited By | Khrystyna Tkachuk |
| Approved By | Kornel Światłowski |
| Website | https://marscat.io→ |
| Changelog | 23/06/2026 - Preliminary Report |
| 26/06/2026 - Final Report | |
| Platform | BSC |
| Language | Solidity |
| Tags | ERC20; Signatures; Claims |
| Methodology | https://docs.hacken.io/methodologies/smart-contracts→ |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for MarsCat
- Audited By
- Khrystyna Tkachuk
- Approved By
- Kornel Światłowski
- Website
- https://marscat.io→
- Changelog
- 23/06/2026 - Preliminary Report
- 26/06/2026 - Final Report
- Platform
- BSC
- Language
- Solidity
- Tags
- ERC20; Signatures; Claims
Review Scope | |
|---|---|
| Repository Part 1 | https://github.com/MarscatTech/Social-Contracts→ |
| Commit | ddf440059a9317439918326fbe505343962ae5b2 |
| Final Commit | 32572f45109729ae84ea05be8d8493331d496ecb |
| Repository Part 2 | https://github.com/MarscatTech/Recharge-Contracts→ |
| Commit | a99bc59c7c24259764da816bc6e24ce87e4cfe06 |
| Final Commit | 53c9dec82a676dbc348667549fb7053d025ed1d8 |
| Repository Part 3 | https://github.com/MarscatTech/Marscat-Token-Contracts→ |
| Commit | a3fa9edd5693bf7ec341c42e444fd9e31532992d |
| Final Commit | 2267a801daf9d9232cf3a2e2cda6879958e90a4b |
Review Scope
- Repository Part 1
- https://github.com/MarscatTech/Social-Contracts→
- Commit
- ddf440059a9317439918326fbe505343962ae5b2
- Final Commit
- 32572f45109729ae84ea05be8d8493331d496ecb
- Repository Part 2
- https://github.com/MarscatTech/Recharge-Contracts→
- Commit
- a99bc59c7c24259764da816bc6e24ce87e4cfe06
- Final Commit
- 53c9dec82a676dbc348667549fb7053d025ed1d8
- Repository Part 3
- https://github.com/MarscatTech/Marscat-Token-Contracts→
- Commit
- a3fa9edd5693bf7ec341c42e444fd9e31532992d
- Final Commit
- 2267a801daf9d9232cf3a2e2cda6879958e90a4b
Audit Summary
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 are partially provided.
NatSpec comments are missed for MarscatToken, MarscatPoints, and MarscatRedPacket.
Code quality
The code leverages OpenZeppelin contracts and follows established patterns.
The development environment is configured.
Test coverage
Code coverage of the Social-Contracts is 62.73% (branch coverage), Marscat-Token-Contracts is 77.27% (branch coverage), and Recharge-Contracts is 0%.
Deployment and basic user interactions are covered with tests.
Negative cases coverage is present.
Interactions by several users are partially tested.
Test cases for MarscatRecharge is missing.
System Overview
The system is organized into three independently deployed sub-projects. The recharge and social contracts share a common security baseline of Ownable, ReentrancyGuard, and Pausable, while the token contract inherits ERC20, Ownable, and Pausable. The token sub-project contains MarscatToken, a fixed-supply ERC-20 with compliance controls. The recharge sub-project contains MarscatRecharge, which accepts ERC-20 payments for subscription purchases. The social sub-project contains MarscatPoints and MarscatRedPacket, which handle off-chain-authorized point distribution, points-based subscription recharge, and peer-to-peer gifting via red packets, respectively.
MarscatToken implements the ERC-20 standard with a fixed total supply of 1,000,000,000 MCAT minted at deployment. It enforces a blacklist mechanism at the transfer and approval level through overridden _update and _approve internals, and provides an owner-only transferBlackFunds function for seizing balances from blacklisted addresses. Ownership renunciation is explicitly disabled.
MarscatRecharge operates as a standalone subscription payment contract that maps configurable package IDs to per-token prices (via a nested packageId => token => amount mapping) and per-package durations. Users call recharge with a package ID, an ERC-20 token address, and a beneficiary address (restricted to EOAs), and the contract extends or initializes a time-bound subscription for that beneficiary. Accumulated token balances are withdrawn by the owner via withdrawToken.
MarscatPoints manages an off-chain-to-on-chain points ledger using EIP-712 typed signatures for authorized point claims. Points are non-transferable and exist only as internal balances. Users spend points through rechargeWithPoints to purchase membership subscriptions from owner-configured packages, with subscription durations that stack additively.
MarscatRedPacket enables users to escrow ERC-20 tokens or native BNB into single-claim red packets, each identified by a unique hash and protected by a temporary claim key. Recipients claim packets by providing a EIP-712 typed signature from the corresponding claim key. Unclaimed packets may be revoked by the original sender after a 24-hour lockup period. The two social contracts are independently deployed and do not interact with each other or with the token or recharge contracts on-chain.
Files in Scope
MarscatToken.sol: An ERC-20 token contract that mints a fixed supply of 1,000,000,000 MCAT to a designated address at construction. It enforces blacklist checks on all transfers and approvals, provides owner-only functions for managing blacklisted addresses and seizing their funds via
transferBlackFunds, and disables ownership renunciation by reverting inrenounceOwnership.MarscatRecharge.sol: A subscription recharge contract that accepts ERC-20 token payments in exchange for time-bound memberships. Package pricing is configured per package ID and per token address via
setPackagePrice, and durations are set per package viasetPackageDuration. Therechargefunction transfers tokens from the caller and extends or initializes a subscription for a specified EOA beneficiary. The owner may withdraw accumulated tokens throughwithdrawToken.MarscatPoints.sol: A points ledger and membership subscription contract that allows users to claim off-chain-authorized points via
claimPointsusing EIP-712 signed messages verified against a configurable signer address. Claimed points are spent throughrechargeWithPointsto purchase owner-configured subscription packages, with durations stacking on active subscriptions. Points balances are non-transferable and tracked internally.MarscatRedPacket.sol: A peer-to-peer red packet contract that allows users to escrow ERC-20 tokens via
createRedPacketor native BNB viacreateNativeRedPacket, each secured by a temporary claim key. A recipient callsclaimRedPacketwith a signature from the claim key to withdraw the escrowed funds. The original sender may reclaim unclaimed packets after 24 hours throughrevokeRedPacket.
Privileged roles
MarscatRedPacket.sol:
Owner (inherited from Ownable): Controls contract pausability. Assigned to
msg.senderat deployment.Can call
pauseto pause red packet creation and claiming.Can call
unpauseto resume red packet creation and claiming.Can call
transferOwnershipto transfer the owner role to a new address (inherited from Ownable).Can call
renounceOwnershipto irrevocably renounce ownership, leaving the contract without an owner (inherited from Ownable).
MarscatPoints.sol:
Owner (inherited from Ownable): Controls the trusted signer, subscription package configuration, and contract pausability. Assigned to
msg.senderat deployment.Can call
setSignerto replace the trusted signer address used to authorize point claims.Can call
setPackagePriceto set or update the point cost of a subscription package.Can call
setPackageDurationto set or update the duration of a subscription package.Can call
removePackageto remove a subscription package by clearing its price and duration.Can call
pauseto pause point claiming and subscription recharging.Can call
unpauseto resume point claiming and subscription recharging.Can call
transferOwnershipto transfer the owner role to a new address (inherited from Ownable).Can call
renounceOwnershipto irrevocably renounce ownership (inherited from Ownable).
Signer: Off-chain trusted address stored in the
signerstate variable. Set via the constructor and updatable by the Owner viasetSigner.Signatures from this address are required to authorize
claimPointscalls, effectively controlling which users may claim points and in what amounts.
MarscatRecharge.sol:
Owner (inherited from Ownable): Controls package configuration, token withdrawals, and contract pausability. Assigned to
msg.senderat deployment.Can call
setPackagePriceto set the token address and amount required for a subscription package.Can call
setPackageDurationto set or update the duration of a subscription package.Can call
withdrawTokento withdraw any ERC-20 tokens held by the contract to a specified recipient address.Can call
pauseto pause subscription recharging.Can call
unpauseto resume subscription recharging.Can call
transferOwnershipto transfer the owner role to a new address (inherited from Ownable).Can call
renounceOwnershipto irrevocably renounce ownership (inherited from Ownable).
MarscatToken.sol:
Owner (inherited from Ownable): Controls token pausability, blacklist management, and forced fund transfers. Assigned to the
mintTo_address at deployment, which also receives the entire fixed supply.Can call
pauseto pause all token transfers and approvals.Can call
unpauseto resume all token transfers and approvals.Can call
addBlacklistto add addresses to the blacklist, preventing them from sending, receiving, or approving tokens.Can call
removeBlacklistto remove addresses from the blacklist, restoring their ability to transact.Can call
transferBlackFundsto forcibly transfer the entire token balance of one or more blacklisted addresses to a specified non-blacklisted recipient.Can call
transferOwnershipto transfer the owner role to a new address. The new owner must not be blacklisted.Ownership renunciation is disabled; calling
renounceOwnershipalways reverts withRenounceNotAllowed.
Potential Risks
Fixed Total Supply Post-Deployment: The entire supply of MarscatToken (1,000,000,000 MCAT) is minted to a single address provided as the mintTo_ constructor parameter during deployment. Because both the recipient address and total supply are determined by the deployment transaction, they cannot be independently verified by stakeholders beforehand.
Arbitrary Signer Rotation for Points Authorization: The setSigner function in MarscatPoints allows the owner to replace the EIP-712 signer address at any time with any non-zero address, without timelock. Since the signer authorizes every point issuance via claimPoints, a compromised or maliciously rotated signer key could be used to issue arbitrary point balances to any address.
Unrestricted State Modification by Owner: Critical operational parameters in MarscatRecharge and MarscatPoints can be modified by the owner without upper-bound constraints, delay, or governance approval. The setPackagePrice and setPackageDuration functions in both contracts allow immediate changes to subscription pricing and duration, directly affecting the cost and value of user subscriptions.
Absence of Time-lock Mechanisms for Critical Operations: Without time-locks on critical operations, there is no buffer to review or revert potentially harmful actions, increasing the risk of rapid exploitation and irreversible changes.
Forced Execution Without User Consent: The transferBlackFunds function in MarscatToken allows the owner to forcibly transfer the entire token balance of any blacklisted address to an owner-designated recipient without the affected account holder's signature or approval. This operation bypasses the standard _update blacklist validation by invoking super._update directly, enabling unilateral movement of user-held tokens.
Single Points of Failure and Absence of Multi-Signature Control: All four in-scope contracts (MarscatToken, MarscatRecharge, MarscatPoints, MarscatRedPacket) consolidate every privileged operation under a single Ownable owner role with no role separation or on-chain multi-signature enforcement. Compromise of any owner key would grant full administrative control over that contract, including pausing, parameter modification, and, where applicable, fund withdrawal and forced token transfers. MarscatToken further enforces perpetual owner dependency by reverting in its renounceOwnership override, ensuring the contract can never become ownerless. The safety of private key storage for privileged addresses cannot be verified during a smart contract audit.
Points Issuance Dependency on Off-Chain Signer: The claimPoints function in MarscatPoints requires a valid EIP-712 signature produced by the off-chain signer address for every point claim. If the off-chain signing service becomes unavailable or the signer key is lost, no new points can be claimed, preventing users from accumulating balances required to call rechargeWithPoints for subscription purchases.
Red Packet Claim Dependency on Off-Chain Key Distribution: The claimRedPacket function in MarscatRedPacket requires a cryptographic signature produced by the claimKey address stored in each red packet. Distribution of claim keys to intended recipients occurs entirely off-chain, and if the off-chain delivery mechanism fails or the claim key is lost, deposited funds remain locked in the contract until the 24-hour revocation window in revokeRedPacket becomes available to the original sender.
Fee-on-Transfer Tokens May Cause Underpaid Recharges: The recharge() function in MarscatRecharge grants a subscription based on the configured package price without verifying the amount actually received. Although only USDT is intended to be supported, this restriction is not enforced on-chain. If the owner approves a fee-on-transfer token, users may receive the full subscription while the contract receives less than the intended price.
Findings
Code ― | Title | Status | Severity | |
|---|---|---|---|---|
| F-2026-1790 | Fee-on-Transfer Token Accounting in createRedPacket Results in Contract Insolvency | fixed | Medium | |
| F-2026-1790 | Owner Can Front-Run Recharge Transactions via Unbounded Price Modification | fixed | Low | |
| F-2026-1790 | Dual Subscription State Tracking Across Contracts Can Cause Subscription Time Loss or Inconsistent Enforcement | accepted | Low | |
| F-2026-1790 | Missing Domain Binding in _verifyClaimSignature Enables Cross-Instance Signature Replay | fixed | Low | |
| F-2026-1790 | Blacklisted Spender With Infinite Allowance Can Execute transferFrom | fixed | Low | |
| F-2026-1790 | Missing Event Emission on Signer Initialization | fixed | Observation | |
| F-2026-1790 | Lack of Dedicated Event Emission for Token Withdrawal Operation | fixed | Observation | |
| F-2026-1790 | Inconsistent Expiration Boundary Check Across Contracts | fixed | Observation | |
| F-2026-1790 | Revert Statements Inside Loops Cause Entire Batch Operations to Fail | accepted | Observation | |
| F-2026-1790 | Redundant Storage Read for Owner Address Inside Loop in addBlacklist | fixed | Observation |
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 | |
|---|---|
| Repository Part 1 | https://github.com/MarscatTech/Social-Contracts→ |
| Commit | ddf440059a9317439918326fbe505343962ae5b2 |
| Final Commit | 32572f45109729ae84ea05be8d8493331d496ecb |
| Repository Part 2 | https://github.com/MarscatTech/Recharge-Contracts→ |
| Commit | a99bc59c7c24259764da816bc6e24ce87e4cfe06 |
| Final Commit | 53c9dec82a676dbc348667549fb7053d025ed1d8 |
| Repository Part 3 | https://github.com/MarscatTech/Marscat-Token-Contracts→ |
| Commit | a3fa9edd5693bf7ec341c42e444fd9e31532992d |
| Final Commit | 2267a801daf9d9232cf3a2e2cda6879958e90a4b |
| Whitepaper | - |
| Requirements | README.md |
| Technical Requirements | README.md |
Scope Details
- Repository Part 1
- https://github.com/MarscatTech/Social-Contracts→
- Commit
- ddf440059a9317439918326fbe505343962ae5b2
- Final Commit
- 32572f45109729ae84ea05be8d8493331d496ecb
- Repository Part 2
- https://github.com/MarscatTech/Recharge-Contracts→
- Commit
- a99bc59c7c24259764da816bc6e24ce87e4cfe06
- Final Commit
- 53c9dec82a676dbc348667549fb7053d025ed1d8
- Repository Part 3
- https://github.com/MarscatTech/Marscat-Token-Contracts→
- Commit
- a3fa9edd5693bf7ec341c42e444fd9e31532992d
- Final Commit
- 2267a801daf9d9232cf3a2e2cda6879958e90a4b
- Whitepaper
- -
- Requirements
- README.md
- Technical Requirements
- README.md
Assets in Scope
Appendix 3. Additional Valuables
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.
Frameworks and Methodologies
This security assessment was conducted in alignment with recognised penetration testing standards, methodologies and guidelines, including the NIST SP 800-115 – Technical Guide to Information Security Testing and Assessment →, and the Penetration Testing Execution Standard (PTES) →, These assets provide a structured foundation for planning, executing, and documenting technical evaluations such as vulnerability assessments, exploitation activities, and security code reviews. Hacken’s internal penetration testing methodology extends these principles to Web2 and Web3 environments to ensure consistency, repeatability, and verifiable outcomes.