Skip to content

Dashboard Analysis

DISCLAIMER

This analysis examines the reconstructed Sentinel dashboard JavaScript code as it existed on January 25, 2026. We document what we observed in the code—nothing more. The findings about simulated claim functionality and unverified registration flows should not be considered accusations of wrongdoing. Dashboard functionality may have changed since this analysis, and there are legitimate reasons to use placeholder implementations during active development. This analysis presents observable facts about code behavior at a specific point in time.

⊙ generated by robots | curated by humans

Analysis Date: January 25, 2026


Overview

This document details the reconstruction and analysis of the Sentinel Dashboard HTML and JavaScript code. The dashboard source code was extracted, deobfuscated, formatted, and combined into single files for analysis purposes.

Source:

Reconstructed Files:

Javascript File Statistics:

  • Total Lines: 136,931
  • File Size: 4.6 MB
  • Chunks Combined: 34 JavaScript files (from chunks.txt)
  • Format: Properly formatted with Prettier

Contract Addresses Identified

The following smart contract addresses were identified hardcoded in the dashboard application:

CONTRACT ADDRESS VARIABLE DESCRIPTION
SENT Token 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 Main SENT ERC-20 token contract
Hive Registry 0x93Ad33AC2d4cbA339389F42D9345Db3B34174c9E L Participant registration and tracking system
Claim Rewards 0x33184cD3E5F9D27C6E102Da6BE33e779528A606D G Token allocation claim contract
Token Allocation 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd Q Allocation tracking contract

All four contracts have been previously analyzed in the Research Timeline section.


Dashboard Features

Hive Registry Contract

Address: 0x93Ad33AC2d4cbA339389F42D9345Db3B34174c9E
JavaScript Variable: L

The Hive Registry provides participant registration and tracking functionality.

Functions Exposed:

  • register() - Register wallet as participant
  • registerPresaleBuyer(address) - Admin function to register presale buyer
  • batchRegisterPresaleBuyers(address[]) - Admin function to batch register buyers
  • reregister() - Re-register after disqualification
  • getParticipant(address) - Retrieve participant details

Return Values (getParticipant):

  • registeredAmount (uint256) - Amount of SENT tokens registered
  • registrationTime (uint256) - Timestamp of registration
  • isActive (bool) - Active participation status
  • isPresaleBuyer (bool) - Presale buyer flag
  • disqualificationTime (uint256) - Timestamp of disqualification
  • disqualificationReason (string) - Reason for disqualification
  • currentBalance (uint256) - Current SENT balance
  • disqualificationCount (uint256) - Number of times disqualified
  • totalTokensSold (uint256) - Total tokens sold to this participant

Claim Rewards Contract

Address: 0x33184cD3E5F9D27C6E102Da6BE33e779528A606D
JavaScript Variable: G

The Claim Rewards contract manages allocation claims for eligible addresses.

Functions Exposed:

  • claim() - Claim allocated tokens
  • hasClaimed(address) - Check if address has already claimed
  • isVisible() - Check if claiming interface is visible/active
  • paused() - Check if contract is paused

Events Monitored:

  • ClaimStatusReset(address indexed account, bool newStatus) - Claim status reset by admin
  • FlexibleAllocationUpdated(address indexed oldAddress, address indexed newAddress) - Allocation contract updated
  • OwnershipTransferred(address indexed previousOwner, address indexed newOwner) - Ownership transferred
  • Paused(address indexed by) - Contract paused

Token Allocation Contract

Address: 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd
JavaScript Variable: Q

The Token Allocation contract tracks allocation amounts for addresses.

Functions Exposed:

  • getAllocation(address) - Returns allocation amount for given address

Technical Stack

The dashboard is built using modern Web3 technologies:

Frontend Framework:

  • Next.js (with Turbopack bundler)
  • React 19.3.0-canary

Blockchain Interaction:

  • Viem v2.39.0 (Ethereum TypeScript library)
  • Wagmi (React Hooks for Ethereum)

Key Features:

  • Real-time contract state polling (30-second intervals)
  • Multi-wallet connection support
  • Transaction confirmation waiting
  • Pool share calculations for Swarm members
  • Member rewards tracking based on pool percentage

