DeFi Risk & Reward Analyzer (Self-Assessment)

A framework to guide your research and subjective assessment of a DeFi opportunity.

Important: DeFi is high-risk. This tool is for educational and self-assessment purposes ONLY. Data is user-inputted, and APY/APRs change rapidly. This tool does NOT provide investment advice or endorse any platform. Scores are based on YOUR ratings. Always Do Your Own Research (DYOR) and consult a financial advisor.

${errorInRewards ? 'N/A' : this.formatPercent(calculatedApy)}

Projected Future Value

${errorInRewards ? 'N/A' : this.formatCurrency(futureValue)}

Est. Gross Interest

${errorInRewards ? 'N/A' : this.formatCurrency(totalInterest)}

(Setup Fees: ${this.formatCurrency(setupFees)})

Est. Net Return

${errorInRewards ? 'N/A' : this.formatCurrency(netReturn)}

`; resultsHtml += `

Your Risk Assessment Summary

Risk LevelCount
High Concern / Significant Risk${riskSummary.HighConcern}
Medium Concern / Needs Monitoring${riskSummary.MediumConcern}
Low Concern / Well Mitigated${riskSummary.LowConcern}
Not Assessed / N/A${riskSummary.NotAssessed}
`; resultsHtml += `

Overall Considerations Based on Your Assessment:

    `; if(errorInRewards){ resultsHtml += `
  • Could not calculate reward projection due to missing/invalid inputs for opportunity details.
  • `; } if (riskSummary.HighConcern > 0) { resultsHtml += `
  • You've identified ${riskSummary.HighConcern} area(s) of 'High Concern'. These represent significant risks that you perceive for this opportunity. Thoroughly review these before proceeding.
  • `; } if (riskSummary.MediumConcern > 0) { resultsHtml += `
  • Your assessment includes ${riskSummary.MediumConcern} area(s) of 'Medium Concern'. These warrant careful monitoring and further investigation.
  • `; } if (riskSummary.HighConcern === 0 && riskSummary.MediumConcern === 0 && riskSummary.LowConcern > 0) { resultsHtml += `
  • Based on your ratings, you perceive mostly 'Low Concern' or well-mitigated risks for the assessed criteria.
  • `; } if (riskSummary.NotAssessed > 0 && totalRiskCriteria > riskSummary.NotAssessed) { resultsHtml += `
  • There are ${riskSummary.NotAssessed} criteria you marked as 'Not Assessed / N/A'. Completing these assessments could provide a more comprehensive view.
  • `; } else if (totalRiskCriteria === riskSummary.NotAssessed && totalRiskCriteria > 0){ resultsHtml += `
  • All risk criteria were marked as 'Not Assessed / N/A'. A thorough risk assessment is crucial in DeFi.
  • `;} resultsHtml += `
  • Always weigh the potential rewards (Projected APY: ${errorInRewards ? 'N/A': this.formatPercent(calculatedApy)}) against your self-assessed risks. Higher returns in DeFi often correlate with higher risks.
  • `; resultsHtml += `
  • This analysis is a reflection of YOUR inputs and understanding. Continue to DYOR and consider consulting multiple sources.
  • `; resultsHtml += `
`; resultsOutputEl.innerHTML = resultsHtml; const pdfBtnSection = document.getElementById('defiPdfDownloadSectionResults'); if(pdfBtnSection) pdfBtnSection.style.display = 'block'; }, getCompoundingPeriods(freqString) { // Copied from thought block switch(freqString) { case 'daily': return 365; case 'weekly': return 52; case 'monthly': return 12; case 'annually': return 1; case 'continuous': return Infinity; default: return 0; } }, formatCurrency: function(value, addSymbol = true) { // General helper if (isNaN(value) || value === null || !isFinite(value)) return addSymbol ? '$ --' : '--'; const symbol = addSymbol ? '$ ' : ''; return symbol + Number(value).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }, formatPercent: function(value, decimals = 2) { // General helper if (isNaN(value) || value === null || !isFinite(value)) return '-- %'; return Number(value).toFixed(decimals) + ' %'; }, generatePDF: async function() { // Copied and adapted from thought block if (!window.jspdf || !window.html2canvas || Object.keys(this.userInputData.opportunity).length === 0) { alert('Please input opportunity details and perform an analysis first.'); return; } await new Promise(resolve => setTimeout(resolve, 50)); const pdfExportContainer = document.createElement('div'); pdfExportContainer.classList.add('defirra-pdf-export-content'); pdfExportContainer.style.width = '800px'; let pdfHtml = `

