This repository contains the fixed OzoneXStaking smart contract along with a fully automated test suite and a modern, interactive dashboard for independently verifying the fixes.
We discovered and patched two critical vulnerabilities in the smart contract:
The Problem: The emergencyWithdrawUSDT and emergencyWithdrawOZONE functions allowed the contract owner to withdraw tokens from the contract in case of an emergency. However, these functions failed to deduct the withdrawn amount from the internal tracking variables (stakingUSDTReserves and ozoneReserves). This meant the contract would think it still had money it didn't, permanently breaking the reward math for all users.
The Fix: We added logic to explicitly deduct the withdrawal amount from internal reserves right before transferring the tokens out to the owner.
Solidity Fix (Line ~1105): stakingUSDTReserves -= _amount; and ozoneReserves -= _amount;
The Problem: The contract established a 15-day "claim interval" for locking user stakes, but the unstake function failed to actually check this interval. A malicious user could stake tokens and immediately unstake them seconds later without penalty, bypassing the lock structure entirely.
The Fix: We added a strict require statement inside the unstake function to enforce that the current block timestamp has exceeded the user's start time plus the configured lock interval.
Solidity Fix (Line ~902): require(block.timestamp >= userStake.startTime + pools[userStake.poolId].claimInterval, "Stake is still locked");
We built a beautiful, interactive local UI so you can manually interact with the fixed smart contract using an isolated Hardhat EVM node.
Make sure you have Node.js installed, then enter the test environment folder:
cd test-env
npm installStep 1: Start the Local Blockchain
Open a terminal locally, navigate to test-env, and run the simulated Hardhat node. Keep this terminal window running in the background!
npx hardhat nodeStep 2: Deploy the Contracts
Open a second terminal window in the test-env folder. Deploy the dummy tokens and the fixed staking contract to your local node. This script safely auto-seeds the contract with 5000 USDT/OZONE to test the internal reserves.
npx hardhat run scripts/deploy.js --network localhostStep 3: Launch the Testing Dashboard In the same second terminal window, launch the interactive UI using Vite:
npx viteOpen the provided local URL (usually http://localhost:5173/) in your browser!
The dashboard is split into two Bug Testing sections, seamlessly hooked up to private test keys specifically securely loaded with fake OZONE and USDT.
- In the top-right Wallet Panel, toggle the role to Owner.
- Click 1. Pause Contract. (Emergency withdrawals are heavily guarded and will revert unless the contract is officially paused by the owner).
- Under the Bug 1 section, enter an amount (e.g. 100) and click Withdraw USDT.
- Check the Contract Reserves grid at the top of the screen. You'll see the internal Reserve numbers flawlessly decrease, proving the math bug is fixed!
- In the top-right Wallet Panel, toggle the role to User.
- Click 1. Stake 100 OZONE. (Your active stake will immediately appear in the UI status grid).
- Click 2. Verify Early Unstake is Blocked. The execution logs at the bottom will prove that the contract safely intercepted the transaction, reverting it with a "Stake is still locked" error!
- Click 3. Fast Forward 15 Days. This calls an RPC method to simulate exactly 15 days of time passing strictly on your local blockchain node.
- Click 4. Click Here for Final Unstake. Because 15 days have legally passed on the chain, the contract will finally approve your withdrawal and refund you!
If you prefer terminal-based algorithmic verification, run the automated Mocha/Chai test suite we created which asserts these bug fixes sequentially behind the scenes without needing the graphical UI:
npx hardhat test