:root {
--bg: #0b0f1a;
--surface: #111827;
--card: #161d2e;
--border: #1e2d45;
--accent: #00c896;
--accent2: #0ea5e9;
--gold: #f59e0b;
--danger: #ef4444;
--text: #e2e8f0;
--muted: #64748b;
--dim: #94a3b8;
--radius: 12px;
--radius-sm: 8px;
--sidebar-w: 230px;
--header-h: 60px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
background: var(--bg);
color: var(--text);
font-family: 'Inter', sans-serif;
font-size: 14px;
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* ── HEADER ── */
header {
height: var(--header-h);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
background: var(--surface);
border-bottom: 1px solid var(--border);
position: fixed;
top: 0; left: 0; right: 0;
z-index: 200;
}
.header-left { display: flex; align-items: center; gap: 12px; }
.hamburger {
display: none;
flex-direction: column;
gap: 5px;
cursor: pointer;
padding: 6px;
border-radius: 6px;
border: none;
background: transparent;
}
.hamburger span { display: block; width: 20px; height: 2px; background: var(--dim); border-radius: 2px; transition: all .2s; }
.logo {
font-family: 'Space Grotesk', sans-serif;
font-size: 18px; font-weight: 700;
color: var(--accent); letter-spacing: -0.5px; text-decoration: none;
}
.logo span { color: var(--text); }
.logo small { font-size: 10px; color: var(--muted); font-weight: 400; margin-left: 4px; }
.sa-badge {
background: rgba(245,158,11,.12);
border: 1px solid rgba(245,158,11,.35);
color: var(--gold);
font-size: 10px; font-weight: 700;
padding: 3px 9px; border-radius: 6px;
letter-spacing: .5px; text-transform: uppercase;
}
.header-right { display: flex; align-items: center; gap: 10px; }
.wallet-badge {
background: var(--card); border: 1px solid var(--border);
border-radius: 8px; padding: 6px 12px;
font-size: 12px; color: var(--dim);
font-family: 'Space Grotesk', monospace; white-space: nowrap;
}
.wallet-badge span { color: var(--accent); font-weight: 600; }
.btn-connect {
background: var(--gold); color: #000;
font-weight: 700; font-size: 13px;
border: none; border-radius: var(--radius-sm);
padding: 8px 16px; cursor: pointer;
transition: opacity .15s; white-space: nowrap;
}
.btn-connect:hover { opacity: .85; }
.btn-disconnect {
background: rgba(239,68,68,.08); color: var(--danger);
font-weight: 700; font-size: 12px;
border: 1px solid rgba(239,68,68,.35);
border-radius: var(--radius-sm); padding: 7px 13px;
cursor: pointer; transition: all .15s; white-space: nowrap;
display: none; align-items: center; gap: 5px;
}
.btn-disconnect:hover { background: rgba(239,68,68,.22); border-color: var(--danger); color:#fff; }
.status-dot {
width: 8px; height: 8px; border-radius: 50%;
background: var(--accent); display: inline-block;
margin-right: 5px; animation: pulse 2s infinite;
}
@keyframes pulse { 0%,100%{opacity:1}50%{opacity:.4} }
/* ── APP SHELL ── */
.app-shell { display: flex; padding-top: var(--header-h); min-height: 100vh; }
/* ── SIDEBAR ── */
.sidebar {
width: var(--sidebar-w); background: var(--surface);
border-right: 1px solid var(--border);
position: fixed; top: var(--header-h); bottom: 0; left: 0;
overflow-y: auto; z-index: 150;
display: flex; flex-direction: column;
transition: transform .25s ease;
}
.sidebar-overlay {
display: none; position: fixed; inset: 0;
background: rgba(0,0,0,.6); z-index: 140;
}
.sidebar-nav { padding: 12px 8px; flex: 1; }
.nav-section-label {
font-size: 9px; font-weight: 700;
letter-spacing: 1.5px; text-transform: uppercase;
color: var(--muted); padding: 8px 12px 4px;
}
.nav-item {
display: flex; align-items: center; gap: 10px;
padding: 10px 12px; border-radius: var(--radius-sm);
color: var(--muted); font-size: 13px; font-weight: 500;
cursor: pointer; transition: all .15s;
border: none; background: transparent;
width: 100%; text-align: left; margin-bottom: 2px;
}
.nav-item:hover { background: var(--card); color: var(--dim); }
.nav-item.active {
background: rgba(245,158,11,.1); color: var(--gold);
border: 1px solid rgba(245,158,11,.2);
}
.nav-item .nav-icon { font-size: 16px; width: 20px; text-align: center; flex-shrink: 0; }
.sidebar-footer {
padding: 12px; border-top: 1px solid var(--border);
font-size: 11px; color: var(--muted);
}
.chain-pill {
display: flex; align-items: center; gap: 6px;
background: var(--card); border: 1px solid var(--border);
border-radius: 6px; padding: 6px 10px;
font-size: 11px; color: var(--dim);
}
.chain-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gold); flex-shrink: 0; }
.sidebar-disconnect {
display: none; width: calc(100% - 16px); margin: 0 8px 8px;
padding: 9px 12px;
background: rgba(239,68,68,.08); color: var(--danger);
font-weight: 700; font-size: 12px;
border: 1px solid rgba(239,68,68,.25); border-radius: var(--radius-sm);
cursor: pointer; transition: all .15s; text-align: left;
align-items: center; gap: 8px;
}
.sidebar-disconnect:hover { background: rgba(239,68,68,.18); border-color: var(--danger); }
/* ── MAIN CONTENT ── */
.main-content { margin-left: var(--sidebar-w); flex: 1; min-width: 0; }
.page { display: none; padding: 24px; max-width: 1100px; }
.page.active { display: block; }
.page-title { font-family: 'Space Grotesk', sans-serif; font-size: 20px; font-weight: 700; margin-bottom: 6px; }
.page-subtitle { font-size: 12px; color: var(--muted); margin-bottom: 20px; }
/* ── NOTICE BAR ── */
.notice-bar {
background: rgba(245,158,11,.06); border: 1px solid rgba(245,158,11,.2);
border-radius: var(--radius-sm); padding: 10px 14px;
font-size: 11px; color: var(--muted);
display: flex; align-items: flex-start; gap: 10px; margin-bottom: 20px;
}
.notice-bar .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gold); flex-shrink: 0; margin-top: 3px; }
/* ── GRIDS ── */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
/* ── SECTION LABEL ── */
.section-label {
font-size: 11px; font-weight: 600; letter-spacing: 1.5px;
text-transform: uppercase; color: var(--muted);
margin-bottom: 12px; display: flex; align-items: center; gap: 8px;
}
.section-label::after { content: ''; flex: 1; height: 1px; background: var(--border); }
/* ── CARDS ── */
.card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; }
.card-title { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 6px; }
.card-value { font-family: 'Space Grotesk', sans-serif; font-size: 24px; font-weight: 700; color: var(--text); line-height: 1.1; }
.card-value.accent { color: var(--accent); }
.card-value.gold { color: var(--gold); }
.card-value.blue { color: var(--accent2); }
.card-value.danger { color: var(--danger); }
.card-sub { font-size: 12px; color: var(--muted); margin-top: 4px; }
/* ── SOLVENCY METER ── */
.solvency-bar { height: 6px; background: var(--border); border-radius: 3px; overflow: hidden; margin-top: 6px; }
.solvency-fill { height: 100%; border-radius: 3px; transition: width .6s ease; }
/* ── INPUTS ── */
.input-group { margin-bottom: 12px; }
.input-label {
font-size: 11px; font-weight: 600; letter-spacing: .5px;
color: var(--muted); margin-bottom: 6px; display: block;
}
.input-wrap { position: relative; }
input[type="text"], input[type="number"], textarea, select {
width: 100%;
background: var(--bg); border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 10px 12px; color: var(--text);
font-family: 'Space Grotesk', sans-serif; font-size: 14px;
outline: none; transition: border-color .15s;
}
input:focus, textarea:focus, select:focus { border-color: var(--gold); }
.input-hint { font-size: 11px; color: var(--muted); margin-top: 5px; }
/* ── BUTTONS ── */
.btn {
width: 100%; padding: 11px; border: none;
border-radius: var(--radius-sm); font-weight: 700; font-size: 13px;
cursor: pointer; transition: opacity .15s, transform .08s;
font-family: 'Inter', sans-serif; letter-spacing: .3px;
}
.btn:hover { opacity: .85; }
.btn:active { transform: scale(.98); }
.btn-primary { background: var(--accent); color: #000; }
.btn-blue { background: var(--accent2); color: #fff; }
.btn-gold { background: var(--gold); color: #000; }
.btn-danger { background: var(--danger); color: #fff; }
.btn-outline { background: transparent; border: 1px solid var(--border); color: var(--dim); }
.btn-sm {
padding: 8px 16px; font-size: 12px; font-weight: 700;
border: none; border-radius: var(--radius-sm);
cursor: pointer; transition: opacity .15s; white-space: nowrap;
}
.btn-sm:hover { opacity: .85; }
/* ── TX ROW ── */
.tx-row {
display: grid;
grid-template-columns: 36px 1fr 120px 90px;
align-items: center; gap: 12px;
padding: 10px 16px;
border-bottom: 1px solid rgba(30,45,69,.6);
transition: background .1s;
font-size: 13px;
}
.tx-row:hover { background: rgba(255,255,255,.02); }
.tx-row:last-child { border-bottom: none; }
.tx-icon { width: 34px; height: 34px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 14px; flex-shrink: 0; }
.tx-info .tx-type { font-weight: 600; font-size: 13px; color: var(--text); }
.tx-info .tx-meta { font-size: 11px; color: var(--muted); margin-top: 1px; font-family: 'Space Grotesk', monospace; }
.tx-amount { font-family: 'Space Grotesk', sans-serif; font-weight: 700; font-size: 14px; text-align: right; }
.tx-amount.pos { color: var(--accent); }
.tx-amount.neg { color: var(--danger); }
.tx-amount.neu { color: var(--dim); }
.tx-time { font-size: 11px; color: var(--muted); text-align: right; font-family: 'Space Grotesk', monospace; }
/* ── TYPE BADGE ── */
.type-badge {
display: inline-flex; align-items: center;
font-size: 9px; font-weight: 700; letter-spacing: .5px;
padding: 2px 7px; border-radius: 4px; text-transform: uppercase;
}
/* ── PASSIVE STAT ── */
.passive-stat-label { font-size: 11px; color: var(--muted); margin-bottom: 3px; }
.passive-stat-value { font-family: 'Space Grotesk', sans-serif; font-weight: 600; font-size: 15px; color: var(--text); }
.passive-stat-value.green { color: var(--accent); }
/* ── REF LEVELS ── */
.ref-levels { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; margin-top: 12px; }
.ref-level-chip { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 8px 6px; text-align: center; }
.ref-level-chip .lvl { font-size: 10px; color: var(--muted); font-weight: 600; }
.ref-level-chip .pct { font-family: 'Space Grotesk', sans-serif; font-weight: 700; font-size: 14px; color: var(--text); }
.ref-level-chip:first-child .pct { color: var(--accent); }
.ref-level-chip:nth-child(2) .pct { color: var(--accent2); }
/* ── ACTION PANEL ── */
.action-panel {
background: var(--card); border: 1px solid var(--border);
border-radius: var(--radius); padding: 20px; margin-bottom: 16px;
}
.action-panel-title {
font-family: 'Space Grotesk', sans-serif; font-size: 15px; font-weight: 600;
margin-bottom: 6px; display: flex; align-items: center; gap: 8px;
}
.action-panel-desc { font-size: 12px; color: var(--muted); margin-bottom: 16px; line-height: 1.6; }
/* ── LOOKUP RESULT ── */
.lookup-field { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 12px 14px; }
.lookup-field-label { font-size: 10px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); margin-bottom: 4px; }
.lookup-field-value { font-family: 'Space Grotesk', sans-serif; font-size: 16px; font-weight: 700; color: var(--text); }
/* ── CONTRACT STATE BADGE ── */
.state-badge {
display: inline-flex; align-items: center; gap: 6px;
font-size: 12px; font-weight: 700;
padding: 5px 12px; border-radius: 20px;
}
.state-active { background: rgba(0,200,150,.12); color: var(--accent); border: 1px solid rgba(0,200,150,.3); }
.state-paused { background: rgba(239,68,68,.12); color: var(--danger); border: 1px solid rgba(239,68,68,.3); }
.state-dot { width: 7px; height: 7px; border-radius: 50%; animation: pulse 2s infinite; }
.state-active .state-dot { background: var(--accent); }
.state-paused .state-dot { background: var(--danger); }
/* ── TOAST ── */
.toast-container { position: fixed; right: 20px; bottom: 20px; z-index: 9999; display: flex; flex-direction: column; gap: 8px; }
.toast {
background: var(--surface); border: 1px solid var(--border);
border-radius: 10px; padding: 12px 16px;
font-size: 13px; color: var(--text);
display: flex; align-items: center; gap: 10px;
min-width: 260px; max-width: 420px;
box-shadow: 0 8px 24px rgba(0,0,0,.4);
animation: slideUp .2s ease;
}
@keyframes slideUp { from{opacity:0;transform:translateY(12px)} to{opacity:1;transform:translateY(0)} }
/* ── UTILS ── */
.mb-4 { margin-bottom: 4px; }
.mb-8 { margin-bottom: 8px; }
.mb-12 { margin-bottom: 12px; }
.mb-16 { margin-bottom: 16px; }
.mb-20 { margin-bottom: 20px; }
.mt-12 { margin-top: 12px; }
.mt-16 { margin-top: 16px; }
.flex { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.font-mono { font-family: 'Space Grotesk', monospace; }
code {
background: var(--surface); border: 1px solid var(--border);
padding: 2px 6px; border-radius: 4px; font-size: 11px;
font-family: 'Space Grotesk', monospace; color: var(--gold);
}
/* ── WALLET MODAL ── */
.wallet-modal-overlay {
display: none; position: fixed; inset: 0;
background: rgba(0,0,0,.7); z-index: 500;
align-items: center; justify-content: center;
}
.wallet-modal-box {
background: var(--surface); border: 1px solid var(--border);
border-radius: 16px; padding: 28px 24px;
width: 360px; max-width: 94vw;
}
.wallet-modal-box h3 { font-family: 'Space Grotesk', sans-serif; font-size: 17px; font-weight: 700; margin-bottom: 6px; }
.modal-sub { font-size: 12px; color: var(--muted); margin-bottom: 20px; }
.wallet-option {
display: flex; align-items: center; gap: 14px; width: 100%;
background: var(--card); border: 1px solid var(--border);
border-radius: var(--radius-sm); padding: 13px 16px;
cursor: pointer; margin-bottom: 8px; transition: border-color .15s, background .15s; text-align: left;
}
.wallet-option:hover { border-color: var(--gold); background: rgba(245,158,11,.04); }
.wallet-option .wo-icon { font-size: 24px; flex-shrink: 0; }
.wallet-option .wo-name { font-family: 'Space Grotesk', sans-serif; font-size: 14px; font-weight: 600; color: var(--text); }
.wallet-option .wo-desc { font-size: 11px; color: var(--muted); margin-top: 1px; }
.wallet-option .wo-badge { margin-left: auto; flex-shrink: 0; font-size: 9px; font-weight: 700; padding: 2px 7px; border-radius: 4px; background: rgba(245,158,11,.15); border: 1px solid rgba(245,158,11,.3); color: var(--gold); }
.wallet-modal-divider { font-size: 10px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); margin: 12px 0 8px; display: flex; align-items: center; gap: 8px; }
.wallet-modal-divider::before, .wallet-modal-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.wallet-modal-close { margin-top: 12px; width: 100%; background: transparent; border: 1px solid var(--border); color: var(--dim); border-radius: var(--radius-sm); padding: 9px; cursor: pointer; font-size: 12px; font-weight: 600; transition: border-color .15s; }
.wallet-modal-close:hover { border-color: var(--muted); }
/* ── RESPONSIVE ── */
@media (max-width: 1024px) { .grid-4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 900px) { .grid-3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 768px) {
:root { --sidebar-w: 240px; }
.hamburger { display: flex; }
.sidebar { transform: translateX(-100%); box-shadow: 4px 0 24px rgba(0,0,0,.4); }
.sidebar.open { transform: translateX(0); }
.sidebar-overlay.open { display: block; }
.main-content { margin-left: 0; }
.page { padding: 16px; }
.grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
.tx-row { grid-template-columns: 36px 1fr 100px; }
.tx-time { display: none; }
.wallet-badge { display: none; }
}
@media (max-width: 480px) {
:root { --header-h: 56px; }
.logo small { display: none; }
.card-value { font-size: 20px; }
.toast-container { right: 12px; bottom: 12px; }
.toast { min-width: 200px; max-width: calc(100vw - 24px); }
}
VantageArb
🛡 SuperAdmin Portal
🔐
Restricted Access
Enter your superAdmin PIN to access
the VantageArb control panel.
👁
🔓 Unlock Portal
🔐
SuperAdmin Access Only
This dashboard is restricted to the superAdmin wallet address.
Please connect wallet 0xbDfe…9CaD to access controls.
🔗 Connect SuperAdmin Wallet
Protocol Statistics
Live on-chain data · VantageArb v7.0 · auto-loads on connect
Total Users
—
Registered wallets
Total USDT Deposited
—
Gross deposits all-time
Total VF Issued
—
Buy + grants combined
VF Granted (Unbacked)
—
SuperAdmin grants only
Vault Balance
—
Live USDT in contract
Outstanding Obligations
—
Total IVF owed to all users
Solvency Ratio
—
vault ÷ obligations
Total Capital Traded
—
Cumulative locked via trade() + topUp()
Total Income Withdrawn
—
Cumulative IVF withdrawn by all traders
Total IVF Withdrawn
—
All wallets · all-time
Admin Fee IVF (Unclaimed)
—
Claimable by admin wallet
Quick Actions
🎁
Generate VF
Grant Virtual Funds to any trader wallet
›
↔️
Transfer VF
Move existing VF between trader wallets
›
Contract Status
Live Contract State
Contract: 0x4Ae30b03…eC1d0
🔄 Refresh Stats
⏸ Manage Pause
Hardcoded Addresses
SuperAdmin (Immutable)
0xbDfeD132275816B94c0af8da2559DD56FFa99CaD
Copy
Deployer Wallet (Immutable · receives 5% fee)
0xEaB87dB79BE94C2c90438361f3B9038b9D390B47
Copy
Admin Wallet (Mutable · receives 5% fee IVF)
Loading…
Copy
Program Settings
All rates, caps, and fees are permanently immutable in bytecode — view only
These parameters are permanently fixed in smart contract bytecode at deployment. No admin, superAdmin, or any party can alter them.
Passive Program
Daily Passive Rate
2.00% / day
0.00138888…% per minute
Income Cap
200% of capital
Passive + referral combined
Rate Formula
200 ÷ 10,000 ÷ 1,440 per min
= exactly 2.00%/day on capital
Fees
Deployer Fee
5% per deposit
Immediate USDT transfer to deployerWallet
Admin Fee
5% per deposit
Credited to adminWallet IVF (claimable)
Transaction Limits
Min Buy / Trade / Claim
$1.00
MIN_BUY = MIN_TRADE = MIN_CLAIM
Min TopUp / Withdraw
$10.00
IVF minimum for topUp and withdraw
Max Per Transaction
$5,000
Buy · Withdraw ceiling
Referral Program
10-Level Upline System
Triggered on trade() and topUp() · Auto-credited to upline IVF
Total max: 15%
L1 5% + L2 2% + L3–L10 8% = 15% maximum total payout per trade/topUp
Generate Virtual Funds
Manually credit VF to any trader wallet — SuperAdmin only · calls grantVF()
Granted VF is unbacked by USDT — it does not deposit real tokens into the vault. The trader must still call trade() to start passive income. Grants are permanently logged to the SuperAdmin event log.
Total VF Granted (All-Time)
—
Unbacked VF issued by superAdmin
Total VF Issued
—
Bought + granted combined
🎁 Generate VF for Trader
Enter the recipient's BSC wallet address and the amount of VF to credit.
The trader's VF balance will increase immediately on-chain.
No USDT is required — this creates virtual funds directly.
🎁 Generate & Credit VF
Recent Grant History
🔄 Refresh
Connect wallet to view recent grants.
Transfer Virtual Funds
Move existing VF between trader wallets — SuperAdmin only · calls transferVF()
This moves existing VF — it does not create new funds. The sender's VF balance decreases by the same amount. Useful for manual fund redistribution between traders.
🔍 Verify Source Wallet
Optionally check the FROM wallet's current VF balance before transferring.
VF Balance:
—
|
—
↔️ Transfer VF Between Wallets
Specify the source wallet (FROM), destination wallet (TO), and the amount of VF to transfer.
Both wallets must be valid BSC addresses. The FROM wallet must have sufficient VF balance.
↔️ Execute Transfer VF
Recent Transfer History
🔄 Refresh
Connect wallet to view recent transfers.
Admin Wallet Management
Update the admin fee wallet address — SuperAdmin only · calls setAdminWallet()
The admin wallet collects the 5% fee IVF from every deposit. Changing it transfers the existing unclaimed IVF balance to the new address automatically. Only superAdmin can perform this action.
Current Admin Wallet
Current Admin Wallet Address
Loading…
Unclaimed Admin IVF Balance
—
Available to claim via adminWithdraw()
📋 Copy Address
🔑 Set New Admin Wallet
Enter the new BSC wallet address for the admin fee account.
The current admin's unclaimed IVF will automatically transfer to the new address.
This cannot be undone — double-check the address before confirming.
⚠️ Change Preview
Current: —
New: —
IVF to transfer: —
🔑 Update Admin Wallet
Pause Control
Pause or unpause the contract — SuperAdmin and AdminWallet can perform this
Current Contract State
Live State
Active — All trader functions enabled
When paused : buyVirtualFunds, trade, topUp, claimPassive, and withdraw are all disabled.
SuperAdmin emergency transfer remains available regardless of pause state.
🔄 Refresh State
⏸ Pause Contract
Immediately disables all trader actions including buy, trade, top-up, claim passive, and withdraw.
Use this during emergencies or maintenance. Admin functions still work while paused.
⚠️ This will immediately prevent all
buyVirtualFunds,
trade,
topUp,
claimPassive, and
withdraw calls from succeeding.
⏸ Pause Contract
▶ Unpause Contract
Re-enables all trader functions. Call this after maintenance or emergency resolution to
restore normal platform operation.
✅ This restores full trader functionality. Passive accrual resumes from the moment the contract is unpaused (the blockchain continues ticking).
▶ Unpause Contract
⚠ Emergency Transfer
🚨 Emergency USDT Transfer
CRITICAL ACTION. Transfers the entire vault USDT balance to the deployerWallet.
Automatically pauses the contract if not already paused.
This is irreversible and will render all IVF obligations unpayable.
Use only in a genuine security emergency.
⚠️ WARNING: Irreversible Action
Destination: 0xEaB87dB79BE94C2c90438361f3B9038b9D390B47 (deployerWallet)
Current vault balance: —
This action will clear all user obligations and cannot be reversed.
🚨 Execute Emergency Transfer
Lookup Trader Account
Fetch full dashboard data and transaction history for any wallet address
Virtual Wallet
VF Balance
—
Trade-only · not withdrawable
IVF Balance
—
Withdrawable or top-up
Pending Passive
—
Unclaimed accrual (live)
Total VF Received
—
Buy + grants all-time
Passive Program
Capital (Locked)
—
Permanently locked in passive
Income Cap (200%)
—
Max payout this cycle
Cycle Earned
—
Passive + referral this cycle
Transaction History
All
Trade
Buy
Claim
Ref
Withdraw
SuperAdmin Event Log
All protocol events mirrored here — calls getSuperAdminHistory()
All
Buy
Trade
Top-Up
Claim
Referral
Withdraw
Grant
Transfer
🔄 Load / Refresh
Click "Load / Refresh" to fetch the SuperAdmin event log.
🔗 Connect SuperAdmin Wallet
Connect the superAdmin wallet (0xbDfe…9CaD) on BSC Mainnet.
🔷
Trust Wallet
Recommended · Mobile & Extension
PRIMARY
🟡
Binance Wallet
Official Binance browser extension
🔵
OKX Wallet
OKX browser extension / app
🟠
Bitget Wallet
Bitget browser extension / app
🔵
Coinbase Wallet
Coinbase browser extension / app
Not Supported
🦊
MetaMask
Not supported on VantageArb
Cancel
// ═══════════════════════════════════════════════════════════
// CONFIG
// ═══════════════════════════════════════════════════════════
const CONTRACT = '0x4Ae30b0381D4D1E2cd40D6C8143ad78fA83eC1d0';
const USDT_ADDR = '0x55d398326f99059fF775485246999027B3197955';
const SA_ADDR = '0xbDfeD132275816B94c0af8da2559DD56FFa99CaD';
const BSC_CHAIN_ID = 56;
const BSC_RPC = 'https://bsc-dataseed.binance.org/';
let account = null, provider = null, signer = null, contract = null;
let _allEventLogs = [], _luAllTxs = [], _logFilter = 0, _luFilter = 0;
let _logPage = 0;
const LOG_PAGE_SIZE = 50;
const ABI = [
// State-changing — superAdmin only
"function grantVF(address _to, uint256 _amt) external",
"function transferVF(address _from, address _to, uint256 _amt) external",
"function setAdminWallet(address _newAdmin) external",
"function pause() external",
"function unpause() external",
"function emergencyTransfer() external",
// View — superAdmin
"function superAdminStats() external view returns (tuple(uint256 users,uint256 usdtIn,uint256 vfIssued,uint256 vfGranted,uint256 obligations,uint256 ivfOut,uint256 vaultBal,uint256 solvency,uint256 adminIVF,uint256 totalCapitalTraded,uint256 totalIncomeWD,address currentAdminWallet))",
"function getSuperAdminHistory() external view returns (tuple(uint8 t,uint256 amt,uint256 ts,address rel,uint8 lvl)[])",
"function getTxHistory(address _addr) external view returns (tuple(uint8 t,uint256 amt,uint256 ts,address rel,uint8 lvl)[])",
"function dashboard(address _addr) external view returns (tuple(uint256 vf,uint256 ivf,uint256 ivfPending,uint256 totalVFIn,uint256 totalIVFEarned,uint256 totalWD,uint256 totalTopup,uint256 capital,uint256 incomeCap,uint256 cycleEarned,uint256 capRoom,bool active,uint256 cycles,uint256 lifePassive,uint256 lifetimeRef,uint256 perMin,uint256 perDay,address referrer,uint256 directRefs))",
"function protocolStats() external view returns (tuple(uint256 users,uint256 usdtIn,uint256 vfIssued,uint256 vfGranted,uint256 obligations,uint256 ivfOut,uint256 vaultBal,uint256 solvency,uint256 adminIVF))",
"function paused() external view returns (bool)",
"function adminWallet() external view returns (address)",
"function totalCapitalTraded() external view returns (uint256)",
"function totalIncomeWithdrawn() external view returns (uint256)",
];
// ═══════════════════════════════════════════════════════════
// HELPERS
// ═══════════════════════════════════════════════════════════
const $ = id => document.getElementById(id);
const setText = (id, v) => { const el = $(id); if (el) el.textContent = v; };
const fmt = n => n >= 1000 ? n.toLocaleString('en-US', {minimumFractionDigits:2, maximumFractionDigits:2}) : n.toFixed(2);
const fmtS = n => n >= 1000 ? n.toLocaleString('en-US', {minimumFractionDigits:0, maximumFractionDigits:2}) : n.toFixed(2);
const u18 = n => parseFloat(ethers.formatUnits(n, 18));
const shortAddr = a => a ? a.slice(0,6) + '…' + a.slice(-4) : '—';
const isSA = () => account && account.toLowerCase() === SA_ADDR.toLowerCase();
function copyText(text) {
navigator.clipboard.writeText(text).then(() => toast('Copied to clipboard!', 'success'));
}
function toast(msg, type = 'info') {
const icons = { success:'✓', error:'✗', info:'ℹ' };
const colors = { success:'var(--accent)', error:'var(--danger)', info:'var(--accent2)' };
const el = document.createElement('div');
el.className = 'toast';
el.innerHTML = `${icons[type]} ${msg}`;
$('toastContainer').appendChild(el);
setTimeout(() => el.remove(), 4000);
}
// ═══════════════════════════════════════════════════════════
// NAV
// ═══════════════════════════════════════════════════════════
function toggleSidebar() {
$('sidebar').classList.toggle('open');
$('sidebarOverlay').classList.toggle('open');
}
function closeSidebar() {
$('sidebar').classList.remove('open');
$('sidebarOverlay').classList.remove('open');
}
function showPage(name, btn) {
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.nav-item').forEach(b => b.classList.remove('active'));
$('page-' + name)?.classList.add('active');
if (btn) btn.classList.add('active');
closeSidebar();
// Lazy-load some pages
if (name === 'grant') loadRecentGrants();
if (name === 'transfer') loadRecentTransfers();
if (name === 'adminwallet') refreshAdminWalletPage();
if (name === 'pause') refreshPauseState();
if (name === 'eventlog') loadEventLog();
}
// ═══════════════════════════════════════════════════════════
// WALLET MODAL
// ═══════════════════════════════════════════════════════════
function openWalletModal() { $('walletSelectModal').style.display = 'flex'; }
function closeWalletModal() { $('walletSelectModal').style.display = 'none'; }
function _getProvider(type) {
const providers = window.ethereum?.providers || [];
switch(type) {
case 'trust':
if (providers.length) { const tw = providers.find(p => p.isTrust || p.isTrustWallet); if (tw) return tw; }
if (window.trustwallet?.ethereum) return window.trustwallet.ethereum;
if (window.ethereum?.isTrust || window.ethereum?.isTrustWallet) return window.ethereum;
return window.ethereum || null;
case 'binance':
if (providers.length) return providers.find(p => p.isBinance || p.isBinanceWallet || p.isBinanceSmartChain) || null;
return window.BinanceChain || window.ethereum || null;
case 'okx':
if (providers.length) return providers.find(p => p.isOKExWallet || p.isOKX) || null;
return window.okxwallet || window.ethereum || null;
case 'bitget':
if (providers.length) return providers.find(p => p.isBitKeep || p.isBitget) || null;
return window.bitkeep?.ethereum || window.ethereum || null;
case 'coinbase':
if (providers.length) return providers.find(p => p.isCoinbaseWallet || p.isCoinbaseBrowser) || null;
return window.coinbaseWalletExtension || window.ethereum || null;
default: return window.ethereum || null;
}
}
function _isMetaMask(eth) {
const p = eth || window.ethereum; if (!p) return false;
return !!(p.isMetaMask && !p.isTrust && !p.isTrustWallet && !p.isOKExWallet && !p.isOKX && !p.isBinance && !p.isBinanceWallet && !p.isBitKeep && !p.isBitget && !p.isRabby && !p.isCoinbaseWallet && !p.isCoinbaseBrowser);
}
async function connectWithProvider(type) {
closeWalletModal();
const ethProvider = _getProvider(type);
if (!ethProvider) { toast(`${type} wallet not detected.`, 'error'); return; }
if (_isMetaMask(ethProvider)) { toast('MetaMask not supported. Please use Trust, Binance, or OKX Wallet.', 'error'); return; }
await _doConnect(ethProvider, type);
}
async function _doConnect(ethProvider, walletType) {
const btn = $('btnConnect');
btn.textContent = 'Connecting…'; btn.disabled = true;
try {
provider = new ethers.BrowserProvider(ethProvider);
const accounts = await provider.send('eth_requestAccounts', []);
if (!accounts?.length) throw new Error('No accounts returned.');
account = accounts[0];
// Switch to BSC if needed
const network = await provider.getNetwork();
if (Number(network.chainId) !== BSC_CHAIN_ID) {
btn.textContent = 'Switching to BSC…';
try {
await ethProvider.request({ method:'wallet_switchEthereumChain', params:[{chainId:'0x38'}] });
} catch(se) {
if (se.code === 4902) {
await ethProvider.request({ method:'wallet_addEthereumChain', params:[{chainId:'0x38',chainName:'BNB Smart Chain Mainnet',nativeCurrency:{name:'BNB',symbol:'BNB',decimals:18},rpcUrls:['https://bsc-dataseed.binance.org/'],blockExplorerUrls:['https://bscscan.com/']}] });
} else if (se.code === 4001) throw new Error('Network switch rejected.');
else throw se;
}
provider = new ethers.BrowserProvider(ethProvider);
account = (await provider.send('eth_requestAccounts', []))[0];
}
const finalNet = await provider.getNetwork();
if (Number(finalNet.chainId) !== BSC_CHAIN_ID) throw new Error('Please switch to BSC Mainnet (Chain 56).');
signer = await provider.getSigner();
contract = new ethers.Contract(CONTRACT, ABI, signer);
window._vaActiveProvider = ethProvider;
if (walletType) localStorage.setItem('sa_connected_type', walletType);
localStorage.setItem('sa_connected_account', account);
_setConnectedUI(account);
// Check if it's actually the superAdmin wallet
if (!isSA()) {
toast(`⚠️ Connected as ${shortAddr(account)} — not superAdmin. Read-only mode.`, 'error');
$('authGate').style.display = '';
} else {
$('authGate').style.display = 'none';
toast('SuperAdmin wallet connected ✓', 'success');
}
await refreshStats();
// Auto-load event log if superAdmin
if (isSA()) { setTimeout(() => loadEventLog(), 800); }
// Listen for account / chain changes
ethProvider.removeAllListeners?.('accountsChanged');
ethProvider.removeAllListeners?.('chainChanged');
ethProvider.on?.('accountsChanged', accs => {
if (!accs.length) { disconnectWallet(); return; }
account = accs[0];
localStorage.setItem('sa_connected_account', account);
_setConnectedUI(account);
refreshStats();
});
ethProvider.on?.('chainChanged', () => location.reload());
} catch(e) {
btn.textContent = 'Connect Wallet'; btn.style.cssText = ''; btn.disabled = false;
toast(e.code === 4001 ? 'Connection rejected.' : (e.message || String(e)).slice(0,120), 'error');
}
}
function _setConnectedUI(addr) {
const btn = $('btnConnect');
const btnDis = $('btnDisconnect');
const sbDis = $('sidebarDisconnect');
$('walletBadge').innerHTML = `${shortAddr(addr)} `;
btn.textContent = 'Connected ✓';
btn.style.cssText = 'background:transparent;color:var(--gold);border:1px solid var(--gold);font-weight:700;font-size:13px;border-radius:8px;padding:8px 16px;cursor:default';
btn.disabled = false;
if (btnDis) btnDis.style.display = 'inline-flex';
if (sbDis) sbDis.style.display = 'flex';
}
function disconnectWallet() {
if (!confirm('Disconnect wallet?')) return;
account = null; provider = null; signer = null; contract = null;
localStorage.removeItem('sa_connected_account');
localStorage.removeItem('sa_connected_type');
const btn = $('btnConnect');
btn.textContent = 'Connect Wallet'; btn.style.cssText = ''; btn.disabled = false;
$('btnDisconnect').style.display = 'none';
$('sidebarDisconnect').style.display = 'none';
$('walletBadge').textContent = 'Not connected';
$('authGate').style.display = 'none';
toast('Wallet disconnected.', 'info');
}
// Auto-reconnect on load
window.addEventListener('load', async () => {
const saved = localStorage.getItem('sa_connected_account');
const savedType = localStorage.getItem('sa_connected_type') || 'auto';
if (!saved) {
// Load readonly stats even without wallet
loadReadonlyStats();
return;
}
const autoProvider = savedType !== 'auto' ? _getProvider(savedType) : (window.ethereum || null);
if (!autoProvider || _isMetaMask(autoProvider)) { loadReadonlyStats(); return; }
try {
const accounts = await autoProvider.request({ method: 'eth_accounts' });
if (!accounts?.length || accounts[0].toLowerCase() !== saved.toLowerCase()) { loadReadonlyStats(); return; }
const chainIdHex = await autoProvider.request({ method: 'eth_chainId' });
if (parseInt(chainIdHex, 16) !== BSC_CHAIN_ID) { loadReadonlyStats(); return; }
account = accounts[0];
provider = new ethers.BrowserProvider(autoProvider);
signer = await provider.getSigner();
contract = new ethers.Contract(CONTRACT, ABI, signer);
window._vaActiveProvider = autoProvider;
_setConnectedUI(account);
if (!isSA()) $('authGate').style.display = '';
await refreshStats();
if (isSA()) { setTimeout(() => loadEventLog(), 1000); }
} catch(e) {
console.warn('Auto-reconnect failed:', e.message);
loadReadonlyStats();
}
});
async function loadReadonlyStats() {
try {
const roProv = new ethers.JsonRpcProvider(BSC_RPC);
const roCont = new ethers.Contract(CONTRACT, ABI, roProv);
const [s, capTraded, incomeWD, isPaused, adminWlt] = await Promise.all([
roCont.protocolStats(),
roCont.totalCapitalTraded(),
roCont.totalIncomeWithdrawn(),
roCont.paused(),
roCont.adminWallet(),
]);
_applyStats({ users:s.users, usdtIn:s.usdtIn, vfIssued:s.vfIssued, vfGranted:s.vfGranted,
obligations:s.obligations, ivfOut:s.ivfOut, vaultBal:s.vaultBal, solvency:s.solvency,
adminIVF:s.adminIVF, totalCapitalTraded:capTraded, totalIncomeWD:incomeWD,
currentAdminWallet:adminWlt }, isPaused);
} catch(e) { console.warn('Readonly stats failed:', e.message); }
}
// ═══════════════════════════════════════════════════════════
// STATS
// ═══════════════════════════════════════════════════════════
async function refreshStats() {
if (!contract) { loadReadonlyStats(); return; }
try {
let s, isPaused, adminWlt;
if (isSA()) {
// superAdminStats() includes totalCapitalTraded, totalIncomeWD, and currentAdminWallet directly
[s, isPaused, adminWlt] = await Promise.all([
contract.superAdminStats(),
contract.paused(),
contract.adminWallet(),
]);
// Map superAdminStats fields to the unified stats object
s = {
users: s.users, usdtIn: s.usdtIn, vfIssued: s.vfIssued, vfGranted: s.vfGranted,
obligations: s.obligations, ivfOut: s.ivfOut, vaultBal: s.vaultBal, solvency: s.solvency,
adminIVF: s.adminIVF, totalCapitalTraded: s.totalCapitalTraded,
totalIncomeWD: s.totalIncomeWD, currentAdminWallet: s.currentAdminWallet,
};
} else {
// Non-SA: use protocolStats() + public vars
let base, capTraded, incomeWD;
[base, capTraded, incomeWD, isPaused, adminWlt] = await Promise.all([
contract.protocolStats(),
contract.totalCapitalTraded(),
contract.totalIncomeWithdrawn(),
contract.paused(),
contract.adminWallet(),
]);
s = {
users: base.users, usdtIn: base.usdtIn, vfIssued: base.vfIssued, vfGranted: base.vfGranted,
obligations: base.obligations, ivfOut: base.ivfOut, vaultBal: base.vaultBal,
solvency: base.solvency, adminIVF: base.adminIVF,
totalCapitalTraded: capTraded, totalIncomeWD: incomeWD, currentAdminWallet: adminWlt,
};
}
_applyStats(s, isPaused);
} catch(e) { toast('Stats refresh failed: ' + (e.message||'').slice(0,60), 'error'); console.error(e); }
}
function _applyStats(s, isPaused) {
setText('pTotalUsers', s.users.toString());
setText('pTotalUSDT', `$${fmt(u18(s.usdtIn))}`);
setText('pTotalVF', `$${fmt(u18(s.vfIssued))}`);
setText('pTotalGranted', `$${fmt(u18(s.vfGranted))}`);
setText('pVaultBal', `$${fmt(u18(s.vaultBal))}`);
setText('pObligations', `$${fmt(u18(s.obligations))}`);
setText('pIVFOut', `$${fmt(u18(s.ivfOut))}`);
setText('pAdminIVF', `$${fmt(u18(s.adminIVF))}`);
setText('pCapitalTraded', `$${fmt(u18(s.totalCapitalTraded))}`);
setText('pIncomeWithdrawn', `$${fmt(u18(s.totalIncomeWD))}`);
// Admin wallet
const adminAddr = s.currentAdminWallet || '—';
setText('pAdminWalletShort', shortAddr(adminAddr));
setText('currentAdminFull', adminAddr);
setText('currentAdminWalletFull', adminAddr);
setText('adminIVFBalance', `$${fmt(u18(s.adminIVF))}`);
// Solvency
const sv = s.obligations > 0n ? Number(s.solvency) / 1e18 : Infinity;
if (sv === Infinity) {
setText('pSolvency', '∞'); setText('pSolvencySub', 'No obligations — fully solvent');
const el = $('pSolvency'); if (el) el.style.color = 'var(--accent)';
const bar = $('pSolvencyBar'); if (bar) { bar.style.width = '100%'; bar.style.background = 'var(--accent)'; }
} else {
setText('pSolvency', sv.toFixed(4) + 'x');
const el = $('pSolvency'); if (el) el.style.color = sv >= 1 ? 'var(--accent)' : 'var(--danger)';
setText('pSolvencySub', sv >= 1 ? '✓ Solvent' : '⚠ Under-collateralized');
const bar = $('pSolvencyBar');
if (bar) {
bar.style.width = Math.min(sv * 100, 100) + '%';
bar.style.background = sv >= 1.5 ? 'var(--accent)' : sv >= 1 ? 'var(--gold)' : 'var(--danger)';
}
}
// Also populate grant page counters
setText('grantTotalGranted', `$${fmt(u18(s.vfGranted))}`);
setText('grantTotalVF', `$${fmt(u18(s.vfIssued))}`);
// Emergency vault balance
setText('emergencyVaultBal', `$${fmt(u18(s.vaultBal))} USDT`);
// Contract state badge
_applyPauseUI(isPaused);
}
function _applyPauseUI(isPaused) {
const badge1 = $('contractStateBadge');
const badge2 = $('pauseStateBadge');
if (isPaused) {
if (badge1) { badge1.className = 'state-badge state-paused'; badge1.innerHTML = '
Paused'; }
if (badge2) { badge2.className = 'state-badge state-paused'; badge2.innerHTML = '
Paused — All trader functions disabled'; }
} else {
if (badge1) { badge1.className = 'state-badge state-active'; badge1.innerHTML = '
Active'; }
if (badge2) { badge2.className = 'state-badge state-active'; badge2.innerHTML = '
Active — All trader functions enabled'; }
}
}
async function refreshPauseState() {
if (!contract) return;
try {
const isPaused = await contract.paused();
_applyPauseUI(isPaused);
} catch(e) { console.error(e); }
}
// ═══════════════════════════════════════════════════════════
// GRANT VF
// ═══════════════════════════════════════════════════════════
// Live preview
$('grantAddr')?.addEventListener('input', updateGrantPreview);
$('grantAmt')?.addEventListener('input', updateGrantPreview);
function updateGrantPreview() {
const addr = $('grantAddr').value.trim();
const amt = parseFloat($('grantAmt').value);
const prev = $('grantPreview');
if (addr.length >= 10 && !isNaN(amt) && amt > 0) {
setText('grantPreviewAddr', addr.length > 20 ? shortAddr(addr) : addr);
setText('grantPreviewAmt', `$${fmtS(amt)} VF`);
prev.style.display = '';
} else {
prev.style.display = 'none';
}
}
// safeAmt: truncate to 6 decimals to avoid JS floating point errors in ethers.parseUnits
function safeAmt(n, decimals = 6) {
const factor = Math.pow(10, decimals);
return (Math.floor(n * factor) / factor).toFixed(decimals);
}
async function doGrantVF() {
if (!isSA()) { toast('SuperAdmin wallet required.', 'error'); return; }
const addr = $('grantAddr').value.trim();
const amt = $('grantAmt').value.trim();
if (!addr || !amt) { toast('Please fill in recipient address and amount.', 'error'); return; }
if (!ethers.isAddress(addr)) { toast('Invalid wallet address.', 'error'); return; }
const parsed = parseFloat(amt);
if (isNaN(parsed) || parsed < 1) { toast('Minimum grant is $1 VF.', 'error'); return; }
if (!confirm(`Grant $${fmtS(parsed)} VF to ${shortAddr(addr)}?\n\nThis creates unbacked virtual funds on-chain.`)) return;
try {
const amtWei = ethers.parseUnits(safeAmt(parsed), 18);
toast('Sending grantVF transaction…', 'info');
const tx = await contract.grantVF(addr, amtWei);
toast('Transaction submitted — waiting for confirmation…', 'info');
await tx.wait();
toast(`✓ Granted $${fmtS(parsed)} VF to ${shortAddr(addr)}`, 'success');
$('grantAddr').value = ''; $('grantAmt').value = '';
$('grantPreview').style.display = 'none';
await new Promise(r => setTimeout(r, 2000));
await refreshStats();
await loadRecentGrants();
} catch(e) { toast(parseErr(e), 'error'); }
}
async function loadRecentGrants() {
const el = $('grantLogList');
if (!el) return;
if (!contract) { el.innerHTML = 'Connect wallet to view grants.
'; return; }
el.innerHTML = 'Loading…
';
try {
const txs = isSA()
? await contract.getSuperAdminHistory()
: [];
const grants = [...txs].filter(t => Number(t.t) === 7).reverse().slice(0, 30);
if (!grants.length) {
el.innerHTML = 'No grants found.
';
return;
}
el.innerHTML = grants.map(tx => renderTxRow(tx, 'grant')).join('');
} catch(e) { el.innerHTML = 'Failed to load.
'; }
}
// ═══════════════════════════════════════════════════════════
// TRANSFER VF
// ═══════════════════════════════════════════════════════════
$('xferFrom')?.addEventListener('input', updateXferPreview);
$('xferTo')?.addEventListener('input', updateXferPreview);
$('xferAmt')?.addEventListener('input', updateXferPreview);
function updateXferPreview() {
const from = $('xferFrom').value.trim();
const to = $('xferTo').value.trim();
const amt = parseFloat($('xferAmt').value);
const prev = $('xferPreview');
if (from.length >= 10 && to.length >= 10 && !isNaN(amt) && amt > 0) {
setText('xferPreviewFrom', shortAddr(from));
setText('xferPreviewTo', shortAddr(to));
setText('xferPreviewAmt', `$${fmtS(amt)} VF`);
prev.style.display = '';
} else {
prev.style.display = 'none';
}
}
async function checkSourceBalance() {
const addr = $('xferFromCheck').value.trim();
if (!addr || !ethers.isAddress(addr)) { toast('Enter a valid BSC address.', 'error'); return; }
if (!contract) { toast('Connect wallet first.', 'error'); return; }
try {
const d = await contract.dashboard(addr);
const vf = u18(d.vf);
setText('xferSourceVF', `$${fmt(vf)} VF`);
setText('xferSourceActive', d.active ? '● Passive Active' : '○ Passive Inactive');
$('xferSourceResult').style.display = '';
// Auto-fill the from field
if (!$('xferFrom').value) { $('xferFrom').value = addr; updateXferPreview(); }
} catch(e) { toast('Lookup failed: ' + (e.message||'').slice(0,60), 'error'); }
}
async function doTransferVF() {
if (!isSA()) { toast('SuperAdmin wallet required.', 'error'); return; }
const from = $('xferFrom').value.trim();
const to = $('xferTo').value.trim();
const amt = $('xferAmt').value.trim();
if (!from || !to || !amt) { toast('Please fill in all fields.', 'error'); return; }
if (!ethers.isAddress(from)) { toast('Invalid FROM address.', 'error'); return; }
if (!ethers.isAddress(to)) { toast('Invalid TO address.', 'error'); return; }
if (from.toLowerCase() === to.toLowerCase()) { toast('FROM and TO cannot be the same address.', 'error'); return; }
const parsed = parseFloat(amt);
if (isNaN(parsed) || parsed < 1) { toast('Minimum transfer is $1 VF.', 'error'); return; }
if (!confirm(`Transfer $${fmtS(parsed)} VF\nFrom: ${shortAddr(from)}\nTo: ${shortAddr(to)}\n\nThis moves existing VF — no new funds are created.`)) return;
try {
const amtWei = ethers.parseUnits(safeAmt(parsed), 18);
toast('Sending transferVF transaction…', 'info');
const tx = await contract.transferVF(from, to, amtWei);
toast('Transaction submitted — waiting for confirmation…', 'info');
await tx.wait();
toast(`✓ Transferred $${fmtS(parsed)} VF from ${shortAddr(from)} to ${shortAddr(to)}`, 'success');
$('xferFrom').value = ''; $('xferTo').value = ''; $('xferAmt').value = '';
$('xferPreview').style.display = 'none';
$('xferSourceResult').style.display = 'none';
await new Promise(r => setTimeout(r, 2000));
await refreshStats();
await loadRecentTransfers();
} catch(e) { toast(parseErr(e), 'error'); }
}
async function loadRecentTransfers() {
const el = $('xferLogList');
if (!el) return;
if (!contract) { el.innerHTML = 'Connect wallet to view transfers.
'; return; }
el.innerHTML = 'Loading…
';
try {
const txs = isSA() ? await contract.getSuperAdminHistory() : [];
const xfers = [...txs].filter(t => Number(t.t) === 8).reverse().slice(0, 30);
if (!xfers.length) {
el.innerHTML = 'No transfers found.
';
return;
}
el.innerHTML = xfers.map(tx => renderTxRow(tx, 'transfer')).join('');
} catch(e) { el.innerHTML = 'Failed to load.
'; }
}
// ═══════════════════════════════════════════════════════════
// ADMIN WALLET
// ═══════════════════════════════════════════════════════════
$('newAdminAddr')?.addEventListener('input', updateAdminChangePreview);
function updateAdminChangePreview() {
const newAddr = $('newAdminAddr').value.trim();
const prev = $('adminChangePreview');
const current = $('currentAdminFull')?.textContent || '—';
const ivf = $('adminIVFBalance')?.textContent || '—';
if (newAddr.length >= 10) {
setText('adminChangeFrom', shortAddr(current));
setText('adminChangeTo', shortAddr(newAddr));
setText('adminChangeIVF', ivf);
prev.style.display = '';
} else {
prev.style.display = 'none';
}
}
async function refreshAdminWalletPage() {
if (!contract) return;
try {
const adminAddr = await contract.adminWallet();
setText('currentAdminFull', adminAddr);
if (isSA()) {
try {
const stats = await contract.superAdminStats();
setText('adminIVFBalance', `$${fmt(u18(stats.adminIVF))}`);
} catch(e) {}
}
} catch(e) { console.error(e); }
}
async function doSetAdminWallet() {
if (!isSA()) { toast('SuperAdmin wallet required.', 'error'); return; }
const newAddr = $('newAdminAddr').value.trim();
if (!newAddr) { toast('Enter the new admin wallet address.', 'error'); return; }
if (!ethers.isAddress(newAddr)) { toast('Invalid wallet address.', 'error'); return; }
const current = $('currentAdminFull')?.textContent;
if (newAddr.toLowerCase() === current?.toLowerCase()) { toast('New address is the same as current admin wallet.', 'error'); return; }
const ivf = $('adminIVFBalance')?.textContent || '—';
if (!confirm(`Update admin wallet?\n\nFrom: ${shortAddr(current)}\nTo: ${shortAddr(newAddr)}\n\nUnclaimed IVF (${ivf}) will transfer automatically.\n\nThis is irreversible — double-check the address.`)) return;
try {
toast('Sending setAdminWallet transaction…', 'info');
const tx = await contract.setAdminWallet(newAddr);
toast('Transaction submitted — waiting for confirmation…', 'info');
await tx.wait();
toast(`✓ Admin wallet updated to ${shortAddr(newAddr)}`, 'success');
$('newAdminAddr').value = '';
$('adminChangePreview').style.display = 'none';
await new Promise(r => setTimeout(r, 2000));
await refreshStats();
await refreshAdminWalletPage();
} catch(e) { toast(parseErr(e), 'error'); }
}
// ═══════════════════════════════════════════════════════════
// PAUSE / UNPAUSE
// ═══════════════════════════════════════════════════════════
async function doPause() {
if (!isSA()) { toast('SuperAdmin wallet required.', 'error'); return; }
if (!confirm('Pause the contract?\n\nAll trader actions (buy, trade, topUp, claimPassive, withdraw) will be immediately disabled.')) return;
try {
toast('Sending pause transaction…', 'info');
const tx = await contract.pause();
await tx.wait();
toast('✓ Contract paused successfully.', 'success');
_applyPauseUI(true);
await refreshStats();
} catch(e) { toast(parseErr(e), 'error'); }
}
async function doUnpause() {
if (!isSA()) { toast('SuperAdmin wallet required.', 'error'); return; }
if (!confirm('Unpause the contract?\n\nAll trader functions will be re-enabled immediately.')) return;
try {
toast('Sending unpause transaction…', 'info');
const tx = await contract.unpause();
await tx.wait();
toast('✓ Contract unpaused. Platform is live.', 'success');
_applyPauseUI(false);
await refreshStats();
} catch(e) { toast(parseErr(e), 'error'); }
}
async function doEmergencyTransfer() {
if (!isSA()) { toast('SuperAdmin wallet required.', 'error'); return; }
const vaultBal = $('emergencyVaultBal')?.textContent || '—';
if (!confirm(`⚠️ EMERGENCY TRANSFER — IRREVERSIBLE\n\nThis will:\n1. Pause the contract (if not already paused)\n2. Transfer ALL vault USDT (${vaultBal}) to deployerWallet\n3. Render all user IVF obligations unpayable\n\nType YES and confirm TWICE — this cannot be undone.`)) return;
const confirm2 = prompt('Type CONFIRM to execute emergency transfer:');
if (confirm2 !== 'CONFIRM') { toast('Emergency transfer cancelled.', 'info'); return; }
try {
toast('🚨 Sending emergency transfer transaction…', 'info');
const tx = await contract.emergencyTransfer();
await tx.wait();
toast('🚨 Emergency transfer executed. All USDT moved to deployerWallet.', 'success');
_applyPauseUI(true);
await refreshStats();
} catch(e) { toast(parseErr(e), 'error'); }
}
// ═══════════════════════════════════════════════════════════
// LOOKUP TRADER
// ═══════════════════════════════════════════════════════════
async function doLookup() {
const addr = $('lookupAddr').value.trim();
if (!addr || !ethers.isAddress(addr)) { toast('Enter a valid BSC address.', 'error'); return; }
if (!contract) { toast('Connect wallet first.', 'error'); return; }
try {
const [d, txs] = await Promise.all([
contract.dashboard(addr),
contract.getTxHistory(addr),
]);
// Balances
setText('luVF', `$${fmt(u18(d.vf))}`);
setText('luIVF', `$${fmt(u18(d.ivf))}`);
setText('luPending', `$${fmt(u18(d.ivfPending))}`);
setText('luTotalVFIn', `$${fmt(u18(d.totalVFIn))}`);
setText('luCapital', `$${fmt(u18(d.capital))}`);
setText('luIncomeCap', `$${fmt(u18(d.incomeCap))}`);
setText('luCycleEarned',`$${fmt(u18(d.cycleEarned))}`);
setText('luLifePassive',`$${fmt(u18(d.lifePassive))}`);
setText('luLifetimeRef',`$${fmt(u18(d.lifetimeRef))}`);
setText('luTotalWD', `$${fmt(u18(d.totalWD))}`);
setText('luCycles', d.cycles.toString());
setText('luDirectRefs', d.directRefs.toString());
setText('luPerDay', d.active ? `$${fmt(u18(d.perDay))}/day` : '$0.00/day');
const statusEl = $('luStatus');
if (statusEl) {
statusEl.textContent = d.active ? '🟢 Active' : '⚫ Inactive';
statusEl.style.color = d.active ? 'var(--accent)' : 'var(--muted)';
}
const ZERO = '0x0000000000000000000000000000000000000000';
setText('luReferrer', d.referrer === ZERO ? 'None' : d.referrer);
setText('luTxCount', `Transaction History (${txs.length})`);
// Store txs for filtering
_luAllTxs = [...txs].reverse();
_luFilter = 0;
renderLuTx();
$('lookupResult').style.display = '';
} catch(e) { toast('Lookup failed: ' + (e.message||'').slice(0,80), 'error'); }
}
function filterLuTx(type) {
_luFilter = type;
document.querySelectorAll('[id^="lf"]').forEach(btn => {
const isActive = btn.id === 'lf' + type;
btn.style.borderColor = isActive ? 'var(--accent)' : 'var(--border)';
btn.style.background = isActive ? 'rgba(0,200,150,.1)' : 'transparent';
btn.style.color = isActive ? 'var(--accent)' : 'var(--muted)';
});
renderLuTx();
}
function renderLuTx() {
const el = $('luTxList');
const filtered = _luFilter === 0 ? _luAllTxs : _luAllTxs.filter(t => Number(t.t) === _luFilter);
if (!filtered.length) {
el.innerHTML = 'No transactions found for this filter.
';
return;
}
el.innerHTML = filtered.map(tx => renderTxRow(tx, 'trader')).join('');
}
// ═══════════════════════════════════════════════════════════
// EVENT LOG
// ═══════════════════════════════════════════════════════════
async function loadEventLog() {
if (!contract) { return; }
if (!isSA()) {
const el = $('eventLogList');
if (el) el.innerHTML = '⚠️ SuperAdmin wallet required to view event log.
';
return;
}
const el = $('eventLogList');
if (el) el.innerHTML = '⏳ Loading all events from blockchain…
';
try {
const txs = await contract.getSuperAdminHistory();
// Deduplicate: in SA log, BUY is logged twice (once for admin fee, once for trader)
// We show ALL entries but filter out admin-fee buy entries (rel = adminWallet) from Buy count
_allEventLogs = [...txs].reverse();
const buys = _allEventLogs.filter(t => Number(t.t) === 1);
const trades = _allEventLogs.filter(t => Number(t.t) === 2);
const withdrawals= _allEventLogs.filter(t => Number(t.t) === 6);
const grants = _allEventLogs.filter(t => Number(t.t) === 7);
const transfers = _allEventLogs.filter(t => Number(t.t) === 8);
// Count unique trader buys (exclude admin fee entries — those have rel = adminWallet)
const adminAddr = ($('currentAdminWalletFull')?.textContent || '').toLowerCase();
const traderBuys = buys.filter(t => {
const rel = (t.rel||'').toLowerCase();
return rel !== adminAddr && rel !== '0x0000000000000000000000000000000000000000';
});
setText('logTotal', _allEventLogs.length.toString());
setText('logBuys', traderBuys.length.toString());
setText('logTrades', trades.length.toString());
setText('logWithdrawals', withdrawals.length.toString());
if (_allEventLogs.length === 0) {
if (el) el.innerHTML = 'No events recorded yet. Events appear here after traders buy VF, trade, or perform other actions.
';
setText('logTotal','0'); setText('logBuys','0'); setText('logTrades','0'); setText('logWithdrawals','0');
return;
}
_logFilter = 0; _logPage = 0;
renderEventLog();
} catch(e) {
console.error('loadEventLog error:', e);
if (el) el.innerHTML = `❌ Failed to load: ${(e.message||'').slice(0,120)}Retry
`;
}
}
function filterLog(type) {
_logFilter = type; _logPage = 0;
document.querySelectorAll('[id^="ef"]').forEach(btn => {
const isActive = btn.id === 'ef' + type;
btn.style.borderColor = isActive ? 'var(--accent)' : 'var(--border)';
btn.style.background = isActive ? 'rgba(0,200,150,.1)' : 'transparent';
btn.style.color = isActive ? 'var(--accent)' : 'var(--muted)';
});
renderEventLog();
}
function renderEventLog() {
const el = $('eventLogList');
const filtered = _logFilter === 0 ? _allEventLogs : _allEventLogs.filter(t => Number(t.t) === _logFilter);
if (!filtered.length) {
el.innerHTML = 'No events match this filter.
';
$('logPagination').style.display = 'none';
return;
}
const totalPages = Math.ceil(filtered.length / LOG_PAGE_SIZE);
const page = filtered.slice(_logPage * LOG_PAGE_SIZE, (_logPage + 1) * LOG_PAGE_SIZE);
el.innerHTML = page.map(tx => renderTxRow(tx, 'log')).join('');
// Pagination
if (filtered.length > LOG_PAGE_SIZE) {
$('logPagination').style.display = 'flex';
setText('logPageInfo', `Page ${_logPage + 1} of ${totalPages} · ${filtered.length} events`);
$('logPrevBtn').disabled = _logPage === 0;
$('logNextBtn').disabled = _logPage >= totalPages - 1;
} else {
$('logPagination').style.display = 'none';
}
}
function logPrevPage() { if (_logPage > 0) { _logPage--; renderEventLog(); } }
function logNextPage() { _logPage++; renderEventLog(); }
// ═══════════════════════════════════════════════════════════
// TX ROW RENDERER
// ═══════════════════════════════════════════════════════════
const TX_META = {
1: { label:'BUY / DEPOSIT', icon:'💰', iconBg:'rgba(96,165,250,.15)', color:'var(--accent2)', amtClass:'pos' },
2: { label:'TRADE', icon:'🔒', iconBg:'rgba(0,200,150,.15)', color:'var(--accent)', amtClass:'pos' },
3: { label:'TOP-UP', icon:'🔼', iconBg:'rgba(245,158,11,.15)', color:'var(--gold)', amtClass:'pos' },
4: { label:'CLAIM', icon:'✨', iconBg:'rgba(167,139,250,.15)', color:'#a78bfa', amtClass:'pos' },
5: { label:'REFERRAL', icon:'👥', iconBg:'rgba(245,158,11,.12)', color:'var(--gold)', amtClass:'pos' },
6: { label:'WITHDRAW', icon:'💸', iconBg:'rgba(239,68,68,.15)', color:'var(--danger)', amtClass:'neg' },
7: { label:'GRANT VF', icon:'🎁', iconBg:'rgba(14,165,233,.15)', color:'var(--accent2)', amtClass:'pos' },
8: { label:'TRANSFER VF', icon:'↔️', iconBg:'rgba(14,165,233,.12)', color:'var(--accent2)', amtClass:'neu' },
9: { label:'ADMIN WITHDRAW', icon:'🏦', iconBg:'rgba(239,68,68,.12)', color:'var(--danger)', amtClass:'neg' },
10: { label:'ADMIN CHG', icon:'🔑', iconBg:'rgba(100,116,139,.15)', color:'var(--muted)', amtClass:'neu' },
};
// Human-readable tx type names (for tooltips/full labels)
const TX_LABELS = {
1: 'Buy Virtual Funds', 2: 'Trade (Start Passive)', 3: 'Top-Up Capital',
4: 'Claim Passive', 5: 'Referral Commission', 6: 'Withdraw IVF',
7: 'Grant VF (SuperAdmin)', 8: 'Transfer VF (SuperAdmin)',
9: 'Admin Fee Withdrawal', 10: 'Admin Wallet Changed',
};
function renderTxRow(tx, mode) {
const t = Number(tx.t);
const m = TX_META[t] || { label:'TX', icon:'•', iconBg:'rgba(100,116,139,.15)', color:'var(--muted)', amtClass:'neu' };
const amt = `$${fmt(u18(tx.amt))}`;
const rawAmt = u18(tx.amt);
const date = new Date(Number(tx.ts) * 1000);
const dateStr = date.toLocaleDateString('en-US', {month:'short',day:'numeric',year:'numeric'});
const timeStr = date.toLocaleTimeString('en-US', {hour:'2-digit',minute:'2-digit'});
const ZERO = '0x0000000000000000000000000000000000000000';
const rel = tx.rel && tx.rel !== ZERO ? tx.rel : null;
const lvlNum = Number(tx.lvl);
const lvl = lvlNum > 0 ? ` L${lvlNum}` : '';
// Build descriptive meta line based on tx type and context (mode: 'log'=SA log, 'trader'=trader view, 'grant'/'transfer'=specific pages)
let meta = '';
let metaColor = 'var(--muted)';
if (mode === 'log' || mode === 'grant' || mode === 'transfer') {
// SuperAdmin event log — rel = the trader/wallet involved
switch(t) {
case 1: // BUY — in SA log: rel = msg.sender (the buyer), OR rel=adminWallet for the admin fee entry
meta = rel ? `Trader: ${shortAddr(rel)}` : 'Deposit recorded'; break;
case 2: // TRADE — rel = msg.sender
meta = rel ? `Trader: ${shortAddr(rel)}` : 'Capital locked'; break;
case 3: // TOP-UP
meta = rel ? `Trader: ${shortAddr(rel)}` : 'IVF → Capital'; break;
case 4: // CLAIM — rel = trader address
meta = rel ? `Passive → ${shortAddr(rel)}` : 'Passive accrued'; break;
case 5: // REFERRAL — rel = from (who triggered it), lvl = level
meta = rel ? `From: ${shortAddr(rel)}${lvl ? ' · ' + lvl.trim() : ''}` : `Referral${lvl}`; break;
case 6: // WITHDRAW
meta = rel ? `To: ${shortAddr(rel)}` : 'IVF withdrawn'; break;
case 7: // GRANT — rel = recipient
meta = rel ? `Recipient: ${shortAddr(rel)}` : 'VF granted'; metaColor = 'var(--accent2)'; break;
case 8: // TRANSFER VF — rel = recipient (TO)
meta = rel ? `To: ${shortAddr(rel)}` : 'VF moved'; metaColor = 'var(--accent2)'; break;
case 9: // ADMIN WITHDRAW
meta = rel ? `Admin: ${shortAddr(rel)}` : 'Admin fee withdrawn'; break;
case 10: // ADMIN CHG
meta = rel ? `New admin: ${shortAddr(rel)}` : 'Admin wallet updated'; break;
default: meta = rel ? shortAddr(rel) : '—';
}
} else {
// Trader's own history view
if (rel) {
if (t === 7) meta = `Granted by: ${shortAddr(rel)}`;
else if (t === 8) meta = `From: ${shortAddr(rel)}`;
else if (t === 5) meta = `From: ${shortAddr(rel)}${lvl}`;
else if (t === 6 || t===9) meta = `To: ${shortAddr(rel)}`;
else if (t === 1) meta = 'Deposit · VF credited';
else if (t === 2) meta = 'VF → Passive capital';
else if (t === 3) meta = 'IVF → Capital';
else if (t === 4) meta = 'Passive income earned';
else meta = shortAddr(rel) + lvl;
} else {
if (t === 1) meta = 'Deposit · VF credited';
else if (t === 2) meta = 'VF → Passive capital locked';
else if (t === 3) meta = 'IVF → Passive capital';
else if (t === 4) meta = 'Passive income earned';
else if (t === 5) meta = `Referral commission${lvl}`;
else if (t === 6) meta = 'IVF → Wallet';
else if (lvl) meta = lvl;
}
}
const fullLabel = TX_LABELS[t] || m.label;
return `
${m.icon}
${m.label}${lvl}
${meta || '—'}
${rawAmt > 0 ? amt : '— '}
${dateStr} ${timeStr}
`;
}
// ═══════════════════════════════════════════════════════════
// ERROR PARSER
// ═══════════════════════════════════════════════════════════
function parseErr(e) {
const msg = (e?.reason || e?.data?.message || e?.message || String(e)).toLowerCase();
if (msg.includes('notsa') || msg.includes('not sa')) return 'Not authorized: SuperAdmin wallet required.';
if (msg.includes('novf') || msg.includes('no vf')) return 'Insufficient VF balance in source wallet.';
if (msg.includes('belowmin') || msg.includes('below min')) return 'Amount is below the minimum allowed.';
if (msg.includes('zeroaddr') || msg.includes('zero addr')) return 'Address cannot be zero.';
if (msg.includes('sameaddr') || msg.includes('same addr')) return 'New admin wallet is same as current.';
if (msg.includes('paused_') || msg.includes('paused')) return 'Contract is currently paused.';
if (msg.includes('notpaused') || msg.includes('not paused'))return 'Contract is not paused.';
if (msg.includes('nofunds') || msg.includes('no funds')) return 'Vault is empty.';
if (msg.includes('user rejected') || msg.includes('rejected')) return 'Transaction rejected by user.';
const raw = e?.reason || e?.message || String(e);
return raw.slice(0, 100) || 'Transaction failed.';
}
// ═══════════════════════════════════════════════════════════
// MISC
// ═══════════════════════════════════════════════════════════
window.addEventListener('resize', () => {
if (window.innerWidth > 768) closeSidebar();
});