DeFi Risk & Reward Analysis Report

`; pdfHtml += `
Disclaimer: This report is based on user-inputted data and subjective risk assessments. It is for educational purposes only and NOT investment advice. DeFi is high-risk. DYOR.
`; const opp = this.userInputData.opportunity || {}; pdfHtml += `

Opportunity Details & Reward Projection

`; pdfHtml += `
Platform: ${opp.platformName || 'N/A'}
`; pdfHtml += `
Protocol/Pool: ${opp.protocolName || 'N/A'}
`; pdfHtml += `
Token(s): ${opp.tokensInvolved || 'N/A'}
`; pdfHtml += `
Investment Amount: ${this.formatCurrency(parseFloat(opp.investmentAmount), false)}
`; pdfHtml += `
Quoted Rate: ${parseFloat(opp.quotedRate).toFixed(2)} (${opp.rateType || 'N/A'})
`; if (opp.rateType === 'APR') { pdfHtml += `
Compounding: ${opp.compoundingFrequencyOpp || 'N/A'}
`; } pdfHtml += `
Term: ${opp.investmentTermOpp} ${opp.termUnitOpp}
`; pdfHtml += `
Est. Setup Fees: ${this.formatCurrency(parseFloat(opp.setupFees) || 0, false)}
`; const reward = this.userInputData.calculatedReward || {}; pdfHtml += `

Projected Rewards (Illustrative):

`; pdfHtml += `
Calculated APY: ${this.formatPercent(reward.calculatedApy).replace(' %','')}
`; pdfHtml += `
Future Value: ${this.formatCurrency(reward.futureValue, false)}
`; pdfHtml += `
Gross Interest: ${this.formatCurrency(reward.totalInterest, false)}
`; pdfHtml += `
Net Return (after setup fees): ${this.formatCurrency(reward.netReturn, false)}
`; pdfHtml += `
`; pdfHtml += `

Your Risk Assessment Details

