Skip to content

Commit c20fd3c

Browse files
committed
Withdrawals are not subject to limits
1 parent 65f70d6 commit c20fd3c

File tree

5 files changed

+53
-18
lines changed

5 files changed

+53
-18
lines changed

pkg/code/aml/guard.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,12 @@ func (g *Guard) AllowMoneyMovement(ctx context.Context, intentRecord *intent.Rec
4949
var action string
5050
switch intentRecord.IntentType {
5151
case intent.SendPublicPayment:
52-
// Public sends are subject to limits
52+
// Public withdrawals are always allowed
53+
if intentRecord.SendPublicPaymentMetadata.IsWithdrawal {
54+
return true, nil
55+
}
56+
57+
// Public gives and sends are subject to limits
5358
currency = intentRecord.SendPublicPaymentMetadata.ExchangeCurrency
5459
nativeAmount = intentRecord.SendPublicPaymentMetadata.NativeAmount
5560
usdMarketValue = intentRecord.SendPublicPaymentMetadata.UsdMarketValue

pkg/code/aml/guard_test.go

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,26 @@ func TestGuard_SendPublicPayment_PerTransactionValue(t *testing.T) {
2828
limit.SendLimits[currency_lib.USD].PerTransaction - 1,
2929
limit.SendLimits[currency_lib.USD].PerTransaction,
3030
} {
31-
intentRecord := makeSendPublicPaymentIntent(t, owner, acceptableValue, time.Now())
31+
for _, isWithdraw := range []bool{true, false} {
32+
intentRecord := makeSendPublicPaymentIntent(t, owner, acceptableValue, isWithdraw, time.Now())
3233

33-
allow, err := env.guard.AllowMoneyMovement(env.ctx, intentRecord)
34-
require.NoError(t, err)
35-
assert.True(t, allow)
34+
allow, err := env.guard.AllowMoneyMovement(env.ctx, intentRecord)
35+
require.NoError(t, err)
36+
assert.True(t, allow)
37+
}
3638
}
3739

3840
for _, unacceptableValue := range []float64{
3941
limit.SendLimits[currency_lib.USD].PerTransaction + 1,
4042
limit.SendLimits[currency_lib.USD].PerTransaction * 10,
4143
} {
42-
intentRecord := makeSendPublicPaymentIntent(t, owner, unacceptableValue, time.Now())
44+
for _, isWithdraw := range []bool{true, false} {
45+
intentRecord := makeSendPublicPaymentIntent(t, owner, unacceptableValue, isWithdraw, time.Now())
4346

44-
allow, err := env.guard.AllowMoneyMovement(env.ctx, intentRecord)
45-
require.NoError(t, err)
46-
assert.False(t, allow)
47+
allow, err := env.guard.AllowMoneyMovement(env.ctx, intentRecord)
48+
require.NoError(t, err)
49+
assert.Equal(t, isWithdraw, allow)
50+
}
4751
}
4852
}
4953

@@ -87,20 +91,29 @@ func TestGuard_SendPublicPayment_DailyUsdLimit(t *testing.T) {
8791
},
8892
} {
8993
owner := testutil.NewRandomAccount(t)
90-
intentRecord := makeSendPublicPaymentIntent(t, owner, 1, time.Now())
94+
giveIntentRecord := makeSendPublicPaymentIntent(t, owner, 1, false, time.Now())
95+
withdrawIntentRecord := makeSendPublicPaymentIntent(t, owner, 1, true, time.Now())
9196

92-
// Sanity check the intent for $1 USD is allowed
93-
allow, err := env.guard.AllowMoneyMovement(env.ctx, intentRecord)
97+
// Sanity check the intents for $1 USD is allowed
98+
allow, err := env.guard.AllowMoneyMovement(env.ctx, giveIntentRecord)
99+
require.NoError(t, err)
100+
assert.True(t, allow)
101+
allow, err = env.guard.AllowMoneyMovement(env.ctx, withdrawIntentRecord)
94102
require.NoError(t, err)
95103
assert.True(t, allow)
96104

97105
// Save an intent to bring the user up to the desired consumed daily USD value
98-
require.NoError(t, env.data.SaveIntent(env.ctx, makeSendPublicPaymentIntent(t, owner, tc.consumedUsdValue, tc.at)))
106+
require.NoError(t, env.data.SaveIntent(env.ctx, makeSendPublicPaymentIntent(t, owner, tc.consumedUsdValue, false, tc.at)))
99107

100-
// Check whether we allow the $1 USD intent
101-
allow, err = env.guard.AllowMoneyMovement(env.ctx, intentRecord)
108+
// Check whether we allow the $1 USD give intent
109+
allow, err = env.guard.AllowMoneyMovement(env.ctx, giveIntentRecord)
102110
require.NoError(t, err)
103111
assert.Equal(t, tc.expected, allow)
112+
113+
// Check whether we allow the $1 USD withdraw intent
114+
allow, err = env.guard.AllowMoneyMovement(env.ctx, withdrawIntentRecord)
115+
require.NoError(t, err)
116+
assert.True(t, allow)
104117
}
105118
}
106119

