DeFi Yield Farming & Staking Calculator
Yield Farming Calculator
Yield Farming Results
Staking Calculator
Staking Results
Investment Duration: ${resultsData.durationValueInput} ${resultsData.durationUnitInput} (${resultsData.durationInYears.toFixed(2)} years)
Input Rate: ${(resultsData.rateInput * 100).toFixed(2)}% ${resultsData.rateTypeInput}
${resultsData.rateTypeInput === 'APR' ? `Calculated Effective APY: ${(resultsData.calculatedEffectiveApy * 100).toFixed(2)}%
` : ''}Compounding: ${document.getElementById(`compounding${type.charAt(0).toUpperCase() + type.slice(1)}`).options[document.getElementById(`compounding${type.charAt(0).toUpperCase() + type.slice(1)}`).selectedIndex].text}
Gross Value (End of Period): $${resultsData.grossFutureValue.toFixed(2)}
Gross Profit: $${resultsData.grossProfit.toFixed(2)}
Fees (${(resultsData.feesInput * 100).toFixed(2)}% on profit): $${resultsData.feeAmount.toFixed(2)}
Net Profit (After Fees): $${resultsData.netProfit.toFixed(2)}
Net Value (End of Period, After Fees): $${resultsData.netFutureValue.toFixed(2)}
`; resultsEl.style.display = 'block'; } /** * Handles the calculation process. * @param {string} type - 'yieldFarming' or 'staking'. */ function handleCalculate(type) { const inputs = getInputs(type); if (!inputs) return; // Error already handled in getInputs if (!validateInputs(inputs, type)) { const resultsEl = (type === 'yieldFarming') ? resultsYieldFarmingEl : resultsStakingEl; if(resultsEl) resultsEl.style.display = 'none'; return; } const calculationResults = calculateReturns(inputs); displayResults(calculationResults, type); } /** * Generates and downloads a PDF of the results. * @param {string} type - 'yieldFarming' or 'staking'. */ function generateAndDownloadPdf(type) { const inputs = getInputs(type); if (!inputs) { alert('Could not retrieve input data for PDF generation. Please calculate first.'); return; } if (!validateInputs(inputs, type)) { // Re-validate before PDF generation alert('Invalid inputs. Please correct them before generating PDF.'); return; } const resultsData = calculateReturns(inputs); // Recalculate to ensure data is fresh if (!resultsData) { alert('Could not calculate results for PDF generation. Please try again.'); return; } const doc = new jsPDF(); const today = new Date(); const formattedDate = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`; const title = `${type === 'yieldFarming' ? 'DeFi Yield Farming' : 'DeFi Staking'} Calculation Report`; doc.setFontSize(18); doc.text(title, 14, 22); doc.setFontSize(11); doc.setTextColor(100); doc.text(`Report Generated: ${formattedDate}`, 14, 30); const headStyle = { fillColor: [79, 70, 229] }; // Indigo for header const bodyStyle = { minCellHeight: 9, fontSize: 10 }; const head = [['Parameter', 'Value']]; const inputBody = [ ['Principal Amount', `$${resultsData.initialPrincipal.toFixed(2)}`], ['Investment Duration', `${resultsData.durationValueInput} ${resultsData.durationUnitInput} (${resultsData.durationInYears.toFixed(2)} years)`], ['Input Rate', `${(resultsData.rateInput * 100).toFixed(2)}% ${resultsData.rateTypeInput}`], ['Compounding Frequency', `${document.getElementById(`compounding${type.charAt(0).toUpperCase() + type.slice(1)}`).options[document.getElementById(`compounding${type.charAt(0).toUpperCase() + type.slice(1)}`).selectedIndex].text}`], ['Overall Fees (on profit)', `${(resultsData.feesInput * 100).toFixed(2)}%`], ]; doc.autoTable({ startY: 40, head: [['Input Parameters', '']], body: inputBody, theme: 'striped', headStyles: headStyle, styles: bodyStyle, tableWidth: 'auto', columnStyles: { 0: { fontStyle: 'bold' } } }); const resultsBody = [ ...(resultsData.rateTypeInput === 'APR' ? [['Calculated Effective APY', `${(resultsData.calculatedEffectiveApy * 100).toFixed(2)}%`]] : []), ['Gross Value (End of Period)', `$${resultsData.grossFutureValue.toFixed(2)}`], ['Gross Profit', `$${resultsData.grossProfit.toFixed(2)}`], ['Total Fees Paid', `$${resultsData.feeAmount.toFixed(2)}`], ['Net Profit (After Fees)', `$${resultsData.netProfit.toFixed(2)}`], ['Net Value (End of Period, After Fees)', `$${resultsData.netFutureValue.toFixed(2)}`], ]; doc.autoTable({ startY: doc.lastAutoTable.finalY + 10, head: [['Calculation Results', '']], body: resultsBody, theme: 'striped', headStyles: headStyle, styles: bodyStyle, tableWidth: 'auto', columnStyles: { 0: { fontStyle: 'bold' } } }); doc.save(`${type}_results_${formattedDate}.pdf`); } // Event listener for DOMContentLoaded document.addEventListener('DOMContentLoaded', function() { // Assign DOM elements tabBtnYieldFarming = document.getElementById('tabBtnYieldFarming'); tabBtnStaking = document.getElementById('tabBtnStaking'); tabContentYieldFarming = document.getElementById('tabContentYieldFarming'); tabContentStaking = document.getElementById('tabContentStaking'); // Yield Farming elements principalYieldFarmingEl = document.getElementById('principalYieldFarming'); rateYieldFarmingEl = document.getElementById('rateYieldFarming'); rateTypeYieldFarmingEl = document.getElementById('rateTypeYieldFarming'); compoundingYieldFarmingEl = document.getElementById('compoundingYieldFarming'); durationYieldFarmingEl = document.getElementById('durationYieldFarming'); durationUnitYieldFarmingEl = document.getElementById('durationUnitYieldFarming'); feesYieldFarmingEl = document.getElementById('feesYieldFarming'); errorYieldFarmingEl = document.getElementById('errorYieldFarming'); resultsYieldFarmingEl = document.getElementById('resultsYieldFarming'); // Staking elements principalStakingEl = document.getElementById('principalStaking'); rateStakingEl = document.getElementById('rateStaking'); rateTypeStakingEl = document.getElementById('rateTypeStaking'); compoundingStakingEl = document.getElementById('compoundingStaking'); durationStakingEl = document.getElementById('durationStaking'); durationUnitStakingEl = document.getElementById('durationUnitStaking'); feesStakingEl = document.getElementById('feesStaking'); errorStakingEl = document.getElementById('errorStaking'); resultsStakingEl = document.getElementById('resultsStaking'); // Initial setup (e.g., ensure first tab is active) // switchTab('yieldFarming'); // Already handled by default classes // Null checks for critical elements to prevent runtime errors if HTML structure changes if (!tabBtnYieldFarming || !tabBtnStaking || !tabContentYieldFarming || !tabContentStaking) { console.error("Critical tab navigation elements are missing from the DOM."); // Optionally display a user-facing error message on the page itself const body = document.querySelector('body'); if (body) { const errorDiv = document.createElement('div'); errorDiv.textContent = "Error: Calculator UI could not be initialized. Please refresh the page or contact support."; errorDiv.style.color = "red"; errorDiv.style.textAlign = "center"; errorDiv.style.padding = "20px"; body.prepend(errorDiv); } } });