`; pdfHtml += ``; for (const categoryId in this.riskAssessmentCriteria) { const category = this.riskAssessmentCriteria[categoryId]; if (category.isResultTab || !category.items) continue; category.items.forEach((item, index) => { const riskData = (this.userInputData.risks[categoryId] && this.userInputData.risks[categoryId][item.id]) || { score: 0, notes: '' }; const ratingOpt = this.riskRatingOptions.find(opt => opt.value === riskData.score); const ratingText = ratingOpt ? ratingOpt.text : 'N/A'; let ratingClass = ''; if(ratingOpt) { if(ratingOpt.value === 3) ratingClass = 'rating-HighConcern-pdf'; else if(ratingOpt.value === 2) ratingClass = 'rating-MediumConcern-pdf'; else if(ratingOpt.value === 1) ratingClass = 'rating-LowConcern-pdf'; } pdfHtml += ` ${index === 0 ? `` : ''} `; }); } pdfHtml += `
CategoryCriterionYour RatingYour Notes
${category.title}${item.text} ${ratingText} ${(riskData.notes || '--').replace(/\n/g, '
')}
`; const riskSummary = this.userInputData.riskSummary || { HighConcern: 0, MediumConcern: 0, LowConcern: 0, NotAssessed: 0 }; pdfHtml += `

Risk Summary Counts:

`; pdfHtml += `

High Concern: ${riskSummary.HighConcern} | Medium Concern: ${riskSummary.MediumConcern} | Low Concern: ${riskSummary.LowConcern} | Not Assessed: ${riskSummary.NotAssessed}

`; pdfHtml += `
`; const qualitativeFeedbackEl = document.querySelector('#defiResultsOutput .defirra-qualitative-feedback'); if(qualitativeFeedbackEl) { pdfHtml += `

Overall Considerations (Based on Your Assessment)

${qualitativeFeedbackEl.innerHTML.replace(/

.*?<\/h4>/, '')}

`; } pdfExportContainer.innerHTML = pdfHtml; document.body.appendChild(pdfExportContainer); try { const canvas = await html2canvas(pdfExportContainer, { scale: 1.2, useCORS: true, logging: false, windowWidth: pdfExportContainer.scrollWidth, windowHeight: pdfExportContainer.scrollHeight }); document.body.removeChild(pdfExportContainer); const imgData = canvas.toDataURL('image/png'); const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgProps = pdf.getImageProperties(imgData); let imgFinalWidth = pdfWidth - 40; let imgFinalHeight = (imgProps.height * imgFinalWidth) / imgProps.width; if (imgFinalHeight > pdfHeight - 40) { // Check if it exceeds one page height // Simple approach for now: scale to fit one page width, height will be proportional // For true multi-page from a single large canvas, more complex slicing of imgData is needed // Or, ensure content is short enough, or accept scrolling in image if PDF viewer supports. // Forcing it onto one page by potentially reducing scale further if too tall: if (imgFinalHeight > pdfHeight - 40) { imgFinalHeight = pdfHeight - 40; // Max height imgFinalWidth = (imgProps.width * imgFinalHeight) / imgProps.height; // Adjust width to maintain aspect ratio } } let position = 20; // This simple addImage might not handle multi-page perfectly for very long content. // For a robust multi-page for very long content, one would typically segment the HTML // or use more advanced jsPDF features with `addHTML` (which has its own complexities) // or split the canvas. For now, it will attempt to fit on one or more pages by scaling. // The loop for multiple pages from previous thought block is good if image can be sliced. // Here's a simplified version that just adds the (potentially long) image. let currentY = position; const pageMargin = 20; const pageHeightAvailable = pdfHeight - 2 * pageMargin; let heightProcessed = 0; while(heightProcessed < imgHeight) { let pageSegmentHeight = Math.min(imgHeight - heightProcessed, pageHeightAvailable); // Create a temporary canvas for the segment const segmentCanvas = document.createElement('canvas'); segmentCanvas.width = canvas.width; // Use original canvas width for source slicing segmentCanvas.height = (pageSegmentHeight / imgHeight) * canvas.height; // Proportional height from original canvas const sctx = segmentCanvas.getContext('2d'); // Source y, source height sctx.drawImage(canvas, 0, (heightProcessed / imgHeight) * canvas.height, canvas.width, segmentCanvas.height, 0, 0, segmentCanvas.width, segmentCanvas.height); const segmentImgData = segmentCanvas.toDataURL('image/png'); const segmentImgProps = pdf.getImageProperties(segmentImgData); let segmentFinalWidth = pdfWidth - 2 * pageMargin; let segmentFinalHeight = (segmentImgProps.height * segmentFinalWidth) / segmentImgProps.width; // Ensure segment fits on current page (it should, as pageSegmentHeight was capped) if(segmentFinalHeight > pageHeightAvailable) { // Should not happen if logic above is correct segmentFinalHeight = pageHeightAvailable; segmentFinalWidth = (segmentImgProps.width * segmentFinalHeight) / segmentImgProps.height; } if(heightProcessed > 0) pdf.addPage(); pdf.addImage(segmentImgData, 'PNG', pageMargin, pageMargin, segmentFinalWidth, segmentFinalHeight); heightProcessed += pageSegmentHeight * (imgHeight / canvas.height) * (canvas.height / segmentCanvas.height); // track original image height processed } pdf.save('DeFi_Risk_Reward_Analysis.pdf'); } catch (error) { console.error("Error generating PDF:", error); alert("An error occurred while generating PDF."); if (document.body.contains(pdfExportContainer)) document.body.removeChild(pdfExportContainer); } } }; document.addEventListener('DOMContentLoaded', function() { defiRRAApp.init(); });
Scroll to Top