@@ -145,7 +158,7 @@ func setupAmlTest(t *testing.T) (env amlTestEnv) {
145158
return env
146159
}
147160

148-
func makeSendPublicPaymentIntent(t *testing.T, owner *common.Account, usdMarketValue float64, at time.Time) *intent.Record {
161+
func makeSendPublicPaymentIntent(t *testing.T, owner *common.Account, usdMarketValue float64, isWithdraw bool, at time.Time) *intent.Record {
149162
return &intent.Record{
150163
IntentId: testutil.NewRandomAccount(t).PublicKey().ToBase58(),
151164
IntentType: intent.SendPublicPayment,
@@ -159,6 +172,8 @@ func makeSendPublicPaymentIntent(t *testing.T, owner *common.Account, usdMarketV
159172
ExchangeCurrency: currency_lib.USD,
160173
NativeAmount: usdMarketValue,
161174
UsdMarketValue: usdMarketValue,
175+
176+
IsWithdrawal: isWithdraw,
162177
},
163178

164179
InitiatorOwnerAccount: owner.PublicKey().ToBase58(),

pkg/code/data/intent/memory/store.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,19 @@ func (s *store) filterByRemoteSendFlag(items []*intent.Record, want bool) []*int
217217
return res
218218
}
219219

220+
func (s *store) filterByWithdrawalFlag(items []*intent.Record, want bool) []*intent.Record {
221+
var res []*intent.Record
222+
for _, item := range items {
223+
switch item.IntentType {
224+
case intent.SendPublicPayment:
225+
if item.SendPublicPaymentMetadata.IsWithdrawal == want {
226+
res = append(res, item)
227+
}
228+
}
229+
}
230+
return res
231+
}
232+
220233
func sumQuarkAmount(items []*intent.Record) uint64 {
221234
var value uint64
222235
for _, item := range items {
@@ -363,7 +376,8 @@ func (s *store) GetTransactedAmountForAntiMoneyLaundering(ctx context.Context, o
363376
defer s.mu.Unlock()
364377

365378
items := s.findByOwnerSinceTimestamp(owner, since)
366-
items = s.filterByState(items, false, intent.StateRevoked)
367379
items = s.filterByType(items, intent.SendPublicPayment)
380+
items = s.filterByState(items, false, intent.StateRevoked)
381+
items = s.filterByWithdrawalFlag(items, false)
368382
return sumQuarkAmount(items), sumUsdMarketValue(items), nil
369383
}

pkg/code/data/intent/postgres/model.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ func dbGetTransactedAmountForAntiMoneyLaundering(ctx context.Context, db *sqlx.D
324324
}{}
325325

326326
query := `SELECT SUM(quantity) AS total_quark_value, SUM(usd_market_value) AS total_usd_value FROM ` + intentTableName + `
327-
WHERE owner = $1 AND created_at >= $2 AND intent_type = $3 AND state != $4
327+
WHERE owner = $1 AND created_at >= $2 AND intent_type = $3 AND state != $4 AND is_withdraw = FALSE
328328
`
329329
err := db.GetContext(
330330
ctx,

pkg/code/data/intent/tests/tests.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ func testGetTransactedAmountForAntiMoneyLaundering(t *testing.T, s intent.Store)
370370
{IntentId: "t5", IntentType: intent.SendPublicPayment, InitiatorOwnerAccount: "o1", SendPublicPaymentMetadata: &intent.SendPublicPaymentMetadata{DestinationOwnerAccount: "o5", DestinationTokenAccount: "a5", Quantity: 10000, ExchangeCurrency: currency.USD, ExchangeRate: 2, NativeAmount: 20000, UsdMarketValue: 20000}, State: intent.StateRevoked, CreatedAt: time.Now().Add(-5 * time.Minute)},
371371
{IntentId: "t6", IntentType: intent.ReceivePaymentsPublicly, InitiatorOwnerAccount: "o1", ReceivePaymentsPubliclyMetadata: &intent.ReceivePaymentsPubliclyMetadata{Source: "a6", Quantity: 100000, UsdMarketValue: 200000, OriginalExchangeCurrency: currency.USD, OriginalExchangeRate: 2, OriginalNativeAmount: 200000}, State: intent.StateConfirmed, CreatedAt: time.Now()},
372372
{IntentId: "t7", IntentType: intent.ExternalDeposit, InitiatorOwnerAccount: "o1", ExternalDepositMetadata: &intent.ExternalDepositMetadata{DestinationTokenAccount: "a7", Quantity: 1000000, UsdMarketValue: 20000}, State: intent.StateConfirmed, CreatedAt: time.Now()},
373+
{IntentId: "t8", IntentType: intent.SendPublicPayment, InitiatorOwnerAccount: "o1", SendPublicPaymentMetadata: &intent.SendPublicPaymentMetadata{DestinationOwnerAccount: "o8", DestinationTokenAccount: "a8", Quantity: 10000000, ExchangeCurrency: currency.USD, ExchangeRate: 2, NativeAmount: 2000000, UsdMarketValue: 2000000, IsWithdrawal: true}, State: intent.StateConfirmed, CreatedAt: time.Now()},
373374
}
374375

375376
for _, record := range records {

0 commit comments

Comments
 (0)