package utils import ( "fmt" "math" "pluja.dev/kycnot.me/database" ) func ComputeScore(s *database.Service) (int, string) { summary := fmt.Sprintf("SCORE BREAKDOWN - %s:\n", s.Name) summary += "\n||-----------------------------------------------" grade := float64(10) // KYC Level Adjustment switch s.KycLevel { case 0: grade = 8 summary += fmt.Sprintf("\n%-*s--> base score for KYC Level %d", 10, fmt.Sprintf("|| %v", grade), s.KycLevel) case 1: grade = 6.5 summary += fmt.Sprintf("\n%-*s--> base score for KYC Level %d", 10, fmt.Sprintf("|| %v", grade), s.KycLevel) case 2: grade = 6 summary += fmt.Sprintf("\n%-*s--> base score for KYC Level %d", 10, fmt.Sprintf("|| %v", grade), s.KycLevel) case 3: grade = 5 summary += fmt.Sprintf("\n%-*s--> base score for KYC Level %d", 10, fmt.Sprintf("|| %v", grade), s.KycLevel) } // Attributes for _, attr := range s.Expand["attributes"] { switch attr.Rating { case "good": grade += 0.1 summary += fmt.Sprintf("\n%-*s--> good attribute.", 10, "|| +0.1") case "warn": grade -= 0.3 summary += fmt.Sprintf("\n%-*s--> warn attribute.", 10, "|| -0.25") case "bad": grade -= 0.7 summary += fmt.Sprintf("\n%-*s--> bad attribute.", 10, "|| -0.65") } } // Tos Highlights Penalty if s.TosReviews == nil { s.TosReviews = []database.TosReview{} } trPenalty := 0.0 wrns := 0 for _, tr := range s.TosReviews { if tr.Warning { trPenalty -= 0.02 wrns++ } } // Tos reviews penalty can't be over 3 points if trPenalty < -3 { trPenalty = -3 } grade += float64(trPenalty) if trPenalty != 0 { summary += fmt.Sprintf("\n|| %-*f--> %d terms of service warnings.", 10, trPenalty, wrns) } // Cash/Monero Bonus if s.Cash || s.Xmr || s.Btc { grade += 0.25 summary += fmt.Sprintf("\n%-*s--> accepting Cash/BTC.", 10, "|| +0.25") if s.Xmr { grade += 0.25 summary += fmt.Sprintf("\n%-*s--> accepting XMR.", 10, "|| +0.25") } } // TODO: Manage bonuses // P2P/OpenSource Bonus isP2PNetwork := false isP2PTrading := false isOpenSource := false for _, attr := range s.Attributes { if attr == database.AttributeP2PNetwork { isP2PNetwork = true } if attr == database.AttributeP2PTrading { isP2PTrading = true } if attr == database.AttributeOpenSource { isOpenSource = true } } // Tor URL Bonus if len(s.OnionUrls) > 0 && s.OnionUrls[0] != "" { grade += 0.5 summary += fmt.Sprintf("\n%-*s--> has Onion links.", 10, "|| +0.5") } // Verified services get a bonus only if score is < 7.5 if s.Verified { if grade < 7.5 { grade += 0.5 summary += fmt.Sprintf("\n%-*s--> verified bonus (only if <7.5).", 10, "|| +0.5") } } // P2P networks or trading have a bonus if isP2PNetwork || isP2PTrading { grade += 0.5 summary += fmt.Sprintf("\n%-*s--> P2P network bonus.", 10, "|| +0.5") } // Only P2P Networks can have a 10/10 if !isP2PNetwork && grade > 9.5 { grade = 9 summary += fmt.Sprintf("\n%-*s--> Not P2P network, score can't be 10.", 10, "|| ----") } // Open source services have a bonus if score is < 7.5 if isOpenSource && grade < 7.5 { grade += 0.25 summary += fmt.Sprintf("\n%-*s--> Open Source bonus (if < 7.5).", 10, "|| +0.25") } // Normalize the grade to be within 0-10 bounds grade = math.Min(10, math.Max(0, grade)) summary += "\n||-----------------------------------------------" summary += fmt.Sprintf("\n|| %-*v--> Total (rounded to even)", 6, math.RoundToEven(grade)) // Call ComputeScore to get the actual score summary += "\n||-----------------------------------------------" summary += "\n\n\nCheck out the score algorithm here: https://github.com/pluja/kycnot.me\nIf you think there's a better way to compute score, please, open an issue with your ideas." return int(math.RoundToEven(grade)), summary } /*func UpdateScore(s *ent.Service) error { score := ComputeScore(s) ctx := context.Background() _, err := database.Client.Service.UpdateOneID(s.ID).SetScore(score).Save(ctx) return err }*/