Dashboard User Flows

Registration Flow

VERIFICATION NEEDED

The registration flow requires further verification. While the dashboard includes writeContract hooks and the Hive Registry ABI defines a register() function, the actual button click handler that would initiate registration could not be definitively located in the reconstructed code. The minified variable names (functions d and b for writeContract instances) make tracing the exact flow difficult without runtime debugging.

Expected flow (if functional):

  1. User connects wallet
  2. Dashboard checks SENT token balance via balanceOf()
  3. Dashboard checks registration status via isRegistered() on Hive Registry
  4. User clicks "Register" button
  5. If implemented: Dashboard calls register() on Hive Registry contract (0x93Ad33AC2d4cbA339389F42D9345Db3B34174c9E)
  6. Transaction confirmed via wallet
  7. Dashboard refetches participant data via getParticipant()

Confirmed real on-chain reads:

  • isRegistered(address) - Checks if wallet is registered
  • getGlobalStats() - Returns total registered members count
  • getAllActiveParticipants() - Returns list of active participants
  • getParticipant(address) - Returns detailed participant information

Defined but unverified writes:

  • register() - User registration function (exists in ABI, call site not confirmed)
  • reregister() - Re-registration after disqualification (exists in ABI)

Claim Flow

SIMULATED CLAIM FUNCTION

The "Claim Rewards" button on the dashboard does NOT call the Claim Rewards contract. The click handler is a simulated function that only updates browser localStorage. No blockchain transaction is initiated.

NOTE TO DEVELOPERS

The simulated claim function creates a convincing illusion of a blockchain transaction: it shows a 2-second delay (mimicking network confirmation time), updates the UI to a "claimed" state, and persists this state in localStorage across page reloads. Users have no indication this is a simulation—they see exactly what they would expect from a real transaction. Consider:

  • Replacing the localStorage simulation with actual contract integration, OR
  • Disabling the claim button entirely with clear messaging ("Integration pending"), OR
  • Adding obvious visual indicators that this is test/demo functionality

The current implementation—a fully functional-appearing button that does nothing on-chain—risks serious user confusion and trust damage.

What the dashboard checks (real on-chain reads):

  1. User connects wallet
  2. Dashboard checks allocation via getAllocation() on Token Allocation contract
  3. Dashboard checks claim status via hasClaimed() on Claim Rewards contract
  4. Dashboard checks if claiming is active via isVisible() and paused()

What happens when user clicks "Claim" (simulated client-side):

  1. User clicks "Claim" button
  2. Dashboard function td() executes:
    • Waits 2 seconds (simulating transaction delay)
    • Sets claim timestamp in localStorage: sentinel_lastClaim_{address}
    • Resets accumulated reward counter to 0
    • Updates UI to show "claimed" state
  3. No contract call is made
  4. No blockchain transaction occurs
  5. Next page load, localStorage data persists the "claimed" state

Code reference:

// From reconstructed JS (lines 94149-94167)
let td = async () => {
  if (t && e && !(t_ <= 0)) {
    tI(!0);  // Set claiming state to true
    try {
      await new Promise((e) => setTimeout(e, 2e3));  // Wait 2 seconds
      let t = new Date();
      t$(t);  // Update claim timestamp
      tk(0);  // Reset accumulated rewards to 0
      localStorage.setItem(
        `sentinel_lastClaim_${e}`,  // Store in browser localStorage
        t.toISOString(),
      );
    } catch (e) {
      console.error("Error claiming rewards:", e);
    } finally {
      tI(!1);  // Set claiming state back to false
    }
  }
};

The actual Claim Rewards contract (0x33184cD3E5F9D27C6E102Da6BE33e779528A606D) has a claim() function that is defined in the ABI but never called by the dashboard code.

Swarm Pool Share Display

MIXED REAL AND SIMULATED DATA

The Swarm Pool Share display combines real on-chain data (member balances, pool share percentages) with simulated reward calculations (weekly profit, reward pool). Users see their actual token holdings alongside estimated rewards derived from hardcoded values and sine wave formulas—not real trading performance. There is no visual distinction between real and simulated values.

NOTE TO DEVELOPERS

