const { ethers } = require("hardhat"); async function main() { console.log("๐Ÿงช FORK TEST: Clear Stakes for Real User"); console.log("========================================"); console.log("Network: BSC Mainnet Fork"); console.log("Testing clearStakes functionality via PacaBotManager"); const targetUser = "0x41970Ce76b656030A79E7C1FA76FC4EB93980255"; const pacaProxyAddress = process.env.PROXY_ADDRESS_BSC || "0x3fF44D639a4982A4436f6d737430141aBE68b4E1"; const botManagerAddress = "0x4E5d3cD7743934b61041ba2ac3E9df39a0A26dcC"; // Deployed mainnet address console.log(`๐ŸŽฏ Target User: ${targetUser}`); console.log(`๐Ÿ”— PACA Proxy: ${pacaProxyAddress}`); console.log(`๐Ÿค– Bot Manager: ${botManagerAddress}`); // Connect to existing contracts on the fork const PacaFactory = await ethers.getContractFactory("PacaFinanceWithBoostAndScheduleBsc"); const paca = PacaFactory.attach(pacaProxyAddress); const BotManagerFactory = await ethers.getContractFactory("PacaBotManager"); const botManager = BotManagerFactory.attach(botManagerAddress); const [deployer] = await ethers.getSigners(); console.log(`๐Ÿ“ Using account: ${deployer.address}`); // ======================================== // PART 1: GET STAKES BEFORE CLEARING // ======================================== console.log("\n" + "=".repeat(60)); console.log("๐Ÿ“Š GETTING STAKES **BEFORE** CLEARING"); console.log("=".repeat(60)); let stakesBefore; try { stakesBefore = await paca.getStakes(targetUser); console.log(`\n๐Ÿ“ˆ getStakes() returned ${stakesBefore.length} stakes BEFORE clearing:`); if (stakesBefore.length === 0) { console.log("๐Ÿ“ญ No stakes found for this user"); console.log("โš ๏ธ This could mean:"); console.log(" โ€ข User has no active stakes"); console.log(" โ€ข All stakes have been withdrawn"); console.log(" โ€ข Connected to wrong contract address"); return; } let totalAmountBefore = 0n; let activeStakesBefore = 0; stakesBefore.forEach((stake, i) => { const isActive = !stake.complete && stake.amount > 0n; if (isActive) { activeStakesBefore++; totalAmountBefore += stake.amount; } console.log(`\n ๐Ÿ“Œ Stake ${i + 1} BEFORE:`); console.log(` Amount: ${ethers.formatEther(stake.amount)} ETH`); console.log(` Complete: ${stake.complete}`); console.log(` Status: ${isActive ? "๐ŸŸข ACTIVE" : "๐Ÿ”ด COMPLETED"}`); // Show additional stake details if available if (stake.startTime && stake.startTime > 0) { const startDate = new Date(Number(stake.startTime) * 1000); console.log(` Start Time: ${startDate.toLocaleString()}`); } if (stake.endTime && stake.endTime > 0) { const endDate = new Date(Number(stake.endTime) * 1000); console.log(` End Time: ${endDate.toLocaleString()}`); } }); console.log(`\n๐Ÿ’Ž SUMMARY BEFORE:`); console.log(` Total Stakes: ${stakesBefore.length}`); console.log(` Active Stakes: ${activeStakesBefore}`); console.log(` Total Active Amount: ${ethers.formatEther(totalAmountBefore)} ETH`); if (activeStakesBefore === 0) { console.log("\nโš ๏ธ No active stakes to clear!"); return; } } catch (error) { console.log(`โŒ Error getting stakes BEFORE: ${error.message}`); // Check if contract exists and is accessible try { const contractCode = await ethers.provider.getCode(pacaProxyAddress); console.log(` Contract has code: ${contractCode.length > 2 ? "โœ… YES" : "โŒ NO"}`); } catch (codeError) { console.log(` Contract code check failed: ${codeError.message}`); } return; } // ======================================== // PART 2: EXECUTE CLEARING VIA BOT MANAGER // ======================================== console.log("\n" + "=".repeat(60)); console.log("๐Ÿ”ฅ EXECUTING clearStakes() VIA BOTMANAGER"); console.log("=".repeat(60)); try { console.log("\nโšก Calling botManager.clearStakes()..."); // Check if bot manager is authorized first const isBotAuthorized = await paca.authorizedBots(botManagerAddress); console.log(`๐Ÿ” Bot Manager authorized: ${isBotAuthorized}`); if (!isBotAuthorized) { console.log("โŒ Bot Manager is not authorized! Cannot proceed."); return; } const clearTx = await botManager.connect(deployer).clearStakes(pacaProxyAddress, targetUser); const receipt = await clearTx.wait(); console.log(`โœ… clearStakes() executed successfully!`); console.log(`โ›ฝ Gas used: ${receipt.gasUsed.toString()}`); console.log(`๐Ÿงพ Transaction: ${receipt.hash}`); // Check for events console.log(`\n๐Ÿ“ก Transaction Events:`); receipt.logs.forEach((log, i) => { try { const parsedLog = botManager.interface.parseLog(log); console.log(` Event ${i + 1}: ${parsedLog.name}`); if (parsedLog.args) { Object.keys(parsedLog.args).forEach(key => { if (isNaN(key)) { // Only show named parameters console.log(` ${key}: ${parsedLog.args[key]}`); } }); } } catch (parseError) { // Not a bot manager event, try PACA events try { const pacaParsedLog = paca.interface.parseLog(log); console.log(` Event ${i + 1}: ${pacaParsedLog.name} (from PACA)`); } catch (pacaParseError) { console.log(` Event ${i + 1}: Unknown event`); } } }); } catch (error) { console.log(`โŒ Failed to execute clearStakes: ${error.message}`); if (error.data) { console.log(`๐Ÿ” Error data: ${error.data}`); } return; } // ======================================== // PART 3: GET STAKES AFTER CLEARING // ======================================== console.log("\n" + "=".repeat(60)); console.log("๐Ÿ“Š GETTING STAKES **AFTER** CLEARING"); console.log("=".repeat(60)); try { const stakesAfter = await paca.getStakes(targetUser); console.log(`\n๐Ÿ“ˆ getStakes() returned ${stakesAfter.length} stakes AFTER clearing:`); let totalAmountAfter = 0n; let activeStakesAfter = 0; let clearedStakes = 0; stakesAfter.forEach((stake, i) => { const isActive = !stake.complete && stake.amount > 0n; const wasCleared = stake.complete && stake.amount === 0n; if (isActive) { activeStakesAfter++; totalAmountAfter += stake.amount; } if (wasCleared) { clearedStakes++; } console.log(`\n ๐Ÿ“Œ Stake ${i + 1} AFTER:`); console.log(` Amount: ${ethers.formatEther(stake.amount)} ETH`); console.log(` Complete: ${stake.complete}`); console.log(` Status: ${wasCleared ? "โœ… CLEARED" : isActive ? "๐ŸŸข STILL ACTIVE" : "โ“ UNKNOWN"}`); }); console.log(`\n๐Ÿ’Ž SUMMARY AFTER:`); console.log(` Total Stakes: ${stakesAfter.length}`); console.log(` Active Stakes: ${activeStakesAfter}`); console.log(` Cleared Stakes: ${clearedStakes}`); console.log(` Total Active Amount: ${ethers.formatEther(totalAmountAfter)} ETH`); // ======================================== // PART 4: COMPARISON & VERIFICATION // ======================================== console.log("\n" + "=".repeat(60)); console.log("๐ŸŽฏ BEFORE vs AFTER COMPARISON"); console.log("=".repeat(60)); const stakesBefore_active = stakesBefore.filter(stake => !stake.complete && stake.amount > 0n).length; const totalBefore = stakesBefore.reduce((sum, stake) => sum + stake.amount, 0n); console.log(`\n๐Ÿ“Š STAKES COUNT:`); console.log(` Before: ${stakesBefore.length} total`); console.log(` After: ${stakesAfter.length} total`); console.log(` Change: ${stakesAfter.length === stakesBefore.length ? "โœ… SAME (expected)" : "โŒ DIFFERENT"}`); console.log(`\n๐ŸŸข ACTIVE STAKES:`); console.log(` Before: ${stakesBefore_active} active`); console.log(` After: ${activeStakesAfter} active`); console.log(` Cleared: ${stakesBefore_active - activeStakesAfter} stakes`); console.log(`\n๐Ÿ’ฐ TOTAL AMOUNT STAKED:`); console.log(` Before: ${ethers.formatEther(totalBefore)} ETH`); console.log(` After: ${ethers.formatEther(totalAmountAfter)} ETH`); console.log(` Difference: ${ethers.formatEther(totalBefore - totalAmountAfter)} ETH cleared`); // FINAL VERIFICATION console.log(`\n๐Ÿ” VERIFICATION RESULTS:`); const allAmountsZeroed = stakesAfter.every(stake => stake.amount === 0n); const allMarkedComplete = stakesAfter.every(stake => stake.complete === true); const noActiveStakes = activeStakesAfter === 0; console.log(` โœ… All amounts zeroed: ${allAmountsZeroed}`); console.log(` โœ… All marked complete: ${allMarkedComplete}`); console.log(` โœ… No active stakes remaining: ${noActiveStakes}`); if (allAmountsZeroed && allMarkedComplete && noActiveStakes) { console.log(`\n๐ŸŽ‰ SUCCESS! Stakes cleared completely!`); console.log(` - Cleared ${stakesBefore_active} active stakes`); console.log(` - Zeroed out ${ethers.formatEther(totalBefore)} ETH`); console.log(` - All stakes marked as complete`); } else { console.log(`\nโš ๏ธ PARTIAL SUCCESS or FAILURE:`); console.log(` - Some stakes may not have been cleared properly`); if (!allAmountsZeroed) console.log(` - Not all amounts were zeroed`); if (!allMarkedComplete) console.log(` - Not all stakes marked as complete`); if (!noActiveStakes) console.log(` - Still have active stakes remaining`); } } catch (error) { console.log(`โŒ Error getting stakes AFTER: ${error.message}`); } console.log("\n" + "=".repeat(60)); console.log("๐Ÿ FORK TEST COMPLETED"); console.log("=".repeat(60)); console.log(`๐ŸŽฏ Target User: ${targetUser}`); console.log(`๐Ÿ”— PACA Contract: ${pacaProxyAddress}`); console.log(`๐Ÿค– Bot Manager: ${botManagerAddress}`); console.log(`โš ๏ธ NOTE: This was a FORK TEST - no real funds affected!`); } main() .then(() => process.exit(0)) .catch((error) => { console.error("๐Ÿ’ฅ Fork test failed:", error); process.exit(1); });