kycnot.me/src/utils/score.go

149 lines
3.9 KiB
Go

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
}*/