The Swarm Pool Share display combines real blockchain data with simulated reward values, which may confuse users about what they're actually seeing. Consider:

  • Adding visual distinction between on-chain data (member list, balances, pool share %) and simulated data (reward pool, estimated rewards)
  • Including tooltips or labels indicating data source: "From blockchain" vs "Estimated (simulated)"
  • Replacing getSwarmProtocolProfit() and getSwarmWeeklyRewardPool() with actual on-chain profit tracking when available
  • If the Day Percent Manager contract is intended to provide real profit data, integrate it and remove the hardcoded $20,000 weekly target

Users seeing their real token balance alongside simulated reward estimates may reasonably assume both values reflect actual protocol state.

Real on-chain data:

  1. Dashboard calls getGlobalStats() on Hive Registry to get total/active member counts
  2. Dashboard calls getAllActiveParticipants() on Hive Registry to get:
    • Member addresses (real)
    • Registered amounts (real)
    • Current SENT balances (real)
  3. For connected wallet, calculates poolShare using real balance data:
    • If circulating supply mechanics active: (userBalance / circulatingSupply) * 100
    • Otherwise: (userBalance / totalPoolBalance) * 100

Simulated data:

  1. getSwarmProtocolProfit() returns a simulated weekly profit using:
    • Hardcoded weeklyTarget: $20,000
    • Sine wave calculation based on elapsed time from 2026-01-20T01:00:00Z
    • Same simulation logic used on the /swarm dashboard
  2. getSwarmWeeklyRewardPool() returns getSwarmProtocolProfit() * 0.2 (20% of simulated profit)

Mixed calculation:

  1. estimatedReward = (poolShare / 100) * getSwarmWeeklyRewardPool()
    • Real pool share percentage × Simulated reward pool = Simulated reward estimate

The member list, balances, and pool share percentages are real on-chain data. However, the reward pool and estimated rewards are derived from the same client-side simulation used on the /swarm page. See Swarm Dashboard Analysis and Jan 18-24 Rewards Analysis for detailed analysis of the simulation logic.


Reconstruction Methodology

Extraction Process

  1. Source Download: Dashboard page saved from https://sentinelox.com/dashboard
  2. Chunk Identification: 34 individual JavaScript chunks identified from Turbopack bundle (listed in chunks.txt)
  3. Deobfuscation: All chunks formatted with Prettier for human readability
  4. Reformatting: Files with extremely long lines (up to 212k characters) were properly reformatted
  5. Combination: Only chunks listed in chunks.txt combined into single file with clear section markers
  6. Documentation: Header added with metadata and contract address summary

Tools Used

  • Prettier - JavaScript code formatting
  • grep/awk/sed - Text extraction and analysis
  • Manual Analysis - Contract address identification and ABI extraction

File Structure

The reconstructed file contains clearly marked sections for each chunk:

// ============================================================================
// CHUNK: [filename].js
// ============================================================================

Each chunk preserves its original formatting and code structure after Prettier formatting.


Security Observations

Hardcoded Contract Addresses

All contract addresses are hardcoded directly into the JavaScript bundle. This is standard practice but means:

  • ☑ No ability for users to verify contract addresses before interaction
  • ☑ Contract upgrades would require redeployment of dashboard code
  • ☑ Addresses could be spoofed via DNS/hosting compromise
  • ◇ Users should independently verify contract addresses before approving transactions

Transaction Approval UX

The dashboard uses standard Web3 wallet approval flows:

  • ☑ Users see transaction details in wallet before signing
  • ☑ Contract addresses visible in wallet approval screen
  • ◇ No additional on-screen warnings about contract permissions

API Endpoints

The reconstructed code does not contain external API endpoints for:

  • Swarm member list retrieval
  • Pool share calculations
  • Reward distribution data

This suggests these operations may be:

  • Server-side rendered during page load
  • Fetched via obfuscated or environment-based configuration
  • Embedded directly in the initial HTML payload


Change Log

DATE AUTHOR NOTES
2026-01-25 Artificial. Reconstructed and analyzed dashboard JavaScript. Gas: 85 tok
2026-01-25 Denizen. Reviewed, edited, and curated by humans.