SCADA Info
Supply Block is SCADA's core innovation — a function that, when triggered, removes a portion of the bonus liquidity SCADA farms from trading and splits the retrieved tokens: 90% of SCADA is permanently burned, reducing total supply forever. The remaining portion is distributed as rewards to stakers and the caller who executed the block. Meanwhile, the paired WPLS is used to market-buy SCADA, creating upward price pressure. This process strengthens the liquidity floor while continuously shrinking the circulating supply — a self-reinforcing cycle that rewards holders over time.
TrustNet Score
The TrustNet Score evaluates crypto projects based on audit results, security, KYC verification, and social media presence. This score offers a quick, transparent view of a project's credibility, helping users make informed decisions in the Web3 space.
Real-Time Threat Detection
Real-time threat detection, powered by Cyvers.io,
is currently not
activated
for this project.
This advanced feature provides continuous monitoring and instant alerts to safeguard your assets from potential security threats. Real-time detection enhances your project's security by proactively identifying and mitigating risks.
For more information, click here.
Security Assessments
Summary and Final Words
No crucial issues found
The contract does not contain issues of high or medium criticality. This means that no known vulnerabilities were found in the source code.
Contract owner cannot mint
It is not possible to mint new tokens.
Contract owner cannot blacklist addresses.
It is not possible to lock user funds by blacklisting addresses.
Contract owner cannot set high fees
The fees, if applicable, can be a maximum of 25% or lower. The contract can therefore not be locked. Please take a look in the comment section for more details.
Contract cannot be locked
Owner cannot lock any user funds.
Token cannot be burned
There is no burning within the contract without any allowances
Ownership is renounced
The contract does not include owner functions that allow post-deployment modifications.
Contract is not upgradeable
The contract does not use proxy patterns or other mechanisms to allow future upgrades. Its behavior is locked in its current state.
Scope of Work
This audit encompasses the evaluation of the files listed below, each verified with a SHA-1 Hash. The team referenced above has provided the necessary files for assessment.
The auditing process consists of the following systematic steps:
- Specification Review: Analyze the provided specifications, source code, and instructions to fully understand the smart contract's size, scope, and functionality.
- Manual Code Examination: Conduct a thorough line-by-line review of the source code to identify potential vulnerabilities and areas for improvement.
- Specification Alignment: Ensure that the code accurately implements the provided specifications and intended functionalities.
- Test Coverage Assessment: Evaluate the extent and effectiveness of test cases in covering the codebase, identifying any gaps in testing.
- Symbolic Execution: Analyze the smart contract to determine how various inputs affect execution paths, identifying potential edge cases and vulnerabilities.
- Best Practices Evaluation: Assess the smart contracts against established industry and academic best practices to enhance efficiency, maintainability, and security.
- Actionable Recommendations: Provide detailed, specific, and actionable steps to secure and optimize the smart contracts.
A file with a different Hash has been intentionally or otherwise modified after the security review. A different Hash may indicate a changed condition or potential vulnerability that was not within the scope of this review.
Final Words
The following provides a concise summary of the audit report, accompanied by insightful comments from the auditor. This overview captures the key findings and observations, offering valuable context and clarity.
Smart Contract Analysis Statement
Contract Analysis
The SCADAMiner contract implements a multi-pool staking and reward distribution system for SCADA. Users deposit whitelisted tokens to earn shares, and SCADA rewards are streamed in only by the SCADAManager during supplyBlock, using a standard accumulator pattern with 1e18 precision. The contract is deployed and immutable, and Ownable owner has been renounced on-chain (miner.owner() returns address(0), verified via transaction 0x79df41...). The team has acknowledged each finding below and provided on-chain mitigations. Residual concerns are summarized as follows:
- distributeRewards reverts when the miner has zero shares. Mitigated on the live deployment by a renounced helper contract (MinerSeeder) that has pre-staked a non-zero position into the miner and itself renounced ownership, so the seeded shares cannot be unilaterally withdrawn and totalShares is permanently greater than zero. The original bricking scenario is no longer reachable; severity downgraded to Low. The defense-in-depth fallback inside distributeRewards is recommended for any future redeployment so the liveness guarantee does not depend on an external seeder contract.
- distributeRewards trusts the manager-supplied reward amount instead of measuring the actual SCADA balance delta. SCADA reverts on failure and unconditionally returns true on success, the SCADA reference is immutable inside SCADAManager, and the manager is fee-exempt on SCADA so its transfers are never taxed. The threat model the finding describes is unreachable on the deployed system; severity downgraded to Low.
- The deposit and withdraw functions update state after the external token transfers. With miner ownership renounced, addPool is permanently uncallable and the pool whitelist is frozen; none of the currently-allowed pool tokens implement ERC-777 hooks or transfer callbacks, so the cross-function reentrancy vector is not reachable. The nonReentrant modifier blocks same-function reentry as a second line of defense; severity downgraded to Low. The CEI ordering correction is recommended for any future redeployment.
Ownership Privileges
The ownership of the contract has been renounced (miner.owner() returns address(0), verified on-chain via transaction 0x79df41...). All pool configuration and parameter setters are now permanently uncallable. The fee recipient role is stored as immutable and remains the only privileged actor. The owner retains full privileges including:
- Owner role (now closed) could addPool, updatePool (rate and active flag), setMinDeposit, and setExitFee
- The immutable feeRecipient can call collectFees to withdraw accumulated exit fees per pool
- Cannot deposit, withdraw, or reassign user shares
- Cannot raise the exit fee above the 10% hardcoded cap
- Cannot mint SCADA - rewards come exclusively from the supplyBlock cycle
- Cannot move or freeze user deposits
- Cannot redirect reward distribution to anyone other than the share holders
- Cannot reconfigure pools after renouncement, including the share-per-token rate
Security Features
The contract implements several positive security features:
- The SCADAToken, SCADAManager, and feeRecipient references are stored as immutable, so they cannot be changed for the lifetime of the contract.
- ReentrancyGuard on every user-facing function (deposit, withdraw, claimRewards, distributeRewards).
- Hardcoded exit-fee cap of 10% and a dummy pool at index 0 that makes pool ID 0 invalid by design.
- Owner ownership renounced on-chain, freezing pool configuration permanently for the deployed instance.
Note - This Audit report consists of a security analysis of the SCADAMiner smart contract. This analysis did not include economic analysis of the contract's tokenomics. Moreover, we only audited the main contract for the SCADAMiner team. Other contracts associated with the project were audited separately by our team. We recommend investors do their own research before investing.
Files and details
Functions
public
/
State variables
public
/
Total lines
of code
/
Capabilities
Hover on items
/
Findings and Audit result
low Issues | 7 findings
Acknowledged
#1 low Issue
No staking duration enables sandwich attack on supplyBlock rewards
There is no minimum staking duration. An attacker can watch the mempool for an imminent supplyBlock call, front-run with a large deposit, capture a pro-rata share of the reward distribution, and immediately withdraw - paying only the 2% exit fee. Honest stakers see their yield diluted on every supplyBlock.
Acknowledged
#2 low Issue
Several admin and fee functions emit no events
setMinDeposit, setExitFee, and collectFees mutate state without emitting events. This makes monitoring fee changes and fee withdrawals harder for off-chain dashboards.
Acknowledged
#3 low Issue
Solidity 0.8.20 has known issues - prefer a newer patch version
Solidity 0.8.20 contains three documented compiler issues. None apply to this codebase, but using the most recent patched compiler is the recommended posture for new deployments.
Acknowledged
#4 low Issue
updatePool can change sharesPerToken arbitrarily (mitigated for deployed instance by ownership renouncement)
updatePool has no bounds on sharesPerToken. Pre-renouncement, the owner could set the rate to zero (bricking deposits) or to an extremely high value (allowing the next depositor to mint astronomical shares and capture all subsequent rewards). Existing depositors are unaffected because their shares are stored at deposit time, but new depositors were exposed during the deployment window.
Acknowledged
#5 low Issue
supplyBlock reverts when the miner has zero shares - permanent liveness DoS until someone stakes (downgraded from H-01)
SCADAMiner.distributeRewards reverts with require(totalShares > 0, "No shares"). SCADAManager.supplyBlock calls distributeRewards directly, without any try/catch wrapper, when sharePoolReward > 0. If no one has staked into the miner, every permissionless supplyBlock call reverts and the deflationary engine is fully bricked. Combined with the fact that supplyBlock is the only path to burn SCADA on Ethereum after deployment, a zero-shares window would freeze the protocol's deflationary mechanics indefinitely.
Acknowledged
#6 low Issue
deposit and withdraw write state after external calls (CEI violation) (downgraded from M-01)
Both deposit and withdraw mutate user-pool, per-user, and per-pool state after calling _claimPending and the pool token's safeTransferFrom or safeTransfer. The nonReentrant guard prevents same-function reentrancy but cross-function reentrancy is theoretically possible if the pool token implements ERC-777 hooks or fallback callbacks. Today the deployed configuration has no such tokens (and ownership is renounced, freezing the set), but the pattern is fragile against any future redeployment.
Acknowledged
#7 low Issue
distributeRewards does not verify that SCADA was actually transferred in (downgraded from M-03)
distributeRewards blindly increments accRewardPerShare based on rewardAmount, without checking that scadaToken.balanceOf(address(this)) actually grew. The caller (SCADAManager) is supposed to transfer SCADA in the same transaction, but if that upstream transfer ever silently fails (return false) or if SCADA were to ever tax the manager (impossible today, but a single configuration change away), the miner credits rewards it does not hold. Users would then accrue pending rewards that the miner cannot pay out, causing _claimPending to revert and locking stakers out.
optimization Issues | 1 findings
Pending
#1 optimization Issue
onlyManager modifier is invoked exactly once
The onlyManager modifier is used only by distributeRewards. Single-use modifiers add unnecessary indirection and a small gas overhead.
informational Issues | 5 findings
Pending
#1 informational Issue
Local ISCADAToken interface duplicates the canonical one
SCADAMiner.sol declares its own minimal 'interface ISCADAToken' with transfer and balanceOf. The same interface name is also defined in src/interfaces/ISCADAToken.sol with a wider surface. The local declaration is a strict subset, but the duplication causes an interface-name collision and makes signature drift possible.
Pending
#2 informational Issue
Contract does not formally inherit from its declared interface
SCADAManager declares a local ISCADAMiner interface with distributeRewards, but SCADAMiner does not inherit from any interface. The compiler cannot verify that the miner's public surface matches what consumers expect.
Pending
#3 informational Issue
Function parameters use leading-underscore naming instead of mixedCase
Several function parameters use leading underscores, deviating from the Solidity style guide's mixedCase convention. Pure style.
Pending
#4 informational Issue
Local struct field 'totalShares' shadows the contract-level totalShares state variable
Both UserInfo and TokenPool define a field named 'totalShares', which shadows the contract-level state variable of the same name. The compiler does not flag this as an error but readers and tooling can be misled by the naming overlap.
Pending
#5 informational Issue
Solidity 0.8.20 has known issues - prefer a newer patch version
Solidity 0.8.20 contains three documented compiler issues. None apply to this codebase, but the most recent patched compiler is preferred for new deployments.