-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathswap.go
79 lines (67 loc) · 2.31 KB
/
swap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package antispam
import (
"context"
"github.com/sirupsen/logrus"
"github.com/code-payments/code-server/pkg/code/common"
"github.com/code-payments/code-server/pkg/code/data/phone"
"github.com/code-payments/code-server/pkg/code/data/user/identity"
"github.com/code-payments/code-server/pkg/grpc/client"
"github.com/code-payments/code-server/pkg/metrics"
)
// AllowSwap determines whether a phone-verified owner account can perform a swap.
// The objective here is to limit attacks against our Swap Subsidizer's SOL balance.
//
// todo: needs tests
func (g *Guard) AllowSwap(ctx context.Context, owner *common.Account) (bool, error) {
tracer := metrics.TraceMethodCall(ctx, metricsStructName, "AllowSwap")
defer tracer.End()
log := g.log.WithFields(logrus.Fields{
"method": "AllowSwap",
"owner": owner.PublicKey().ToBase58(),
})
log = client.InjectLoggingMetadata(ctx, log)
// Deny abusers from known IPs
if isIpBanned(ctx) {
log.Info("ip is banned")
recordDenialEvent(ctx, actionSwap, "ip banned")
return false, nil
}
verification, err := g.data.GetLatestPhoneVerificationForAccount(ctx, owner.PublicKey().ToBase58())
if err == phone.ErrVerificationNotFound {
// Owner account was never phone verified, so deny the action.
log.Info("owner account is not phone verified")
recordDenialEvent(ctx, actionSwap, "not phone verified")
return false, nil
} else if err != nil {
tracer.OnError(err)
log.WithError(err).Warn("failure getting phone verification record")
return false, err
}
log = log.WithField("phone", verification.PhoneNumber)
// Deny abusers from known phone ranges
if hasBannedPhoneNumberPrefix(verification.PhoneNumber) {
log.Info("denying phone prefix")
recordDenialEvent(ctx, actionSwap, "phone prefix banned")
return false, nil
}
user, err := g.data.GetUserByPhoneView(ctx, verification.PhoneNumber)
switch err {
case nil:
// Deny banned users forever
if user.IsBanned {
log.Info("denying banned user")
recordDenialEvent(ctx, actionSwap, "user banned")
return false, nil
}
// Staff users have unlimited access to enable testing and demoing.
if user.IsStaffUser {
return true, nil
}
case identity.ErrNotFound:
default:
tracer.OnError(err)
log.WithError(err).Warn("failure getting user identity by phone view")
return false, err
}
return true, nil
}